了解透视投影失真ImageMagick

时间:2012-09-05 07:00:37

标签: imagemagick command-line-interface perspective

对于一个项目,我试图创建一个图像的透视扭曲,以匹配DVD案例前端模板。所以我想使用ImageMagick(CLI)自动执行此操作,但我很难理解这种转换的数学方面。

convert \
  -verbose mw2.png \
  -alpha set \
  -virtual-pixel transparent \
  -distort Perspective-Projection '0,0 0,0   0,0 0,0' \
   box.png

这段代码是空的坐标集,我已经彻底阅读了文档,但我似乎无法理解什么参数代表什么点。文档给了我变量和名称,我不知道它们实际意味着什么(对数学策划者来说更有用)。因此,如果有人可以解释我(视觉上优先,或给我一个有用信息的链接),因为我不清楚我在做什么。只是玩这个工作的参数就不用了,我需要计算这些点。

在这里,您将找到我想要实现的目标的简单图像(使用CLI工具):

input example image http://img707.imageshack.us/img707/5419/objecttoachieve.jpg

更新

   convert \
        -virtual-pixel transparent \
        -size 159x92 \
        -verbose \
        cd_empty.png \
        \(mw2.png -distort Perspective '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30'\) \
         -geometry +3+20 \
        -composite cover-after.png

给我输出:

cd_empty.png PNG 92x159 92x159+0+0 8-bit sRGB 16.1KB 0.000u 0:00.000
convert: unable to open image `(mw2.png': No such file or directory @ error/blob.c/OpenBlob/2641.
convert: unable to open file `(mw2.png' @ error/png.c/ReadPNGImage/3741.
convert: invalid argument for option Perspective : 'require at least 4 CPs' @ error/distort.c/GenerateCoefficients/807.
convert: no images defined `cover-after.png' @ error/convert.c/ConvertImageCommand/3044.

Kurt Pfeifle的更正:

该命令有语法错误,因为它不会像ImageMagick所要求的那样,每边都有\(\)分隔符(至少一个)空白!

由于没有提供源图像的链接,我无法测试此更正命令的结果:

   convert                         \
        -virtual-pixel transparent \
        -size 159x92               \
        -verbose                   \
         cd_empty.png              \
           \(                      \
           mw2.png -distort Perspective '7,40 4,30  4,124 4,123  85,122 100,123  85,2  100,30' \
           \)                      \
        -geometry +3+20            \
        -composite                 \
         cover-after.png

2 个答案:

答案 0 :(得分:17)

你有没有看到ImageMagick失真算法的this very detailed explanation?它附带了不少插图。

通过查看您的示例图片,我的猜测是您将使用Four Point Distortion Method到达目的地。

当然,您使用0,0 0,0 0,0 0,0参数提供的示例并不能满足您的需求。

ImageMagick中提供的许多失真方法都是这样的:

  • 该方法使用一组控制点
  • 值是数字(可能是浮点,不仅是整数)。
  • 每对控制点代表一个像素坐标。
  • 每组四个值代表一个源图像坐标,紧接着是目标图像坐标。
  • 将每个源图像控制点的坐标完全按照相应参数的指定传输到相应的目标图像控制点。
  • 根据给定的失真方法传输所有其他像素的坐标。

示例:

  

S x1 ,S y1 D x1 ,D y1    S x2 ,S y2 D x2 ,D y2    S x3 ,S y3 D x3 ,D y3    ...    S xn ,S yn D xn ,D yn

x 用于表示X坐标    y 用于表示Y坐标    123,... n 用于表示第1,第2,第3,......第n像素。
  此处使用S作为源像素   此处使用D作为目标像素。

首先:方法-distort perspective

失真方法perspective将确保源图像中的直线在目标图像中保持直线。其他方法,如barrelbilinearforward则不会:它们会将直线扭曲成曲线。

-distort perspective需要一组至少 4个预先计算的像素坐标对(其中最后一个可能为零)。超过4对像素坐标提供更准确的失真。所以,如果您使用例如:

-distort perspective '1,2  3,4     5,6  7,8     9,10  11,12     13,14  15,16'

(出于可读性的原因,在映射对之间使用比所需更多的{optional}空格)意味着:

  1. 从源图像中取坐标(1,2)处的像素,并将其绘制在目标图像中的坐标(3,4)处。
  2. 从源图像中取坐标(5,6)处的像素,并在目标图像中的坐标(7,8)处绘制它。
  3. 从源图像获取坐标(9,10)处的像素,并在目标图像中的坐标(11,12)处绘制它。
  4. 从源图像中获取坐标(13,14)处的像素,并将其绘制在目标图像中的坐标(15,16)处。
  5. 您可能已经看过照片图像,其中垂直线(如建筑物墙壁的角落)看起来根本不垂直(由于拍摄快照时相机有些倾斜)。方法-distort perspective可以解决这个问题。

    它甚至可以实现这样的事情,“矫正”或“纠正”建筑物的一面,出现在原始照片的“正确”视角中:

    original image ==> distorted image

    用于此失真的控制点由原始图像上绘制的红色(控件)和蓝色矩形(目标控件)的角指示:< / p>

    source control points: corners of 'red' ==> destination control points: corners of 'blue'

    使用了这种特殊的失真

    -distort perspective '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30'
    

    完成你的拷贝'快乐的命令:

    convert                                                                      \
      -verbose                                                                   \
       http://i.stack.imgur.com/SN7sm.jpg                                        \
      -matte                                                                     \
      -virtual-pixel transparent                                                 \
      -distort perspective '7,40 4,30  4,124 4,123  85,122 100,123  85,2 100,30' \
       output.png
    

    第二种:方法-distort perspective-projection

    方法-distort perspective-projection源自易于理解的perspective方法。它实现了与-distort perspective完全相同的失真结果,但不使用(至少)4对坐标值(至少16个整数)作为参数,而是使用8个浮点系数。

    它使用......

    1. 一组正好8 预先计算的系数;
    2. 这些系数中的每一个都是浮点值(与-distort perspective不同,其中只允许整数的值);
    3. 这8个值代表

      形式的矩阵

       sx   ry   tx
       rx   sy   ty
       px   py

      用于根据以下公式计算源像素的目标像素:

      X-of-destination = (sx*xs + ry+ys +tx) / (px*xs + py*ys +1)
      Y-of-destination = (rx*xs + sy+ys +ty) / (px*xs + py*ys +1)
      
      (TO BE DONE -- 
          I've no time right now to find out how to
          properly format + put formulas into the SO editor)
      
    4. 为避免(更难)计算可重复使用的 -distort perspective-projection 方法所需的8个系数,您可以......

      • 首先,(更轻松地)计算 -distort perspective 的坐标,
      • 第二次,运行此 -distort perspective 并添加了 -verbose 参数,
      • 最后,从打印到 stderr 的输出中读取8个系数。

      (上面引用的)完整命令示例会吐出这个信息:

      Perspective Projection:
        -distort PerspectiveProjection \
          '1.945622, 0.071451, -12.187838, 0.799032, 
           1.276214, -24.470275, 0.006258, 0.000715'
      

答案 1 :(得分:1)

感谢this page和上一个答案,我最终得到了这个清晰易懂的代码...希望您发现它有用:)))

$points = array(

                0,0, # Source Top Left
                0,0, # Destination Top Left

                0,490, # Source Bottom Left 
                2.2,512, # Destination Bottom Left 

                490,838, # Source Bottom Right 
                490,768, # Destination Bottom Right 

                838,0, # Source Top Right 
                838,50 # Destination Top Right 

                );

$imagick->distortImage(Imagick::DISTORTION_PERSPECTIVE, $points, false);
  

请记住,每组坐标都分为两部分   部分。第一个是X轴,第二个是Y轴..所以当我们说838,0时   在“目的地右上角”,我们指的是目的地右上角的X轴   是838,Y轴是零(0)。

我很乐意回答您的问题:)