使用OpenCV进行目标提取详细教程(附python代码演练)
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
今天的文章将讨论并指导你识别图像中的对象,使用 OpenCV 对这些对象进行遮罩处理。让我们开始吧!
HSV 色标
请花一点时间观察下面的图片。每个图块似乎是不同的颜色,对吧?但是有一个有趣的地方:如果我们仔细思考,实际上可以将它们都归为绿色。然而,如果我们仔细观察,我们会注意到它们是不同的绿色调。这是怎么回事呢?
绿色色调
尽管这些瓷砖具有相同的总体颜色,但它们有不同的组成部分,构成了它们各自的特定绿色调。正如我们之前讨论的那样,这些组成部分被称为红色、绿色和蓝色(RGB)。因此,虽然它们都属于绿色类别,但它们的RGB组合是不同的,从而形成我们观察到的不同绿色调。
但是,请等一下,这背后是否还有更多的东西?这个有趣的现象背后是否还有其他原因?确实如此!
你以前一定在画图软件中见过这个选项卡。
定义绘画上的自定义颜色
你可以看到,除了 (R)ed、(G)reen、(B)lue 之外,还有 3 个参数,分别是 (H)ue、(S)at 和 (L)um(HSL 色调)。
由于 HSL 和 HSV,我们可以实现如此多种色调。HSV 代表色相、饱和度和值。让我们谈谈 HSV,这对我们在 OpenCV 中的工作很有用。
HSV 色锥
H = 色调:当我们谈论色调时,我们谈论的是最纯粹的颜色形式。想想你在彩虹中看到的颜色——红色、橙色、黄色、绿色、蓝色、靛蓝和紫色。每一种都是不同的色调,代表特定的光波长。
色调的范围是 0 到 360 度。
S = 饱和度:饱和度是指颜色的鲜艳程度和强度。高度饱和的颜色鲜艳而丰富,而不饱和的颜色则显得更加柔和或浅色。饱和度赋予颜色深度和影响力。
饱和度的范围为 0–1(或 0–255)。
V = 值:颜色值与颜色的亮度或暗度有关。它由物体反射或吸收的光量决定。高值的颜色是亮的,而低值的颜色是暗的。值在创造对比和增加视觉构图的深度方面起着至关重要的作用。
值的范围为 0–1(或 0–255)。
让我们了解为什么需要将 BGR 图像转换为 HSV 颜色。
改进的颜色处理
简化的基于颜色的分析
对光照变化的鲁棒性
与人类感知的兼容性
现在我们将了解如何在 Spyder OpenCV 中使用 HSV 图像。
对象遮罩
假设你有 3 张车牌照。
我们正在尝试提取这些车辆的车牌号。我们可以用 BGR 图像来实现吗?
我们当然不能。这背后的原因是,我们在这里看到的橙色/黄色是由 (R)ed、(G)reen、(B)lue 的不同成分组成的,并且它们不是恒定的。此外,图像之间的亮度、饱和度和曝光度也完全不同。
每幅图像中橙色的 RBG 成分
因此很明显,我们无法从 BGR 图像中提取某种颜色。我们需要将此 BGR 图像转换为 HSV 图像。让我们看看如何做到这一点。
#import necessary libraries
import cv2
import numpy as np
import matplotlib.pyplot as plt
#using opencv to read an image
#BGR Image
plate_image_1 = cv2.imread("C:/users/public/pictures/numberp_1.png")
让我们想象一下这个plate_image_1。
cv2.namedWindow("BGR Image", cv2.WINDOW_NORMAL);
cv2.imshow("BGR Image",plate_image_1);
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
现在让我们将此plate_image_1 转换为HSV 格式。为此,我们使用cv2.cvtColor() 。我们可以使用此函数将 BGR/RGB 转换为 HSV、RGB 转换为 BGR、在 RGB/BGR 和灰度之间转换以及更多选项。
HSV_im_1 = cv2.cvtColor(plate_image_1,cv2.COLOR_BGR2HSV)
让我们想象一下这个 HSV 图像。
使用 OpenCV 将 BGR 图像转换为 HSV 色标
这对我们来说确实很奇怪,我们将看看如何从中提取橙色/黄色。
之前我们讨论过图像之间的亮度、饱和度和曝光完全不同。为了解决这个问题,我们为要提取的颜色定义了一个范围。准确地说,我们按照自己的意愿为某种颜色定义了上边界和下边界。
这是通过查看 HSV 色锥来完成的。
首先,我们确定色相的范围。色调范围从 0 到 360。每 30 度我们就会得到一种不同的颜色。让我们看看它的橙色。
通过粗略估计 15-20 度的下色相和 40-50 度的上色相,我们可以清楚地确定包含橙色每种色调的范围。
对于饱和度和明度,我们获得从 0 到 1 的整个范围,以适应图像中的全部亮度变化。这样可以准确表示色谱内较亮或较暗的色调。
让我们在 Spyder 中定义它。
Orange_UB = np.array([40,255,255])
Orange_LB = np.array([20,0,0])
现在我们定义一个遮罩来跟踪图像中的橙色。这是通过使用 cv2.inRange() 来完成的。我们介绍了上界和下界以及执行遮罩所需的图像。
mask = cv2.inRange(HSV_im_1,Orange_LB,Orange_UB)
让我们想象一下这个遮罩。
cv2.namedWindow("HSV Orange masked", cv2.WINDOW_NORMAL);
cv2.imshow("HSV Orange masked",mask);
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
就快到了!!我们可以几乎清楚地看到车牌,但也有其他不必要的像素被掩盖。我们如何优化我们的遮罩?我们需要改变饱和度和值的范围,直到我们得到一个令人满意的遮罩。
差不多了!让我们对其进行更多微调。
看起来不错!!
这就是我们从图像中提取特定颜色(范围)的对象的方法。
完整代码
#import necessary libraries
import cv2
import numpy as np
import matplotlib.pyplot as plt
#using opencv to read an image #BGR Image
plate_image_1 = cv2.imread("C:/users/public/pictures/numberp_1.png")
#converting BGR to HSV
HSV_im_1 = cv2.cvtColor(plate_image_1,cv2.COLOR_BGR2HSV)
#defining HSV range
Orange_UB = np.array([40,255,245])
Orange_LB = np.array([20,55,180])
#masking
mask = cv2.inRange(HSV_im_1,Orange_LB,Orange_UB)
#visualizing
cv2.namedWindow("HSV Orange masked", cv2.WINDOW_NORMAL);
cv2.imshow("HSV Orange masked",mask);
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲 在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲 在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~