Python图像处理经典实例
上QQ阅读APP看书,第一时间看更新

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会员卡,近千本电子书免费畅读。