利用霍夫变换检测圆形,识别变异物料

失效分析是可靠性工作中的重要内容。

最近想批量检测一些物料的圆度是否符合。

传统检测手段,我们可以用二次元影像仪去检查,但急需分析,手头没有设备的时候,就无从下手。

另外一个思路是把图片导入CAD里采用三点画圆去检查,只是需要重复性的操作,数量大的时候比较麻烦。

而且用CAD确定圆,有一个非常重要的问题,你怎么判断所选取的三个点确定的这个圆就是准确圆?圆周上有无穷多个点,只有大多数点指向的圆心是同一个时,才有理由相信这个真的就是我们要找的圆。所以这个方法只能大概的估计一下,不具有准确性。

按照上面CAD的思路,如果我们从圆周上选取多个点,都去做了圆心判断,那可以认可是需要的圆。只是人工去做,肯定不现实。于是周末研究了下,网上还挺多参考资料的,用的是霍夫变换找圆。

一个用来尝试找圆的效果图:

卡爪找圆效果图:

其实我想先检测的是卡爪外边缘,通过外边缘求得圆心,再以圆心画圆,判断内部刀片特征与所画的圆的重合度,以此评估是否有变异。

不过当时拍照的时候用了显微镜,聚焦到了内圈,外边缘很模糊,就只把里面的圆检测出来了。

按照这个思路,我试了一下直接拍照,没有显微聚焦。但手机不太行,灯光也没有调好,拍的效果不好,有阴影,不够清晰。

不过这不影响试验,识别效果如下:

红色圆的为检测到的外围边缘,蓝色为程序在此圆心上画的圆。

这样肉眼可以看出实物与标准尺寸的差异,判断卡爪是否有发生变化。

当然,我们可以用程序去判断是否有变化。比如,在刚才这张图基础上,再做一次检测。用程序判断卡爪的圆和人工画出的圆的重叠度,超出阈值则认为存在变化。

绿色为卡爪边缘检测后画出的圆,可以看出与蓝色的圆不重叠,有一定的偏差。

简单点可以用圆心和半径偏差去评估。

至于偏差多少在生产上可以接受,这就需要研究了。

比较麻烦的是调参的过程,这主要是拍的照片不太好导致的。经验是先进行边缘检测,这样能看出阈值是否合适,比较快把参数调整到合适范围。

附:示例代码及参数含义,以及霍夫变换的原理

霍夫变换找圆代码(开头圆盘那个案例):

#!/usr/bin/python
# -*- coding: gbk -*-
# 用霍夫变换找圆
# 王永平 2022.7.17
import cv2
import numpy as np
import os

ii=10

for k in range(1):
  try:
    source_pic = cv2.imread(r"D:/0/IMG000"+str(ii+k)+".jpg")
    gray_img= cv2.cvtColor(source_pic,cv2.COLOR_BGR2GRAY)
    #进行中值滤波
    img = cv2.medianBlur(gray_img,5)

    #显示灰度图
    #cv2.namedWindow("Gray", cv2.WINDOW_NORMAL)
    cv2.imshow("Gray",img)
    cv2.waitKey(1000)

    #显示边缘检测结果
    edges = cv2.Canny(img,200,300)
    #cv2.namedWindow("Edges", cv2.WINDOW_NORMAL)
    cv2.imshow("Edges",edges)
    cv2.waitKey(1000)

    circles = cv2.HoughCircles(edges,cv2.HOUGH_GRADIENT,1,100,param1=300,param2=20,minRadius=0,maxRadius=0)
    #对数据进行四舍五入变为整数
    circles = np.uint16(np.around(circles))
    for i in circles[0:]:
      #画出来圆的边界
      cv2.circle(source_pic,(i[0],i[1]),i[2],(0,0,255),2)
      #画出来圆心
      cv2.circle(source_pic,(i[0],i[1]),2,(0,255,255),3)

    #cv2.namedWindow("Circle", cv2.WINDOW_NORMAL)
    cv2.imshow("Circle",source_pic)

    imgpath = 'D:/1/'
    
    #保存图片到另外一个文件夹
    cv2.imwrite(os.path.join(imgpath , 'IMG000'+str(ii+k)+'.jpg'),source_pic)
    cv2.waitKey(1000)
    cv2.destroyAllWindows()
  except:
    print('IMG000'+str(ii+k)+'.jpg'+"未找到")

霍夫变换的参数:

image: 输入图像,8位灰度单通道图像

method: 检测圆的方法,目前OpenCV中有HOUGH_GRADIENT和HOUGH_GRADIENT_ALT两种方法。

dp: 检测圆心的累加器图像的分辨率与输入图像之比的倒数,如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器输入图像便有输入图像一半那么大的宽度和高度。减少图像的分辨率(宽高变小)是为了减少计算量,一般默认为1就好,保持原有图像精度。

minDist: 检测到的两个圆心之间的最小距离。如果参数太小,除了真实的一个圆圈之外,可能错误地检测到多个相邻的圆圈。如果太大,可能会遗漏一些圆圈。

circles: 检测到的圆的信息输出向量(x,y,r),分别代表检测到圆的中心坐标和圆半径。

param1: Canny 边缘检测的高阈值,低阈值被自动置为高阈值的一半,默认为 100。也就是说检测图像中像素点的值大于param1是会检测为边缘。

param2: 表示在检测阶段圆心的累加器阈值。它越小的话,会误检测到更多根本不存在的小圆,而越大,能通过检测的圆就更加接近完美的圆形了。

minRadius: 表示图像中能检测到最小圆的半径的值。

maxRadius: 表示图像中检测到的圆的最大半径的值。

(摘自CSDN,原文链接:

https://blog.csdn.net/weixin_45192980/article/details/119814390)

再了解下霍夫变换的原理:

霍夫圆变换是将二维图像空间中一个圆转换为该圆半径、圆心横纵坐标所确定的三维参数空间中一个点的过程,因此,圆周上任意三点所确定的圆,经Hough变换后在 三维参数空间应对应一点。该过程类似于选举投票过程,圆周上任意三个点为一选举人,而这三个点所确定的圆则为一侯选人(以下称为候选圆)。遍历圆周上所有点,任意三个点所确定的候选圆进行投票。遍历结束后,得票数最高点(理论上圆周上任意三点确定的圆在Hough变换后均对应三维参数空间中的同一点)所确定的圆即为该圆周上绝大多数点所确定的圆(以下称为当选圆),即绝大多数点均在该当选圆的圆周上,以此确定该圆。(摘自CSDN,有删改使得通顺,原文链接https://blog.csdn.net/u010368556/article/details/70167993)

因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。

基于效率考虑,Opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:

1. 检测边缘,发现可能的圆心

2. 基于第一步的基础上从候选圆心开始计算最佳半径大小

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值