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检测二维码的大概位置,裁剪并只留下那部分吗?

进一步更新
我看到您首先与 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 个图块。但我认为它可以构成一种方法的基础。