Поворот сотен файлов JPEG за секунды, а не часы

У нас есть сотни изображений, которые наш компьютер получает за раз, и нам нужно как можно быстрее вращать и изменять их размер. Вращение осуществляется на 90, 180 или 270 градусов.

В настоящее время мы используем инструмент командной строки GraphicsMagick для поворота изображения. Поворот изображений (5760 * 3840 ~ 22MP) занимает от 4 до 7 секунд.

Следующий код Python к сожалению дает нам одинаковые результаты

import cv
img = cv.LoadImage("image.jpg")
timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image

# rotate counter-clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=0)
cv.SaveImage("rotated_counter_clockwise.jpg", timg)

Есть ли более быстрый способ повернуть изображения, используя мощность видеокарты? На ум приходят OpenCL и OpenGL, но нам интересно, будет ли заметно увеличение производительности.

Используемое нами оборудование довольно ограничено, так как устройство должно быть как можно меньше.

Программное обеспечение - debian 6 с официальными драйверами Radeon (с закрытым исходным кодом).


person Thomaschaaf    schedule 09.07.2012    source источник
comment
Читая этот вопрос, я задавался вопросом: какой процент времени уходит на выполнение каждой части этой операции? Сколько времени нужно ждать от кодирования JPEG по сравнению с фактической операцией вращения? И сколько ожидания от ввода-вывода диска? Ответы на эти вопросы могут повлиять на вашу оптимизацию.   -  person csd    schedule 09.07.2012
comment
Просто используйте jpeg tran, что, как приятный побочный эффект, не ухудшает качество.   -  person datenwolf    schedule 09.07.2012
comment
Можете ли вы указать время для каждой части вставленного кода (после загрузки, после транспонирования, после переворота, после сохранения)?   -  person Daniel Mošmondor    schedule 11.07.2012


Ответы (3)


вы можете выполнить вращение без потерь, которое просто изменит раздел EXIF. Это ускорит поворот ваших изображений.

и взгляните на утилиту jpegtran, которая выполняет модификации jpeg без потерь. http://linuxmanpages.com/man1/jpegtran.1.php

person A.G.    schedule 09.07.2012
comment
Изменение тега Exif Orientation, вероятно, самый быстрый способ. Однако не все зрители изображения его уважают. jpegtran кажется хорошим решением. Он лишь частично повторно сожмет ваше изображение, что по-прежнему должно быть довольно быстрым. - person Piotr Praszmo; 09.07.2012
comment
Если ширина / высота изображения кратны 8, вы можете повернуть на 90/180/270 градусов, просто переупорядочив компоненты без повторного сжатия. - person Martin Beckett; 09.07.2012
comment
@MartinBeckett: обратите внимание, что большинство изображений JPEG хранятся в формате, кратном 8 размерам, и после этого просто применяется обрезка, поэтому jpegtran должен иметь возможность переупорядочивать компоненты для большинства изображений. - person datenwolf; 09.07.2012

Существует плагин без повторного сжатия jpeg для irfanview, который IIRC может вращать и изменять размер изображений (простыми способами) без повторного сжатия , он также может запускать каталог изображений - это должно быть намного быстрее

Графический процессор, вероятно, не поможет, вы почти наверняка ограничены вводом-выводом в opencv, на самом деле он не предназначен для высокоскоростного доступа к файлам.

person Martin Beckett    schedule 09.07.2012
comment
Здесь вы найдете больше утилит, которые сделают это вращение без потерь без распаковки и повторного сжатия изображения: jpegclub.org/losslessapps. html - person Mārtiņš Možeiko; 09.07.2012
comment
Для большого количества изображений буферизация и / или асинхронная передача памяти могут облегчить узкое место ввода-вывода, поэтому я бы не сказал, что реализация на основе графического процессора не поможет. - person Ani; 09.07.2012
comment
@ananthonline - если jpeg просто вращает числа, кратные 90, вам просто нужно перетасовать сжатые значения в каждом блоке 8x8. Графический процессор здесь не очень помогает и обычно работает медленно при произвольном чтении / записи в память, даже если у вас есть данные на карте. Это может быть быстрее, если вы повторно сжимаете, хотя DCT с SSE2 очень быстро - person Martin Beckett; 09.07.2012
comment
Что ж, вам НЕОБХОДИМО повторно сжимать определенные блоки, потому что размер изображения изменился, не так ли? А для больших изображений даже они выиграют от массивного параллелизма графического процессора. А возможности декодирования + вращения с потерями становятся возможными при использовании графического процессора. - person Ani; 09.07.2012

Я не эксперт в вопросах jpeg и сжатия, но поскольку ваша проблема в значительной степени ограничена вводом-выводом (при условии, что вы можете вращать без тяжелых вычислений, связанных с де / кодированием), вы, возможно, не сможете сильно ускорьте его на имеющемся у вас графическом процессоре. (Не) К счастью, ваша ссылка - довольно медленный процессор Atom.

Я предполагаю, что у Radeon есть отдельная основная память. Это означает, что данные должны передаваться через PCI-E, что является дополнительной задержкой по сравнению с выполнением ЦП, и, не скрываясь, вы можете быть уверены, что это узкое место. Это наиболее вероятная причина того, почему ваш код, использующий OpenCV на графическом процессоре, работает медленно (помимо того факта, что вы выполняете две операции с привязкой к памяти, транспонирование и переворачивание вместо одной).

Главное - максимально скрыть время передачи PCI-E с помощью вычислений, используя множественную буферизацию < / а>. Перекрытие передач как к графическому процессору, так и от него с вычислением с использованием полнодуплексной возможности PCI-E будет работать только в том случае, если рассматриваемая карта имеет механизмы двойного DMA, такие как high-end Radeon или Карты NVIDIA Quadro / Tesla, в чем я очень сомневаюсь.

Если время вычисления вашего графического процессора (время, необходимое графическому процессору для выполнения вращения) меньше, чем время, необходимое для передачи, вы не сможете полностью перекрыть друг друга. HD 4530 имеет довольно медленный интерфейс памяти с пиковым значением только 12,8 Гбит / с, а ядро вращения должно быть достаточно ограниченным по памяти. Тем не менее, я могу только предполагать, но я бы сказал, что если вы достигнете пиковой скорости передачи PCI-E ~ 1,5 Гбит / с (4x PCI-E AFAIK), вычислительное ядро ​​будет в несколько раз быстрее, чем передача, и вы ' будет очень мало перекрываться. Вы можете просто синхронизировать части по отдельности, не требуя сложного асинхронного кода, и вы можете оценить, насколько быстро вы можете получить вещи с оптимальным перекрытием.

Одна вещь, которую вы, возможно, захотите рассмотреть, - это получить оборудование, которое не демонстрирует PCI-E как узкое место, например:

  • Система на базе AMD APU. На этих платформах вы сможете блокировать страницы памяти и использовать ее непосредственно с графического процессора;
  • встроенные графические процессоры, которые разделяют основную память с хостом;
  • быстрый процессор с низким энергопотреблением, такой как мобильный Intel Ivy Bridge, например i5-3427U, который потребляет почти так же мало, как Atom D525, но имеет поддержку AVX и должно быть в несколько раз быстрее.
person pszilard    schedule 10.07.2012