抱歉,我不知道 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)
霍夫变换可以用来检测像这样由“边缘像素”组成的脊椭圆,尽管它在计算和内存方面确实很昂贵,而且它们不是完美的椭圆,所以它必须是一个有点“草率”的检测器。我从来没有做过,但是有很多关于“霍夫椭圆检测”的谷歌结果。我会说,如果您在一定大小的搜索空间内检测到另一个椭圆内的一个椭圆,则应将其视为造口。
另见: