python_Opencv_图像的基础操作
目标
- 获取像素值并修改
- 获取图像的属性(信息)
- 图像的ROI()
- 图像通道的拆分及合并
- 为图像扩充边缘
几乎所有以上的操作,与Numpy 的关系都比与OpenCV 的关系更加紧密,因此熟练Numpy 可以帮助我们写出性能更好的代码。
获取像素值并修改
代码:
1 # 2 3 import cv2 4 import numpy as np 5 6 # 首先打开一张图片 7 img=cv2.imread('Koala.jpg') 8 9 # 在图片中获取一个像素点 10 px=img[100,100] 11 # 打印出像素值,BGR图片显示【B,G,R】值 12 print px 13 14 # 第三个参数0,1,2分别代表B,G,R 15 blue=img[100,100,0] 16 green=img[100,100,1] 17 red=img[100,100,2] 18 19 print blue 20 print green 21 print red 22 23 # 打印结果: 24 # [143 152 161] 25 # 143 26 # 152 27 # 161 28 29 # 类似的方式可以用于修改像素值 30 img[100,100]=[255,255,255] 31 print img[100,100] 32 # 打印结果:[255 255 255] 33 34 # 效率更快的方法,numpy中这些方法经过快速矩阵运算的优化 35 # 显示[10,10]位置的R值 36 print img.item(10,10,2) 37 # 修改它并显示 38 img.itemset((10,10,2),200) 39 print img.item(10,10,2) 40 #打印结果: 41 # 108 42 # 200
注意:
Numpy 是经过优化了的进行快速矩阵运算的软件包。所以我们不推荐逐个获取像素值并修改,这样会很慢,能有矩阵运算就不要用循环。
对于获取每一个像素值,也许使用Numpy 的array.item() 和array.itemset() 会更好。但是返回值是标量。如果你想获得所有B,G,R 的值,
你需要使用array.item() 分割他们。
获取图像的属性(信息)
- 图像的属性包括:行,列,通道,图像数据类型,像素数目等。
- img.shape 可以获取图像的形状。
- 他的返回值是一个包含行数,列数,通道数的元组。
- img.size返回像素点总数
- img.dtype 返回的是图像的数据类型.
看代码:
1 import cv2 2 import numpy as np 3 4 # 首先打开一张图片 5 img=cv2.imread('Koala.jpg') 6 7 #图像形状 8 print img.shape 9 ## (384L, 512L, 3L) 10 11 # 像素的数量 12 print img.size 13 ## 589824 14 15 # 图像的数据类型 16 print img.dtype 17 ## uint8
图像ROI
- 有时候我们需要对一幅图像的特定区域进行操作。
- 例如我们要检测一副图像中眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。
- 这样会提高程序的准确性和性能。ROI 也是使用Numpy 索引来获得的。
参照PDF中的一个例子,直接拿过来:
1 import cv2 2 import numpy as np 3 img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg') 4 5 ball=img[280:340,330:390] 6 img[273:333,100:160]=ball 7 8 cv2.imshow('image',img) 9 cv2.waitKey(0) 10 cv2.destroyAllWindows()
结果:图中的球的部分整体复制一块到其他位置
图像通道的拆分及合并
代码
1 # -*- coding: utf-8 -*- 2 3 # 有时需要对BGR 三个通道分别进行操作。 4 # 就需要把BGR 拆分成单个通道。 5 # 有时也需要把独立通道的图片合并成一个BGR 图像 6 import cv2 7 import numpy as np 8 9 img=cv2.imread('Koala.jpg') # 载入图片 10 11 cv2.imshow("img0",img) # 未处理的图片 12 b,g,r=cv2.split(img) # 拆分通道 13 14 cv2.imshow("Red",r) # R、G、B单通道图 15 cv2.imshow("Green",g) 16 cv2.imshow("Blue",b) 17 18 img=cv2.merge([b,g,r]) # 合并图像 19 20 cv2.imshow("img",img) # 合并3个通道的结果 21 cv2.waitKey(0) 22 cv2.destroyAllWindows()
1 # -*- coding: utf-8 -*- 2 3 # 之前的方法是用split切分,比较耗时,一般可以用numpy索引,如下 4 import cv2 5 import numpy as np 6 7 img=cv2.imread('Koala.jpg') 8 b=img[:,:,0] # g=img[:,:,1] ,r=img[:,:,2] 9 10 cv2.imshow("blue",b) 11 12 img[:,:,2]=0 #表示r通道置0 13 14 cv2.imshow("r0",img) 15 16 cv2.waitKey(0) 17 cv2.destroyAllWindows()
为图像扩充边缘
1 # -*- coding: utf-8 -*- 2 3 #为图像扩边(填充),有多种边框形式 4 5 import cv2 6 import numpy as np 7 from matplotlib import pyplot as plt 8 9 BLUE=[255,0,0] # 蓝色 10 11 img1=cv2.imread('Koala.jpg') 12 13 # copyMakeBorder函数的参数:src源,top, bottom, left, right 对应边界的像素数目, 14 # 最后一个是borderType :边界类型 15 replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE) 16 reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT) 17 reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101) 18 wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP) 19 constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE) 20 21 22 plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL') #231代表2行3列第一个 23 plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE') #以此类推 24 plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT') 25 plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101') 26 plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP') 27 plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT') 28 29 plt.show()
代码中都有一些注释,这些都是我自己跟着PDF敲的一些例子程序.