OpenCV:对象遮罩

[复制链接]
查看68122 | 回复0 | 2024-4-28 20:44:48 | 显示全部楼层 |阅读模式


今天的文章将讨论并指导你识别图像中的对象,使用 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()

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则