LINUX.ORG.RU

Обработка изображений при помощи OpenGL и шейдеров

 , ,


8

1

При помощи технологии OpenGL и библиотеки GLUT вы можете ускорить процесс обработки изображений, используя всю мощь видеоадаптера вашей системы.

>>> Подробности

★★★

Проверено: Shaman007 ()

Любопытно, надо почитать. Но почему не OpenCL/CUDA?

unfo ★★★★★ ()

В чём новизна? Шейдеры для обработки изображений используют уже лет восемь.

imtw ()

Но зачем? Все-это изначально предназначалось именно для реалтайм графики.

buddhist ★★★★★ ()

Интересная статья. Спасибо!

vada ★★★★★ ()

Как обычно, готового решения с новой модной мулькой нет, «сделай сам»?

yu-boot ★★ ()

спасибо, читаю попивая чаек - актуально для меня

I-Love-Microsoft ★★★★★ ()

Хорошая идея. А то я вейвлеты на CPU считал. А ведь можно их в шейдер запихать. Хотя, по-моему, лучше уж вообще CUDA'у какую-нибудь для этого использовать и выводить результат в openGL.

Eddy_Em ☆☆☆☆☆ ()

хм... а это точно /распознавание/ контура? может таки просто выделение краёв? ибо на картинку просто лапласа набрасывают. без последующего поиска собссно контуров (как замкнутого геометрического места точек и тэ дэ и тэ пэ).

gour ()
Ответ на: комментарий от yu-boot

GPU для обработки изображений только ленивый не использует. Даже в гимпе, afaik. Тема - жуткий баян.

imtw ()
Ответ на: комментарий от gour

++

Поиск контуров реализовать несложно (правда, я убил, наверное, несколько дней на реализацию метода шагающих квадратов). Но еще ведь контуры сгладить надо. А это — совсем уж нетривиальная операция. Правда, учитывая то, что после нахождения контуров мы можем распараллелить процесс сглаживания, работу можно ускорить. Правда, тут уже лучше нормальную куду использовать, а не шейдеры.

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

Причём есть готовые примеры работы с edge avoiding wavelets на OpenCL. В darktable.

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

на шейдерах их считать скажем так нереально. просто в силу того, что локальная память НЕПРЕДСТАВИМА в GLSL никак. а это штука полезная весьма.

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

Тогда я даже не представляю, как можно шрейдеры использовать для вычисления контуров…

// А ведь и правда: получается, что и Хафа не посчитаешь, и Фурье не сделаешь, и даже простенькую вейвлет-фильтрацию… Ну и нафига эти шрейдеры нужны тогда? Какая связь между ними и обработкой изображений?

// А с другой стороны: ты ведь работаешь с текстурой, т.е. массив у тебя есть. Берешь новую текстуру в качестве промежуточного + еще одну — окончательного вариантов. Вуаля! Элементарнейшие операции сделать можно. Но таки с контурами не прокатит, да.

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

локальная память - это не совсем тоже самое, что и «глобальная» память. в частности, она не представима как текстура изза своей локальности: каждый счетный блок видит только свой кусочек. Если угодно, считайте ее каналами передачи данных между соседними пикселями. Штука удобная, позволяет избежать многократных чтений с обсчетами там, где можно воспользоваться кэшированным значением из соседнего пикселя. Но в силу чисто аппаратных свойств, не представима как примитив GLSL, да и OpenCL

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

Как-то бестолково и сумбурно написано...

mine ()

На самом деле, полезная статья, в свое время она мне очень помогла. Делался проигрывающий модуль на ffmpeg'е в кроссплатформенную (lin/win/mac) софтину, и тут оказалось, что с реализацией видео-оверлея в таком ракурсе дофига проблем, а делать yuv->rgb и масштабирование на процессоре - нереально. В ходе гугленья была найдена эта статейка и реализован вполне переносимый код на OpenGL+GLSL, по производительности не уступал решению с оверлеем.

Salieff ()

Статья может и хорошая, но явно на новость не катит :)

rtvd ★★★★★ ()

Исходные коды программы Glutcam: 10575.tar

Ссылка недоступна. Где скачать-то? А то заинтересовало (сейчас как раз решил ускорить процесс построения модели зеркала и переписать с octave на С). Там у меня самое стремное — трассировка лучей. Octave считал несколько дней (поэтому приходилось сильно загрублять модель). А при помощи шейдеров по идее построить внефокальное изображение маски будет проще.

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

И действительно, не обратил внимания: должно быть

http://www.linuxjournal.com/files/linuxjournal.com/ufiles/10575.tar

Ē-моē, что это

CPU_OPT = -march=pentium3
¿?????¿

Без этого скомпилировалось. Сейчас буду препарировать...

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

Так вы же вроде на CUDA кодите. Шейдер - не более, чем CUDA-ядро, загнанное в прокрустово ложе графического конвейера.

Обработка изображений шейдерами делается очень костыльно: придётся рисовать натянутый на весь экран прямоугольник, писать для этого абсолютно не нужный вершинный шейдер-пустышку, возиться с render-target'ами. Короче, будет очень много лишних сущностей, CUDA рулит.

imtw ()
Ответ на: комментарий от Eddy_Em
CPU_OPT = -march=pentium3

Так лучше, наверное:

CPU_OPT = -march=native

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

Да я вообще подумывал было возложить эту задачу на плечи openGL: нарисовать «кривое зеркало», перед ним — диафрагму, автоматом получить «снимок».

Просто мой метод «тупого перебора» слишком долго будет и на CUDA работать, а вникать в суть алгоритмов выборочной трассировки лучей как-то не хочется…

Хотя, да: я и забыл, что шейдеру нельзя задать форму поверхности формулой. А делать матрицу эдак 10000х10000 3D-float'ов — никакой памяти не хватит...

Ладно, буду дальше кумекать, как мне попроще все реализовать. Или действительно на куде тупой перебор сделать…

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

Хотя, да: я и забыл, что шейдеру нельзя задать форму поверхности формулой. А делать матрицу эдак 10000х10000 3D-float'ов — никакой памяти не хватит...

В принципе можно. Есть костыль под названием программируемая тесселяция, но я её не тыкал и насчёт 10000х10000 не скажу, плюс она есть только в DirectX11, версию OpenGL не скажу.

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

Да ладно: я уже примерно прикинул, как ускорить процесс. Сначала сканировать с большим шагом для выявления теневых областей, затем подробно исследовать только то, что явно будет видно + небольшую область по соседству. Хотя, можно и просто случайным образом «бросать» фотоны и вычислять, куда они попадут (просто это явно будет дольше).

Ладно, рано пока говорить: сначала «пробник» сделать надо.

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

Кстати, вы же вроде в AMD работаете. Не в курсе, как реализуются вещи вроде той же тесселяции и растеризации? Программно, или эти алгоритмы заложены прямо в железо?

imtw ()

Только лучше не GLUT лучше freeGLUT.

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

в HD5000 уже были в железе. точнее растеризатор всегда в железе был. просто его упростили в HD5000. тесселяция идет с поддержкой со стороны железа но это по сути уже софт для видяхи. железо больше буферизует по всякому и думает как разделить ресурсы между шейдерами

доки все тут:

http://www.x.org/docs/AMD/

там есть по evergreen isa дока, в ней в разделе 2.1.4-2.1.5 описано как оно работает в общих чертах.

NI похожи на evergreen в этом плане, а в SI просто перегруппировали ALUшки из 64*4 -> 4*64

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

Просто мой метод «тупого перебора» слишком долго будет и на CUDA работать, а вникать в суть алгоритмов выборочной трассировки лучей как-то не хочется…

А это не подходит в качестве образца?

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

Cпасибо, интересное чтиво. Довольно много вопросов отпало.

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

2.6 еще гляньте. можно считать что данные текут только сверху вниз на схеме, кроме коричневых квадратов - это можно читать-писать.

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

P.S. Фразу

The Evergreen hardware assembles primitives from data in the position
buffer and the vertex geometry translator (VGT), performs scan conversion
and final pixel interpolation, and loads these values into GPRs.

следует понимать, что эти этапы растеризации заложены прямо в железо?

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

политрук немного лжет. финальную интерполяцию ведет шейдер, вернее та часть, которую вы не видите.

растеризатор просто берет треугольник, нарезает его на блоки 8*8 пикселей, ну как получится.не всегда оптимально. посмотрите в инете демо атомарных счетчиков для nvidia и radeon. у радеона явно видна шахматная доска. железо режет квадраты от «первого» вертекса, поэтому порядок именно такой: для квадрата

1  4 
2  3
рисуется 1-2-3, затем 3-4-1

в общем, железо формирует задачу: 3 вершины в Global Data Storage, их адреса, и координаты пикселя xy в регистрах. Дальше SP проверяют а попали ли мы в треугольник(квадраты 8х8 могут мазать), если нет отрубаются, затем интерполируют глубину, читают буферы глубины и шаблона, если не ок, вырубаются. затем интерполируют остальные параметры и рубят уже собственно пиксельные шейдеры.

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

С подобной схемой я знаком, в общих чертах похоже на то, что рисуют в доках по CUDA. Непонятки были с деталями, специфичными именно для графического конвейера.

imtw ()
Ответ на: комментарий от gag

Не, не подходит: во-первых, там C++, а во-вторых — OpenCL. Ни в том, ни в другом я разбираться не хочу. Муторно и противно.

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

атишники все упрощают а невидия усложняет. если честно, GPU неправильно представляется для разраба. как набор из кусков по «64 ядра». это не только неверно, но и мешает на OpenCL кодить.

на самом деле, можно смотреть на atiшную видяху, как на набор CPU, которые имеют а)обрабатывать несколько потоков и имеют аппаратные семафоры(16 шт). выгодно чтоб разные потоки лупили разные виды команд.

обрабатывать по (для hd5000-6800-7700)4 вектора по 64 32битных значения за цикл. Плюс hd5000 умеет обработать чуть урезанее еще один такой вектор, всего 5.

у проца пять групп регистров, 4 группы по 256 векторов по 64 32битных значения. то ли 32 вектора, то ли 123 можно пошарить между потоками. еще одна из 128 векторов по 64 32битных значения, где можно делать атомарные операции на целыми числами, а еще кое-как переставлять элементы. и адресовать разные элементы векторов можно отдельно. т.е. X взять из первого, Y из второго и т.д.

т.е. LDS - это те же регистры по сути. только представить себе эту хрень проще чем «64 процессора».

ckotinko ☆☆☆ ()

В Gimp и ImageMagic не скоро подобное запилят? А то вся нагрузка у линуксовых графических редакторов ложится на CPU, что печально.

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

GPU для обработки изображений только ленивый не использует.

Вот только при сохранении на диск предпочитают пересчитывать на CPU. Может точности не хватает.

DNA_Seq ★★☆☆☆ ()

Спасибо, кэп:) Уже CUDA давно пропихивают в массы.

RPG ()
Ответ на: комментарий от imtw

Обработка изображений шейдерами делается очень костыльно: придётся рисовать натянутый на весь экран прямоугольник, писать для этого абсолютно не нужный вершинный шейдер-пустышку, возиться с render-target'ами. Короче, будет очень много лишних сущностей, CUDA рулит.

local img = newImage('img.jpg')
local shader = newShader('shader.frag')

Entity:new(screen):draw(function()
	local w, h = getWindowWidth(), getWindowHeight()
	shader:bind()
	shader:set('texel', 1/w, 1/h)
	shader:set('radius', 8)
	img:draw(0, 0, w, h)
	shader:unbind()
end)

mainLoop()

И где тут костыли?:)

RPG ()
Ответ на: комментарий от lucentcode

В гимп уже есть. В IM незачем - там затрат на перегон картинки из системной памяти в GPU, а потом обратно ещё больше. Действительно быстро когда картинка постоянно в GPU и отображается им же.

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

Щито это? Я говорил про голые OpenGL/DirectX, которые не умеют даже jpg грузить.

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

Это - код, который получается, если спрятать все страхи API. А jpg и куда грузить не может.

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

Значит все перечисленные выше костыли находятся внутри. Внутри CUDA их совсем нет. А что за обёртка-то?

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