当前位置: 首页 > article >正文

python学opencv|读取图像(七十)使用cv2.HoughCircles()函数实现图像中的霍夫圆形检测

【1】引言

前序学习进程中,已经掌握了使用cv2.HoughLinesP()函数实现图像中的霍夫直线检测,相关文章链接为:

python学opencv|读取图像(六十九)使用cv2.HoughLinesP()函数实现图像中的霍夫直线检测-CSDN博客

在此基础上,很容易想到进行圆形检测,这就是本次文章的学习目标: 使用cv2.HoughCircles()函数实现图像中的霍夫圆形检测。

【2】官网教程

点击下方链接,直达霍夫圆形检测cv2.HoughCircles()函数的官网教程:

OpenCV: Feature Detection

官网页面对cv2.HoughCircles()函数的说明为:

图1  cv2.HoughCircles()函数的官网说明

具体的,官网页面对cv2.HoughCircles()函数的参数说明为:

cv.HoughCircles(    

image                 #输入图像,要求是8位单通道图像

method               #检测方法,包括HOUGH_GRADIENT和HOUGH_GRADIENT_ALT两种

dp                       #累加器和图片分辨率比值的倒数,一般取1

minDist               #圆心之间的最小距离

param1              #边缘检测的第一个阈值,一般较大

param2              #边缘检测的第二个阈值,一般较小

minRadius         #小圆半径

maxRadius    )   #大圆半径

【3】代码检测

代码设计包括三大部分。

第一部分是引入模块和相关图像:

import cv2 as cv #引入cv2模块
import numpy as np #引入numpy模块

# 读取图片
src = cv.imread('srcpp.png')

第二部分是对图像进行预处理,因为霍夫圆形检测只能对灰度图执行,所以需要提前转化图像:

# 预处理图像
srcb = cv.medianBlur(src, 3)  # 中值滤波
gray = cv.cvtColor(srcb, cv.COLOR_BGR2GRAY)  # 将图像转化为灰度图

第三部分是对图像进行霍夫圆形检测,由于逐个调整参数,所以需要设置for循环:

# 定义霍夫圆检测的参数列表
hough_params_list = [
    (70, 100, 25, 10, 50),
    (100, 100, 25, 10, 50),
    (100, 120, 25, 10, 50),
    (100, 120, 50, 10, 50),
    (100, 120, 50, 25, 50)
]

transformed_images = [src.copy()]  # 先将原始图像添加到列表中

# 进行霍夫圆检测并绘制圆形
for i,(minDist, param1, param2, minRadius, maxRadius) in enumerate(hough_params_list,start=1):
    circleparams = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
    circleimg =src.copy() #复制原始图像进行绘图
    if circleparams is not None:
        circles = np.uint16(np.around(circleparams))
        for circle in circles[0,:]:
            x, y, r = circle
            circleimg=cv.circle(circleimg, (x, y), r, (200, 150, 200), 5)
        transformed_images.append(circleimg) #图像逐个累加

上述代码中,cv2.HoughCircles()函数通过enumerate()函数逐项调取hough_params_list矩阵中的参数,执行了5次霍夫圆形检测。

每次检测完毕后,都直接进行了圆形绘制,transformed_images.append(circleimg)把绘制的圆形按照顺序叠加在一起。

第四部分是对图像进行横向组合和竖向组合:

# 确保图像数量足够进行两行三列的拼接
while len(transformed_images) < 6:
    # 如果图像数量不足 6 个,用空白图像填充
    blank_image = np.zeros_like(src)
    transformed_images.append(blank_image)

# 分割图像列表为两行
first_row = transformed_images[:3]
second_row = transformed_images[3:6]

# 水平拼接每行的图像
h_concat_first_row = cv.hconcat(first_row)
h_concat_second_row = cv.hconcat(second_row)

# 垂直拼接两行的图像
final_image = cv.vconcat([h_concat_first_row, h_concat_second_row])

第五部分是显示和保存图像:

# 显示和保存最终拼接图像
cv.imshow('Concatenated Images', final_image)
cv.imwrite('concatenated_images.png', final_image)

# 等待按键关闭窗口
cv.waitKey()
cv.destroyAllWindows()

代码运行相关的图像有:

图2 初始图像

 图3 多个霍夫曲线变换图像对比图像

图5显示了多个霍夫直线变换图像对比效果,相对来说,第一行第三列的图像效果好一些。

第一行第三列的图像和第一行第二列的图像相比,调高了圆心最小间距,从70到100,圆形数量减少;

第二行第一列的图像和第一行第三列的图像相比。提高了线段最小长度,从80到100,影响不大,圆形数量和位置均没有变化;

第二行第二列的图像和第二行第一列的图像相比。提高了第二个阈值,从25到50,圆形数量减少,两个较小的圆形消失了;

第二行第三列的图像和第二行第二列的图像相比。增大了最小圆形半径,从10增大到25,圆形数量减少,又一个较小的圆形消失了。

此时的完整代码为:

import cv2 as cv #引入cv2模块
import numpy as np #引入numpy模块

# 读取图片
src = cv.imread('srcpp.png')

# 预处理图像
srcb = cv.medianBlur(src, 3)  # 中值滤波
gray = cv.cvtColor(srcb, cv.COLOR_BGR2GRAY)  # 将图像转化为灰度图

# 定义霍夫圆检测的参数列表
hough_params_list = [
    (70, 100, 25, 10, 50),
    (100, 100, 25, 10, 50),
    (100, 120, 25, 10, 50),
    (100, 120, 50, 10, 50),
    (100, 120, 50, 25, 50)
]

transformed_images = [src.copy()]  # 先将原始图像添加到列表中

# 进行霍夫圆检测并绘制圆形
for i,(minDist, param1, param2, minRadius, maxRadius) in enumerate(hough_params_list,start=1):
    circleparams = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
    circleimg =src.copy() #复制原始图像进行绘图
    if circleparams is not None:
        circles = np.uint16(np.around(circleparams))
        for circle in circles[0,:]:
            x, y, r = circle
            circleimg=cv.circle(circleimg, (x, y), r, (200, 150, 200), 5)
        transformed_images.append(circleimg) #图像逐个累加

# 确保图像数量足够进行两行三列的拼接
while len(transformed_images) < 6:
    # 如果图像数量不足 6 个,用空白图像填充
    blank_image = np.zeros_like(src)
    transformed_images.append(blank_image)

# 分割图像列表为两行
first_row = transformed_images[:3]
second_row = transformed_images[3:6]

# 水平拼接每行的图像
h_concat_first_row = cv.hconcat(first_row)
h_concat_second_row = cv.hconcat(second_row)

# 垂直拼接两行的图像
final_image = cv.vconcat([h_concat_first_row, h_concat_second_row])

# 显示和保存最终拼接图像
cv.imshow('Concatenated Images', final_image)
cv.imwrite('concatenated_images.png', final_image)

# 等待按键关闭窗口
cv.waitKey()
cv.destroyAllWindows()

【4】细节说明

cv.circle()函数有一个特点是,如果没有反复说明,多个cv.circle()函数依次放在一起时,后面的圆形其实会在前面已经画过圆形的图像上继续画圆,并且每个图都指向了最后的画圆效果。

比如圆形绘制代码:

c1=cv.circle(src,(x1,y1),r,(200,150,200),5)
c2=cv.circle(c1,(x1,y1),50,(200,150,200),5)
cv.imshow('c1', c1)
cv.imshow('c2', c2)

图像c1和c2显示的效果一样。

为了让每次绘制圆形的效果单独呈现,需要不断把最初的圆形绘制模板复制出来,这就是 circleimg =src.copy() #复制原始图像进行绘图代码的意义:

for i,(minDist, param1, param2, minRadius, maxRadius) in enumerate(hough_params_list,start=1):
    circleparams = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, minDist=minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
    circleimg =src.copy() #复制原始图像进行绘图
    if circleparams is not None:
        circles = np.uint16(np.around(circleparams))
        for circle in circles[0,:]:
            x, y, r = circle
            circleimg=cv.circle(circleimg, (x, y), r, (200, 150, 200), 5)
        transformed_images.append(circleimg) #图像逐个累加

如果对圆形绘制技巧不太熟悉,可以通过下述链接回忆:

python学opencv|读取图像(二十)使用cv2.circle()绘制圆形_python cv2.circle-CSDN博客

【5】总结

掌握了python+opencv实现使用cv2.HoughCircles()函数实现图像中的霍夫圆形检测的技巧。


http://www.kler.cn/a/547813.html

相关文章:

  • MES管理系统解决方案在制造企业中的实施路径
  • mybatis-lombok工具包介绍
  • 阿里云视频点播,基于thinkphp8上传视频
  • 游戏引擎学习第101天
  • 登录演示和功能拆解
  • Unity-New Input System
  • 【Film Shot】CineScale: Recognising Cinematic Features with AI
  • 审计费用差10倍?项目规模如何影响报价
  • 考研高数复习规范
  • Java练习(21)
  • 【php】Static 关键字注意事项
  • 机器学习+生信多组学联合构建牙周炎“线粒体功能障碍与免疫微环境“关联网络
  • PVE 磁盘管理详解:从 Windows 到 Linux 的思维转换(文末附资源)
  • Kubernetes (k8s) 常用指令速查表
  • 鲸鱼算法优化Transformer+KAN网络并应用于时序预测任务
  • AI Agent 有哪些痛点问题
  • 《A++ 敏捷开发》- 15 TDD与重构
  • java集合框架之Map系列
  • 计算机组成原理—— 总线系统(十一)
  • MATLAB 图像处理基础:读取、显示与保存图像