NumPy + PIL 处理图像

  • NumPy
  • PIL
    PIL(Python Image Library)库是一个具有强大图像处理能力的第三方库

图像=>数组

图像采用的色彩模式为RGB模式,即每个像素点由R(红色)、G(绿色)、B(蓝色)组成。我们人眼所能看到的颜色都是由这三种颜色变化叠加得到的。

  • R红色,取值范围,0~255
  • G绿色,取值范围,0~255
  • B蓝色,取值范围,0~255

图像是一个由像素组成的二维矩阵,每个元素是一个RGB值。

PIL安装

OSX: pip install pillow

图像处理

图像加载

turkey_orig.jpg

1
2
3
4
5
6
7
8
9
10
>>> from PIL import Image
>>> import numpy as np
>>> img = np.array(Image.open("turkey_orig.jpg"))
>>> img_l = np.array(Image.open("turkey_orig.jpg").convert('L'))
>>> print img.shape, img.dtype
(1184, 2104, 3) uint8
# img是一个三维数组每一个元素代表RGB的一个值
>>> print img_l.shape, img_l.shape
(1184, 2104) uint8
# img_l是一个二维数组每一个元素对应一个灰度值

图像变换

返选效果

1
md_img = [255,255,255] - img

turkey_modify_1.jpg

底片效果

1
md_img = 255 - img_l

turkey_modify_2.jpg

区间变换

1
md_img = (100.0/255.0)*img_l + 150

turkey_modify_3.jpg

平方变换

1
md_img = 255 * ((img_l/255.0)**2)

turkey_modify_4.jpg

手绘效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
img_l_float = img_l.astype("float")

# 深度值,范围为0~100
depth = 10

# 提取x和y方向的梯度值
grad = np.gradient(img_l_float)
grad_x, grad_y = grad

# 根据深度调整梯度值
grad_x = grad_x*depth/100
grad_y = grad_y*depth/100

# 此处计算的是什么?
A = np.sqrt(grad_x**2 + grad_y**2 + 1.0)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1.0/A

# 为什么要引入光源?
vec_el = np.pi/2.2
vec_az = np.pi/4.0
dx = np.cos(vec_el)*np.cos(vec_az)
dy = np.cos(vec_el)*np.sin(vec_az)
dz = np.sin(vec_el)

#dx, dy, dz = 1,1,1
md_img = 255*(dx*uni_x + dy*uni_y + dz*uni_z)
md_img = md_img.clip(0,255)

无光源效果:
turkey_modify_6.jpg

有光源效果:
turkey_modify_5.jpg

图像保存

1
2
save_img = Image.fromarray(md_img.astype('uint8'))
save_img.save("turkey_modify.jpg")

参考&鸣谢