1. 图像 ROI
有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。这样会提高程序的准确性和性能。
图像的 ROI (region of interest) 是指图像中感兴趣区域、在 OpenCV 中图像设置图像 ROI 区域,实现只对 ROI 区域操作。例如,下面这个例子,我们把原始图片中下面的花拷贝到第二幅图片中。
import cv2
image_name = "img/003.jpg"
img = cv2.imread(image_name)
cv2.imshow("origin", img)
target = img[70:150, 30:110] # 70:150 表示 h 的范围, 30:110 表示 w 的范围
img[90:170, 110:190] = target
cv2.imshow("dst", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 拆分及合并图像通道
OpenCV 中默认 imread 函数加载图像文件,加载进来的是三通道彩色图像,色彩空间是 RGB 色彩空间、通道顺序是 BGR(蓝色、绿色、红色)。有时我们需要对 BGR 三个通道分别进行操作。这时你就需要把 BGR 拆分成单个通道。有时你需要把独立通道的图片合并成一个 BGR 图像。使用到的 API 函数如下:
- split 通道分类
- merge 通道合并
import cv2
import numpy as np
image_name = "img/003.jpg"
img = cv2.imread(image_name)
print "img is {}".format(img)
cv2.imshow("origin", img)
mv = cv2.split(img)
# print "mv is {}".format(mv)
mv[0][:, :] = 255
dst1 = cv2.merge(mv)
cv2.imshow("dst1", dst1)
mv = cv2.split(img)
mv[1][:, :] = 0
dst2 = cv2.merge(mv)
cv2.imshow("dst2", dst2)
mv = cv2.split(img)
mv[2][:, :] = 0
dst3 = cv2.merge(mv)
cv2.imshow("dst3", dst3)
dst4 = np.zeros(img.shape, img.dtype)
cv2.mixChannels(img, dst4, [2, 0])
cv2.imshow("dst4", dst4)
cv2.waitKey(0)
cv2.destroyAllWindows()
mv 的打印结果如下:
mv is
[
array([[131, 107, 82, ..., 67, 67, 66],
[130, 109, 88, ..., 66, 66, 65],
[118, 104, 90, ..., 67, 66, 65],
...,
[ 6, 8, 9, ..., 44, 45, 46],
[ 4, 7, 10, ..., 41, 42, 44],
[ 0, 5, 8, ..., 39, 40, 41]], dtype=uint8),
array([[190, 167, 140, ..., 125, 125, 124],
[187, 167, 144, ..., 124, 124, 123],
[170, 156, 141, ..., 125, 124, 123],
...,
[ 73, 75, 73, ..., 58, 59, 60],
[ 68, 71, 71, ..., 55, 56, 58],
[ 63, 69, 69, ..., 53, 54, 55]], dtype=uint8),
array([[199, 173, 145, ..., 97, 97, 96],
[196, 173, 149, ..., 96, 96, 95],
[177, 162, 144, ..., 100, 99, 98],
...,
[ 36, 38, 38, ..., 30, 31, 32],
[ 38, 41, 43, ..., 27, 28, 30],
[ 34, 40, 43, ..., 25, 26, 27]], dtype=uint8)
]
'''
警告:cv2.split() 是一个比较耗时的操作。只有真正需要时才用它,能用 Numpy 索引就尽量用。