PythonMagickWand Shepards 扭曲(ctypes LP_c_double 问题)

发布于 2024-09-05 07:41:31 字数 2606 浏览 9 评论 0 原文

我正在尝试使用 PythonMagickWand 来使用 图像上的谢泼德变形。您还可以查看 violet.c 的来源,即由 ImageMagick 使用。

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

ShepardsDistortion = DistortImageMethod(15)

到 PythonMagickWand 的第 544 行(参见这里是我修改后的PythonMagicWand)。 15 指针引用 Distor.h (行51) MagickWand 源,其中 ShepardsDistortion 是列表中的第 15 项。这适合所有其他支持的失真方法。

现在,我可能做错的事情是假设 PythonMagickWand 支持的现有扭曲方法使用与 Shepards 相同类型的参数。他们可能不会,但我不知道如何判断。我知道 Distortion.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: : Expected LP_c_double instance代替list

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

convert image.jpg -virtual-pixel Black -violet Shepards 121.523809524,317.79638009 141,275 346.158730159,312.628959276 319,275 239.365079365,42 1.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_double 列表? 或者我将 Shepards Distortion 添加到 PythonMagickWand 中的做法完全错误吗?

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

I am trying to use PythonMagickWand to use a Shepards distortion on an image. You can also see the source of distort.c that is used by ImageMagick.

PythonMagickWand does not by default support Shepards distortion. To fix this, I added in:

ShepardsDistortion = DistortImageMethod(15)

to line 544 of PythonMagickWand (See here for my modified PythonMagicWand). The 15 pointer is in reference to distort.h (line 51) of the MagickWand source in which ShepardsDistortion is the 15th item on the list. This fits with all of the other supported distortion methods.

Now, something that I may be doing wrong is presuming that the existing distortion methods that are supported by PythonMagickWand use the same type of arguments as the Shepards. They might not but I do not know how I can tell. I know that distort.c is doing the work, but I can't work out if the arguments it takes in are the same or different.

I have the following code (snippet):

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

I get the following error:

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

I am aware that pointsNew is the wrong way of providing the arguments.. But I just don't know what is the right format. This is an example distort command that works when run in Terminal:

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

So I guess the question is: How do I create a list of c_doubles that will be accepted by PythonMagickWand? Or is my hack to add Shepards Distortion into PythonMagickWand completely wrong?

I basically need to re-create the terminal command. I have got it working by using subprocess to run the command from Python but that is not how I want to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暗喜 2024-09-12 07:41:31

来自 NeedMoreBeer Reddit.com

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

From NeedMoreBeer on Reddit.com:

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

More specifically for me, it was the following line:

ShepardsDistortion = DistortImageMethod(14)

That fixed it for me! Thanks again to NeedMoreBeer from Reddit.

站稳脚跟 2024-09-12 07:41:31

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

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

>>> arr = (c_double * 8)()
>>> arr # just an array...
<__main__.c_double_Array_8 object at 0x1004ad050>
>>> arr[0] = 5
# ...
>>> cast(arr, POINTER(c_double)) # now it's the right type
<__main__.LP_c_double object at 0x1004ad0e0>
>>> cast(arr, POINTER(c_double))[0]
5.0

As the error message indicates, the function is expecting a pointer (LP_c_double), but all you have is an array.

You'll need to explicitly cast your array to a pointer, for the purposes of passing it as a pointer to the external function:

>>> arr = (c_double * 8)()
>>> arr # just an array...
<__main__.c_double_Array_8 object at 0x1004ad050>
>>> arr[0] = 5
# ...
>>> cast(arr, POINTER(c_double)) # now it's the right type
<__main__.LP_c_double object at 0x1004ad0e0>
>>> cast(arr, POINTER(c_double))[0]
5.0
小猫一只 2024-09-12 07:41:31

这是 OT,但是:

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

最后我发现:

GraphicsMagick是ImageMagick早期版本的移植;但由于 ImageMagick 改变了很多 API,PythonMagickWant 无法与 GraphicsMagick 一起使用。

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

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

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

This is OT, but:

I really liked python magick wand, but when I used it on 600+ images there was a memory leak somewhere, which ate all the memory in the (32 bit) machine. I was inclined to think possibly in ImageMagick itself, but I might've been wrong.

In the end I found out that:

GraphicsMagick is a port of an earlier version of ImageMagick; but because ImageMagick changes their API a lot, PythonMagickWant won't work with GraphicsMagick.

GraphicsMagick, also seems to be faster than ImageMagick (using better multitasking).

In order to get my script working quickly, in a few days I changed it so that instead of using ImageMagick, the script loaded the gimp, which then ran my script using python-scriptfu.
Everything seemed to work OK.

If it works for you, then use it; also the PythonMagickWand guy is really helpful + the bindings are nice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文