2013-06-15 3 views
2

Я пишу программу, которая рисует несколько слоев, которые должны имитировать входное (растровое) изображение. После рисования фигур мне нужно сравнить мое визуализированное изображение с входным, а затем решить, достиг ли я своей цели или нет. В настоящее время я использую библиотеку CIMG для рисования. Вся программа работает на процессоре. Я попытался использовать SFML, который использует OpenGL для рисования - рендеринг был очень быстрым, но копирование изображения с графического процессора в CPU (для создания коагуляции со входным изображением) занимает очень много времени. Я хочу:Сравнение двух изображений с использованием OpenGL

  • визуализации многоугольников на GPU
  • отправить вход (растровые) изображения на GPU
  • сравнить изображения на GPU с помощью простой "пиксель после пикселя" сравнения: (r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2
  • отправить результат сравнения (один номер) к CPU

Unfortunatelly Я не знаю, если он (сравнение двух изображений) является возможно достигнуть wi го OpenGL. Если это возможно, я изучу OpenGL или любую другую библиотеку, которая позволяет выполнять мою задачу очень быстро.

+0

Вы можете сделать это в OpenGL, используя программирование в стиле GPGPU. В вашем случае, возможно, фрагментарный шейдер для сравнения отдельных значений пикселей, а затем другой шейдерный проход для вычисления максимальной разницы. Но это не похоже на разумное решение. На самом деле можно получить идеальную копию изображения с графического процессора до CPU. Ваш исходный код копирования GPU-> CPU был неправильным. Я бы поработал над его исправлением вместо кодирования сравнения на стороне GPU. – Angew

+0

Копирование с GPU на CPU работает хорошо, но я занимаю очень много времени, я повторяю эту операцию тысячи раз, поэтому для меня важно ускорить эту операцию. – Sparkzi

+0

Я вижу. Не совсем ясно, что значит «уничтожить все». В этом случае вы можете попробовать подход фрагментарного шейдера. – Angew

ответ

5

Вот схема возможного подхода. Они на самом деле просто советы, чтобы вы начали.

  1. Рендер изображения в текстуру (я буду называть его Render) и скопировать оригинал в другие текстуры (я буду называть его Orig). Отключите любую фильтрацию текстуры.

  2. Создайте один фрагментный шейдер, который будет вычислять разницу. В псевдокоде:

    vec3 render = texture2D(Render, fragmentPosition.xy); 
    vec3 orig = texture2D(Orig, fragmentPosition.xy); 
    gl_FragColor.r = (render - orig).dot(render - orig); 
    

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

  3. Создайте еще один фрагмент шейдеров для вычисления частичных сумм:

    float sum = 0; 
    for (row = 0; row < imageHeight; ++row) { 
        sum += texture2D(Difference, vec2(fragmentPosition.x, row)); 
    } 
    gl_FragColor.r = sum; 
    

    Выполнить этот фрагмент шейдера на квадроцикле размером image_width x 1, посылая вывод в другую текстуру (PartialSum).

  4. Либо прочитайте обратно PartialSum на CPU (он намного меньше), и суммируйте его там, либо создайте одноразрядный квадрант и запустите модифицированный шейдер суммирования, чтобы получить одно число, чем считать это обратно.

Смежные вопросы