Skip to content

关于图像颜色识别和去除背景

识别颜色一般先把图像转化为HSV颜色空间

HSV颜色空间由三个分量组成:色相(Hue)、饱和度(Saturation)和明度(Value)。通过调整这些分量的值,我们可以选择特定的颜色范围,HSV具体含义如下:

色相(Hue):色相值表示颜色在颜色轮上的位置。不同的颜色在色相上有不同的取值范围。例如,红色的色相值约为0-10或160-180,蓝色的色相值约为110-130,绿色的色相值约为50-70。根据所需识别的颜色,选择相应的色相范围。

饱和度(Saturation):饱和度值表示颜色的纯度或鲜艳程度。较高的饱和度值表示颜色更加鲜艳,而较低的饱和度值表示颜色较为灰暗。根据实际场景中颜色的饱和度,选择适当的饱和度范围。

明度(Value):明度值表示颜色的亮度或明暗程度。较高的明度值表示颜色较亮,而较低的明度值表示颜色较暗。根据实际场景中颜色的明度,选择适当的明度范围。

这些值是根据经验和实验进行调整的,以获得最佳的颜色识别效果。我们可以根据具体的应用场景和需求进行调整,以适应不同的颜色识别任务。在实际使用中,我们可能需要进行多次尝试和调整,以找到最适合需求的颜色范围。

对于每种颜色(红色、蓝色和绿色),我们使用np.array()函数创建了一个包含三个元素的NumPy数组。这些元素分别代表HSV颜色空间中的色相、饱和度和明度的下限和上限。

确定绿色的区域范围

mingreen=np.array([30,60,60])

maxgreen=np.array([90,255,255])

这个值是通过多次测试得出效果相对较好的数据

71982532776

这就是用颜色识别的弊端,会受到其他相同颜色的干扰。

关于去除背景还有另一种比较好的方式(GrabCut)

GrabCut算法的工作原理可概括为以下几个步骤:

用户输入:用户在图像上绘制一个矩形框,圈定前景对象。 初始标记:算法使用高斯混合模型(GMM)对框选区域内的像素进行初始标记,区分前景和背景。 图割算法:基于像素的颜色分布,构建一个图,并添加源节点和汇聚节点,像素之间的连接权重基于颜色相似性。 迭代优化:通过迭代方式,利用最小割算法对前景和背景的分割进行优化。 结果修正:用户可根据分割结果进行手动修正,提高分割的准确性。

71982477677

效果感觉比颜色识别后用阈值去除背景的效果要好很多。但是缺点就是需要手动框区出你需要的部分(也就是感兴趣区域)。

还有一种更先进的去背景方法也略有了解就是使用U-Net

什么是U-Net?(简单了解了一下是什么东西)

U-Net是一个全卷积网络,最初为生物医学图像分割设计。由于其卓越的性能和结构的对称性,它已被广泛应用于各种图像分割任务,包括背景去除。

使用摄像头框出标签

第一步,高斯模糊

将原图像进行模糊处理,方便颜色的提取 gs_frame = cv2.GaussianBlur(frame, (5, 5), 0),其中 参数一:frame需要高斯模糊的图像 参数二:(5, 5)高斯矩阵的长与宽都是5 参数三:0标准差是0

第二步,BGR转换为HSV

刚刚高斯模糊后的图像的颜色模式从BGR转换为HSV(在OpenCV中不使用RGB模式,而是使用BGR模式)。为什么使用HSV模式呢?因为这种模式更加方便单一颜色的提取,具体原理我也不懂。 hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV) 参数一:gs_frame原图像 参数二:cv2.COLOR_BGR2HSV颜色转换方式,从BGR to HSV

第三步,腐蚀

通俗来说,就是将图像变瘦,用于去除噪声点。 erode_hsv = cv2.erode(hsv, None, iterations=2) 参数一:hsv原图像 参数三:iterations=2腐蚀的宽度

可以看出少了很多干扰(紫色的点点少了很多)。

第四步,去除背景部分

将绿色以外的其他部分去除掉,并将图像转化为二值化图像 inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper']) 参数一:erode_hsv原图像 参数二:color_dist[ball_color]['Lower']颜色的下限 参数三:color_dist[ball_color]['Upper']颜色的上限

第五步,用矩形框出

第一步,找出外边界
cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]

使用该函数找出方框外边界,并存储在cnts中。 findContours 参考资料

第二步,找出矩形

在边界中找出面积最大的区域,选定该区域为方块所在区域,并绘制出该区域的最小外接矩形,并记录该矩形的位置坐标。 c = max(cnts, key=cv2.contourArea) 在边界中找出面积最大的区域 rect = cv2.minAreaRect(c) 绘制出该区域的最小外接矩形 box = cv2.boxPoints(rect) 记录该矩形四个点的位置坐标

第三步,绘制矩形

在原图像上将分析出的矩形边界绘制出来 cv2.drawContours(frame, [np.int0(box)], -1, (0, 255, 255), 2) 参数一:frame目标图像 参数二:[np.int0(box)]轮廓本身,在Python中是一个list 参数三:-1指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。 参数四:(0, 255, 255)轮廓颜色BGR 参数五:2廓线的宽度

幕截图 2024-07-01 17364

这种方式的弊端和第一种是一样的,并不是很稳定容易受到和所需相同颜色的干扰而变得不稳定。我尝试把这两种方法结合起来(GrabCut和使用摄像头框出标签结合)但是失败了哈哈哈哈。