结合ImageMagick中“切断”的图像?

时间:2015-01-20 14:06:38

标签: image-processing imagemagick imagemagick-convert

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

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

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

1 个答案:

答案 0 :(得分:2)

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. 但两张图片都使用不同的'画布'尺寸。
  5. 第一张图片使用720x994像素画布(显示部分的偏移量为+10+0)。
  6. 第二张图片使用720x773像素画布(显示部分的偏移量为+10+46)。
  7. 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. 第二列,第三列和第四列以不同方式指示像素的颜色(但它们各自包含相同的信息)。
    4. 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生成的文件中的行175 - 722都匹配。

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

      1. 0img1.png175的行img2.png匹配(匹配开始)。 img1.png共有974行像素。
      2. 547的{​​{1}}行匹配img1.png的行722(匹配结束)。 img2.png共有723行像素。
      3. (请记住,我们使用了基于img2.png的行号...)

        10。现在把它们放在一起

        从上述调查中我们可以得出结论,我们只需要0中的前174行,并在其下方附加完整的img1.png以获得正确的结果:

        img2.png


        <子> <强> 注意:

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

        1. 我们可以使用任何其他ImageMagick支持的格式(PNG,PPM,...)而不是将行转换为'txt'格式,并创建MD5总和以进行比较。
        2. 我们也可以使用 convert img1.png[701x174+0+0] img2.png -append complete.png 来叠加它们(当然还有适当的偏移量),而不是使用-append连接两个图像部分。
        3. 正如@MarkSetchell在他的评论中所说:不是将“像素行”输出汇总到-composite,也可以使用md5sum直接从相应的像素生成哈希值 - 行。我已经忘记了这个选项,因为(几年前)我试图将它用于类似的目的,并且不知何故它不起作用,因为我需要它。这就是为什么我习惯了'管道到md5sum'的方法......