LINUX.ORG.RU

Библиотека/функция для изменение размера изображения

 ,


0

2

Дано:

struct image_t
{
    uint32_t width;
    uint32_t height;
    uint32_t *data;
};
В data пиксели в RGBA формате.
Хочется:
int scale_image(struct image_t *img, float rate);
Пусть меняет прям img (ставит новые размеры, удаляет предыдущую data и присваивает новую), меня это устраивает.

При уменьшении вроде достаточно линейной интерполяции, а при увеличении хотелось бы фильтр Ланцоша (Lanczos).

Самому писать долго. Откуда лучше/проще/быстрее стащить готовую реализацию? Но только по честному, чтоб лицензия была BSD, MIT и т. п.

Ну и вообще, у кого какие мысли по поводу вышенаписанного?

ImageMagick/GraphicsMagick, у них там есть библиотека libmagick для Си/Си++. Ещё GDK-PixBuf, там есть scale с хорошей интерполяцией:

GDK_INTERP_HYPER

This is the slowest and highest quality reconstruction function. It is derived from the hyperbolic filters in Wolberg's «Digital Image Warping», and is formally defined as the hyperbolic-filter sampling the ideal hyperbolic-filter interpolated image (the filter is designed to be idempotent for 1:1 pixel mapping).

Если доступна графическая карта, можно использовать NPP от nVidia.

Ignatik ()
Ответ на: комментарий от mv

Кстати я тестировал её как-то, реально быстрая. Быстрее алгоритмов резайза в Qt QImage и OpenCV.

dmitryalexeeff ()
Последнее исправление: dmitryalexeeff (всего исправлений: 1)

Если закрытость не напрягает, то возьмите либу от xnview. Она кроме ресайза умеет еще кучу всего.
Или возьмите открытый imagemagick.

andreyu ★★★★★ ()

Взять опенЖЛ и реализовать на нем, но только в том случае, если вы уже хорошо знакомы с GL и EGL.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

Мне надо максимально качественно, а OpenGL будет стараться сделать быстрее.
Да и потом доступные в нём методы зависят от видеокарты.

LinuxUser ★★ ()
Ответ на: комментарий от LinuxUser

Мне надо максимально качественно, а OpenGL будет стараться сделать быстрее. Да и потом доступные в нём методы зависят от видеокарты.

Вы просто еще не научились его правильно готовить. Для решения конкретно вашей задачи хватить 2х простеньких шейдеров. Ну а результат будет зависеть только от вас.

В любом случае этот путь не для вас.

trex6 ★★★★★ ()
Ответ на: комментарий от mv

sws_scale

Кстати, если работает медленно, можно попробовать поиграться форматами. RGB->RGB может работать в разы медленнее, чем BGR->BGR.

А, ещё есть libpixman, cairo. Есть ещё libfreeimage, но оно заброшено.

i-rinat ★★★★★ ()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

RGB->RGB может работать в разы медленнее, чем BGR->BGR.

С чего бы вдруг? Там вообще ни коим боком не принципиально, в каком порядке идут поля. Может, в первом случае был RGB24, а во втором RGBA (32 т.е.)?

mv ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Инкрементирую OpenGL, если самому лень. Да и быстрей будет на GPU посчитать…

Считать картику из основной памяти, записать её по pcie в память видеокарты, там gpu считает данные из памяти, растянет, запишет в память, после чего по pcie надо будет считать память видеокарты и записать полученные данные в основную память, так?

Проц с SSE4 уже три раза обернётся, причём, конвейер основное время будет находиться в ожидании поступающих из памяти данных.

mv ★★★★★ ()
Ответ на: комментарий от mv

С чего бы вдруг? Там вообще ни коим боком не принципиально, в каком порядке идут поля. Может, в первом случае был RGB24, а во втором RGBA (32 т.е.)?

libswscale переводит RGBA картинку в YUV, а её уже масштабирует с одновременным преобразованием в RGBA. И так вышло, что для BGRA написаны быстрые пути, а для RGBA используется реализация на простом C.

При масштабировании действительно нет разницы, RGBA→RGBA или BGRA→BGRA, так что для RGBA данных можно делать BGRA→BGRA, это будет быстрее. Пока не столкнулся, тоже думал, что нет разницы.

i-rinat ★★★★★ ()
Ответ на: комментарий от mv

так?

Так.

Проц с SSE4 уже три раза обернётся

Ничего подобного. Если у тебя текстура, скажем, 10000х10000, быстрее на GPU.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от i-rinat

libswscale переводит RGBA картинку в YUV

Раньше самому надо было, все кишки avcodev/avformat только с yuv420p работали.

И так вышло, что для BGRA написаны быстрые пути, а для RGBA используется реализация на простом C.

Из-за преобразования в цветоразность проблема, чтоль?

mv ★★★★★ ()
Ответ на: комментарий от mv

все кишки avcodev/avformat только с yuv420p работали.

Ну и сейчас там всё это чисто номинально. Похоже, это мало кому нужно.

Из-за преобразования в цветоразность проблема, чтоль?

Да.

i-rinat ★★★★★ ()
Ответ на: комментарий от mv

В жожошке моей посмотри (кажись, один-полтора порядка разница в скорости интерполяции B-сплайнами на CPU в 4 потока и на GPU). Но я пока что хрен пинаю: отпуск у меня до 20-го марта, в лом что-нибудь делать.

// как надумаю, сделаю.

Eddy_Em ☆☆☆☆☆ ()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Там разницы на современном проце (SandyBridge и новее) только в пропускной способности памяти должно быть.

mv ★★★★★ ()
Ответ на: комментарий от mv

Не могу ничего сказать про скорость, но на celeron p4500 (1.87) c ironlake-видео масштабирование картинки на opengl греет проц значительно меньше, чем аналогичная процедура на libswscale.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Не могу ничего сказать про скорость, но на celeron p4500 (1.87) c ironlake-видео масштабирование картинки на opengl греет проц значительно меньше, чем аналогичная процедура на libswscale.

Вывод через оверлей или прям масштабирование (туда-тянем-обратно)?

mv ★★★★★ ()
Ответ на: комментарий от mv

Вывод через оверлей или прям масштабирование (туда-тянем-обратно)?

Нет, только вывод на экран. Обратно мне не надо было.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Нет, только вывод на экран.

Хех, ну дело не хитрое ;) Оверлейный скейлер даже не пишет ничего в память.

mv ★★★★★ ()
Ответ на: комментарий от mv

Оверлейный скейлер

Через оверлей мне нельзя, мне на растянутой картинке ещё рисовать потом надо. Я пока что yuv->rgb всё ещё через libswscale делаю, но без апскейла.

i-rinat ★★★★★ ()

Всем спасибо. Буду использовать magickwand.

LinuxUser ★★ ()
Ответ на: комментарий от mv

Таки оба правы. (и Eddy_Em тоже)

 256; 256;0.002582;0.005684;0.007081;0.000657;0.002122
 256; 512;0.002958;0.009531;0.011303;0.000887;0.002118
 256; 768;0.003201;0.013818;0.015991;0.000859;0.002552
 256;1024;0.003485;0.018340;0.019503;0.001634;0.002126
 512; 256;0.003370;0.009567;0.011041;0.001214;0.002147
 512; 512;0.003848;0.019100;0.019351;0.001630;0.002103
 512; 768;0.004408;0.027939;0.028123;0.001745;0.002439
 512;1024;0.004896;0.036727;0.035284;0.002099;0.002110
 768; 256;0.004105;0.014059;0.015718;0.000943;0.002477
 768; 512;0.004929;0.027467;0.027748;0.001842;0.002419
 768; 768;0.005623;0.041481;0.040696;0.002376;0.002828
 768;1024;0.006465;0.056259;0.051331;0.002579;0.002218
1024; 256;0.004955;0.019852;0.019108;0.001627;0.002216
1024; 512;0.006256;0.037294;0.035924;0.002014;0.002284
1024; 768;0.006949;0.055599;0.052430;0.002492;0.002436
1024;1024;0.007896;0.073875;0.067410;0.002786;0.002413
1280; 256;0.005839;0.023752;0.024084;0.001527;0.002734
1280; 512;0.006979;0.045716;0.043938;0.002335;0.002552
1280; 768;0.008185;0.069451;0.063058;0.002651;0.002615
1280;1024;0.009488;0.093946;0.084176;0.003533;0.002774
1536; 256;0.006622;0.029007;0.028052;0.001837;0.002686
1536; 512;0.008031;0.055607;0.051383;0.002668;0.002287
1536; 768;0.009423;0.084270;0.076563;0.003294;0.002679
1536;1024;0.010719;0.114334;0.100322;0.003849;0.003139
1792; 256;0.007528;0.033786;0.032293;0.001866;0.002958
1792; 512;0.009060;0.064492;0.059214;0.002730;0.002416
1792; 768;0.010708;0.097901;0.087288;0.003630;0.002867
1792;1024;0.012345;0.131178;0.117498;0.003919;0.004337
2048; 256;0.008322;0.038345;0.035222;0.001984;0.002280
2048; 512;0.010135;0.074094;0.067603;0.002736;0.002468
2048; 768;0.011943;0.111330;0.101121;0.003874;0.003175
2048;1024;0.013746;0.149898;0.134717;0.004516;0.004226

ширина (1) и высота (2) назначения, время libswscale (3), время gl1 с получением результата (4), время gl2 с получением результата (5), время gl1 без получения результата (6), время gl2 без получения результата (7). По 100 повторов, значения — секунд на один вызов скейла.

gl1 — текстуры создаются и уничтожаются каждый раз, gl2 — создаются две текстуры 2048x1024 для источника и назначения, обновляются значения в них.

Львиную долю съедает получение результатов из opengl, а именно memcpy где-то в нутрах mesa.

Проц/видео: Celeron P4500. Исходное изображение было 600x372.

i-rinat ★★★★★ ()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от mv

На нормальном проце всё ещё быстрее будет.

В GL тоже в проц упирается, так что не факт. Это похоже на баг mesa.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

В GL тоже в проц упирается, так что не факт. Это похоже на баг mesa.

Проц копированием занят. В итоге, всё упирается в память.

mv ★★★★★ ()
Ответ на: комментарий от i-rinat

А чего это так шустро? Тупая линейная интерполяция что ли?

// кстати, у меня в ЖЖшке — про интерполяцию B-cплайнами. И замеры (в среднем разница между CPU и GPU — полтора порядка).

Eddy_Em ☆☆☆☆☆ ()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Тупая линейная интерполяция что ли?

SWS_FAST_BILINEAR на CPU и простая отрисовка текстуры в текстуру в GPU.

про интерполяцию B-cплайнами

У тебя реализация на CPU не использует SIMD возможностей. Возьми libswscale и проверь заново. Наверняка CPU реализация станет быстрее в разы. Интересно посмотреть, как в этом случае соотнесутся CPU и GPU.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

SWS_FAST_BILINEAR

Это и есть тупая линейная.

У тебя реализация на CPU не использует SIMD возможностей

Я таких слов-то не знаю! Не выражайся!

Возьми libswscale

Там есть B-сплайны?

Между прочим, у меня и на GPU далеко не оптимизированный код!

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Там есть B-сплайны?

Вот полный список: http://ffmpeg.org/doxygen/0.6/libswscale_2options_8c.html#384ff94b5139f441c28...

Между прочим, у меня и на GPU далеко не оптимизированный код!

Для CUDA с её массово перекрывающимися нитями почти любой код близок к оптимальному.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Вот полный список: http://ffmpeg.org/doxygen/0.6/libswscale_2options_8c.html#384ff94b5139f441c28...

Неплохо. Только нет реализации на CUDA. Поэтому лучше свой велосипед.

Для CUDA с её массово перекрывающимися нитями почти любой код близок к оптимальному.

Не совсем так.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Только нет реализации на CUDA. Поэтому лучше свой велосипед.

Ты сравнил свой CPU-велосипед со своим GPU-велосипедом и на основании этого выбрал инструмент. Ты же понимаешь, что если использовать оптимизированный CPU-вариант, расклад может поменяться? Или это культ карго: «на GPU a priori быстрее»?

Для CUDA с её массово перекрывающимися нитями почти любой код близок к оптимальному.

Не совсем так.

Это ты на BrookGPU не пробовал писать. Там надо постоянно думать об архитектуре. Что спарится, а что нет. CUDA в этом плане экономит (экономила) много сил.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Ты же понимаешь, что если использовать оптимизированный CPU-вариант, расклад может поменяться?

Да, но у меня куча других вещей на GPU считается, поэтому мне больше мое подходит.

Eddy_Em ☆☆☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.