PDA

View Full Version : Two images difference using OpenGL



LusoTec
09-22-2008, 04:10 AM
Hi all.

This post is a bit long but please read on. Thanks.

I'm working on an interesting project where I have to find an object on an
scene's image.

I have a previously prepared RGBA image with only the object. Put in other
words, the background is black and fully transparent and the object's
pixels are fully opaque.

The algorithm I'm currently using works (most of the time, > 95%) but is
slow, especially because the object can appear in the image partially
occluded and in various sizes. Basically, I have a need for speed, so I'm
thinking OpenGL and GPU power to the rescue.

By far, the most time consuming part of the processing is comparing the
object's image with part of the scene's image.

I have used OpenGL in the past for model/data visualization with texture and
shading and I have a medium understanding of the API but never did image
processing so if you kind souls could give some pointers.

Next follows a detailed description of what I'm trying to calculate.

I have a RGB image named S (for Scene) and a RGBA image named B (for
oBject). All calculation work on an "infinite" 2D space that is black and
transparent by default.

The image S is "mapped" in the 2D space at the vertex coordinates
(0,0)-(1,0)-(1,1)-(0,1). The image B is "mapped" "warped" in the 2D space
with vertex coordinates (x1,y1)-(x2,y2)-(x3,y3)-(x4,y4). In practice, image
B will have a small "warp" but lets keep it general.

ASCII Image (hope it helps):


----------------------------------------------
| * * * * * * * * * * * * * * * * * * * * * *|
| * * S......................S * * * * * * * |
| * * . * * * * * * * * * * *. * * * * * * * |
| * * . * * *B..... * * * * *. * * * * * * * |
| * * . * * ,............B * . * * * * * * * |
| * * . * *,. *... *...., * *. * * * * * * * |
| * * . * B.. *.. * ..., * * . * * * * * * * |
| * * . * * ....... .., * * *. * * * * * * * |
| * * . * * * * .....B * * * . * * * * * * * |
| * * . * * * * * * * * * * *. * * * * * * * |
| * * . * * * * * * * * * * *. * * * * * * * |
| * * . * * * * * * * * * * *. * * * * * * * |
| * * S......................S * * * * * * * |
| * * * * * * * * * * * * * * * * * * * * * *|
| * * * * * * * * * * * * * * * * * * * * * *|
----------------------------------------------

Now, I need to calculate the color difference between image S and B for
those pixels/points in the 2D space that are in both images (and not
transparent in image B).

First draw the B image with no blending. Then draw the S image with the
following blending mode:

glBlendFunc( GL_DST_ALPHA, GL_DST_ALPHA );
glBlendEquationEXT( GL_FUNC_SUBTRACT_EXT );

Q1: Am I thinking this correctly? Does it do what I described?

After that, I need to square all those color differences, sum them, and
divide the sum by the number opaque pixel (to get some
normalization).

The best I get for this is to use glReadPixels to get the color difference
values and use the CPU to do the calculations.

Q2: Any way to do this using OpenGL? (with out pixel shader)

Thanks for your time.
Regards

Ilian Dinev
09-22-2008, 06:54 PM
Without a pixel-shader, you won't get the absolute difference [diff = abs(x-y) ], I think. Negative values will be clamped, unless you use float textures as render-targets and disable color clamping (it's some extension).

LusoTec
09-23-2008, 04:35 AM
Transforming the image pixel values solves that problem.

Red component for pixel in image B: RcB
Red component for pixel in image S: RcS
(the same goes for the other components but is excluded)

RcB in [0 , 1]
RcS in [0 , 1]
Diff = RcB - RcB
Diff in [-1 , 1]

To avoid clamping of Diff to [0,1], the following transform is applied:

RcBT = RcB / 2 + 0.5
RcST = RcS / 2
DiffT = RcBT - RcBT

RcBT in [0.5 , 1.0]
RcST in [0.0 , 0.5]
DiffT in [0.0 , 1.0]

-------------------------------------------------

Using OpenGL for the first part of the calculation saves some time, because "warping" the image B is CPU intensive.

The second part, calculating the sum of the squares using OpenGL is where I have no idea how to do it using OpenGL.

Thanks.