设置:
对不起图片链接,但一张图片大约是20MB,也不想丢失任何质量
图像示例:
https://drive.google.com/file/d/11PU-5fzvSJt1lKlmP-lQXhdsuCJPGKbN/view?usp=sharinghttps://drive.google.com/file/d/1B3lSFx8YvTYv3hzuuuYtphoHBuyEdc4o/view
案例: 有不同形状的金属部件,尺寸从5x5到10x10(cm)。在这些金属零件内部有很多2到10个圆孔,必须非常精确地检测出来。孔的实际尺寸未知,因为可能的零件种类繁多。目标是用OpenCV编写一个通用算法,可以处理任何金属零件并检测圆孔。在
我们所做的: 我们尝试用HoughCircles算法来检测这些漏洞,但几乎没有成功。该算法要么过于敏感,要么根本检测不到漏洞。我们尝试了不同的param1和param2值,但是没有成功。在使用HoughCircles之前,我们也尝试过模糊图像并将其传递给Canny,但这样的方法并没有产生更好的效果。同样的算法在分辨率较低的图片上效果更好。然而,不能牺牲分辨率,因为在这个项目中精度是极其重要的。在
https://drive.google.com/file/d/1TRdDbperi37bha0uJVALS4C2dBuaNz6u/view?usp=sharing
使用以下参数检测到上述圆圈:
minradius=0
maxradius=0
dp=1
param1=100
param2=21
通过使用上述参数,我们几乎可以得到我们想要的结果。当我们对不同的图片使用相同的参数时,问题就出现了。在
我们想要得到的最终结果是一个给定圆的直径,并且我们希望相同的算法可以用于不同的零件图片
这个问题与其他问题不同的是,我们不知道给定圆的近似半径(因此我们无法操纵minradius、maxradius、param1、param2或任何其他值)。在
您可以设置图像的阈值并使用
findContours
来查找孔的轮廓,然后用minEnclosingCircle
将圆拟合到它们上面。通过将拟合圆与轮廓面积进行比较,可以检查拟合圆是否完好。在通过健全性检查的圆在所有以蓝色显示的轮廓顶部以绿色显示。在
这是一种方法
在找到轮廓后,我们进行轮廓近似。其思想是,如果近似轮廓有三个顶点,那么它必须是一个三角形。类似地,如果它有四个,它必须是正方形或矩形。因此,我们可以假设,如果它的顶点数大于某个数,那么它就是一个圆。在
有几种方法可以得到直径,一种方法是找到轮廓的边界矩形并使用其宽度。另一种方法是从质心坐标计算。在
关于这些图像,我们知道两件事:
所以我们要做的就是探测漏洞。这实际上是非常微不足道的:
剩下的是那些洞。不包括任何接触图像边缘的孔。我们现在可以很容易地测量这些孔。既然我们假设它们是圆形的,我们可以做三件事:
这段Python代码使用DIPlib(我是作者)演示了如何执行以下三种方法:
这将产生以下输出:
^{pr2}$在图像的大小上,{cd2>仍然是一个整数值。我没有费心制作一个显示图像大小的标记图像,但是这可以很容易地完成,正如您在其他答案中看到的那样。在
因为图像文件中没有像素大小信息,所以我将每个像素设置为1微米。这可能不正确,您必须进行校准以获得像素大小信息。在
这里的一个问题是背景照明太亮,导致像素饱和。这会导致孔看起来比实际大。校准系统很重要,这样背景照明接近相机可以记录的最大值,但不在该最大值或以上。例如,尝试将背景强度设置为245或250。第三种方法受光照不良影响最大。在
对于第二个图像,亮度非常低,给出的图像比必要的噪声更大。我需要将
bin = dip.Label(bin)
行修改为:也许做些噪声过滤会更容易些。结果是:
方法3快速讲解
方法在the PhD thesis of Lucas van Vliet (Delft University of Technology, 1993), chapter 6中描述。在
可以这样想:通过孔的光的量与孔的面积成正比(实际上它是由“面积”x“光强度”给出的)。把通过洞的光加起来,我们就知道洞的面积了。代码将对象的所有像素强度以及对象外部的一些像素相加(我在那里使用了10个像素,要走多远取决于模糊)。在
erfclip
函数被称为“软剪辑”函数,它确保孔内强度一致为1,孔外强度一致为0,并且仅在边缘周围留下中间灰度值。在这种特殊情况下,这种软剪辑避免了成像系统中偏移的一些问题,以及对光强度的估计不好。在其他情况下,这一点更为重要,避免被测物体颜色不均匀的问题。它还可以减少噪音的影响。在相关问题 更多 >
编程相关推荐