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

Posted

技术标签:

【中文标题】用于识别 2D 特征的图像处理【英文标题】:Image Processing for recognizing 2D features 【发布时间】:2012-03-19 20:36:48 【问题描述】:

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

我通过从左到右扫描并使用方格纸的线条作为指南来做到这一点。当我遇到方格纸线时,我开始寻找黑色,直到我再次击中方格纸线。然后,我不再沿着扫描线继续,而是继续完全扫描正方形的黑色。然后我继续下一个框。在行尾,我在开始新行扫描之前跳过了这么多像素(因为我已经计算出每个框的高度)。

这种工作,但有问题。有时我将图形线误认为是“黑色”。有时,如果图像偏斜,或者整个页面的光照不均匀,那么我就不会得到好的结果。

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

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

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

需要注意的问题:

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

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

【问题讨论】:

请发几张实际照片。 @Maurits 添加。谢谢你的要求。 算法可以使用蓝色网格吗? 在第一次迭代中,是的。然而,在未来,为了使机制更加稳健,它可能应该创建自己的虚拟边界,而不是依赖蓝色网格。我正在发布另一张图片以显示标记如何与蓝色网格重叠并可能导致问题。 【参考方案1】:

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

The DNA microarray image processing The Matlab Sudoku solver The Iphone Sudoku solver博文,解释图像处理

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

1) 去除背景和小杂物

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

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

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

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

3) 使用来自regionprops 的“扩展”检测正方形。 “范围”指标衡量边界框的填充比例。这使它成为 区分圆形和正方形的好方法

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

4) 这让您可以使用您的功能来同步或校正图像。一种简单而可靠的方法是使用自相关函数。

这会产生很好的峰,很容易检测到。这些峰值可以通过匈牙利算法与模板图像中的 ACF 峰值进行匹配。匹配后,您可以更正旋转和缩放,因为您现在有一个可以解决的线性系统:

x = Ax'

然后可以使用针对相同预定义模板的普通互相关来纠正翻译。

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

【讨论】:

谢谢。这给了我很多思考。您的示例是 MatLab 代码,对吗? iPhone Soduku 链接非常有帮助。我也会研究 OpenCV。 它是 Matlab,我可以分享一个函数,如果你愿意,我可以做任何事情。 iPhone开发我帮不了你... 我很想看看一些 C 代码,如果有的话。但是像你给我的那样获得一般的想法也很有帮助。我可以轻松地做黑白、 和逆。我不确定 bwareaopen、strele 和 imerode 是做什么的,但我想我可以轻松查找它们。我也很好奇 OpenCV 做了多少。然后,我有这样的想法,一旦我把所有东西都关联起来,我可以很容易地查看我可以找到圆圈的位置,并检测它们——因为它们要么是白色的,要么是黑色的,而不必与周围环境形成对比。 另外,您认为 MatLab 是一个很好的工具,在决定编写我自己的代码来做类似的事情之前必须测试所有可能性? 一切都可以通过opencv来完成,我相信。总的来说,我认为对于图像处理,Matlab 是最容易进行原型(和学习)的工具和环境。编写脚本很容易,它的工具箱和文档形成了一个很好的综合包。免费选项是 python + numpy/scipy 和 opencv 绑定。【参考方案2】:

我已经开始使用我的GPUImage ios 框架做一些类似的事情,所以这可能是在 OpenCV 或其他东西中做所有这些的替代方法。顾名思义,GPUImage 完全基于 GPU,因此与 CPU 密集型处理相比,它具有一些巨大的性能优势(处理实时视频等操作的速度提高了 180 倍)。

作为第一阶段,我拍摄了您的图像,并通过一个阈值为 0.5 的简单亮度阈值过滤器运行它们,并为您的两张图像得出以下结果:

我刚刚添加了一个自适应阈值过滤器,它尝试校正局部照明差异,并且非常适合挑选文本。但是,在您的图像中,它使用的平均半径太小而无法很好地处理您的斑点:

并且似乎带出了你的网格线,听起来你想忽略它。

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

这些基于 GPU 的阈值运算在 iPhone 4 上运行 640x480 帧的时间不到 2 毫秒,因此可以将过滤器链接在一起以尽可能快地分析传入的视频帧,因为设备的摄像机可以提供它们。

【讨论】:

我现在看到了您指向 GPUImage 的链接。将进行调查。

以上是关于用于识别 2D 特征的图像处理的主要内容,如果未能解决你的问题,请参考以下文章

尺度不变特征方法在图像识别与目标定位中的应用(上)

人脸识别技术

人脸识别技术

论文推介|融合判别式深度特征学习的图像识别算法

使用 PCA 进行图像分析/特征提取

人脸识别到底是怎么个过程呢?