Python/Image

维基教科书,自由的教学读本
跳到导航 跳到搜索

在Python 2使用PIL包,在Python 3使用pillow包。后者是前者的衍生版本。采用相同的包名导入:

from PIL import Image

Image类[编辑]

  • im=Image.open(filename,mode)(打开一张图像)
  • im.show()
  • im.size
  • im.format #JPEG,PNG等格式
  • im.mode #RGB,HSV,L,CMYK
  • im.save(filename,format)(保存指定格式的图像)
  • im.thumbnail(size,resample)(创建缩略图)
  • im.crop( (left,top,right,down) )
  • im.transpose(method)(图像翻转或者旋转)
  • img.rotate(45)#逆时针旋转45度
  • im.paste(anotherImg,box,mask)(将一个图像粘贴到另一个图像)
  • r,g,b = im.split() 颜色通道分离
  • im_merge = Image.merge("RGB",[b,r,g]) 颜色通道合并
  • im.resize(size,resample,box) size是转换之后的大小,resample是重新采样使用的方法,仍然有Image.BICUBIC,PIL.Image.LANCZOS,PIL.Image.BILINEAR,PIL.Image.NEAREST这四种采样方法,默认是PIL.Image.NEAREST,box是指定的要resize的图像区域
  • im.convert(mode,matrix,dither,palette,colors) 可以改变图像的mode,一般是在'RGB'(真彩图)、'L'(灰度图)、'CMYK'(压缩图)之间转换
  • im.filter(filter) filter是过滤器函数,在PIL.ImageFilter函数中定义了大量内置的filter函数,比如BLUR(模糊操作),GaussianBlur(高斯模糊),MedianFilter(中值过滤器),FIND_EDGES(查找边)等
  • im.point(lut,mode)(对图像像素操作)lut是对单个像素点操作的函数。 mode是返回的图像的模式,默认是和原来图像的mode是一样

mode:

  • · 1 (1-bit pixels, black and white, stored with one pixel per byte)
  • · L (8-bit pixels, black and white)
  • · P (8-bit pixels, mapped to any other mode using a colour palette)
  • · RGB (3x8-bit pixels, true colour)
  • · RGBA (4x8-bit pixels, true colour with transparency mask)
  • · CMYK (4x8-bit pixels, colour separation)
  • · YCbCr (3x8-bit pixels, colour video format)
  • · I (32-bit signed integer pixels)
  • · F (32-bit floating point pixels)

ImageEnhance类[编辑]

用于图像增强,比如增加亮度(Brightness),增加对比度(Contrast)等。

from PIL import ImageEnhance
brightness = ImageEnhanBce.Brightness(im)
im_brightness = brightness.enhance(1.5)
im_brightness.show()
im_contrast = ImageEnhance.Contrast(im)
im_contrast.enhance(1.5) 
im_contrast.enhance(1.5).show()

ImageSequence[编辑]

下面的代码可以遍历gif图像中的所有帧,并分别保存为图像

>>> from PIL import ImageSequence
>>> from PIL import Image 
>>> gif = Image.open("pipixia.gif")
>>> for i,frame in enumerate(ImageSequence.Iterator(gif),1):
...     if frame.mode == 'JPEG':
...         frame.save("%d.jpg" %i)
...     else:
...         frame.save("%d.png" % i)

除了上面使用迭代器的方式以外,还可以一帧一帧读取gif,比如下面的代码:

>>> index = 0
>>> while 1:
...     try:
...         gif.seek(index)
...         gif.save("%d.%s" %(index,'jpg' if gif.mode == 'JPEG' else 'png'))
...         index += 1
...     except EOFError:
...         print("Reach the end of gif sequence!")
...         break

上面的代码在读取到gif的最后一帧之后,会throw 一个 EOFError,所以我们只要捕获这个异常就可以了。

添加文字水印[编辑]

from PIL import Image, ImageDraw,ImageFont
im = Image.open("d:/pic/lena.jpg").convert('RGBA')
txt=Image.new('RGBA', im.size, (0,0,0,0))
fnt=ImageFont.truetype("c:/Windows/fonts/Tahoma.ttf", 20)
d=ImageDraw.Draw(txt)
d.text((txt.size[0]-80,txt.size[1]-30), "cnBlogs",font=fnt, fill=(255,255,255,255))
out=Image.alpha_composite(im, txt)
out.show()

#添加小图片水印
from PIL import Image
im = Image.open("d:/pic/lena.jpg")
mark=Image.open("d:/logo_small.gif")
layer=Image.new('RGBA', im.size, (0,0,0,0))
layer.paste(mark, (im.size[0]-150,im.size[1]-60))
out=Image.composite(layer,im,layer)
out.show()

PIL Image 图像互转 numpy 数组[编辑]

im_array = np.array(im)
# 也可以用 np.asarray(im) 区别是 np.array() 是深拷贝,np.asarray() 是浅拷贝

#numpy 查看图片信息,可用如下的方法
print img.shape  
print img.dtype 

#将 numpy 数组转换为 PIL 图片
#这里采用 matplotlib.image 读入图片数组,注意这里读入的数组是 float32 型的,范围是 0-1,而 PIL.Image 数据是 uinit8 型的,范围是0-255,所以要进行转换:
import matplotlib.image as mpimg
from PIL import Image
lena = mpimg.imread('lena.png') # 这里读入的数据是 float32 型的,范围是0-1
im = Image.fromarray(np.uinit8(lena*255))
im.show()

#PIL image 查看图片信息,可用如下的方法
print type(img)
print img.size  #图片的尺寸
print img.mode  #图片的模式
print img.format  #图片的格式
print(img.getpixel((0,0))[0])#得到像素:
#img读出来的图片获得某点像素用getpixel((w,h))可以直接返回这个点三个通道的像素值

读取指定文件夹下的所有图像[编辑]

'''
Load the image files form the folder
input:
    imgDir: the direction of the folder
    imgName:the name of the folder
output:
    data:the data of the dataset
    label:the label of the datset
'''
def load_Img(imgDir,imgFoldName):
    imgs = os.listdir(imgDir+imgFoldName)
    imgNum = len(imgs)
    data = np.empty((imgNum,1,12,12),dtype="float32")
    label = np.empty((imgNum,),dtype="uint8")
    for i in range (imgNum):
        img = Image.open(imgDir+imgFoldName+"/"+imgs[i])
        arr = np.asarray(img,dtype="float32")
        data[i,:,:,:] = arr
        label[i] = int(imgs[i].split('.')[0])
    return data,label

图像打印[编辑]

Python映像库包括用于在Postscript打印机上打印图像、文本和图形的函数

from PIL import Image
from PIL import PSDraw

im = Image.open("hopper.ppm")
title = "hopper"
box = (1*72, 2*72, 7*72, 10*72) # in points

ps = PSDraw.PSDraw() # default is sys.stdout
ps.begin_document(title)

# draw the image (75 dpi)
ps.image(box, im, 75)
ps.rectangle(box)

# draw title
ps.setfont("HelveticaNarrow-Bold", 36)
ps.text((3*72, 4*72), title)

ps.end_document()