命令行工具用于匹配图像相似部分

3 投票
1 回答
647 浏览
提问于 2025-04-17 08:02

我有几千张扫描的图片需要裁剪。我正在写一个脚本,想要根据未裁剪的边框(扫描仪的盖子)来判断源图像是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自己写一个也很简单。基本的步骤是:

  1. 把扫描仪盖子的普通图片加载到一个ndarray中。
  2. 把每张照片/图片也加载到一个ndarray中。
  3. 比较这两者的重要部分,并给它们打分。
  4. 如果分数超过你的设定值……

如果你担心性能问题,第二步可以通过使用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

当然,在实际应用中,你可能需要测量像素值之间的差异,因为每次扫描的亮度和颜色平衡可能会有所不同等等……不过,我觉得花点时间做出一个能用的东西应该不难。

希望这对你有帮助!

撰写回答