1

Here's what I have:

  1. I load a texture from disk, say 256x256, say a picture of penguin
  2. I create another texture with same dimensions and I draw some stuff on it

I want to find distance between the two openGL textures AS FAST AS POSSIBLE (accuracy of the distance function is of LEAST concern).

Actually, they might not be textures in the first place. I might as well compare a region of the framebuffer to the loaded texture or do some other "magic".

How to do this super-fast?

JBeurer
  • 1,707
  • 3
  • 19
  • 38

2 Answers2

5

This has little to do with OpenGL in fact. OpenGL is just a 3D rasterization "driver".

The main idea is to get a distance/similarity algorithm, which is a tricky task. For beginning you could do a Root Mean Square Deviation algorithm. It will give you a number of how far away pixel values are.

When you implement it on CPU you could benchmark it for your needs and maybe convert to OpenCL. I don't think loading the "penguin" to GPU just to compare it to other shapes you prepare there is a super-fast process by itself.

Try to be more specific with your next question and avoid attitude of "I have a very well microscope, how do I hit nails with it super-fast?"

Kromster
  • 7,181
  • 7
  • 63
  • 111
  • 1
    +1 though it should be noted that RMSD works excellent for a _technical_ figure of "noise" differences, but is not so well suited for e.g. two otherwise identical pictures that are offset by a few pixels, and it can sometimes give unjustifiably bad values for _visually_ perfectly identical pictures. Still, this is probably the best, easiest, and fastest solution (other than maybe generating mipmaps and doing a sum-of-differences at mip-level 3 or 4). It really depends what one wants, too. – Damon Dec 30 '11 at 13:16
  • 1
    I'd say it has to do plenty with OpenGL, because the biggest performance hit comes from the glReadPixels and comparing pixel per pixel to source image on CPU. I'm pretty sure that if this similarity calculation is done on the GPU somehow, the performance would be like at least 10 times better. – JBeurer Dec 30 '11 at 13:43
  • It depends on your application a lot. We don't know what is that you render that needs to be compared to "penguin" images. – Kromster Dec 30 '11 at 13:45
  • Doesn't really matter, the rendering part takes negligible part of the time here. Comparing images by pixel on cpu however takes ALOT of time. It doesn't really matter what kind of image similarity function is used as long as it gives a value that semi-accurately represents the distance. – JBeurer Dec 30 '11 at 13:49
  • And the image distance calculation seems very fit for the GPU, you basically do some operation say len(src_color-dst_color) for each pixel and then you sum it up and return it as a similarity result. – JBeurer Dec 30 '11 at 13:53
  • So you say that you render random triangles and constantly compare then to "penguin" image. Then you keep on making adjustments to the triangles until they resemble the "penguin" close enough. Like so? – Kromster Dec 30 '11 at 14:11
  • It is hard to recommend anything without more detail. Maybe you need another question with detailed example of what you have and what you want to get, without mandatory tool choice. – Kromster Dec 30 '11 at 15:59
2

You could use the Pearson-Product for matching different images. You can find it on an answer of mine. Instead of matching a template more little than the original image, you could correlated directly two images.

Shortly, you get the deviation of each textel from the average, giving you a correlation factor.

But improving that algorithm by using shaders could be a little hard. First, you have to compute the textel average: maybe some OpenGL extension (like histogram) may help you in this task.

Then, you could use fragment shaders to perform single-component computation (the difference between each textel with the averaged one computed previously. The average textel has to be passed as uniform, and the result should be stored in floating-point texture (you can render it on a framebuffer object).

Then, you should sum up all textel of the resulting texture in order to get the correlation between the two souce textures.

This may worth in the case images are very big. Otherwise I think it's just better to execute the algorithm on CPU, using SIMD instruction set (like MMX, SSE, AVX).

Community
  • 1
  • 1
Luca
  • 11,646
  • 11
  • 70
  • 125