【问题标题】:Combining images that are "cut off" in ImageMagick?组合在 ImageMagick 中被“截断”的图像?
【发布时间】:2015-01-22 04:27:08
【问题描述】:

我想合并 2 张宽度相同但高度不同的图像。它们在底部/顶部是相同的,但不知道有多少。

1) 识别相同的部分
2)合并图像,使相同的部分匹配

示例:
第 1 部分:http://i.imgur.com/rZtAk2c.png
第二部分:http://i.imgur.com/CQaQbr8.png

【问题讨论】:

标签: image-processing imagemagick imagemagick-convert


【解决方案1】:

1。确定图片尺寸

使用identify获取每张图片的宽高:

identify                          \
   http://i.imgur.com/rZtAk2c.png \
   http://i.imgur.com/CQaQbr8.png

CQaQbr8.png PNG 701x974 720x994+10+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
rZtAk2c.png PNG 701x723 720x773+10+46 8-bit sRGB 256c 25.6KB 0.000u 0:00.000

2。解读结果

上述命令的结果如下:

  1. 两幅图像显示 701 像素宽行。
  2. 一张图片显示974 不同的行。
  3. 另一张图片显示 723 不同的行。
  4. 但两张图片使用不同的'canvas'尺寸。
  5. 第一张图片使用720x994 像素画布(所示部分的偏移量为+10+0)。
  6. 第二张图片使用720x773 像素画布(所示部分的偏移量为+10+46)。

3。将画布标准化为与显示的像素相同

我们使用+repage 图像运算符来规范化两个图像的画布:

convert CQaQbr8.png +repage img1.png
convert rZtAk2c.png +repage img2.png

   

4。再次检查两个新图像的尺寸

identify img1.png img2.png

 img1.png PNG 701x974 701x974+0+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
 img2.png PNG 701x723 701x723+0+0 8-bit sRGB 256c 25.5KB 0.000u 0:00.000

5。了解如何从图像中提取单行。

例如,我们从img1.png中提取第3行(编号以0开头):

convert img1.png[701x1+0+3] +repage img1---row3.png

identify img---row3.png
  img1---row3.png PNG 701x1 701x1+0+0 8-bit sRGB 256c 335B 0.000u 0:00.000

6。了解如何以 ImageMagick 的“txt”格式提取同一行:

convert img1.png[701x1+0+3] +repage img---row3.txt

如果您不熟悉“txt”格式,这里是摘录:

cat img---row3.txt
 # ImageMagick pixel enumeration: 701,1,255,gray
 0,0:   (255,255,255)  #FFFFFF  gray(255)
 1,0:   (255,255,255)  #FFFFFF  gray(255)
 2,0:   (255,255,255)  #FFFFFF  gray(255)
 3,0:   (255,255,255)  #FFFFFF  gray(255)
 4,0:   (255,255,255)  #FFFFFF  gray(255)
 5,0:   (255,255,255)  #FFFFFF  gray(255)
 6,0:   (255,255,255)  #FFFFFF  gray(255)
 7,0:   (255,255,255)  #FFFFFF  gray(255)
 8,0:   (255,255,255)  #FFFFFF  gray(255)
 9,0:   (255,255,255)  #FFFFFF  gray(255)
 [...skipping many lines...]
 695,0: (255,255,255)  #FFFFFF  gray(255)
 696,0: (255,255,255)  #FFFFFF  gray(255)
 697,0: (255,255,255)  #FFFFFF  gray(255)
 698,0: (255,255,255)  #FFFFFF  gray(255)
 699,0: (255,255,255)  #FFFFFF  gray(255)
 700,0: (255,255,255)  #FFFFFF  gray(255)
  1. “txt”输出文件通过文本行描述每个像素。
  2. 在每一行中,第一列表示相应像素的坐标。
  3. 第二、第三和第四列以不同的方式表示像素的颜色(但它们各自包含相同的信息)。

7。将每一行转换成它的 'txt' 格式并创建它的 MD5 和

此命令还创建“txt”输出。但这次“目标”文件以txt:- 给出。这意味着输出流式传输到<stdout>

for i in {0..973}; do                       \
  convert img1.png[701x1+0+${i}] txt:-      \
     | md5sum > md5sum--img1--row${i}.md5 ; \
done

此命令创建 974 个不同的文件,其中包含相应行的 'txt' 表示的 MD5 和。

我们还可以将所有 MD5 和写入单个文件:

for i in {0..973}; do                         \
  convert img1.png[701x1+0+${i}] txt:-        \
     | md5sum >> md5sum--img1--all-rows.md5 ; \
done

现在对img2.png做同样的事情:

for i in {0..722}; do                         \
  convert img2.png[701x1+0+${i}] txt:-        \
     | md5sum >> md5sum--img2--all-rows.md5 ; \
done

8。使用sdiff 确定.md5 文件的哪些行匹配

我们可以使用 sdiff 逐行比较两个.md5 文件并将输出写入日志文件。以下命令的nl -v 0 部分会自动在结果中插入以0 开头的行号:

sdiff md5sum--img{1,2}--all-rows.md5 | nl -v 0 > md5sums.log

9。检查md5sums.log 是否有相同的行

 cat md5sums.log

     0                                       > 38c6cd70c39ffc853d1195a0da6474f8  -
     1                                       > 85100351b390ace5a7caca11776666d5  -
     2                                       > 66e2940dbb390e635eeba9a2944960dc  -
     3                                       > 8e93c1ed5c89aead8333f569cb768e4a  -
     4                                       > 8e93c1ed5c89aead8333f569cb768e4a  -
        [... skip many lines ...]
   172                                       > f9fece874b60fa1af24516c4bcee7302  -
   173                                       > edbe62592a3de60d18971dece07e3beb  -
   174                                       > 18a28776cc64ead860a99213644b0574  -
   175  0d0753c587dc3c46078ac265895a3f6c  -  | 0d0753c587dc3c46078ac265895a3f6c  -
   176  5ecc2b5a61af4120151fed4cd2c3d305  -  | 5ecc2b5a61af4120151fed4cd2c3d305  -
   177  3f2857594fe410dc7fe42b4bef724a87  -  | 3f2857594fe410dc7fe42b4bef724a87  -
   178  2fade815d804b6af96550860602ec1ba  -  | 2fade815d804b6af96550860602ec1ba  -
        [... skip many lines ...]
   719  127e6d52095db20f0bcb1fe6ff843da0  -  | 127e6d52095db20f0bcb1fe6ff843da0  -
   720  aef15dde4909e9c467f11a64198ba6d2  -  | aef15dde4909e9c467f11a64198ba6d2  -
   721  6320863dd7d747356f4b23fb7ba28a73  -  | 6320863dd7d747356f4b23fb7ba28a73  -
   722  2e32ceb7cc89d7bb038805e484dc7bc9  -  | 2e32ceb7cc89d7bb038805e484dc7bc9  -
   723  f9fece874b60fa1af24516c4bcee7302  -  <
   724  f9fece874b60fa1af24516c4bcee7302  -  <
   725  f9fece874b60fa1af24516c4bcee7302  -  <
   726  f9fece874b60fa1af24516c4bcee7302  -  <
        [... skip many lines ...]
  1146  3e18a7db0aed8b6ac6a3467c6887b733  -  <
  1147  62866c8ef78cdcd88128b699794d93e6  -  <
  1148  7dbed48a0e083d03a6d731a6864d1172  -  <

从这个输出中,我们可以得出结论,sdiff-produced 文件中的第 175 - 722 行都匹配。

这意味着原始图像的以下行中存在匹配:

  1. img1.png 的行 0 匹配 img2.png 的行 175(匹配开始)。 img1.png 共有 974 行像素。
  2. img1.png 的行 547 匹配 img2.png 的行 722(匹配结束)。 img2.png 共有 723 行像素。

(请记住,我们使用基于0 的行编号...)

10.现在把它们放在一起

从以上调查我们可以得出结论,我们只需要 img1.png 的前 174 行并将完整的 img2.png 添加到其下方以获得正确的结果:

 convert img1.png[701x174+0+0] img2.png -append complete.png


注意:

对于 OP 提出的问题,有许多可能的解决方案(以及到达那里的方法)。例如:

  1. 除了将行转换为“txt”格式外,我们还可以使用任何其他 ImageMagick 支持的格式(PNG、PPM、...)并创建 MD5 和以进行比较。李>
  2. 除了使用-append 来连接两个图像部分,我们还可以使用-composite 来叠加它们(当然要使用适当的偏移量)。
  3. 正如@MarkSetchell 在他的评论中所说:除了将“像素行”输出传送到md5sum 之外,还可以使用-format '%#' info:- 直接从相应的像素行生成哈希值。我已经忘记了那个选项,因为(几年前)我试图将它用于类似的目的,但不知何故它没有按我的需要工作。这就是为什么我习惯了我的“管道到 md5sum”方法...

【讨论】:

  • 感谢您花时间写出如此详细的答案!如果可行,我将尝试对此进行测试并接受答案。 :)
  • @Joona:哦?我不知道。
  • 嗨,Kurt,您可能想添加另一个注释...我认为您可以像这样直接从 IM 获取校验和 convert image.png[0x1+0+)] -format "%#" info:
  • 感谢您的超详细说明,我设法使用 Pillow 在 Python 中完成了所有工作! :) 这也是代码:pastebin.com/RRXfXV21(它会扫描目录中的 .png 文件,并期望它们的顺序正确,并且不会执行您的第 3 步,但至少它可以工作)。
  • @Joona:我的第 3 步是“安全网”:大多数图像不需要,但对于某些图像仍然是必需的。您只有在首先查看输入图像时才知道是否需要应用它。
猜你喜欢
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多