2012-03-19 56 views
3

我已经创建了一个iPhone应用程序,可以扫描方格纸页面的图像,然后可以告诉我哪些方块已被黑掉,哪些方块为空。用于识别2D特征的图像处理

我通过从左到右扫描并使用方格纸的线条作为参考。当我遇到一个方格纸线时,我开始寻找黑色,直到我再次点击方格纸线。然后,我继续沿着扫描线继续前进,并完全扫描黑色方块。然后我继续到下一个框。在该行的最后,我开始扫描新行之前忽略了很多像素(因为我已经知道每个盒子的高度)。

这类作品,但有问题。有时我会将图形线条误认为“黑色”。有时,如果图像偏斜,或者整个页面没有统一的光照,那么我的效果不好。

我想要做的是指定一些“对齐”框,然后调整大小并旋转(和倾斜)图片以与这些对齐。然后,我想,一旦我将图像对齐后,我就会知道所有的盒子在哪里,不需要扫描盒子,只需扫描盒子的位置,看它们是否是黑色的。这应该更快,更可靠。如果我要操作来自相机的图像,我会更灵活地要求用户对齐图片以匹配对齐标记,而不必自己对齐图像。

鉴于这是我的第一个图像处理项目,我觉得我正在重新发明轮子。我想就如何做到这一点以及是否利用OpenCV等库提出建议。

我附上了一张类似于我想处理的图像。我正在寻找有大量黑色标记的所有方块的列表,即A8,C4,E7,G4,H1,J9。 enter image description here

需要注意的问题的:

  • 图像的光覆盖范围可能不理想,但应该是在图像相对一致的(即无阴影)
  • 所有的广场可能是空的或全黑,并且该算法需要能够确定图像可能偏斜或围绕任何轴旋转。围绕z轴旋转可能很容易修复。围绕x或y轴可能会有旋转,使图像的一侧比另一侧宽。但是,如果我从相机中实时扫描图像,我可以要求用户将对齐标记与屏幕上的标记对齐。如何最好地确保对齐以给用户提供适当的反馈?只要检查以确保4个角落是黑暗的,当相机指向黑色表面时可能会导致误报。
  • 并非每一个方格都会同样或一致地变黑,但我认为会有足够的黑色使它对人眼无可怀疑。
  • 蓝色网格可能很有用,但有些情况下黑色标记可能与蓝色网格重叠。我认为虚拟网格可能比依靠印刷网格更好。我认为使用对齐标记来对齐图像可以实现精确的虚拟网格布局。然后可以对每个网格框的内容进行采样,以查看它是否主要是黑色,与从左到右的扫描相比,不是?这是另一幅在网格上有更多标记的图像。在这张图片中,除了之前在A8,C4,E7,G4,H1,J9中的标记之外,我标记了E2,G8和G9以及I4和J4,您可以看到蓝色网格是如何被遮挡的。

2nd image

  • 这是我这个项目的第一阶段。最终,我想扩展这种算法,以便能够处理至少几百个插槽和可能不同的颜色。
+1

请发表几个实际的图片。 – Maurits 2012-03-19 21:29:36

+0

@Maurits补充说。感谢您的要求。 – mahboudz 2012-03-19 22:06:51

+0

算法可以使用蓝色网格吗? – Maurits 2012-03-20 22:03:48

回答

5

首先,这个问题让我想起了一下这些演示的的,可能是从学习有用:

个人而言,我认为最简单的方法是检测s夸张在你的形象。

1)取下的背景和小的cruft

f_makebw = @(I) im2bw(I.data, double(median(I.data(:)))/1.3); 
bw = ~blockproc(im, [128 128], f_makebw); 
bw = bwareaopen(bw, 30); 

enter image description here

2)拆下的一切,但正方形和圆形。

se = strel('disk', 5); 
bw = imerode(bw, se); 

% Detect the squares and cricles via morphology 
[B, L] = bwboundaries(bw, 'noholes'); 

3)使用regionprops的'extend'检测正方形。 “范围”度量度量了边框的哪个比例被填充。这使得它 不错的措施,圆形和方形

stats = regionprops(L, 'Extent'); 
extent = [stats.Extent]; 
idx1 = find(extent > 0.8); 
bw = ismember(L, idx1); 

enter image description here

4)这让你与你的功能进行区分,以同步或纠正与图像。一个简单而可靠的方法就是通过自相关函数。

enter image description here

这给了很好的峰值,这很容易被发现。这些峰可以通过匈牙利算法与来自模板图像的ACF峰匹配。一旦匹配,则可以纠正旋转和缩放,你现在具有可以求解线性系统:

x = Ax'

翻译然后可以使用针对所定义的相同的预运行的设施,工厂互相关来校正模板。

如果一切顺利,您知道有一个对齐或同步的图像,这应该有助于确定点的位置。

+0

谢谢。这给了我很多想法。你的例子是MatLab代码,对吗? iPhone Soduku链接非常有帮助。我也会研究OpenCV。 – mahboudz 2012-03-22 21:28:41

+0

这是Matlab,我可以共享一个功能,如果你想要做任何事情。随着iPhone的发展,我不能帮你... – Maurits 2012-03-22 21:51:23

+0

我很想看到一些C代码,如果可用的话。但是获得一般想法,就像你给我的一样,也是有帮助的。我可以很容易地做到黑白,和反。我不确定bwareaopen,strele和imerode是做什么的,但我想我可以很容易地看到它们。我也很好奇OpenCV做了多少。 然后,我有这样的想法,一旦我有一切相关,我可以很容易地看看我可以期望找到圈子的位置,并检测它们 - 因为它们将是白色或黑色,并且不会有与周围环境区分开来。 – mahboudz 2012-03-24 02:09:03

3

我已经开始使用我的GPUImage iOS框架做类似的事情,所以这可能是在OpenCV或其他方面做所有这些的替代方案。正如其名称所示,GPUImage完全基于GPU,所以它可以比CPU绑定处理带来巨大的性能优势(处理实况视频等处理速度高达180倍)。

在第一阶段,我把你的图像,并把它们放到了与0.5阈值的简单的亮度阈值过滤,抵达你的两个图像以下几点:

Threshold image 1 Threshold image 2

我只是增加了一个自适应阈值滤波器,该滤波器试图校正局部光照变化,并且非常适合拾取文本。然而,在你的图片,它使用过小的平均半径来处理您的blob好:

Adaptive threshold image 1 Adaptive threshold image 2

,似乎衬托出你的网格线,它听起来像你希望忽略。

Maurits提供了一个更全面的描述你可以做什么,但可能有一种方法来实现这些处理操作作为高性能的基于GPU的过滤器,而不是依赖相同计算的较慢的OpenCV版本。如果您可以从此阈值图像中获取旋转和缩放信息,则可以构建一个转换,该转换也可以作为筛选器应用于阈值图像,以生成最终对齐的图像,然后可以由应用程序对其进行降采样并读出,以确定这些网格位置被填充。

这些基于GPU的阈值操作对于iPhone 4上的640x480帧运行时间小于2毫秒,因此可以将滤波器链接在一起以分析传入视频帧的速度与设备的速度一样快摄像机可以提供它们。

+0

这听起来很强大。我在哪里可以学到更多? – mahboudz 2012-03-27 10:32:48

+0

我现在看到您的链接到GPUImage。将调查。 – mahboudz 2012-03-27 10:34:42