最近在动手使用imagenet数据集,发现很多代码都是用opencv读取或者处理图片数据的,但是据说有些格式的rgb顺序不一样,多个库之间不太兼容,同时在windows下面安装opencv还挺麻烦的,有很多版本的问题,于是就想着使用老牌的pil画图库。
以下是转载内容。
利用python的Numpy及PIL第三方库实现图片的手绘效果。PIL第三方库是一个具有强大图像处理能力的第三方库。
数字图像数据可以用矩阵来表示,因此可以采用矩阵理论和矩阵算法对数字图像进行分析和处理。最典型的例子是灰度图像,如图1-2所示。灰度图像的像素数据就是一个矩阵,矩阵的行对应图像的高(单位为像素),矩阵的列对应图像的宽(单位为像素),矩阵的元素对应图像的像素,矩阵元素的值就是像素的灰度值。
由于数字图像可以表示为矩阵的形式,所以在计算机数字图像处理程序中,通常用二维数组来存放图像数据,参见图1-3。二维数组的行对应图像的高,二维数组的列对应图像的宽,二维数组的元素对应图像的像素,二维数组元素的值就是像素的灰度值。采用二维数组来存储数字图像,符合二维图像的行列特性,同时也便于程序的寻址操作,使得计算机图像编程十分方便。
根据上面的描述,我们对图像的矩阵描述有了一个初步认识。而在python中我们可以采用numpy库来创建矩阵。要实现图像的手绘效果其实只需简单的几步即可:
(1) 读取原图片
(2) 获取像素RGB值
(3) 修改像素RGB值
(4) 将修改后的像素值保存
具体的代码展示如下:from PIL import Imageimport numpy as np
a=np.asarray(Image.open(r"C:UsersZXLDesktop照片pic1163.jpg").convert('L')).astype("float")
depth=10. #预设深度为10,取值范围0-100
grad=np.gradient(a)
grad_x,grad_y=grad #提取x,y方向的梯度值
grad_x=grad_x*depth/100.
grad_y=grad_y*depth/100. #根据深度分别调整x,y方向的梯度值
A=np.sqrt(grad_x**2+grad_y**2+1.)#构造x,y轴梯度的三维归一化单位坐标系
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,y,z三个方向的影响程度
dy=np.cos(vec_el)*np.sin(vec_az)
dz=np.sin(vec_el)
b=255*(dx*uni_x+dy*uni_y+dz*uni_z) #梯度与光源结合,将梯度转换为灰度
b=b.clip(0,255)
im=Image.fromarray(b.astype("uint8"))
im.save(r"C:UsersZXLDesktop照片picture.jpg"效果图如下图所示: