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

学习目标:

利用python+opencv对某颜色范围进行识别


准备工作:

1、 Pycharm 开发环境
2、 Python 3.8.3
3、 opencv4 HSV基本颜色分量范围


程序说明:

其目标是为了检测颜色为黄色的物体,然后对其质心和轮廓标注出来。黄色设置的上下限来自转载博客 HSV基本颜色分量范围(侵权即删)
检测图像为下方(图片网上找到的,侵权即删):

程序比较简单,主要流程为:
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 imutils

colorLower = (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. 矩计算函数

程序说明

在这个程序中,有很多函数被注释掉,比如说开运算等等,这些都是在调试程序的时候,去看看最终的效果在目测的情况下到底是那种方法最好。要是你问我为啥这样弄,为啥滤波用中值滤波而不用高斯滤波,我只能说这是我调的结果。我掌握的知识还特别少,还不足以直接通过计算找到一个效果比较好的算法,目前还是停留在通过不断地调试,改变参数,查网上资料去找到一个识别度相对不错的流程。

识别结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_50303783/article/details/109232486