检测黑色&的角度。白色半色调屏幕

时间:2014-06-17 08:38:22

标签: c++ algorithm image-processing

拥有1位黑色&白色半色调图像作为输入,我需要提取用于定位点的角度,如下例所示:

Halftone screen with detected images

我的意图是识别低于特定阈值的所有孤立区域(我可以假设所有点都在20x20区域内)并列出这些点的所有中心点。第二步是对这些特定点运行Hough变换以找到有趣的角度。主要的问题是,这似乎产生了很多点,使霍夫变换(i)变慢,(ii)给出误报,这需要依次过滤掉。

我无法帮助,但感觉我过于复杂,我忽略了一个简单优雅的解决方案。我可能忽略了哪些想法或方法?

2 个答案:

答案 0 :(得分:3)

<强> FFT

尝试对图像运行傅立叶变换。屏幕将产生非常尖锐的频率峰值。通过这些峰值,您甚至可以从嘈杂的图像中获得相当准确的屏幕频率和角度。

我刚刚将图像转换回灰度图像:

Grayscale image with screen dots

然后我在它上面运行2D fft:

FFT power spectrum of the image above

(20,27)处的亮点及其镜像位置是非常强的峰值,比图像中的任何其他值都强。该曲线显示了第20行的功率谱:

enter image description here

因此,y方向上的屏幕频率约为193/20 = 9.7像素(图像高度193),并且在x方向上的屏幕频率为263/27 = 9.7像素。这是每个方向上的点间距离,通常需要一些三角法来计算轴。如果需要,可以通过使用峰值周围的区域从傅立叶功率谱中更精确地插值峰值位置。峰值也可以叠在一起,以减少噪音。

<强>性能吗

FFT是一种相当快速的计算变换(至少与Hough&amp; al相比),但是对于大图像,它需要大量的空间和时间。您可以在几个小区域(例如10个点)上使用它,这也可以帮助您防止屏幕不均匀。至少在那种情况下它会很快。在我的计算机上运行128x128像素2D FFT需要418 us。

有关FFT的说明

不熟悉傅里叶变换的读者应该意识到我在上面和评论中使用了一些草率的语言。变换本身是&#34;傅里叶变换&#34;,FFT只是一种算法(图像处理中的事实上的标准)来执行离散傅里叶变换(DFT)。

在计算FFT和将结果与文献进行比较时往往会让人迷惑的一件事是图像中零频率的位置。在大多数教科书中,零频率(实际上是图像像素值的总和)位于图像的中心。大多数FFT库将零频率放在左上角(如我的例子所示)。

因此,在教科书中,零频率分量通常接近变换图像的中心。对于大多数FFT库,低频接近图像的每个角。 (通常有一些名称如fftshift的函数可以在这两个表示之间进行转换。)

FT是一个复杂的转型。如果变换实值信号(例如单个图像),则在所得到的变换图像中将存在大量对称性。这通常不是很重要,但有时它可以用来加快速度或节省一些内存。

一维FFT的复杂度为O(n log n)。在二维情况下,首先对每列运行FFT,然后每行运行,因此为O(xy log y + yx log x)= O(xy(log x + log y))或O(n ^ 2) log n)用于方形图像。现代计算机使用FFT非常快(并且可以通过使用GPU进一步提升),但是每个方向上有数千个点的大型FFT是一个使用错误算法的警告信号。

答案 1 :(得分:1)

这只是一个想法,我实际上没有尝试过:

  • 运行侵蚀,直到每个点数为1个像素
  • 用最近的一行连接每一个点(我的意思是,只记住该行的参数,不要绘制它)。
  • 连接几个点后(取决于你找到最佳数字)你应该能够平均连接点的线的角度