用于识别2D特征的图像处理

mah*_*udz 3 opencv image-processing

我创建了一个iPhone应用程序,可以扫描一页方格纸的图像,然后可以告诉我哪些方块已被涂黑,哪些方块是空白的.

我这样做是通过从左到右扫描并使用方格纸的线作为指南.当我遇到方格纸线时,我开始寻找黑色,直到我再次点击方格纸线.然后,我继续沿着扫描线继续前进,完全扫描方块为黑色.然后我继续下一个方框.在该行的最后,我在新行开始扫描之前跳过这么多像素(因为我已经弄清楚每个盒子有多高).

这种作品,但有问题.有时我把图形线误认为是"黑色".有时,如果图像歪斜,或者我的页面上没有均匀的照明,那么我就不会得到好的结果.

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

鉴于这是我的第一个图像处理项目,我觉得我正在重新发明轮子.我想知道如何做到这一点,以及是否利用像OpenCV这样的库.

我附上的图像类似于我想要处理的图像.我正在寻找具有大量黑色标记的所有正方形的列表,即A8,C4,E7,G4,H1,J9. 在此输入图像描述

需要注意的问题:

  • 图像的光线覆盖可能不理想,但在整个图像中应该相对一致(即没有阴影)
  • 所有方块都可以是空的或全黑的,算法需要能够确定
  • 图像可以绕任何轴倾斜或旋转.绕z轴的旋转可能很容易修复.可以围绕x轴或y轴旋转,使得图像的一侧比另一侧宽.但是,如果我实时扫描图像来自相机,我可以要求用户将对齐标记与屏幕上的标记对齐.如何最好地确保对齐以便为用户提供适当的反馈?只需检查以确保4个角落较暗可能会在相机指向黑色表面时导致误报.
  • 不是每个方块都会同样或持续地涂黑,但我认为会有足够的黑色使人眼无可置疑.
  • 蓝色网格可能很有用,但有时黑色标记可能与蓝色网格重叠.我认为虚拟网格可能比依赖打印网格更好.我认为使用对齐标记来对齐图像,然后可以布置精确的虚拟网格.然后可以对每个网格框的内容进行采样,以查看它是否主要是黑色,而不是从左到右扫描,不是吗?这是另一个在网格上有更多标记的图像.在此图像中,除了A8,C4,E7,G4,H1,J9中的先前标记外,我还标记了E2,G8和G9,以及I4和J4,您可以看到蓝色网格是如何被遮挡的.

第二张图片

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

Mau*_*its 5

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

就个人而言,我认为最简单的方法是检测图像中的方块.

1)删除背景和小瑕疵

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

在此输入图像描述

2)删除除正方形和圆形之外的所有内容.

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

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

3)使用'extend'检测方块regionprops."范围"度量标准衡量填充边界框的比例.这使得它成为区分圆形和正方形的好方法

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

在此输入图像描述

4)这将为您提供功能,同步或纠正图像.一种简单而强大的方法是通过自相关函数.

在此输入图像描述

这提供了很好的峰值,很容易检测到.可以通过匈牙利算法将这些峰与来自模板图像的ACF峰匹配.匹配后,您可以校正旋转和缩放,因为您现在拥有一个可以解决的线性系统:

x = Ax'

然后可以使用针对相同的预定义模板的普通交叉相关来校正翻译.

如果一切顺利,您就会知道对齐或同步的图像,这有助于确定点的位置.