命令行工具用于匹配图像相似部分
我有几千张扫描的图片需要裁剪。我正在写一个脚本,想要根据未裁剪的边框(扫描仪的盖子)来判断源图像是3x5的照片还是4x6的照片,从而进行裁剪。
我找到了一些命令行工具,可以比较和匹配整个图像(使用imagemagick convert),但没有找到可以比较图像中特定区域的工具:
convert img1.jpg "img2.jpg" -compose difference -composite -colorspace gray miff:- | identify -verbose - | sed -n '/^.*mean: */{s//scale=2;/;s/(.*)//;s/$/*100\/32768/;p;q;}' | bc
(通常如果结果小于0.10,就可以认为是匹配的,但这会消耗很多CPU资源)
有没有什么工具或者Python的图像库,可以让我比较两张图片的某些区域,看看它们是否匹配?未裁剪的区域并不是纯白色的,下面的示例图片就能证明这一点(1张3x5,1张4x6)。我只需要匹配前面大约100个像素,显然我不能匹配整个图像。我考虑过复制并裁剪图像,然后将裁剪后的部分与参考图像进行匹配,但这似乎不是最好的方法。
1 个回答
2
我不知道有没有专门的命令行工具可以做到这一点,但其实用numpy
自己写一个也很简单。基本的步骤是:
- 把扫描仪盖子的普通图片加载到一个
ndarray
中。 - 把每张照片/图片也加载到一个
ndarray
中。 - 比较这两者的重要部分,并给它们打分。
- 如果分数超过你的设定值……
如果你担心性能问题,第二步可以通过使用seek()
来优化,只读取文件的一部分,这样可以加快速度。
这是一个关于numpy
部分的概念验证实现:
>>> import numpy as np
>>> scanner_lid = np.ones((5, 5))
>>> scanner_lid
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
>>> photo = np.random.randint(0, 2, (5, 5))
>>> photo
array([[0, 0, 1, 1, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 1, 1],
[1, 1, 0, 0, 1],
[1, 0, 1, 1, 1]])
>>> matching_pixels = scanner_lid[0:2, 0:2] == photo[0:2, 0:2] #compare the top-left 4 pixels
>>> matching_pixels
array([[False, False],
[False, True]], dtype=bool)
>>> np.sum(matching_pixels)
1
当然,在实际应用中,你可能需要测量像素值之间的差异,因为每次扫描的亮度和颜色平衡可能会有所不同等等……不过,我觉得花点时间做出一个能用的东西应该不难。
希望这对你有帮助!