ImageMagick透视失真性能

时间:2016-04-18 19:40:06

标签: opengl 3d imagemagick projection perspectivecamera

我的要求是透视将用户提交的图像旋转到预渲染的背景图像(实际上是视频中每帧的图像)。

最简单的方法是使用ImageMagick,我编写了一个非常粗糙的简单bash脚本来实现我需要的内容如下:

#!/bin/bash
# @author: neurosys
# @Description: Perspective transforms and projects an alpha image
# onto a background image.

if [ $# -ne 11 ]
then
    echo 'Usage: ./map_image.sh background.jpg image.png output.jpg x1 y1 x2 y2 x3 y3 x4 y4';
    exit;
fi

BG=$1
IMAGE=$2
DEST=$3
TEMP='temp.png'

BG_SIZE_W=$(convert $BG -print "%w\n" /dev/null)
BG_SIZE_H=$(convert $BG -print "%h\n" /dev/null)

IMAGE_W=$(convert $IMAGE -print "%w\n" /dev/null)
IMAGE_H=$(convert $IMAGE -print "%h\n" /dev/null)

X1=$4
Y1=$5

X2=$6
Y2=$7

X3=$8
Y3=$9

X4=${10}
Y4=${11}

OFFSET=15

TRANSFORM="$OFFSET,$OFFSET, $X1,$Y1  $(($IMAGE_W+$OFFSET)),$OFFSET $X2,$Y2  $OFFSET, $(($IMAGE_H+$OFFSET)) $X3,$Y3   $(($IMAGE_W+$OFFSET)), $(($IMAGE_H+$OFFSET)) $X4,$Y4"

echo "Transform matrix: $TRANSFORM"

convert $IMAGE -background transparent -extent $BG_SIZE_W\x$BG_SIZE_H-$OFFSET-$OFFSET $TEMP
convert $TEMP -background transparent -distort Perspective "$TRANSFORM" $TEMP
convert $BG $TEMP -composite $DEST
rm -f $TEMP

但是,大约需要4秒才能在我的计算机上生成所需的图像,如下所示:

[neuro@neuro-linux ~]$ time ./map_image.sh bg.png Hp-lovecraft.jpg output.jpg 494 108 579 120 494 183 576 196 && nomacs output.jpg
Transform matrix: 15,15, 494,108  195,15 579,120  15, 267 494,183   195, 267 576,196

real   0m3.852s
user   0m3.437s
sys   0m0.037s
[neuro@neuro-linux ~]$

我在上面的ImageMagick脚本中使用的操作顺序和参数可能不是最佳的。因此,非常欢迎任何达到我需要的意见或替代方案。

用于上述示例的图像是

  • 背景 Background image
  • 用户提交的图片 User submitted image
  • 输出 Output

我想知道是否有办法加速这么快,以便我可以在几秒钟内为一分钟长的视频(25 fps * 60秒)生成帧?

事实上,如果这种方法失败,我可能会专门为此编写OpenGL程序,我相信在硬件利用的情况下会更快。

有些偏离主题的注意事项:背景图像是在动画软件(3ds Max)中预呈现的。如果我求助于编写一个opengl渲染器,我可以从3ds Max导入网格和相机,这样做可以获得更好的透视和照明。

感谢。

修改

在ImageMagick论坛的帮助下,瓶颈在-extent的第一次转换中出现了,这是不必要的。

我最终将所有命令合并为一个:

convert image.png -background transparent +distort Perspective "1,1, 494,108  201,1 579,120  1, 201 494,183   201, 201 576,196" -compose DstOver -composite bg.png out.png

它在0.6秒内运行,但透明度不知何故不起作用,因此输出图像最终只是带有黑色背景的扭曲图像。

修改

ImageMagick论坛上的某个人写了一个非常快速和干净的脚本,将其缩短为0.13秒。

以下是链接,万一有人需要它: https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=29495&p=132182#p132141

2 个答案:

答案 0 :(得分:2)

尝试使用MPC格式作为$ TEMP而不是PNG。 MPC的编码速度要快得多。它设计用作临时文件,与ImageMagick一起使用。

MPC实际上创建了两个文件,* .mpc和* .cache,所以你需要 删除两者。在您的脚本中,设置TEMP = temp.mpc和TEMPCACHE = temp.cache, 然后在脚本的末尾,rm $ TEMP TEMPCACHE

请参阅ImageMagick Formats页面上的MPC条目。

答案 1 :(得分:1)

如果我使用您的技术获得图像的尺寸,宽度需要大约0.4秒,高度需要0.4秒。我的意思是这样的:

BG_SIZE_W=$(convert $BG -print "%w\n" /dev/null)   # 0.48 sec
BG_SIZE_H=$(convert $BG -print "%h\n" /dev/null)   # 0.48 sec

如果同时获得宽度和高度,请在我的机器上完成0.006秒:

read BG_SIZE_W BG_SIZE_H < <(identify -ping -format "%w %h" bg.png)

我仍在查看其余的代码。