·访问像素值并修改它们
·访问图片属性
·设置ROI
·分割和合并图片
基本上本节所有的操作都是和Numpy相关的而不是OpenCV
访问和修改像素值
让我们加载一张彩色图片:
>>>import cv2
>>>import numpy as np
>>>img = cv2.imread('messi5.jpg')
你可以通过行和列坐标访问一个像素值。对于BGR图片,它会返回一个蓝,绿,红值的数组。对于灰度图片,只会返回对应的深度。
>>>px = img[100,100]
>>>print px[157 166 200]
# accessing only blue pixel
>>>blue = img[100,100,0]
>>>print blue
157
你可以修改这个像素值:
>>>img[100,100] = [255,255,255]
>>>print img[100,100]
[255 255 255]
警告:
Numpy是一个优化的库,能够快速计算数组。所以如果一个个访问每个像素并修改它的值是很慢的,也不推荐
注意:
一般来说,都是选择数组的一片区域,比如头5行或者最后三列。对于某个像素点的访问,Numpy数组方法,array.item() 和array.itemset()更好。但是它总是返回标量。所以如果你想访问所有的B, G, R值,你需要分开调用array.item()
更好的访问和编辑方式:
# accessing RED value
>>>img.item(10,10,2)
59
# modifying RED value
>>>img.itemset((10,10,2), 100)
>>>img.item(10,10,2)
100
访问图片属性
图片属性包括行数,列数,通道数,图片数据类型,像素数等。
图片的形状可以通过img.shape获得,它会放回一个包含行数,列数的通道数的元组(如果图片是彩色的):
>>>print img.shape
(342, 548, 3)
注意:
如果图片是灰度的,返回的元组只包含行数和列数。所以检查是否加载的图片是灰度的还是彩色的可以通过这个来做
所有的像素数可以通过img.size来访问:
>>>print img.size
562248
图片数据类型可以通过img.dtype获得:
>>>print img.dtype
uint8
注意:
img.dtype在调试的时候很重要,因为大量OpenCV-Python代码里的错误都是有错误的数据类型导致的。
图片ROI
有时候,你会需要处理图片的特定区域。对于图片的眼部识别,首先对整个图片进行面部识别,找到脸以后,在脸的区域内找眼睛。这个方法能够提高准确度(因为眼睛总是在脸上的:D)性能上也好(因为我们找的区域更小)
ROI是通过Numpy的索引来获得的,这里我们选择球,然后把它复制到图片的另一个区域:
>>>ball = img[280:340,330:390]
>>>img[273:333,100:160] = ball
分割和合并图片
图片的B, G, R通道可以被分割成他们各自的片,各个通道可以被合并成BGR图片。
>>>b,g,r = cv2.split(img)
>>>img=cv2.merge((b,g,r))
或者
>>>b = img[:,:,0]
假设你想把所有的红色像素变成0,你不用这么分割,你可以简单的使用Numpy索引,这样更快
>>>img[:,:,2]=0
警告:
cv2.split()是一个成本很高的操作(执行时间),所以只在必要的时候使用。Numpy索引要更有效率,能用就用。
制作图片的边框
如果你想要在图片周围生成边框,类似于相框,你可以使用cv2.copyMakeBorder()函数。但是它还能用于卷积,0内边距等。这个函数有下面这些参数:
·src - 输入图片
·top, bottom, left, right - 各个方向的边框像素宽度
·borderType - 标志位,定义要加什么样的边框,可以是下列类型:
·cv2.BORDER_CONSTANT - 添加固定的彩色边。值需要在后面的参数提供。
·cv2.BORDER_REFLECT - 边框是镜像的,像这样:fedcba/abcdefgh/hgfedcb
·cv2.BORDER_REFLECT_101或cv2.BORDER_DEFAULT - 和上面一样,但是有点变化,像这样:gfedcb/abcdefgh/gfedcba
·cv2.BORDER_REPLICATE - 最后的元素是重复的,像这样:aaaaaa/abcdefgh/hhhhhhh
·cv2.BORDER_WRAP - 没法解释,看上去是这样: cdefgh/abcdefgh/abcdefg
·value - 如果边的类型是cv2.BORDER_CONSTANT 这个值就是边的颜色。
下面是个列子,展示了所有这些边框的类型:
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv2.imread('opencv_logo.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10, cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
END
网友评论