#python #image-processing #imagemagick
#python #обработка изображений #imagemagick
Вопрос:
В настоящее время я работаю с изображениями и хотел бы узнать самую быструю библиотеку обработки изображений в отношении аннотирования. В настоящее время я использую эту команду:
convert orig.tif -background Red -density 300 -font /usr/share/fonts/truetype/msttcorefonts/Arial.ttf -pointsize 12 -gravity south -splice 0x150 -gravity southwest -annotate 50 50 "left corner" -gravity southeast -annotate 50 50 'right corner' repage endorsed.tif
Я вызываю это в рамках подпроцесса.вызов метода в python. Если я сделаю это в командной строке, общее время работы составит около 1 секунды:
real 0m0.162s
user 0m0.940s
sys 0m0.030s
Моя программа составляет в среднем 1,96 секунды:
[**copied_from** avg] 0:00:00.071887
[**mysql** avg] 0:00:00.000265
[**cropped** avg] 0:00:00.433935
[**rm** avg] 0:00:00.007758
[**copied_to** avg] 0:00:00.147880
[**endorsed** avg] 0:00:01.963496
[**mssql** avg] 0:00:00.000010
Я не уверен, почему существует несоответствие между вызовом его из командной строки или через python subprocess.call(cmd, shell =True). В любом случае, оба они слишком медленные.
В основном я кадрирую и комментирую изображения. Кажется, что обрезка выполняется достаточно быстро с помощью преобразования imagemagick, но аннотирование выполняется слишком медленно. Кто-нибудь знает о более быстрой библиотеке изображений? Мне удобно использовать python / ruby, но на данный момент было бы полезно любое более быстрое решение.
Спасибо всем.
Ответ №1:
Вызов чего-либо из subprocess.call
всегда сопряжен с немалыми накладными расходами по сравнению с реальной оболочкой (например, bash).
Вы пробовали использовать привязки imagemagick к python вместо вызова через subprocess
? (Редактировать: Отмените это… Эти привязки довольно устарели. Однако я не знаю ничего лучшего… Я давно не использовал imagemagick через python …)
Вы также могли бы сделать это с помощью PIL, хотя это немного менее гибко и, вероятно, ненамного быстрее.
Чего бы это ни стоило, вот эквивалент вашей команды imagemagick с использованием PIL.
import Image
import ImageDraw
import ImageFont
rect_height = 150
im_orig = Image.open('orig.tif')
width, height = im_orig.size
im = Image.new('RGB', (width, height rect_height))
im.paste(im_orig, (0,0))
width, height = im.size
dpi = 300
im.info['dpi'] = (dpi, dpi)
font_size = 12
font = ImageFont.truetype('/usr/share/fonts/truetype/arial.ttf',
int(dpi * font_size / 72.0))
draw = ImageDraw.Draw(im)
draw.rectangle([(0,height-rect_height), (width, height)], fill='red')
text = 'left corner'
text_width, text_height = font.getsize(text)
draw.text((50, height - 50 - text_height),
text, fill='black', font=font)
text = 'right corner'
text_width, text_height = font.getsize(text)
draw.text((width - 50 - text_width, height - 50 - text_height),
text, fill='black', font=font)
im.save('output.tif')
Как вы можете видеть, это немного менее удобно, но это работает. Кроме того, это, похоже, быстрее, чем imagemagick на моем компьютере. Приведенный выше скрипт занимает ~ 0,43 секунды для создания большого изображения, в то время как ваша эквивалентная команда imagemagick (просто запускаемая непосредственно из командной строки) занимает ~ 1,1 секунды. Конечно, imagemagick может делать намного больше, чем PIL, но для простых манипуляций с изображениями в python PIL работает довольно хорошо.
(Редактировать: разница в скорости заключается в том, что PIL сохраняет входной tif (который является сжатым в формате LZW) как несжатый tif, в то время как imagemagick сохраняет его как сжатый в формате LZW tiff, аналогичный входному.)
Комментарии:
1. Джо, спасибо за быстрый ответ. Я еще не использовал PythonMagick. Я использовал RMagick, привязки ruby и обнаружил, что скорости были примерно одинаковыми.
2. Большое спасибо за понимание. Я собираюсь попробовать это в PIL. Ты потрясающий.
3. Джо, я попробовал твой код, и кажется, что аннотация работает отлично, и это намного быстрее, 0,11 секунды в среднем, но исходное изображение грязное и не отображается должным образом. Я использую eog output.tif для ее просмотра. Я делаю что-то не так?
4. Еще одна вещь, команда оболочки, которую я использую, добавляет к изображению полосу высотой 150 пикселей. Итак, если исходное изображение было 100×100, результирующее изображение будет 100×250. Приведенный выше код, похоже, этого не делает.
5. Какой тип сжатия у ваших tiff? PIL не поддерживает столько типов сжатия, сколько imagemagick… Это может быть связано с тем, что он неправильно распознает тип сжатия изображения. Можете ли вы где-нибудь опубликовать пример изображения?