【Python+OpenCV】识别颜色方块并提取轮廓

前一阵在做机械臂下井字棋的综合设计,在网上直接购买了一套机械臂装置(包括机械臂,摄像头,树莓派,花费1600元),机械臂不是很高级、精度很低。源码里提供识别红绿蓝三种颜色方块的识别和抓取。

经过多次尝试,最终决定井字棋的棋子也采用3cm * 3cm * 3cm的颜色方块。今天就来写一些第一步,而第一步就是解决识别颜色方块的问题。

演示效果图

手移动方块,外轮廓始终贴合方块边缘。
识别绿色物块

代码

使用笔记本自带摄像头捕获画面,并识别绿色方块。

import cv2
import numpy as np

ball_color = 'green'

color_dist = {'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},
              'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
              'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
              }

cap = cv2.VideoCapture(0)
cv2.namedWindow('camera', cv2.WINDOW_AUTOSIZE)

while cap.isOpened():
    ret, frame = cap.read()
    if ret:
        if frame is not None:
            gs_frame = cv2.GaussianBlur(frame, (5, 5), 0)                     # 高斯模糊
            hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)                 # 转化成HSV图像
            erode_hsv = cv2.erode(hsv, None, iterations=2)                   # 腐蚀 粗的变细
            inRange_hsv = cv2.inRange(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]

            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)

            cv2.imshow('camera', frame)
            cv2.waitKey(1)
        else:
            print("无画面")
    else:
        print("无法读取摄像头!")

cap.release()
cv2.waitKey(0)
cv2.destroyAllWindows()

代码解析

1 读取图像
使用python读取摄像头图像可参考:【Python+OpenCV】捕捉笔记本和外接摄像头

2 颜色定义

ball_color = 'green'

color_dist = {'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},
              'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
              'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
              }

如果只是想识别绿色,那这一段就显得多余了。但是如果你想识别红色或是蓝色,可以直接将ball_color = 'green'改成ball_color = 'red'或是ball_color = 'blue'。其中color_dist内包含的是颜色在HSV模式下的范围,稍后再讲解。

3 图像处理

gs_frame = cv2.GaussianBlur(frame, (5, 5), 0)                   # 高斯模糊
hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)                 # 转化成HSV图像
erode_hsv = cv2.erode(hsv, None, iterations=2)                  # 腐蚀 粗的变细
inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])

第一步,高斯模糊
将原图像进行模糊处理,方便颜色的提取
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

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']颜色的上限

如图
去除背景色
4 绘制矩形边框

cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
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)

第一步,找出外边界
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廓线的宽度
最终结果如图
在这里插入图片描述

文章最开始的图像是笔记本内置摄像头拍摄的图像;
为了方便拍摄图像,代码分析过程中的图像是外接usb摄像头,像素太低。

  • 134
    点赞
  • 815
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 44
    评论
在计算机视觉中,可以使用PythonOpenCV库来识别物体的颜色。以下是实现物体颜色识别的步骤: 1.导入OpenCV库和其他必要的库: ``` import cv2 import numpy as np ``` 2.读取图像并进行预处理: ``` img = cv2.imread('object.jpg') hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) ``` 3.设置颜色范围: ``` lower_color = np.array([0, 100, 100]) upper_color = np.array([10, 255, 255]) ``` 这里的颜色范围是根据要识别的物体颜色设置的。HSV颜色空间中,H表示色调,S表示饱和度,V表示亮度。 4.使用颜色范围进行掩膜操作: ``` mask = cv2.inRange(hsv, lower_color, upper_color) ``` 这里使用cv2.inRange()函数来创建一个掩膜,将在颜色范围内的像素设置为255,其他像素设置为0。 5.对掩膜进行形态学操作: ``` kernel = np.ones((5, 5), np.uint8) mask = cv2.erode(mask, kernel, iterations=1) mask = cv2.dilate(mask, kernel, iterations=1) ``` 这里使用形态学操作来去除噪点,使掩膜更加平滑。 6.查找物体的轮廓: ``` contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ``` 这里使用cv2.findContours()函数查找掩膜中的轮廓。 7.遍历轮廓并绘制矩形框: ``` for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) ``` 这里遍历轮廓并使用cv2.boundingRect()函数获取每个轮廓矩形框。然后使用cv2.rectangle()函数在原图像中绘制矩形框。 8.显示结果: ``` cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上就是使用PythonOpenCV识别物体颜色的基本步骤。需要注意的是,颜色范围的设置和形态学操作的参数需要根据实际情况进行调整,以达到最佳效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

望天边星宿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值