How can I remove shadows from an image?
There are dozens of publications dealing with shadow-detection, generating shadow-masks, and indeed some that actually remove shadows - such as the ones mentioned in the previous posts. I could add some to the list, if needed. The problem, however, is IMHO far from being solved. For a quick-start, given a shadow-mask, I suggest (and have tried in the past) the two following approaches. They definitely reduce shadows - just not always seamless, and I'm sure there are publications (not by me) dealing with shadow-removal in similar ways.


Gradient Domain Manipulation Techniques as described here (C and Matlab Codes provided):
http://www.umiacs.umd.edu/~aagrawal/ICCV2007Course/index.html
The gradient-integration approach can be used for a number of image-processing problems, see the slides/presentation for further examples.

The general idea:


Compute the spatial derivatives (gradient-images) for all color-channels.
Use the shadow-boundaries from the shadow-mask to generate a weight-mask that is close to zero on shadow-boundaries and increases to one within a specified neighborhood along the shadow-edge, i.e. orthogonal to a given edge-point.
Multiply the weight-mask from (2.) with all the gradient-images to reduce/damp the shadow-boundaries/edges.
Integrate the gradient-images using the code from the above link.
For RGB-images, from my experience, compute the average of the separate channels of the original images, and scale the integrated images to match these values to prevent "funny" color-artifacts.

Brightness manipulation in the original image-domain.


Use the shadow-mask to generate a weight-mask that is one outside shadow regions, has a smooth transition (upwards) across the shadow-boundary and a larger than one scale-factor inside shadow-regions. As suggested in a previous post, the scale-factor can be estimated from the area immediately surrounding a shadow-area using the average-brightness together with the average-brightness of the shadow-region.
Multiply the original images (per channel) with the weight-mask, subject to clipping.



I have also tried using different color-models, e.g. HSV, that present luminance or brightness directly, which can then be modified independent of color (hue/saturation). This works essentially like the brightness-manipulation, i.e. generate a smooth weight-mask and multiply it with the luminance-channel. Maybe the two approaches, i.e. gradient-integration and brightness-manipulation, can be combined in a clever way, but someone has probably tried that before too.

Hope that helps, kind regards, Derik.