opencv|Opencv简单实现对某颜色范围物体的识别

学习目标: 利用python+opencv对某颜色范围进行识别
准备工作: 1、 Pycharm 开发环境
2、 Python 3.8.3
3、 opencv4 HSV基本颜色分量范围
程序说明: 【opencv|Opencv简单实现对某颜色范围物体的识别】其目标是为了检测颜色为黄色的物体,然后对其质心和轮廓标注出来。黄色设置的上下限来自转载博客 HSV基本颜色分量范围(侵权即删)
检测图像为下方(图片网上找到的,侵权即删):
opencv|Opencv简单实现对某颜色范围物体的识别
文章图片

程序比较简单,主要流程为:
Videocapture获取图像 --> set重置图像大小提高程序速度 --> cvtColor转换成hsv图像格式 --> inRange二值化 --> medianBlur中值滤波 --> erode腐蚀 --> dilate膨胀 --> findContours找轮廓 --> max找到最大的轮廓 --> minEnclosingCircle找到包含该轮廓最小的圆 --> moment计算矩 --> 由矩计算质心 --> 标注质心和圆
代码如下:

import cv2 as cv import numpy as np import matplotlib as plt import imutilscolorLower = (26, 43, 46)# 二值化下限 colorUpper = (34, 255, 255)# 二值化上限cap = cv.VideoCapture(0) # cap.set(3, 320)# 为快速运算,把图片变成缩小成320*240 # cap.set(4, 240) kerne = np.ones((10, 10), np.uint8)# 开运算参数while True: ret, frame = cap.read()# 读取图像 # cv.namedWindow('frame', cv.WINDOW_AUTOSIZE) # cv.imshow('frame', frame)hsv = cv.cvtColor(frame.copy(), cv.COLOR_BGR2HSV)# 转化成hsv格式 # cv.namedWindow('hsv', cv.WINDOW_AUTOSIZE) # cv.imshow('hsv', frame)mask = cv.inRange(hsv.copy(), colorLower, colorUpper)# 根据范围二值化 # cv.namedWindow('mask', cv.WINDOW_AUTOSIZE) # cv.imshow('mask', mask)# ################### 先开运算再滤波测试################### # opening = cv.morphologyEx(mask.copy(), cv.MORPH_OPEN, kerne) # cv.namedWindow('opening', cv.WINDOW_AUTOSIZE) # cv.imshow('opening', opening) # # median = cv.medianBlur(opening.copy(), 3) # cv.namedWindow('median', cv.WINDOW_AUTOSIZE) # cv.imshow('median', median) # #########################################################median = cv.medianBlur(mask.copy(), 3)# 中值滤波 去掉椒盐噪点,参数3表示中值运算方块3*3 # cv.namedWindow('median', cv.WINDOW_AUTOSIZE) # cv.imshow('median', median)# ############################ 开运算(先腐蚀再运算)########################### # opening = cv.morphologyEx(median.copy(), cv.MORPH_OPEN, kerne)# 进行开运算 # cv.namedWindow('opening', cv.WINDOW_AUTOSIZE) # cv.imshow('opening', opening) # ################################################################################################# 先腐蚀再膨胀########################### erode = cv.erode(mask.copy(), None, iterations=2) dilate = cv.dilate(erode.copy(), None, iterations=2) # cv.namedWindow('dilate', cv.WINDOW_AUTOSIZE) # cv.imshow('dilate', dilate) #开运算去掉的比较多 ####################################################################### 找轮廓 cnts = cv.findContours(mask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[-2] center = None# 如果在图中找到一定的轮廓就进行计算,否则不进行计算 if len(cnts) > 0:c = max(cnts, key=cv.contourArea)# 找到图像中最大的轮廓 ((x, y), radius) = cv.minEnclosingCircle(c)# 找到最小的圆包含这个轮廓,返回坐标和半径M = cv.moments(c)# 计算图像的矩 center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))# 通过矩计算图像的质心# 判断以下他的半径,太小的话就认为是噪声,就忽略掉 if radius > 10: cv.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2)# 在检测到的轮廓周围画圆圈 cv.circle(frame, center, 5, (0, 0, 255), -1)cv.namedWindow('frame', cv.WINDOW_AUTOSIZE) cv.imshow('frame', frame)if cv.waitKey(1) == 27:# 按下Esc键就停止 break cap.release() cv.destroyAllWindows()

部分函数说明 (以下函数均为转载,侵权即删,(写的都特别好))
  1. 膨胀腐蚀函数
  2. 找轮廓函数
  3. 矩计算函数
程序说明 在这个程序中,有很多函数被注释掉,比如说开运算等等,这些都是在调试程序的时候,去看看最终的效果在目测的情况下到底是那种方法最好。要是你问我为啥这样弄,为啥滤波用中值滤波而不用高斯滤波,我只能说这是我调的结果。我掌握的知识还特别少,还不足以直接通过计算找到一个效果比较好的算法,目前还是停留在通过不断地调试,改变参数,查网上资料去找到一个识别度相对不错的流程。
识别结果: opencv|Opencv简单实现对某颜色范围物体的识别
文章图片

    推荐阅读