[Digikam-devel] RFC, fix overexposing white balance

Giuliano Pochini pochini at shiny.it
Mon Dec 6 22:06:39 GMT 2010


Hi all!

IMHO the white balance tool is quite useless in its current form because it
overexposes and clips at least one of the rgb components almost always. The
exposure compensation thing does not help because it is applied on the
already clipped image. I wrote the simple patch below that makes the wb
tool useable by scaling down the wb multipiers just enough to prevent
clipping.

The biggest problem is that the final result can be quite a lot dimmer than
the preview image because the scaler smooths the (usually tiny) brightest
spots of the photo.



--- digikam-1.6.0/libs/dimg/filters/wb/wbfilter.cpp__orig	2010-11-22 18:47:36.000000000 +0100
+++ digikam-1.6.0/libs/dimg/filters/wb/wbfilter.cpp	2010-12-06 22:37:29.000000000 +0100
@@ -294,6 +294,38 @@ void WBFilter::adjustWhiteBalance(uchar*
         uchar  red, green, blue;
         uchar* ptr = data;
 
+
+        int maxr, maxg, maxb, max;
+        double adjust;
+
+        // Look for the maximum r, g, b values in the given image
+        maxr = maxg = maxb = 0;
+        for (j = 0 ; j < size; ++j) {
+            if (maxb < ptr[0])  maxb = ptr[0];
+            if (maxg < ptr[1])  maxg = ptr[1];
+            if (maxr < ptr[2])  maxr = ptr[2];
+            ptr += 4;
+        }
+printf("maxrgb=%d, %d, %d\n", maxr, maxg, maxb);
+printf("mrgb=%f, %f, %f\n", d->mr, d->mg, d->mb);
+        // White balance them and find the most overexposed one
+        maxr *= d->mr;
+        maxg *= d->mg;
+        maxb *= d->mb;
+        max = qMax(maxb, maxg);
+        max = qMax(max, maxr);
+printf("m*maxrgb=%d, %d, %d  m*max=%d clamp_at=%d\n", maxr, maxg, maxb, max, d->rgbMax-1);
+        // Scale wb coefficients down if needed
+        if (max > d->rgbMax-1) {
+            adjust = (double)(d->rgbMax-1) / max;
+printf("adjust=%f\n", adjust);
+            d->mb = d->mb * adjust;		// Overwrites d->mx !!
+            d->mg = d->mg * adjust;
+            d->mr = d->mr * adjust;
+        }
+        ptr = data;
+
+
         for (j = 0 ; runningFlag() && (j < size) ; ++j)
         {
             int v, rv[3];




-- 
Giuliano.



More information about the Digikam-devel mailing list