Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm
像素是图像构成的基本单位,像素处理是图像处理的基本操作,可以通过位置索引的形式对图像内的元素进行访问、处理。
1.二值图像及灰度图像
需要说明的是,在OpenCV中,最小的数据类型是无符号的8位数。因此,在OpenCV中实际上并没有二值图像这种数据类型,二值图像经常是通过处理得到的,然后使用0表示黑色,使用255表示白色,可以将二值图像理解为特殊的灰度图像。
eg1:读取一个灰度图像,并对其像素进行访问、修改。
代码如下:
import cv2
img=cv2.imread("lena.bmp",0)
cv2.imshow("before",img)
for i in range(10,100):
for j in range(80,100):
img[i,j]=255
cv2.imshow("after",img)
cv2.waitKey()
cv2.destroyAllWindows()
在本例中,使用了一个嵌套循环语句,将图像img中“第10行到99行”与“第80列到99列”交叉区域内的像素值设置为255。从图像img上来看,该交叉区域被设置为白色。
运行结果如下:
左图是读取的原始图像,右图是经过修改后的图像。
2.彩色图像
RGB模式的彩色图像在读入OpenCV内进行处理时,会按照行方向依次读取该RGB图像的B通道、G通道、R通道的像素点,并将像素点以行为单位存储在ndarray的列中。例如,有一幅大小为R行×C列的原始RGB图像,其在OpenCV内以BGR模式的三维数组形式存储。
eg2:使用Numpy生成三维数组,用来观察三个通道值的变化情况。
代码如下:
import numpy as np
import cv2
img=np.zeros((300,300,3),dtype=np.uint8)
img[:,0:100,0]=255
img[:,100:200,1]=255
img[:,200:300,2]=255
print("img=\n",img)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
结果如下:
eg3:读取一幅彩色图像,并对其像素进行访问、修改。
代码如下:
import cv2
img=cv2.imread("lenacolor.png")
cv2.imshow("before",img)
print("访问img[0,0]=",img[0,0])
print("访问img[0,0,0]=",img[0,0,0])
print("访问img[0,0,1]=",img[0,0,1])
print("访问img[0,0,2]=",img[0,0,2])
print("访问img[50,0]=",img[50,0])
print("访问img[100,0]=",img[100,0])
#区域1
for i in range(0,50):
for j in range(0,100):
for k in range(0,3):
img[i,j,k]=255 #白色
#区域2
for i in range(50,100):
for j in range(0,100):
img[i,j]=[128,128,128] #灰色
#区域3
for i in range(100,150):
for j in range(0,100):
img[i,j]=0 #黑色
cv2.imshow("after",img)
print("修改后img[0,0]=",img[0,0])
print("修改后img[0,0,0]=",img[0,0,0])
print("修改后img[0,0,1]=",img[0,0,1])
print("修改后img[0,0,2]=",img[0,0,2])
print("修改后img[50,0]=",img[50,0])
print("修改后img[100,0]=",img[100,0])
cv2.waitKey()
cv2.destroyAllWindows()
上述程序进行了如下操作。
● 第2行使用imread()函数读取当前目录下的一幅彩色RGB图像。
● 第4行的img[0,0]语句会访问img中第0行第0列位置上的B通道、G通道、R通道三个像素点。
● 第5~7行分别会访问img中第0行第0列位置上的B通道、G通道、R通道三个像素点。
● 第8行的img[50,0]语句会访问第50行第0列位置上的B通道、G通道、R通道三个像素点。
● 第9行的img[100,0]语句会访问第100行第0列位置上的B通道、G通道、R通道三个像素点。
● 第10~14行使用三个for语句的嵌套循环,对图像左上角区域(即“第0行到第49行”与“第0列到第99列”的行列交叉区域,我们称之为区域1)内的像素值进行设定。借助img[i, j, k]=255语句将该区域内的三个通道的像素值都设置为255,让该区域变为白色。
● 第15~18行使用两个for语句的嵌套循环,对图像左上角位于区域1正下方的区域(即“第50行到第99行”与“第0列到第99列”的行列交叉区域,我们称之为区域2)内的像素值进行设定。借助img[i, j]=[128,128,128]语句将该区域内的三个通道的像素值都设置为128,让该区域变为灰色。
● 第19~21行使用两个for语句的嵌套循环,对图像左上角位于区域2正下方的区域(即“第100行到第149行”与“第0列到第99列”的行列交叉区域,我们称之为区域3)内的像素值进行设定。借助img[i, j]=0语句将该区域内的三个通道的像素值都设置为0,让该区域变为黑色。
运行程序,结果如下图所示,其中图(before)是读取的原始图像,图(after)是经过修改后的图像。
同时,在控制台会输出如下内容:
访问img[0,0]= [125 137 226]
访问img[0,0,0]= 125
访问img[0,0,1]= 137
访问img[0,0,2]= 226
访问img[50,0]= [114 136 230]
访问img[100,0]= [ 75 55 155]
修改后img[0,0]= [255 255 255]
修改后img[0,0,0]= 255
修改后img[0,0,1]= 255
修改后img[0,0,2]= 255
修改后img[50,0]= [128 128 128]
修改后img[100,0]= [0 0 0]