线上初赛1——小球识别

发布时间 2023-05-25 19:24:39作者: 车车cccc

线上初赛1——小球识别

本文转载自python下用OpenCV的圆形检测 - CosmosbipinnatusCav - 博客园 (cnblogs.com)

一、简介

​ 对于圆形物体识别问题,opencv提供了大量方法。

二、检测步骤

2.1 读取图像

调用imread函数即可。

img = cv.imread('ball.png')
cv.imshow('image', img)

2.2 模糊处理

模糊处理,减少噪音影响。

由于图像中存在大量噪点(什么是噪点参考https://www.zhihu.com/question/23877970),利用降噪方法cv2.blur(img, (5,5))。其中两个参数为横向纵向的模糊程度,数值越大越模糊,这是5,5的模糊程度。

# 进行模糊处理,帮助减少噪音
blurred = cv.blur(img, (5, 5))

2.3 灰度处理

# 转换为灰度图像
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)

2.4 霍夫变换圆检测

那么什么是canny算法呢?简单来说就是边缘检测算法

具体实现效果可以参考方法:cv2.Canny(img, 27, 54),显示效果为

加大参数边缘就越少,我们用到的就是这种效果,即设置上限为80

cv2.Canny(img, 40, 80)

canny = cv.Canny(img, 40, 80)
cv.imshow('canny', canny)

之前的降噪和灰度化都是为了这一步的检测。

参考文章http://lib.csdn.net/article/opencv/24037

方法如下:

cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,50,param1=80,param2=30,minRadius=15,maxRadius=20

参数1 image:传递图像

参数2 method:默认,不用理解

参数3 dp:默认,不用理解

参数4 minDist:不同圆心的最小距离,单位为像素

参数5 涉及到Canny算法,这里的80为canny算法的上限,这里的canny算法下限自动设置为为上限一半,马上介绍canny算法

参数6 需要理解上面的参考文章,可以认为是需要达到的累加数量

参数7,8 为最小半径和最大半径,避免识别白色的圆圈

效果如下图所示:

2.5 结果


2.6 完整代码

import cv2 as cv
import numpy as np

if __name__ == '__main__':
    img = cv.imread('ball.png')
    cv.imshow('image', img)

    # 进行模糊处理,帮助减少噪音
    blurred = cv.blur(img, (5, 5))

    # 转换为灰度图像
    gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)

    # cv.imshow("gray image", gray)

    canny = cv.Canny(img, 40, 80)
    cv.imshow('canny', canny)

    # 使用Hough变换检测圆形
    circles = cv.HoughCircles(
        gray, cv.HOUGH_GRADIENT, dp=1, minDist=20, param1=50, param2=30, minRadius=80, maxRadius=100
    )

    # 确保至少检测到一个圆
    if circles is not None:
        circles = np.round(circles[0, :]).astype("int")

        # 循环遍历检测到的圆并绘制它们
        for (x, y, r) in circles:
            print("radius: %d, x_axis: %d, y_axis: %d" % (r, x, y))
            cv.circle(img, (x, y), r, (0, 255, 0), 4)
            cv.rectangle(img, (x-5, y-5), (x+5, y+5), (0, 128, 255), -1)
            cv.putText(img, "center", (x - 20, y - 20), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

        # 显示带有圆心的图像
        cv.imshow("Detected Circles", img)
        cv.waitKey(0)
        cv.destroyAllWindows()