抱歉,我不了解OpenCV,这不是完整的答案,而是更多的预处理步骤:
首先,您不需要边缘检测器。边缘检测器转换过渡(如这种从暗到亮的方式):
变成山脊(深色的亮线),像这样:
换句话说,它执行区分。
但是在您的图像中,有一束光从一个方向向下照射,这向我们展示了3D表面的浮雕。我们将其视为线条和边缘,因为我们习惯于以3D形式看到事物,但实际上并非如此,这就是边缘检测器无法工作的原因,并且模板匹配在旋转的图像上不容易工作(完美在0度旋转时,匹配实际上会完全抵消180度,因为明暗会相互对齐)。
如果从侧面看这些模糊线之一的高度看起来像这样:
那么从一侧照亮时的亮度函数将如下所示:
这就是您在图像中看到的。面对的表面变亮,尾部的表面变暗。因此,您不想与众不同。您需要沿照明方向积分图像,这将为您提供表面的原始高度图(大约)。这样一来,无论是通过霍夫变换还是模板匹配或其他方式,都可以更轻松地匹配事物。
我不确定如何自动找到照明方向。如果所有图片都一样,那就太好了。否则,您将必须找到最大的对比线并假定光线垂直于它或其他东西。对于我的示例,我将图像手动旋转到我认为是正确的方向,而光线来自左侧:
但是,您还需要消除图像中所有的低频变化,以仅突出显示快速变化的线状特征。为了避免产生伪影,我使用了2D高斯模糊,然后从原始图像中减去了它:
积分(累计和)很容易失控,从而产生水平条纹。我用另一个高斯高通去除了这些,但是这次仅在水平方向上:
现在,气孔一直是白色的椭圆形,而不是在某些地方是白色,在其他地方是黑色。
原版的:
集成:
from pylab import *
import Image
from scipy.ndimage import gaussian_filter, gaussian_filter1d
filename = 'rotated_sample.jpg'
I = Image.open(filename).convert('L')
I = asarray(I)
# Remove DC offset
I = I - average(I)
close('all')
figure()
imshow(I)
gray()
show()
title('Original')
# Remove slowly-varying features
sigma_2d = 2
I = I - gaussian_filter(I, sigma_2d)
figure()
imshow(I)
title('2D filtered with %s' % sigma_2d)
# Integrate
summed = cumsum(I, 1)
# Remove slowly-changing streaks in horizontal direction
sigma_1d = 5
output = summed - gaussian_filter1d(summed, sigma_1d, axis=1)
figure()
imshow(output)
title('1D filtered with %s' % sigma_1d)
该霍夫变换可以用来检测脊椭圆这样,由“边缘像素”,虽然它在计算和存储真的很贵,而且他们是不完美的椭圆所以它必须是一个有点“邋遢”探测器。我从来没有做过,但是Google有很多关于“ 霍夫椭圆检测 ”的结果。我想说的是,如果您在一个特定大小的搜索空间内在另一个椭圆内检测到一个椭圆,则应将其视为气孔。
另请参阅: