图像的基本表示方法
二值图像
二值图像是指包含白色和黑色两种颜色的图像,
在计算机中,通过一个栅格状排列的数据集(矩阵)来表示和处理图像,其中“1”为白色,“0”为黑色。
灰度图像
通常,计算机会将灰度处理为256个等级,用数值区间【0,255】,其中255表示纯白色,0表示纯黑色,其余的数值表示从纯白色到纯黑之间不同级别的灰度。
彩色图像
彩色图像为由色彩空间来表示颜色的图像,色彩空间有红、绿和蓝,主波长、纯度和明度,色调、饱和度和亮点等等。
像素处理
像素是图像构成的基本单位,像素处理时图像处理的基本操作,可以通过位置索引的形式对图像内的元素进行访问、处理。
二值图像以及灰度图像
需要说明,在OpenCV中,最小的数据类型为uint8,因此,在OpenCV实际上没有二值图像这种数据类型,二值图像被处理为0表示黑色,255表示白色。
img = np.zeros((100,100),dtype=np.uint8)
print("img=\n",img)
cv2.imshow("one",img)
print("读取像素点img[0,3]=",img[0,3])
img[0,3]=255
print("修改后img=\n",img)
print("修改后像素点img[0,3]=",img[0,3])
cv2.imshow("two",img)
cv2.waitKey()
cv2.destroyAllWindows()
img = cv2.imread("./lena.jpg")
cv2.imshow("before",img)
for i in range(10,100):
for j in range(80,100):
img[i,j]=255
print(img[i,j])
cv2.imshow("after",img)
cv2.waitKey()
cv2.destroyAllWindows()
彩色图像
RGB模式的彩色图像在读入OpenCV内进行处理时,会按照行方向依次读取该RGB图像的B通道、G通道、R通道的像素点,并将像素点以行为单位存储在ndarray的列中。
blue = np.zeros((300,300,3),dtype=np.uint8)
blue[:,:,0]=255
print("blue=\b",blue)
cv2.imshow("blue",blue)
green = np.zeros((300,300,3),dtype=np.uint8)
green[:,:,1]=255
print("green=\b",green)
cv2.imshow("green",green)
red = np.zeros((300,300,3),dtype=np.uint8)
red[:,:,2]=255
print("red=\b",red)
cv2.imshow("red",red)
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()
img = np.zeros((2,4,3),dtype=np.uint8)
print("img=\n",img)
print("读取像素点img[0,3]=",img[0,3])
print("读取像素点img[1,2,2]=",img[1,2,2])
img[0,3]=255
img[0,0]=[66,77,88]
img[1,1,1]=3
img[1,2,2]=4
img[0,2,0]=5
print("修改后 img\n",img)
print("读取修改后像素点img[1,2,2]=",img[1,2,2])
cv2.waitKey()
cv2.destroyAllWindows()
img = cv2.imread("lena.jpg")
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])
#区域2
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()
使用numpy.array访问像素
numpy.array提供了item()和itemset()函数来访问和修改像素值。使用numpy.array提供的函数比直接使用索引要快得多。
二值图像以及灰度图像
函数item()能更加高效地访问图像的像素点,该函数的语法格式为:
item(行,列)
函数itemset()可以用来修改像素点,其的语法格式为:
itemset(索引值,新值)
img = np.random.randint(10,99,size=[5,5],dtype=np.uint8)
print("img=\n",img)
print("读取像素点img.item(3,2)=",img.item(3,2))
img.itemset((3,2),255)
print("修改后 img=\n",img)
print("修改后像素点 img.item(3,2)=",img.item(3,2))
img = cv2.imread("lena.jpg",0)
cv2.imshow("before1", img)
# 测试读取,修改单个像素值
print("读取像素点img.item(3,2)=",img.item(3,2))
img.itemset((3, 2), 255)
print("修改后像素点 img.item(3,2)=",img.item(3,2))
# 测试修改一个区域的像素值
cv2.imshow("before1", img)
for i in range(10, 100):
for j in range(80, 100):
img.itemset((i, j), 255)
cv2.imshow("after", img)
cv2.waitKey()
cv2.destroyAllWindows()
彩色图像
函数item()访问RGB模式图像的像素值时,该函数的语法格式为:
item(行,列,通道)
函数itemset()修改RGB模式图像的像素值时,其的语法格式为:
itemset(三元组索引值,新值)
img = np.random.randint(10, 99, size=[2, 4, 3], dtype=np.uint8)
print("img=\n", img)
print("读取像素点 img[1,2,0]=", img.item(1, 2, 0))
print("读取像素点 img[0,2,1]=", img.item(0, 2, 1))
print("读取像素点 img[1,0,2]=", img.item(1, 0, 2))
img.itemset((1, 2, 0), 255)
img.itemset((0, 2, 1), 255)
img.itemset((1, 0, 2), 255)
print("修改后 img=\n", img)
print("修改后像素点 img[1,2,0]=", img.item(1, 2, 0))
print("修改后像素点 img[0,2,1]=", img.item(0, 2, 1))
print("修改后像素点 img[1,0,2]=", img.item(1, 0, 2))
img = cv2.imread("lena.jpg")
cv2.imshow("before1", img)
print("读取像素点 img[0,0,0]=", img.item(0, 0, 0))
print("读取像素点 img[0,0,1]=", img.item(0, 0, 1))
print("读取像素点 img[0,0,2]=", img.item(0, 0, 2))
for i in range(0, 50):
for j in range(0, 100):
for k in range(0, 3):
img.itemset((i, j, k),255) #白色
cv2.imshow("after", img)
print("修改后像素点 img[0,0,0]=", img.item(0, 0, 0))
print("修改后像素点 img[0,0,1]=", img.item(0, 0, 1))
print("修改后像素点 img[0,0,2]=", img.item(0, 0, 2))
cv2.waitKey()
cv2.destroyAllWindows()
感兴趣区域(ROI)
在图像处理过程中,我们可能会对图像的某一个特定区域感兴趣,该区域被称为感兴趣区域(ROI)。
通道操作
在RGB图像中,图像是由R、G、B三个通道构成的。在OpenCV中,通道是按照B、G、R通道的顺序存储的。
通道拆分
通过索引拆分
通过索引的方式,可以直接将各个通道从图像内提取出来
img = cv2.imread("lena.jpg")
cv2.imshow("lena1",img)
b=img[:,:,0]
g=img[:,:,1]
r=img[:,:,2]
cv2.imshow("b",b)
cv2.imshow("g",g)
cv2.imshow("r",r)
img[:,:,0]=0
img[:,:,1]=0
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
通过函数拆分
函数cv2.split()能够拆分图像的通道
img = cv2.imread("lena.jpg")
b,g,r=cv2.split(img)
cv2.imshow("B1",b)
cv2.imshow("G1",g)
cv2.imshow("R1",r)
b=cv2.split(img)[0]
g=cv2.split(img)[1]
r=cv2.split(img)[2]
cv2.imshow("B2",b)
cv2.imshow("G2",g)
cv2.imshow("R2",r)
cv2.waitKey()
cv2.destroyAllWindows()
通道合并
通道合并通过拆分的逆过程,通过合并通道可以将三个通道的灰度图像构成一幅彩色图像。函数cv2.merge()可以实现图像通道的合并。
img = cv2.imread("lena.jpg")
b,g,r=cv2.split(img)
bgr=cv2.merge([b,g,r])
rgb=cv2.merge([r,g,b])
cv2.imshow("img",img)
cv2.imshow("bgr",bgr)
cv2.imshow("rgb",rgb)
rgb = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imshow("rgb",rgb)
cv2.waitKey()
cv2.destroyAllWindows()
获取图像属性
在图像处理过程中,经常需要获取图像的属性。
shape:如果是彩色图像,则返回包含行数、列数、通道数的数值;如果是二值图像或者灰度图像,则仅返回行数和列数。通过盖属性的返回值是否包含通道数,可以判断一幅图像是灰度图像(或者是二值图像)还是彩色图像。
size:返回图像的像素数目,其值为”行列通道数“,灰度图像或者二值图像的通道数为1.
dtpye:返回图像的数据类型
imgColor = cv2.imread("lena.jpg")
imgGray = cv2.imread("lena.jpg", 0)
print("图像imgGray属性:")
print("imgGray.shape=",imgGray.shape)
print("imgGray.size==",imgGray.size)
print("imgGray.dtype=",imgGray.dtype)
print("图像imgColor属性:")
print("imgColor.shape=",imgColor.shape)
print("imgColor.size==",imgColor.size)
print("imgColor.dtype=",imgColor.dtype)