6

在过去的两天里,我一直在浏览帖子和示例,我尝试过并经过广泛测试的所有片段都被证明是毫无用处的,至少对我来说是这样。

我想做的是比较从墙上或纸上拍摄的黑色矢量符号(质量类似于人们可能会说的扫描不良的图像),并将其与相同或相似符号的电子版本(将存储在本地和与照片相比)。请看一下所附的两张图片,第一张干净的(参考图片)是符号的数据库版本,第二张是我在一张纸上画的蹩脚的图画,然后用我的 iPad 拍照。

参考图像

测试图像

我希望程序如下:

  • 加载这两个图像,然后使用我在此处找到的此修剪算法的修改版本进行修剪:使用 PIL 修剪图像。我发现 50 的“阈值”值和 20 的“明显性”值(链接脚本中的参数)为这些图像提供了良好的结果
  • 然后将图像调整为相同大小并进行比较

现在为了比较,我尝试了很多不同的建议方法,但到目前为止结果很糟糕。实际上,我可以通过随机图像获得比测试图像更好的比较结果。我已经尝试了基于实际图像的RMS 差异比较,它们的边缘(使用 ImageFilter.CONTOUR 或 ImageFilter.FIND_EDGES 的“过滤器”函数创建),基于像素的比较,但到目前为止我在网上找不到任何东西(尽管我不断地谷歌搜索)或者在 StackOverflow 中给了我不错的结果。

我认为问题在于测试图像的嘈杂背景,但我无法证明这一点。有谁知道是否有办法从这些图像的边缘中获取矢量轮廓,并将它们不仅作为图像进行比较,而且作为图像矢量进行比较?尽管我的画很糟糕,但我发现这两张图片非常相似,应该可以从中得到一个很好的比较。

4

5 回答 5

5

为了获得更好的响应,您需要更好地限制应用程序的范围。这里有一些可以帮助你的东西。我想您的“糟糕的绘图”输入始终与您提供的输入相似,因为它具有很强的边缘,并且其上存在的颜色无关紧要。要以简单的方式解决(或者更好地接近解决方案)您的问题,您需要根据尺度不变描述符来描述这两个图像。

我对此的看法:对两个图像进行二值化,计算两个图像中的连接组件(CC)的数量,丢弃不相关大小的 CC(离中位数太远,平均值,与 stddev 相关等,你决定)。您可能想要补充第二步,以便更好地将您的图像与其他输入区分开来,即,您希望您的方法越强大,您需要的判别描述符就越多。在某些时候,您可能还想考虑使用 SVM 或其他机器学习技术。

因此,二值化步骤:执行形态梯度并丢弃弱梯度。如果输入与发布的内容相似,这将非常容易。这是我在强度为 60 时得到的阈值(我还假设您的输入在 [0, 255] 范围内):

在此处输入图像描述 在此处输入图像描述

我很快尝试了直到 90 的阈值,所有这些阈值都适用于这些图像。裁剪这些很容易,您还可以填充背景和对象:

在此处输入图像描述 在此处输入图像描述

现在您可以提取白色的连接组件并对其进行分析。在这种情况下,最简单的方法就是对它们进行计数。对于这些输入,我们在“完美”图像中得到 12 个,在“坏”图像中得到 14 个。但是,在“坏”的部分中,我们有 2 个大小为 1 的组件(每个组件中只有一个像素),它们被简单地消除了。还有许多其他方法可以比较连接的组件,但我希望这可以帮助您入门。如果您需要这些任务的代码,我可以将其包含在内。

于 2012-12-01T21:15:39.830 回答
1

我不确定如何专门使用 PIL 来做到这一点,但我可以为您指出一些很好的工作示例来帮助您自学(这是图像处理的一项重要任务!)。

一个很好的工作示例是DeTeXify,这是一个将鼠标绘制的符号与大量已知符号库相匹配的程序(在这种情况下,符号可以在排版程序 LaTeX 中创建)。前端和后端的源代码都可用。

另一个例子是ShapeCatcher,它:

... 使用所谓的“形状上下文”来查找两个形状之间的相似性。形状上下文是描述形状之间相似性概念的一种强大的数学方法,是由 Serge Belongie 和 Jitendra Malik 首次提出的特征描述符。

可以在他们的伯克利网站上找到关于形状上下文的免费研究论文。

于 2012-11-30T15:01:12.627 回答
0

有一种方法称为SIFT。OpenCV 使用它,并且在 Python OpenCV 中也有一个实现。实现是OpenCV中的SURF,各种问题和例子都能找到,效果很好。这个问题有一个例子。

(发布此答案作为额外参考)

于 2012-12-03T11:05:59.093 回答
0

我认为,如果您将线可视化为图形上的边,而将交叉点可视化为节点,即使一个很丑,计算机也应该能够看到它们是相同的符号。只需使用关卡来获得您的白人和黑人,然后尝试分析连续的黑点。

于 2012-11-30T14:11:58.173 回答
0

我知道这已经得到了回答,但也许有人仍然会找到这个。

与公认的答案不同,我不会处理梯度来执行二值化,而是查看Otsu 的 Thresholding。如果您的所有图像仅包含非常暗和非常亮的区域,这应该会很好,因为它会查找图像直方图中的两个峰值(一个用于所有亮像素,一个用于所有暗像素),然后在值上设置阈值两峰之间。

于 2017-06-13T18:28:04.943 回答