图像像素的访问、通道的合并与分离
(一)像素访问
在第一篇博客中,向大家介绍了,所谓的图像在计算机看来就是一个矩阵,对于RGB图像矩阵一共有三层,分别代表着RGB通道,矩阵中每一个数的大小代表着不同通道的亮度,范围在0~255之间。
访问图像的像素,就如同对矩阵元素的访问,很好理解。
print(img[0][0][0])
输出为:
34
也可以对所读取的图像矩阵的像素进行赋值
for i in range(400):for j in range(400):for k in range(3):img[i][j][k] = 255
显示图像为:
可以看到上图左上角形成了400x400像素的白色区域。
利用这个图像矩阵的特点,我们还可以做一些有趣的事情。比如说,椒盐现象。
我们需要先写一个椒盐函数,将我们想要的像素随机的分布在图像上。
def salt(img, numbers):for x in range(numbers):i = np.random.randint(img.shape[0])j = np.random.randint(img.shape[1])for k in range(3):img[i][j][k] = 255return img
嘿嘿,先来上1000个点!
img = salt(img, 1000)
图像显示为:
(二)通道分离
对于RGB图像,拥有RGB三原色通道,从矩阵的角度来讲,可以理解为三层矩阵,也就是三维的矩阵,每一层代表着一个通道。将图片进行通道分离可以使用OpenCV里的split函数,也可以通过numpy库对图像矩阵进行直接操作。图像展示的是不同通道的256级灰度图。
b, g, r = cv2.split(img)cv2.namedWindow('Blue')
cv2.imshow('Blue', b)
cv2.waitKey(0)cv2.namedWindow('Green')
cv2.imshow('Green', g)
cv2.waitKey(0)cv2.namedWindow('Red')
cv2.imshow('Red', r)
cv2.waitKey(0)
如果单独保留一个通道,并且令其它通道的图像矩阵的值全为零,将会变得更加好看,特意找了一个小的图片,避免篇幅过长。
img = cv2.imread('tongren.jpg')
b, g, r = cv2.split(img)pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 0] = b
cv2.namedWindow('Blue')
cv2.imshow('Blue', pic)
cv2.waitKey(0)pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 1] = g
cv2.namedWindow('Green')
cv2.imshow('Green', pic)
cv2.waitKey(0)pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 2] = r
cv2.namedWindow('Red')
cv2.imshow('Red', pic)
cv2.waitKey(0)cv2.destroyAllWindows()
也可以任选两个通道进行拼接。
pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 0] = b
pic[:, :, 1] = g
cv2.namedWindow('Blue-Green')
cv2.imshow('Blue-Green', pic)
cv2.waitKey(0)pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 0] = b
pic[:, :, 2] = r
cv2.namedWindow('Blue-Red')
cv2.imshow('Blue-Red', pic)
cv2.waitKey(0)pic = np.zeros(np.shape(img), np.uint8)
pic[:, :, 1] = g
pic[:, :, 2] = r
cv2.namedWindow('Green-Red')
cv2.imshow('Green-Red', pic)
cv2.waitKey(0)cv2.destroyAllWindows()
(三)通道合并
通道合并经常用的有两种方法
第一个是:OpenCV中自带的函数megre
megre = cv2.merge([b, g, r])
第二个是:numpy模块中的dstack,深度拼接函数
dstack = np.dstack([b, g, r])
但这两种拼接方式是不一样的,这一点一定要注意。pandas中也有对矩阵的拼接操作也可实现np.dstack()相同的效果,这里就不介绍了。