5

I have implemented an image blending method for seamless blending using plain C++. Now I want to convert this code for GPU (using OpenGL ES 2 Shaders for mobile devices). Basically the method creates Gaussian and Laplacian Pyramides for each image which are then combined from low-resolution to top (see also the paper "The Laplacian Pyramid as a Compact Image Code" from Burt et.al. 1983).

My problem is that the Laplacian pyramid levels can have negative values but my devices do not support float or integer type textures (using the ORB_texture_float extension e.g.).

I already looked for papers dealing with GPU-based pyramids but without finding something really useful.

  1. How can I implement such a pyramid efficiently for a GPU?
  2. Is it possible to calculate a Gaussian/Laplacian pyramid level without iterating through the preceding levels?

Regards,

EDIT It seems as if there is no "good" way to calculate Laplacian Pyramids completely on GPU except using two passes (one for signs, one for values) which do not have support for either signed types (for instance ARB_texture_float) or types larger than byte when the the image's data range is between [0..255]. My Laplacian Pyramid runs perfectly on GPUs with ARB_texture_float extension but without the extension (and some adjustments to compress the range) the pyramid gets "wrong" due to range compression.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Hyndrix
  • 4,282
  • 7
  • 41
  • 82

1 Answers1

6
  1. The safest way for you to implement a Laplacian pyramid if your textures are unsigned integers is to store two pyramids - one pyramid that contains the gradient magnitude of the Laplacian and another pyramid that stores the sign of the pixel at that location.

  2. Yes. Any level in a Gaussian or Laplacian pyramid has a closed form solution based on the sigma value that you want to compute. Consider the base case of a LoG pyramid computed at intervals of sigma = (2/3). The first level of the pyramid has sigma 2/3 and is produced simply by convolving with a 5x5 LoG filter with sigma 2/3. The second convolution with the same filter produces an LoG image with sigma 4/3, and finally the third has sigma 6/3, or 2, so we subsample the image to produce the next integer level of the pyramid. If you want to compute the LoG of an image at sigma 2, the levels at sigma 2/3 and 4/3 are not necessary - simply subsample the image one time and convolve with an LoG filter with sigma 1.

If you want to compute the LoG at sigma = 20, quad-subsample the image (16 pixel blocks become 1 pixel) to give you a sigma 16 image, then convolve once with a sigma 4/3 LoG filter.

Thomson Comer
  • 3,919
  • 3
  • 30
  • 32
  • Thanks for the hints. Did I get it right that I have to calculate the Laplacian pyramid twice (one for the signs, one for the absolute values)? – Hyndrix Sep 24 '12 at 16:35
  • After re-thinking your comment, it might also be possible to encode the signs of RGB in the alpha channel (which I do not use). This is probably slower than calculating the Pyramid twice, but it saves memory which is also sparse on my devices. – Hyndrix Sep 24 '12 at 17:21
  • Good idea to use the alpha channel, now you don't need to compute the pyramid twice or store two pyramids. Compute the Laplacian value via the filter and store it in a signed variable. Place the abs() of the signed variable into r/g/b. Divide the signed variable by the value stored in the texture, add 1 to the result, and store that in the alpha channel. If the value in alpha is 0 then your original gradient is negative, if it is two then the gradient is positive. – Thomson Comer Sep 24 '12 at 20:48