1.8 在HSV颜色模型中使用颜色进行目标检测
在本实例中,我们将介绍如何利用OpenCV-Python库在HSV颜色空间中使用颜色来进行目标检测。首先,由读者指定一个颜色值范围,然后本实例可以通过该颜色值范围识别和提取读者感兴趣的目标。实例可以更改被检测目标的颜色,甚至可以使所检测到的目标变得透明。
1.8.1 准备工作
在本实例中,我们会用到的输入图像是水族馆中一条橙色的鱼,而(实例)感兴趣的目标就是这条鱼。实例将检测这条鱼,改变它的颜色,并使用HSV空间中鱼的颜色范围来使其变得透明。让我们先导入所需要的Python库:
import cv2 import numpy as np import matplotlib.pylab as plt
1.8.2 执行步骤
要执行该实例,需要执行以下步骤。
1.读取输入图像和背景图像。将BGR输入图像转换为HSV颜色空间中的图像:
bck = cv2.imread("images/fish_bg.png") img = cv2.imread("images/fish.png") hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
2.通过选择鱼的HSV颜色范围,为鱼创建一个掩膜图像:
mask = cv2.inRange(hsv, (5, 75, 25), (25, 255, 255))
3.使用掩膜图像将鱼图像进行图像分片处理:
imask = mask>0 orange = np.zeros_like(img, np.uint8) orange[imask] = img[imask]
4.仅通过改变色调通道值(加20)将橙色的鱼的颜色改为黄色,并将图像转换回BGR颜色空间:
yellow = img.copy() hsv[...,0] = hsv[...,0] + 20 yellow[imask] = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)[imask] yellow = np.clip(yellow, 0, 255)
5.先在没有鱼的输入图像中提取背景,然后从背景图像中提取出前景对象(鱼)所对应的区域,将这两幅图像叠加起来创建透明鱼图像:
bckfish = cv2.bitwise_and(bck, bck, mask=imask.astype(np.uint8)) nofish = img.copy() nofish = cv2.bitwise_and(nofish, nofish, mask=(np.bitwise_not(imask)).astype(np.uint8)) nofish = nofish + bckfish
1.8.3 工作原理
图1-18所示的是一幅用于快速查找颜色的 HSV 色图。x轴表示色调,取值范围为 (0,180);y轴 (1) 表示饱和度,取值范围为 (0,255);y 轴 (2) 表示S =255和V=255时所对应的色调值。要在色图中找到一个特定的颜色,只需查找所对应的H和S值的范围,然后设置V值的范围为(25,255)。实例感兴趣的鱼的橙色可以从(5,75,25)到(25,255,255)的HSV范围中搜索,具体如下所示。
图1-18
调用OpenCV-Python库中的inRange()函数,通过该函数进行颜色检测。函数接收HSV颜色模型的输入图像以及输入图像的颜色范围(需提前确定)作为参数。
cv2.inRange()接收3个参数,分别为输入图像、所检测的颜色的下限值和上限值。该函数会返回一个二值掩膜图像,其中,白色像素代表指定范围内的像素,黑色像素代表指定范围外的像素。
要改变所检测到的鱼的颜色,只需改变色调(颜色)通道值。本实例不涉及饱和度和值通道的修改。
通过OpenCV-Python库中的按位运算提取前景图像/背景图像。
注意:透明鱼的背景图像与鱼图像的背景的颜色略有不同,否则透明鱼就真的消失了(隐形障眼法!)。
运行上述代码并绘制图像,则会得到图1-19所示的输出。
图1-19
注意,在OpenCV-Python库中,RGB颜色空间中的图像以BGR格式存储。如果读者想以适当的颜色显示图像,例如在使用Matplotlib中的imshow()函数(该函数需要RGB格式的图像)显示图像之前,必须使用cv2.cvtColor(image, cv2.COLOR_BGR2RGB)来转换图像格式。
读者服务:
微信扫码关注【异步社区】微信公众号,回复“e58895”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。