Искажение PythonMagickWand Shepards (проблема ctypes LP_c_double) - PullRequest
1 голос
/ 07 июня 2010

Я пытаюсь использовать PythonMagickWand , чтобы использовать искажение Шепардса на изображении. Вы также можете увидеть источник distort.c , который используется ImageMagick.

PythonMagickWand по умолчанию не поддерживает искажения Шепарда. Чтобы это исправить, я добавил:

ShepardsDistortion = DistortImageMethod(15)

в строке 544 PythonMagickWand ( Смотрите здесь мой измененный PythonMagicWand ). Указатель 15 относится к distort.h (строка 51) источника MagickWand, в котором ShepardsDistortion является 15-м элементом в списке. Это подходит для всех других поддерживаемых методов искажения.

Теперь я могу ошибаться, предполагая, что существующие методы искажения, поддерживаемые PythonMagickWand, используют аргументы того же типа, что и Шепардс. Они не могут, но я не знаю, как я могу сказать. Я знаю, что 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 - это неправильный способ предоставления аргументов ... Но я просто не знаю, какой формат правильный. Это пример команды distort, которая работает при запуске в Терминале:

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

Итак, я предполагаю, что вопрос заключается в следующем: как мне создать список c_doubles, который будет принят PythonMagickWand? Или мой хак, чтобы добавить искажение Шепарда в PythonMagick, и совершенно неправильно?

Мне нужно заново создать команду терминала. Я получил его с помощью подпроцесса для запуска команды из Python, но я не хочу это делать.

Ответы [ 3 ]

2 голосов
/ 16 июня 2010

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

Это исправило это для меня! Еще раз спасибо NeedMoreBeer от Reddit .

0 голосов
/ 08 июня 2010

Это ОТ, но:

Мне очень понравилась волшебная палочка Python, но когда я использовал ее на 600+ изображениях, где-то произошла утечка памяти, которая съела всю память на (32-битной) машине. Я был склонен думать, возможно, в самом ImageMagick, но я мог ошибаться.

В итоге я узнал, что:

GraphicsMagick - это порт более ранней версии ImageMagick; но поскольку ImageMagick сильно меняет свой API, PythonMagickWant не будет работать с GraphicsMagick.

GraphicsMagick, также, кажется, быстрее, чем ImageMagick (использует лучшую многозадачность).

Чтобы мой скрипт работал быстро, через несколько дней я изменил его так, чтобы вместо использования ImageMagick, скрипт загружал gimp, который затем запускал мой скрипт, используя python-scriptfu. Казалось, все работает хорошо.

Если это работает для вас, тогда используйте его; Парень из PythonMagickWand действительно полезен + привязки хороши.

0 голосов
/ 08 июня 2010

Как указывает сообщение об ошибке, функция ожидает указатель (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
...