15

对于一个项目,我正在尝试创建图像的透视失真以匹配 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 工具):

输入示例图像

更新:

   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
4

1 回答 1

22

你看到这个对 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用于表示第 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) 处。

您可能已经看到照片图像,其中垂直线(如建筑物墙壁的角落)看起来根本不垂直(由于拍摄快照时相机的一些倾斜)。该方法-distort perspective可以纠正这一点。

它甚至可以实现这样的效果,“拉直”或“矫正”以原始照片“正确”视角出现的建筑物的一面:

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

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

源代码控制点:“红色”的角落 ==> 目的地控制点:“蓝色”的角落

这种特殊的失真使用

-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)
    

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

  • 首先,(更容易)计算 a 的坐标 -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'
于 2012-09-05T09:47:16.710 回答