了解透视投影失真ImageMagick

Jur*_*gen 14 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
Run Code Online (Sandbox Code Playgroud)

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

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

输入示例图像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
Run Code Online (Sandbox Code Playgroud)

给我输出:

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.
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Kur*_*fle 18

您是否看到了ImageMagick失真算法的详细解释?它附带了不少插图.

通过查看您的示例图像,我的猜测是您将使用四点失真方法到达那里.

当然,您使用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坐标.
1,2,3,...n用于表示所述第一,第二,第三,...第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'
Run Code Online (Sandbox Code Playgroud)

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

  1. 从源图像获取坐标(1,2)处的像素,并在目标图像中的坐标(3,4)处绘制它.
  2. 从源图像获取坐标(5,6)处的像素,并在目标图像中的坐标(7,8)处绘制它.
  3. 从源图像获取坐标(9,10)处的像素,并在目标图像中的坐标(11,12)处绘制它.
  4. 从源图像获取坐标(13,14)处的像素,并在目标图像中的坐标(15,16)处绘制它.

您可能已经看过照片图像,其中垂直线(如建筑物墙壁的角落)看起来并不垂直(由于拍摄快照时相机有些倾斜).该方法-distort perspective可以纠正这个问题.

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

原始图像 ==> 扭曲的形象

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

源控制点:'红色'的角落 ==> 目的地控制点:'蓝色'的角落

使用这种特殊的失真

-distort perspective '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30'
Run Code Online (Sandbox Code Playgroud)

完成对copy'n'paste乐趣的指挥:

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
Run Code Online (Sandbox Code Playgroud)

第二:方法 -distort perspective-projection

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

它用...

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

    -distort perspective-projection

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

    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)
    
    Run Code Online (Sandbox Code Playgroud)

为了避免(更难)计算可重复使用 方法的8个所需系数-distort perspective ,你可以......

  • 首先,(更容易)计算a的坐标 -distort perspective ,
  • 第二,运行这个 -verbose 0,0 0,0 0,0 0,0 参数添加,
  • 最后,从打印到 stderr 的输出中读取8个系数.

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

Perspective Projection:
  -distort PerspectiveProjection \
    '1.945622, 0.071451, -12.187838, 0.799032, 
     1.276214, -24.470275, 0.006258, 0.000715'
Run Code Online (Sandbox Code Playgroud)