1

我正在尝试使用PythonMagickWand在图像上使用Shepards失真。您还可以查看ImageMagick 使用的 distort.c 的来源

PythonMagickWand 默认不支持 Shepards 失真。为了解决这个问题,我添加了:

ShepardsDistortion = DistortImageMethod(15)

到 PythonMagickWand 的第 544 行(请参阅此处了解我修改后的 PythonMagicWand)。15 指针引用了MagickWand 源代码的distort.h(第 51 行),其中 ShepardsDistortion 是列表中的第 15 项。这适合所有其他支持的失真方法。

现在,我可能做错的事情是假设 PythonMagickWand 支持的现有失真方法使用与 Shepards 相同类型的参数。他们可能不会,但我不知道我怎么知道。我知道distort.c正在做这项工作,但我无法确定它接受的参数是相同还是不同。

我有以下代码(片段):

from PythonMagickWand import *
from ctypes import *

arrayType = c_double * 8  
pointsNew = arrayType()
pointsNew[0] = c_double(eyeLeft[0])
pointsNew[1] = c_double(eyeLeft[1])
pointsNew[2] = c_double(eyeLeftDest[0])
pointsNew[3] = c_double(eyeLeftDest[1])
pointsNew[4] = c_double(eyeRight[0])
pointsNew[5] = c_double(eyeRight[1])
pointsNew[6] = c_double(eyeRightDest[0])
pointsNew[7] = c_double(eyeRightDest[1])

MagickWandGenesis()
wand = NewMagickWand()
MagickReadImage(wand,path_to_image+'image_mod.jpg')
MagickDistortImage(wand,ShepardsDistortion, 8, pointsNew, False)
MagickWriteImage(wand,path_to_image+'image_mod22.jpg')

我收到以下错误:

MagickDistortImage(wand,ShepardsDistortion, 8, pointsNew, False) ctypes.ArgumentError: argument 4: <type 'exceptions.TypeError'>: expected LP_c_double instance instead of list

我知道 pointsNew 是提供参数的错误方式。但我只是不知道什么是正确的格式。这是在终端中运行时有效的示例扭曲命令:

convert image.jpg -virtual-pixel Black -distort Shepards 121.523809524,317.79638009 141,275 346.158730159,312.628959276 319,275 239.365079365,421.14479638 232,376 158.349206349,483.153846154 165,455 313.015873016,483.153846154 300,455 0,0 0,0 0,571.0 0,571.0 464.0,571.0 464.0,571.0 0,571.0 0,571.0 image_out.jpg

所以我想问题是:如何创建一个将被 PythonMagickWand 接受的 c_doubles 列表?还是我将 Shepards Distortion 添加到 PythonMagickWand 的技巧完全错误?

我基本上需要重新创建终端命令。我已经通过使用 subprocess 从 Python 运行命令来使其工作,但这不是我想要的方式。

4

3 回答 3

2

来自Reddit.com上的NeedMoreBeer

from PythonMagickWand import *
from ctypes import *

arrayType = c_double * 8  
pointsNew = arrayType()
pointsNew[0] = c_double(121.523809524)
pointsNew[1] = c_double(317.79638009)
pointsNew[2] = c_double(141)
pointsNew[3] = c_double(275) 
pointsNew[4] = c_double(346.158730159)
pointsNew[5] = c_double(312.628959276)
pointsNew[6] = c_double(319)
pointsNew[7] = c_double(275)

ShepardsDistortion = DistortImageMethod(14)

MagickWandGenesis()
wand = NewMagickWand()
MagickReadImage(wand,'/home/user/image.png')
MagickDistortImage(wand,ShepardsDistortion, 8, pointsNew, False)
MagickWriteImage(wand,'/home/user/image_mod22.jpg')

更具体地说,它是以下行:

ShepardsDistortion = DistortImageMethod(14)

那为我修好了!再次感谢RedditNeedMoreBeer

于 2010-06-16T16:21:39.343 回答
0

这是旧约,但是:

我真的很喜欢 python magick wand,但是当我在 600 多张图像上使用它时,某处出现了内存泄漏,它吃掉了(32 位)机器中的所有内存。我倾向于认为可能是 ImageMagick 本身,但我可能错了。

最后我发现:

GraphicsMagick 是 ImageMagick 早期版本的一个端口;但是因为 ImageMagick 改变了他们的 API,PythonMagickWant 不能和 GraphicsMagick 一起工作。

GraphicsMagick,似乎也比 ImageMagick 更快(使用更好的多任务处理)。

为了让我的脚本快速运行,几天后我对其进行了更改,以便脚本加载 gimp 而不是使用 ImageMagick,然后使用 python-scriptfu 运行我的脚本。一切似乎都正常。

如果它对您有用,请使用它;PythonMagickWand 的家伙也非常有帮助 + 绑定很好。

于 2010-06-08T13:30:49.580 回答
0

如错误消息所示,该函数需要一个指针 ( LP_c_double),但您所拥有的只是一个数组。

您需要将数组显式转换为指针,以便将其作为指针传递给外部函数:

>>> arr = (c_double * 8)()
>>> arr # 只是一个数组...
<__main__.c_double_Array_8 对象位于 0x1004ad050>
>>> arr[0] = 5
# ...
>>> cast(arr, POINTER(c_double)) # 现在是正确的类型
<__main__.LP_c_double 对象位于 0x1004ad0e0>
>>> cast(arr, POINTER(c_double))[0]
5.0
于 2010-06-08T11:00:50.553 回答