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

Ash*_*yan 3 pdf qr-code imagemagick image-processing

我有很多 PDF 扫描文件。

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

我可以用 ImageMagick检测二维码的大概位置,裁剪并只留下那部分吗?

转换后的 png

示例 PDF

转换后的 PNG

Mar*_*ell 5

进一步更新

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

brew install poppler
Run Code Online (Sandbox Code Playgroud)

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

更新答案

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

convert -density 288 pdf2.pdf -crop 100x100 tile%04d.png
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

最后列出的 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
Run Code Online (Sandbox Code Playgroud)

这意味着这些瓷砖

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

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

原答案

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

convert image.png -crop 400x400 tile%03d.png
Run Code Online (Sandbox Code Playgroud)

这给了我 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
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

我使用此命令在其位置周围绘制了一个矩形

convert image.png -stroke red -fill none -strokewidth 3 -draw "rectangle 1200,2400 1600,2800" a.jpg
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

  • 请再看一看 - 就像我说的那样,您可能需要调整磁贴大小,并猜测有关您的文档的一些内容,就像 Kurt 在您原始问题下方的评论/问题中所建议的那样。 (2认同)