我需要检测扫描图像中 QR 码的大致位置(PDF 转换为 PNG)

Posted

技术标签:

【中文标题】我需要检测扫描图像中 QR 码的大致位置(PDF 转换为 PNG)【英文标题】:I need detect the approximate location of QR code in scanned image (PDF converted to PNG) 【发布时间】:2015-07-13 12:00:38 【问题描述】:

我有很多 PDF 格式的扫描文档。

我使用 ImageMagick 和 Ghostscript 将 PDF 转换为大密度的 PNG。我使用convert -density 288 2.pdf 2.png。之后,我用 php 读取像素并找到 QR 码并对其进行解码。因为图像非常大(~ 2500px),它需要非常多的 RAM。我想,在我用 PHP 读取像素之前,用 ImageMagick 裁剪图像,只留下 QR 码的那部分。

我可以用 ImageMagick 检测 QR 码的大致位置,然后裁剪并只留下那部分吗?

Sample PDF

Converted PNG

【问题讨论】:

您能否就您的二维码的位置和其他细节提供更多提示?例如:它们总是相同的尺寸和相同的 QR 版本吗?他们的位置总是在页面的右半边吗?对于一般情况,任何可以使任务更容易完成的事情......(对于发布的示例来说很容易完成)。 我不需要解码,但只需要留下二维码的一部分,不完全是二维码,而是像这样缩小dl.dropboxusercontent.com/u/59611541/2_crop.png我不知道放置在哪里,并且图片和二维码的大小会有所不同。 一般提示:您的示例 PDF 页面基本上只包含一个图像。如果您的所有(或至少许多)文档都是这样,您应该提取这些图像,而不是将 PDF 呈现为新图像。它们是您可以获得的最佳品质。 @mkl:我会用什么程序? 我将使用什么程序 - 也许@KurtPfeifle 或其他人可以在这里提供帮助。我更喜欢编写 PDF 处理工具的编程,我不知道现有的工具有多好。 【参考方案1】:

进一步更新

我看到您首先与 Kurt 讨论了如何更好地从 PDF 中提取图像,他的建议是使用 pdfimages。我只是想补充一点,如果你这样做brew search pdfimages,你不会发现,但你实际上需要使用

brew install poppler

然后你会得到pdfimages 可执行文件。

更新答案

如果您在裁剪命令中将图块大小更改为 100x100 并为您提供的第二个 PDF 运行此命令:

convert -density 288 pdf2.pdf -crop 100x100 tile%04d.png

然后使用相同的熵分析命令

convert -format "%[entropy]:%X%Y:%f\n" tile*.png info: | sort -n
...
...
0.84432:+600+3100:tile0750.png
0.846019:+600+2800:tile0678.png
0.980938:+700+400:tile0103.png
0.984906:+700+500:tile0127.png
0.988808:+600+400:tile0102.png
0.998365:+600+500:tile0126.png

最后列出的 4 个图块是

同样,对于您提供的其他 PDF 文件,您会得到

0.863498:+1900+500:tile0139.png
0.954581:+2000+500:tile0140.png
0.974077:+1900+600:tile0163.png
0.97671:+2000+600:tile0164.png

这意味着这些瓷砖

我认为这应该可以帮助您大致定位 QR 码。

原答案

这并不是那么科学,但它可以帮助您入门。我认为,关键是图像各个区域的熵。二维码在一个小区域内编码了很多信息,因此它应该具有高熵。因此,我使用 ImageMagick 将图像拆分为 400x400 的正方形图块,如下所示:

convert image.png -crop 400x400 tile%03d.png

这给了我 54 块瓷砖。然后我计算每个图块的熵并通过增加熵对它们进行排序,还输出它们从框架左上角的偏移量和它们的名称,如下所示:

convert -format "%[entropy]:%X%Y:%f\n" tile*.png info: | sort -n

0.00408949:+1200+2800:tile045.png
0.00473755:+1600+2800:tile046.png
0.00944815:+800+2800:tile044.png
0.0142171:+1200+3200:tile051.png
0.0143607:+1600+3200:tile052.png
0.0341039:+400+2800:tile043.png
0.0349564:+800+3200:tile050.png
0.0359226:+800+0:tile002.png
0.0549334:+800+400:tile008.png
0.0556793:+400+3200:tile049.png
0.0589632:+400+0:tile001.png
0.0649078:+1200+0:tile003.png
0.10811:+1200+400:tile009.png
0.116287:+2000+3200:tile053.png
0.120092:+800+800:tile014.png
0.12454:+0+2800:tile042.png
0.125963:+1600+0:tile004.png
0.128795:+800+1200:tile020.png
0.133506:+0+400:tile006.png
0.139894:+1600+400:tile010.png
0.143205:+2000+2800:tile047.png
0.144552:+400+2400:tile037.png
0.153143:+0+0:tile000.png
0.154167:+400+400:tile007.png
0.173786:+0+2400:tile036.png
0.17545:+400+1600:tile025.png
0.193964:+2000+400:tile011.png
0.209993:+0+3200:tile048.png
0.211954:+1200+800:tile015.png
0.215337:+400+2000:tile031.png
0.218159:+800+1600:tile026.png
0.230095:+2000+1200:tile023.png
0.237791:+2000+0:tile005.png
0.239336:+2000+1600:tile029.png
0.24275:+800+2400:tile038.png
0.244751:+0+2000:tile030.png
0.254958:+800+2000:tile032.png
0.271722:+2000+2000:tile035.png
0.275329:+0+1600:tile024.png
0.278992:+2000+800:tile017.png
0.282241:+400+1200:tile019.png
0.285228:+1200+1200:tile021.png
0.290524:+400+800:tile013.png
0.320734:+0+800:tile012.png
0.330168:+1600+2000:tile034.png
0.360795:+1200+2000:tile033.png
0.391519:+0+1200:tile018.png
0.421396:+1200+1600:tile027.png
0.421421:+2000+2400:tile041.png
0.421696:+1600+2400:tile040.png
0.486866:+1600+1600:tile028.png
0.489479:+1600+800:tile016.png
0.611449:+1600+1200:tile022.png
0.674079:+1200+2400:tile039.png

而且,嘿,很快,列出的最后一个(即熵最高的那个)tile039.png 就是这个。

我使用这个命令在它的位置周围画了一个矩形

convert image.png -stroke red -fill none -strokewidth 3 -draw "rectangle 1200,2400 1600,2800" a.jpg

我承认这可能涉及运气,但我只有一张图片来检验我的疯狂理论。您可能需要平铺两次,第二次使用半个平铺宽度的 x 偏移和 y 偏移,这样您就不会剪切 QR 码并将其拆分为 2 个平铺。对于不同尺寸的条形码,您可能需要不同尺寸的瓷砖。您可能需要考虑为您的下一个算法定位的最后 3-5 个图块。但我认为它可以构成一种方法的基础。

【讨论】:

但是我需要二维码可以在哪里,大小可以不一样。 dl.dropboxusercontent.com/u/59611541/1.pdfdl.dropboxusercontent.com/u/59611541/3.pdfdl.dropboxusercontent.com/u/59611541/4.pdf @MarkSetchell:非常好的方法!您还可以通过发现以下情况来“完善”它:对整个页面进行分段会导致二维码也被拆分,因此它不会完全包含在一个图块中,而是分布在 2 个甚至 4 个图块中。 @KurtPfeifle 谢谢。我可能可以按照你说的做,但我怀疑你会在几分钟内产生一个更简单、更准确、像素完美的方法:-) 请再看看 - 就像我说的那样,您可能需要调整图块大小,并猜测有关您的文档的一些内容,就像 Kurt 在他的评论/问题中在您原始问题下方的建议一样。 查看更新后的答案,其中包含改进的从 PDF 中初始提取图像的功能,而不是让 ImageMagick 将它们呈现为新图像。

以上是关于我需要检测扫描图像中 QR 码的大致位置(PDF 转换为 PNG)的主要内容,如果未能解决你的问题,请参考以下文章

无法获取 QR 码的正确坐标,ARKit - Swift

qr码和二维码区别

通过在图像标签中传递链接生成 QR 码扫描仪

移动 - 从相机扫描文本,无需拍照

读取QR码 - base64图像高度和宽度

QR(write2DBarcode)TCPDF上的代码