[Digikam-devel] extragear/graphics/digikamimageplugins/whitebalance
Gilles Caulier
caulier.gilles at kdemail.net
Tue Jan 16 12:52:35 GMT 2007
SVN commit 624124 by cgilles:
digiKam from trunk : White Balance image plugin :
* Prepare source code to give an image auto-exposure filter.
* Separate algorithm from gui.
* Code polishing and optimizations.
CCMAIL: digikam-devel at kde.org
M +1 -1 Makefile.am
M +65 -269 imageeffect_whitebalance.cpp
M +0 -30 imageeffect_whitebalance.h
AM whitebalance.cpp [License: GPL]
AM whitebalance.h [License: GPL]
--- trunk/extragear/graphics/digikamimageplugins/whitebalance/Makefile.am #624123:624124
@@ -8,7 +8,7 @@
kde_module_LTLIBRARIES = digikamimageplugin_whitebalance.la
digikamimageplugin_whitebalance_la_SOURCES = imageplugin_whitebalance.cpp \
- imageeffect_whitebalance.cpp
+ imageeffect_whitebalance.cpp whitebalance.cpp
digikamimageplugin_whitebalance_la_LIBADD = $(LIB_KPARTS) $(LIBDIGIKAM_LIBS)\
$(top_builddir)/digikamimageplugins/common/widgets/libdigikamimagepluginswidget.la
--- trunk/extragear/graphics/digikamimageplugins/whitebalance/imageeffect_whitebalance.cpp #624123:624124
@@ -6,9 +6,6 @@
*
* Copyright 2005-2007 by Gilles Caulier
*
- * Some parts are inspired from RawPhoto implementation copyrighted
- * 2004-2005 by Pawel T. Jochym <jochym at ifj edu pl>
- *
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
@@ -65,7 +62,7 @@
// Local includes.
#include "version.h"
-#include "blackbody.h"
+#include "whitebalance.h"
#include "imageeffect_whitebalance.h"
#include "imageeffect_whitebalance.moc"
@@ -77,19 +74,8 @@
{
QString whatsThis;
- m_clipSat = true;
- m_overExp = false; // Obsolete in algorithm since over/under exposure indicators
- m_WBind = false; // are implemented directly with preview widget.
- m_mr = 1.0;
- m_mg = 1.0;
- m_mb = 1.0;
- m_BP = 0;
-
Digikam::ImageIface iface(0, 0);
- m_WP = iface.originalSixteenBit() ? 65536 : 256;
- m_rgbMax = iface.originalSixteenBit() ? 65536 : 256;
-
m_destinationPreviewData = 0L;
// About data and help button.
@@ -469,54 +455,22 @@
m_previewWidget->setRenderingPreviewMode(Digikam::ImageGuideWidget::PreviewOriginalImage);
}
-void ImageEffect_WhiteBalance::slotColorSelectedFromOriginal( const Digikam::DColor &color )
+void ImageEffect_WhiteBalance::slotColorSelectedFromOriginal(const Digikam::DColor &color)
{
if ( m_pickTemperature->isOn() )
{
- Digikam::DColor dc = color;
- QColor tc = dc.getQColor();
-
- // Calculate Temperature and Green component from color picked.
-
- register int l, r, m;
- double sR, sG, sB, mRB, t;
+ Digikam::DColor dc = color;
+ QColor tc = dc.getQColor();
+ double temperatureLevel, greenLevel;
- t = QMAX( QMAX(tc.red(), tc.green()), tc.blue());
- sR = tc.red() / t;
- sG = tc.green() / t;
- sB = tc.blue() / t;
- mRB = sR / sB;
-
- DDebug() << "Sums: R:" << sR << " G:" << sG << " B:" << sB << endl;
-
- l = 0;
- r = sizeof(bbWB)/(sizeof(float)*3);
- m = (r + l) / 2;
-
- for (l = 0, r = sizeof(bbWB)/(sizeof(float)*3), m = (l+r)/2 ; r-l > 1 ; m = (l+r)/2)
- {
- if (bbWB[m][0]/bbWB[m][2] > mRB)
- l = m;
- else
- r = m;
-
- DDebug() << "L,M,R: " << l << " " << m << " " << r
- << " bbWB[m]=:" << bbWB[m][0]/bbWB[m][2]
- << endl;
- }
-
- DDebug() << "Temperature (K):" << m*10.0+2000.0 << endl;
-
- t = (bbWB[m][1]/bbWB[m][0]) / (sG/sR);
-
- DDebug() << "Green component:" << t << endl;
-
- m_temperatureInput->setValue(m*10.0+2000.0);
- m_greenInput->setValue(t);
- m_pickTemperature->setOn(false);
+ WhiteBalance::autoWBAdjustementFromColor(tc, temperatureLevel, greenLevel);
+
+ m_temperatureInput->setValue(temperatureLevel);
+ m_greenInput->setValue(greenLevel);
+ m_pickTemperature->setOn(false);
}
else
- return;
+ return;
// restore previous rendering mode.
m_previewWidget->setRenderingPreviewMode(m_currentPreviewMode);
@@ -563,6 +517,29 @@
m_histogramWidget->repaint(false);
}
+void ImageEffect_WhiteBalance::slotAutoAdjustExposure()
+{
+ parentWidget()->setCursor( KCursor::waitCursor() );
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int width = iface->originalWidth();
+ int height = iface->originalHeight();
+ bool sb = iface->originalSixteenBit();
+
+ double blackLevel;
+ double exposureLevel;
+
+ WhiteBalance::autoExposureAdjustement(data, width, height, sb, blackLevel, exposureLevel);
+ delete [] data;
+
+ m_blackInput->setValue(blackLevel);
+ m_exposureInput->setValue(exposureLevel);
+
+ parentWidget()->unsetCursor();
+ slotEffect();
+}
+
void ImageEffect_WhiteBalance::slotEffect()
{
Digikam::ImageIface* iface = m_previewWidget->imageIface();
@@ -579,24 +556,27 @@
m_destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)];
- // Update settings
- m_temperature = m_temperatureInput->value()/1000.0;
- m_dark = m_darkInput->value();
- m_black = m_blackInput->value();
- m_exposition = m_exposureInput->value();
- m_gamma = 2.0-m_gammaInput->value();
- m_saturation = m_saturationInput->value();
- m_green = m_greenInput->value();
-
+ double temperature = m_temperatureInput->value()/1000.0;
+ double dark = m_darkInput->value();
+ double black = m_blackInput->value();
+ double exposure = m_exposureInput->value();
+ double gamma = 2.0-m_gammaInput->value();
+ double saturation = m_saturationInput->value();
+ double green = m_greenInput->value();
+
+ WhiteBalance wbFilter(sb);
+ wbFilter.whiteBalance(data, w, h, sb,
+ temperature, dark, black, exposure,
+ gamma, saturation, green);
+
+/*
// Set preview lut.
setRGBmult();
m_mg = 1.0;
setLUTv();
setRGBmult();
-
- // Apply White balance adjustments.
- whiteBalance(data, w, h, sb);
-
+ */
+
iface->putPreviewImage(data);
m_previewWidget->updatePreview();
@@ -614,25 +594,28 @@
int w = iface->originalWidth();
int h = iface->originalHeight();
bool sb = iface->originalSixteenBit();
+
+ double temperature = m_temperatureInput->value()/1000.0;
+ double dark = m_darkInput->value();
+ double black = m_blackInput->value();
+ double exposure = m_exposureInput->value();
+ double gamma = 2.0-m_gammaInput->value();
+ double saturation = m_saturationInput->value();
+ double green = m_greenInput->value();
- // Update settings
- m_temperature = m_temperatureInput->value()/1000.0;
- m_dark = m_darkInput->value();
- m_black = m_blackInput->value();
- m_exposition = m_exposureInput->value();
- m_gamma = 2.0-m_gammaInput->value();
- m_saturation = m_saturationInput->value();
- m_green = m_greenInput->value();
-
+ WhiteBalance wbFilter(sb);
+ wbFilter.whiteBalance(data, w, h, sb,
+ temperature, dark, black, exposure,
+ gamma, saturation, green);
+
+/*
// Set final lut.
setRGBmult();
m_mr = m_mb = 1.0;
if (m_clipSat) m_mg = 1.0;
setLUTv();
setRGBmult();
-
- // Apply White balance adjustments.
- whiteBalance(data, w, h, sb);
+ */
iface->putOriginalImage(i18n("White Balance"), data);
delete [] data;
@@ -748,192 +731,5 @@
file.close();
}
-// -- White Balance algorithm -------------------------------------------
-
-void ImageEffect_WhiteBalance::slotAutoAdjustExposure(void)
-{
- parentWidget()->setCursor( KCursor::waitCursor() );
-
- // Create an histogram of original image.
-
- Digikam::ImageIface* iface = m_previewWidget->imageIface();
- uchar *data = iface->getOriginalImage();
- int width = iface->originalWidth();
- int height = iface->originalHeight();
- bool sb = iface->originalSixteenBit();
-
- Digikam::ImageHistogram *histogram = new Digikam::ImageHistogram(data, width, height, sb);
-
- // Calculate optimal exposition and black level
-
- int stop, i, scale, w, h;
- double black, expo, sum;
-
- w = width / 400;
- h = height / 400;
- scale = QMAX(w, h);
- scale = QMAX(1, scale);
-
- // Cutoff at 0.5% of the histogram.
-
- stop = ((uint)(width / scale)*(uint)(height / scale)) / 200;
-
- for (i = m_rgbMax, sum = 0; (i >= 0) && (sum < stop); i--)
- sum += histogram->getValue(Digikam::ImageHistogram::ValueChannel, i);
-
- expo = -log((float)(i+1) / m_rgbMax) / log(2);
- DDebug() << "White level at:" << i << endl;
-
- // Cutoff at 0.5% of the histogram.
-
- stop = ((uint)(width / scale)*(uint)(height / scale)) / 200;
-
- for (i = 1, sum = 0; (i < (int)m_rgbMax) && (sum < stop); i++)
- sum += histogram->getValue(Digikam::ImageHistogram::ValueChannel, i);
-
- black = (double)i / m_rgbMax;
- black /= 2;
-
- DDebug() << "Black:" << black << " Exposition:" << expo << endl;
-
- m_blackInput->setValue(black);
- m_exposureInput->setValue(expo);
-
- delete histogram;
- delete [] data;
-
- parentWidget()->unsetCursor();
- slotEffect();
-}
-
-void ImageEffect_WhiteBalance::setRGBmult(void)
-{
- int t;
- float mi;
-
- if ( m_temperature > 7.0 ) m_temperature = 7.0;
-
- t = (int)(m_temperature * 100.0 - 200.0);
- m_mr = 1.0 / bbWB[t][0];
- m_mg = 1.0 / bbWB[t][1];
- m_mb = 1.0 / bbWB[t][2];
- m_mg *= m_green;
-
- // Normalize to at least 1.0, so we are not dimming colors only bumping.
- mi = QMIN(m_mr, m_mg);
- mi = QMIN(mi, m_mb);
- m_mr /= mi;
- m_mg /= mi;
- m_mb /= mi;
-}
-
-void ImageEffect_WhiteBalance::setLUTv(void)
-{
- double b, g;
-
- b = m_mg * pow(2, m_exposition);
- g = m_gamma;
- m_BP = (uint)(m_rgbMax * m_black);
- m_WP = (uint)(m_rgbMax / b);
-
- if (m_WP - m_BP < 1) m_WP = m_BP + 1;
-
- DDebug() << "T(K): " << m_temperature
- << " => R:" << m_mr
- << " G:" << m_mg
- << " B:" << m_mb
- << " BP:" << m_BP
- << " WP:" << m_WP
- << endl;
-
- m_curve[0] = 0;
-
- for (int i = 1; i < (int)m_rgbMax; i++)
- {
- float x = (float)(i - m_BP)/(m_WP - m_BP);
- m_curve[i] = (i < m_BP) ? 0 : (m_rgbMax-1) * pow(x, g);
- m_curve[i] *= (1 - m_dark * exp(-x * x / 0.002));
- m_curve[i] /= (float)i;
- }
-}
-
-void ImageEffect_WhiteBalance::whiteBalance(uchar *data, int width, int height, bool sixteenBit)
-{
- uint i, j;
-
- if (!sixteenBit) // 8 bits image.
- {
- uchar red, green, blue;
- uchar *ptr = data;
-
- for (j = 0 ; j < (uint)(width*height) ; j++)
- {
- int v, rv[3];
-
- blue = ptr[0];
- green = ptr[1];
- red = ptr[2];
-
- rv[0] = (int)(blue * m_mb);
- rv[1] = (int)(green * m_mg);
- rv[2] = (int)(red * m_mr);
- v = QMAX(rv[0], rv[1]);
- v = QMAX(v, rv[2]);
-
- if (m_clipSat) v = QMIN(v, (int)m_rgbMax-1);
- i = v;
-
- ptr[0] = (uchar)pixelColor(rv[0], i, v);
- ptr[1] = (uchar)pixelColor(rv[1], i, v);
- ptr[2] = (uchar)pixelColor(rv[2], i, v);
- ptr += 4;
- }
- }
- else // 16 bits image.
- {
- unsigned short red, green, blue;
- unsigned short *ptr = (unsigned short *)data;
-
- for (j = 0 ; j < (uint)(width*height) ; j++)
- {
- int v, rv[3];
-
- blue = ptr[0];
- green = ptr[1];
- red = ptr[2];
-
- rv[0] = (int)(blue * m_mb);
- rv[1] = (int)(green * m_mg);
- rv[2] = (int)(red * m_mr);
- v = QMAX(rv[0], rv[1]);
- v = QMAX(v, rv[2]);
-
- if (m_clipSat) v = QMIN(v, (int)m_rgbMax-1);
- i = v;
-
- ptr[0] = pixelColor(rv[0], i, v);
- ptr[1] = pixelColor(rv[1], i, v);
- ptr[2] = pixelColor(rv[2], i, v);
- ptr += 4;
- }
- }
-}
-
-unsigned short ImageEffect_WhiteBalance::pixelColor(int colorMult, int index, int value)
-{
- int r = (m_clipSat && colorMult > (int)m_rgbMax) ? m_rgbMax : colorMult;
-
- if (value > m_BP && m_overExp && value > m_WP)
- {
- if (m_WBind)
- r = (colorMult > m_WP) ? 0 : r;
- else
- r = 0;
- }
-
- return( (unsigned short)CLAMP((int)((index - m_saturation*(index - r)) * m_curve[index]),
- 0, (int)(m_rgbMax-1)) );
-}
-
} // NameSpace DigikamWhiteBalanceImagesPlugin
--- trunk/extragear/graphics/digikamimageplugins/whitebalance/imageeffect_whitebalance.h #624123:624124
@@ -54,13 +54,6 @@
void finalRendering();
-private:
-
- void setRGBmult(void);
- void setLUTv(void);
- void whiteBalance(uchar *data, int width, int height, bool sixteenBit);
- inline unsigned short pixelColor(int colorMult, int index, int value);
-
private slots:
void slotDefault();
@@ -78,29 +71,6 @@
private:
- // -- White Balance algorithm -------------------------------------------
-
- bool m_clipSat;
- bool m_overExp;
- bool m_WBind;
-
- double m_saturation;
- double m_temperature;
- double m_gamma;
- double m_black;
- double m_exposition;
- double m_dark;
- double m_green;
-
- int m_BP, m_WP;
-
- uint m_rgbMax;
-
- float m_curve[65536];
- float m_mr, m_mg, m_mb;
-
- // -- Dialog ------------------------------------------------------------
-
enum HistogramScale
{
Linear=0,
** trunk/extragear/graphics/digikamimageplugins/whitebalance/whitebalance.cpp #property svn:eol-style
+ native
** trunk/extragear/graphics/digikamimageplugins/whitebalance/whitebalance.h #property svn:eol-style
+ native
More information about the Digikam-devel
mailing list