views:

129

answers:

3

I wish to give an effect to images, where the resultant image would appear as if it is painted on a rough cemented background, and the cemented background customizes itself near the edges to highlight them... Please help me in writing an algorithm to generate such an effect. The first image is the original image

alt text

and the second image is the output im looking for. alt text

please note the edges are detected and the mask changes near the edges to indicate the edges clearly

+1  A: 

This is called bump mapping. It is used to give a non flat appearance to a surface.

Didier Trosset
i have applied Bump map..but please look at the edges.. that's where i'm stuck
megha
+3  A: 

You need to read up on Bump Mapping. There are plenty of bump mapping algorithms.

The basic algorithm is:

for each pixel

  1. Look up the position on the bump map texture that corresponds to the position on the bumped image.
  2. Calculate the surface normal of the bump map
  3. Add the surface normal from step 2 to the geometric surface normal (in case of an image it's a vector pointing up) so that the normal points in a new direction.
  4. Calculate the interaction of the new 'bumpy' surface with lights in the scene using, for example, Phong shading -- light placement is up to you, and decides where will the shadows lie.

Finally, here's a plain C implementation for 2D images.

Kornel Kisielewicz
i have already tried the Bump map composition. But the problem is that the cement mask adjusts itself in such a manner, that it appears to be highlighting the edges. What i mean to say is that the Cement mask dynamically changes to reflect the edges in the original image. Please refer the Output/Resultant Image carefully. The Cement mask at the edges of the circle and flower like shape is adjusted in such a manner that it appears to have detected the edges and is highlighting them.
megha
@megha: just do it. Just change the cement mask to reflect the edges in the original image, before you apply the bump mapping.
MSalters
@megha that looks like the brightness of the drawing is used to modify the bumpmap by reducing the z component of the normal as brightness decreases (or something like that).
phkahler
+2  A: 

Starting with 1) the input image as R, G, B, and 2) a texture image, grayscale.

The images are likely in bytes, 0 to 255. Divide it by 255.0 so we have them as being from 0.0 to 1.0. This makes the math easier. For performance, you wouldn't actually do this but instead use clever fixed-point math, an implementation matter I leave to you.

First, to get the edge effects between different colored areas, add or subtract some fraction of the R, G, and B channels to the texture image:

texture_mod = texture - 0.2*R - 0.3*B

You could get fancier with with nonlinear forumulas, e.g. thresholding the R, G and B channels, or computing some mathematical expression involving them. This is always fun to experiment with; I'm not sure what would work best to recreate your example.

Next, compute an embossed version of texture_mod to create the lighting effect. This is the difference of the texture slid up and right one pixel (or however much you like), and the same texture slid. This give the 3D lighting effect.

emboss =  shift(texture_mod, 1,1) - shift(texture_mod, -1, -1)

(Should you use texture_mod or the original texture data in this formula? Experiment and see.)

Here's the power step. Convert the input image to HSV space. (LAB or other colorspaces may work better, or not - experiment and see.) Note that in your desired final image, the cracks between the "mesas" are darker, so we will use the original texture_mod and the emboss difference to alter the V channel, with coefficients to control the strength of the effect:

Vmod = V * ( 1.0 + C_depth * texture_mod + C_light * emboss)

Both C_depth and C_light should be between 0 and 1, probably smaller fractions like 0.2 to 0.5 or so. You will need a fudge factor to keep Vmod from overflowing or clamping at its maximum - divide by (1+C_depth+C_light). Some clamping at the bright end may help the highlights look brighter. As always experiment and see...

As fine point, you could also modify the Saturation channel in some way, perhaps decreasing it where texture_mod is lower.

Finally, convert (H, S, Vmod) back to RGB color space.

If memory is tight or performance critical, you could skip the HSV conversion, and apply the Vmod formula instead to the individual R,G, B channels, but this will cause shifts in hue and saturation. It's a tradeoff between speed and good looks.

DarenW