Подсчет схожести изображений на графическом процессоре [OpenGL/OcclusionQuery]

OpenGL. Допустим, я нарисовал одно изображение, а затем второе с помощью XOR. Теперь у меня где-то есть черный буфер с нечерными пикселями, я читал, что могу использовать шейдеры для подсчета черных [ rgb (0,0,0) ] пикселей на графическом процессоре?

Я также читал, что он должен что-то делать с OcclusionQuery. http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt

Возможно ли это и как? [любой язык программирования]

Если у вас есть другая идея, как найти сходство с помощью OpenGL/GPU - это тоже было бы здорово.


person Slava V    schedule 19.09.2008    source источник


Ответы (1)


Я не уверен, как вы выполняете бит XOR (по крайней мере, он должен быть медленным; я не думаю, что какой-либо из современных графических процессоров ускоряет это), но вот моя идея:

  1. иметь два входных изображения
  2. включить запрос окклюзии.
  3. нарисуйте два изображения на экране (т.е. полноэкранный четырехугольник с двумя настроенными текстурами) с помощью фрагментного шейдера, который вычисляет abs(texel1-texel2) и уничтожает пиксель (отбрасывает в GLSL), если пиксели одинаковы (разница равна нулю или ниже некоторого порога). Проще всего, вероятно, просто использовать фрагментный шейдер GLSL, и там вы просто читаете две текстуры, вычисляете abs() разницы и отбрасываете пиксель. Здесь достаточно базовых знаний GLSL.
  4. получить количество пикселей, которые прошли запрос. Для одинаковых пикселей запрос не пройдет (пиксели будут отброшены шейдером), а для разных пикселей запрос пройдет.

Сначала я думал о более сложном подходе с использованием буфера глубины, но потом понял, что достаточно просто убить пиксели. Вот мой оригинал (но приведенный выше проще и эффективнее):

  1. иметь два входных изображения
  2. очистить экран и буфер глубины
  3. нарисуйте два изображения на экране (т.е. полноэкранный четырехугольник с двумя настроенными текстурами) с помощью фрагментного шейдера, который вычисляет abs(texel1-texel2) и уничтожает пиксель (отбрасывает в GLSL), если пиксели разные. Нарисуйте четырехугольник так, чтобы его значение буфера глубины было близко к ближней плоскости.
  4. после этого шага буфер глубины будет содержать небольшие значения глубины для одинаковых пикселей и большие значения глубины (в дальней плоскости) для разных пикселей.
  5. включите запрос окклюзии и нарисуйте еще один полноэкранный четырехугольник с глубиной ближе, чем дальняя плоскость, но больше, чем предыдущий четырехугольник.
  6. получить количество пикселей, которые прошли запрос. Для одинаковых пикселей запрос не пройдет (буфер глубины уже ближе), а для разных пикселей запрос пройдет. Вы бы использовали SAMPLES_PASSED_ARB, чтобы получить это. На CodeSampler.com есть пример запроса на перекрытие, который поможет вам начать работу.

Конечно, для всего этого требуется GPU с поддержкой запросов окклюзии. Большинство графических процессоров с 2002 года или около того поддерживают это, за исключением некоторых бюджетных (в частности, Intel 915 (он же GMA 900) и Intel 945 (он же GMA 950)).

person NeARAZ    schedule 19.09.2008
comment
Ну да, примерно так я и думал, но есть ли примеры кода в Интернете? Специально для вычислений abs(texel1-texel2) и количества пикселей, прошедших запрос. - person Slava V; 19.09.2008
comment
@yoihj: это очень простое использование GLSL и запроса окклюзии. Найдите любое руководство по GLSL, и я добавил ссылку на образец запроса окклюзии. - person NeARAZ; 19.09.2008