Python 第三方模块 图像处理 Pillow模块

一.简介
1.简介:

PIL(Python Imaging Library)模块是Python中的1个图像处理模块,但只支持Python2.Pillow则是PIL的1个派生分支,同时支持python2/3

2.安装:

pip install pillow

3.导入:

import PIL

二.相关概念

参见:https://blog.csdn.net/gqixf/article/details/84324419

三.Image子模块
1.简介
(1)简介:

这是PIL中最重要的子模块.其中定义了Image类

(2)导入:

#需要单独导入(2种方法均可):
import PIL.Image
from PIL import Image

2.Image类

Image类是PIL模块中用于代表图像的类.每个Image object都代表1个图像

#可转换为ndarray:
>>> np.array(im)
array([[124, 102, 174, ..., 102, 174, 255],
       [124, 102, 174, ..., 102, 174, 255],
       [124, 102, 174, ..., 102, 174, 255],
       ...,
       [124, 102, 174, ..., 102, 174, 255],
       [124, 102, 174, ..., 102, 174, 255],
       [124, 102, 174, ..., 102, 174, 255]], dtype=uint8)
>>> np.array(im1)
array([[[124, 102, 174],
        [124, 102, 174],
        [124, 102, 174],
        ...,
        [124, 102, 174],
        [124, 102, 174],
        [124, 102, 174]]], dtype=uint8)

(1)创建Image对象:

通常使用工厂函数创建而非直接实例化Image类

######################################################################################################################

打开图像:[<im>=]PIL.Image.open("<fp>"[,mode="r"])
  #但并不立即读取图像数据,而是在开始处理图像数据时才读取
  #参数说明:
  	fp:指定要打开的图像;str/file object/pathlib.Path object
  	mode:指定打开模式;必须为"r"
  	im:返回打开的图像

#实例:
>>> im=PIL.Image.open("E:\Pictures\\111.jfif")
>>> im
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=1920x1080 at 0x234240ADA30>

######################################################################################################################

创建图像:[<im>=]PIL.Image.new(<mode>,<size>[,color=0])
  #参数说明:
  	mode:指定图像的模式
  	size:指定图像尺寸;(<width>,<height>)
  	color:指定图像的颜色;为num(0/-255)/tuple/str(颜色的英文名)

#实例:
>>> nim=PIL.Image.new("P",(99,99),255)
>>> PIL.Image.new("P",(99,99),color="red")
<PIL.Image.Image image mode=P size=99x99 at 0x23423D85340>

######################################################################################################################

插值得到新图像:[<out>=]PIL.Image.blend(<im1>,<im2>,<alpha>)
  #合成公式为:<out>=<im1>*(1.0-<alpha>)+<im2>*<alpha>
插值得到新图像:[<out>=]PIL.Image.composite(<im1>,<im2>,<mask>)
  #参数说明:
  	im1,im2:指定用于插值的图像(要求二者的尺寸/模式相同)
  	alpha:指定透明度;为num
  	  #为1,则返回<im2>的拷贝;为0,则返回<im1>的拷贝
	mask:用于指定透明度的图像(模式为"1"/"L"/"RGBA",尺寸与<im1>/<im2>相同)
  	out:返回新图像

#实例:
>>> a=np.random.randint(0,255,(100,100,3))
>>> PIL.Image.fromarray(a,"RGB").show()

######################################################################################################################

通过数组创建图像:PIL.Image.fromarray(<obj>[,mode=None])
  #参数说明:
  	obj:指定像素数据;object with attribute '__array_interface__'(主要是array)

#实例:
>>> a=np.random.randint(0,255,(100,100))
>>> a
array([[ 29, 183, 120, ...,  91,  81,  56],
       [111,  35,  45, ..., 108,  24,  31],
       [ 92, 112, 254, ...,  56,   3, 107],
       ...,
       [208, 145, 216, ...,   8,   0,  88],
       [178, 185, 165, ..., 133,  69,   7],
       [ 57, 189, 196, ..., 167, 136, 240]])
>>> PIL.Image.fromarray(a).show()

######################################################################################################################

通过缓存创建图像:PIL.Image.frombuffer(<mode>,<size>,<data>[,*args,decoder_name="raw"])

######################################################################################################################

通过字节数据创建图像:PIL.Image.frombytes(<mode>,<size>,<data>[,*args,decoder_name="raw"])

######################################################################################################################

PIL.Image.fromstring()已被移除

######################################################################################################################

将单通道图像合并为多通道图像:PIL.Image.merge(<mode>,<bands>)
  #参数说明:
  	bands:指定要合并的单通道图像(要求尺寸相同);为sequence

#实例:
>>> im1=PIL.Image.fromarray(np.random.randint(0,255,(100,100,3)),"RGB")
>>> im2=PIL.Image.fromarray(np.random.randint(0,255,(100,100,3)),"RGB")
>>> im3=PIL.Image.fromarray(np.random.randint(0,255,(100,100,3)),"RGB")
>>> r1,g1,b1=im1.split()
>>> r2,g2,b2=im2.split()
>>> r3,g3,b3=im3.split()
>>> im=PIL.Image.merge("RGB",[r1,g2,b3])

(2)其他类方法:

处理图像的每个像素:PIL.Image.eval(<image>,<func>)
  #如果图像包含多个通道,也会单独处理每个通道
  #参数说明:
  	image:指定要处理的图像
  	func:指定用于处理的函数;为function(接收1int类型的参数)

#实例:
>>> def f(i):
...     return i**2
...
>>> PIL.Image.eval(im,f).show()

(3)对象属性:

图像的模式:<im>.mode

#实例:
>>> im.mode
'RGB'
>>> nim.mode
'P'

######################################################################################################################

图像尺寸:<im>.size
  #单位为像素

#实例:
>>> im.size
(1920, 1080)

######################################################################################################################

辅助信息:<im>.info

#实例:
>>> im.info
{'jfif': 257, 'jfif_version': (1, 1), 'dpi': (72, 72), 'jfif_unit': 1, 'jfif_density': (72, 72)}

######################################################################################################################

图像格式.<im>.format
  #由PIL创建的图像的格式为None

#属性:
>>> im.format
'JPEG'
>>> rim.format

######################################################################################################################

图像的调色板:[<p>=]<im>.palette
  #参数说明:
  	p:返回调色板;如图像模式为"P",为PIL.ImagePalette.ImagePalette;否则,None

#实例:
>>> im.palette
>>> nim.palette
<PIL.ImagePalette.ImagePalette object at 0x00000234243BFB80>

(4)对象方法:

获取图像的所有通道:<im>.getbands()

#实例:
>>> im.getbands()
('R', 'G', 'B')

######################################################################################################################

修改图像的形状:[<rim>=]<im>.resize(<size>[,resample=PIL.Image.BICUBIC,box=None,reducing_gap=None])
  #参数说明:size同 (1) 部分的PIL.Image.new()
  	resample:指定滤波器;可为PIL.Image.NEAREST/PIL.Image.BOX/PIL.Image.BILINEAR/PIL.Image.HAMMING/PIL.Image.BICUBIC/PIL.Image.LANCZOS
  	rim:返回修改后的图像

#实例:
>>> rim=im.resize((16,9))

######################################################################################################################

保存图像:<im>.save(<fp>[,format=None,**params])
  #参数说明:
  	fp:指定要保存到的文件;str/file object/pathlib.Path object
  	format:保存的格式;None表示同扩展名

#实例:
>>> im1.save("E:\\123.jpeg")

######################################################################################################################

显示图像:<im>.show()

######################################################################################################################

转换图像的模式:<im>.convert([mode=None,matrix=None,dither=None,palette=WEB,colors=256])

######################################################################################################################

复制图像:<im>.copy()
复制图像的指定区域:<im>.crop([box=None])
  #注意:对源图像的改变可能也可能不体现在复制下来的图像中
  #参数说明:
  	box:指定要复制的区域;(<left>,<upper>,<right>,<lower>),None表示全部
  	  #4个元素分别表示左/上/右/下界处像素的坐标

######################################################################################################################

配置图像加载器以最大程度契合给定的模式和尺寸:<im>.draft(<mode>,<size>)

######################################################################################################################

使用滤波器处理:<im>.filter(<filter>)
  #参数说明:
	filter:指定滤波器

######################################################################################################################

加载图像数据到当前图像:<im>.frombytes(<data>[,*args,decoder_name="raw"])
  #<im>.fromstring()已被移除
  #参数说明:同 (1) b部分的PIL.Image.frombytes()

######################################################################################################################

返回图像的所有通道:<im>.getbands()

######################################################################################################################

返回图像的非零区域的包围盒:<im>.getbbox()
  #即上下左右边界处像素的坐标;若图像为空,返回None

######################################################################################################################

返回图像包含的颜色:[<colors>=]<im>.getcolors([maxcolors=256])
  #参数说明:
    maxcolors:指定最大颜色数(超过则返回None)
    colors:返回图像中的颜色;tuple list
      #格式为:[(<count>,<color>)...],count表示该颜色出现的次数,color表示颜色

#实例:
>>> im=PIL.Image.fromarray(np.array([[1,2,3,4],[4,3,2,1],[1,2,3,4]]))
>>> im.getcolors()
[(3, 4), (3, 3), (3, 2), (3, 1)]

######################################################################################################################

返回图像内容:<im>.getdata([band=None])
  #注意:返回的内容是按1维排列的
  #参数说明:
    band:指定返回哪些通道的内容;默认为所有

#实例:接上
>>> list(im.getdata())
[1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4]

######################################################################################################################

返回图像的最大和最小值:<im>.getextrema()

######################################################################################################################

返回指定位置处的像素值:<im>.getpixel(<xy>)
  #参数说明:
  	xy:指定位置;(<x>,<y>)
  	  #注意:索引从0开始

######################################################################################################################

加载图像:<im>.load()
  #通常无需用户手动调用

######################################################################################################################

粘贴图像到当前图像:<im>.paste(<im>[,box=None,mask=None])
  #参数说明:
	im:指定要粘贴的图像:
	box:指定粘贴到的位置

四.图像处理
1.步骤:

①打开图像
②转换为数组的形式
③进行处理
④保存处理后的图像

2.实例
(1)彩图转灰度图并反转:

>>> im=PIL.Image.open("E:\\Pictures\\aaa.jfif")#原图见下图1
>>> iml=im.convert("L")
>>> a=np.array(iml)
>>> b=255-a
>>> nim=PIL.Image.fromarray(b)
>>> nim.save("E:\\Pictures\\new.png")#新图见下图2

在这里插入图片描述
在这里插入图片描述
(2)图像的手绘效果:

>>> a=np.asarray(PIL.Image.open("E:\\Pictures\\aaa.jfif").convert("L")).astype("float")#原图见上图2
>>> depth=10#范围为[0,100]
>>> grad_x,grad_y=np.gradient(a)#取图像灰度的横/纵梯度值
>>> grad_x=grad_x*depth/100
>>> grad_y=grad_y*depth/100
>>> A=np.sqrt(grad_x**2+grad_y**2+1.)
>>> uni_x=grad_x/A
>>> uni_y=grad_y/A
>>> uni_z=1./A
>>> vec_el=np.pi/2.2#光源的俯视角度(弧度值)
>>> vec_az=np.pi/4.#光源的方位角度(弧度值)
>>> dx=np.cos(vec_el)*np.cos(vec_az)#光源对x轴的影响
>>> dy=np.cos(vec_el)*np.sin(vec_az)#光源对y轴的影响
>>> dz=np.sin(vec_el)#光源对z轴的影响
>>> b=255*(dx*uni_x+dy*uni_y+dz*uni_z)#光源归一化
>>> b=b.clip(0,255)#裁剪到[0,255]的范围内
>>> im=PIL.Image.fromarray(b)
>>> im.convert("RGB").save("E:\\Pictures\\new.png")#新图见下图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值