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

您所在的位置:网站首页 Python方框透视 【Python+OpenCV】识别颜色方块并提取轮廓

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

2024-01-24 19:36| 来源: 网络整理| 查看: 265

前一阵在做机械臂下井字棋的综合设计,在网上直接购买了一套机械臂装置(包括机械臂,摄像头,树莓派,花费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摄像头,像素太低。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3