digikam/custom-whitebalance-778164.diff

410 lines
19 KiB
Diff

------------------------------------------------------------------------
r778164 | abaecker | 2008-02-22 18:52:23 +0100 (Fri, 22 Feb 2008) | 8 lines
More flexible WB adjustment during raw decoding
(many thanks to Guillaume Castagnino for the patch).
Note that a current libkdcraw is needed as this had to be changed.
CCBUGS: 142055
TODO:KDE4PORT
------------------------------------------------------------------------
Index: digikam/imageplugins/whitebalance/imageeffect_whitebalance.cpp
===================================================================
--- digikam/imageplugins/whitebalance/imageeffect_whitebalance.cpp (revision 778163)
+++ digikam/imageplugins/whitebalance/imageeffect_whitebalance.cpp (revision 778164)
@@ -7,7 +7,8 @@
* Description : a digiKam image editor plugin to correct
* image white balance
*
- * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2008 by Guillaume Castagnino <casta at xwing dot info>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -191,7 +192,7 @@ ImageEffect_WhiteBalance::ImageEffect_Wh
m_adjTemperatureLabel = new QLabel(i18n("Adjustment:"), gboxSettings);
m_temperatureInput = new KDoubleNumInput(gboxSettings);
m_temperatureInput->setPrecision(1);
- m_temperatureInput->setRange(2200.0, 7000.0, 10.0, true);
+ m_temperatureInput->setRange(2000.0, 12000.0, 10.0, true);
QWhatsThis::add( m_temperatureInput, i18n("<p>Set here the white balance color temperature in Kelvin."));
m_temperaturePresetLabel = new QLabel(i18n("Preset:"), gboxSettings);
@@ -268,7 +269,7 @@ ImageEffect_WhiteBalance::ImageEffect_Wh
m_greenLabel = new QLabel(i18n("Green:"), gboxSettings);
m_greenInput = new KDoubleNumInput(gboxSettings);
m_greenInput->setPrecision(2);
- m_greenInput->setRange(1.0, 2.5, 0.01, true);
+ m_greenInput->setRange(0.2, 2.5, 0.01, true);
QWhatsThis::add(m_greenInput, i18n("<p>Set here the green component to set magenta color "
"cast removal level."));
@@ -633,7 +634,7 @@ void ImageEffect_WhiteBalance::slotEffec
m_destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)];
- double temperature = m_temperatureInput->value()/1000.0;
+ double temperature = m_temperatureInput->value();
double dark = m_darkInput->value();
double black = m_blackInput->value();
double mainExposure = m_mainExposureInput->value();
@@ -666,7 +667,7 @@ void ImageEffect_WhiteBalance::finalRend
int h = iface->originalHeight();
bool sb = iface->originalSixteenBit();
- double temperature = m_temperatureInput->value()/1000.0;
+ double temperature = m_temperatureInput->value();
double dark = m_darkInput->value();
double black = m_blackInput->value();
double mainExposure = m_mainExposureInput->value();
@@ -698,16 +699,16 @@ void ImageEffect_WhiteBalance::resetValu
m_greenInput->blockSignals(true);
m_temperaturePresetCB->blockSignals(true);
- // Neutral color temperature settings.
+ // Neutral color temperature settings is D65
m_darkInput->setValue(0.5);
m_blackInput->setValue(0.0);
m_mainExposureInput->setValue(0.0);
m_fineExposureInput->setValue(0.0);
m_gammaInput->setValue(1.0);
m_saturationInput->setValue(1.0);
- m_greenInput->setValue(1.2);
- m_temperaturePresetCB->setCurrentItem(Neutral);
- slotTemperaturePresetChanged(Neutral);
+ m_greenInput->setValue(1.0);
+ m_temperaturePresetCB->setCurrentItem(DaylightD65);
+ slotTemperaturePresetChanged(DaylightD65);
m_previewWidget->resetSpotPosition();
m_channelCB->setCurrentItem(LuminosityChannel);
@@ -739,8 +740,8 @@ void ImageEffect_WhiteBalance::readUserS
m_fineExposureInput->setValue(config->readDoubleNumEntry("FineExposure", 0.0));
m_gammaInput->setValue(config->readDoubleNumEntry("Gamma", 1.0));
m_saturationInput->setValue(config->readDoubleNumEntry("Saturation", 1.0));
- m_greenInput->setValue(config->readDoubleNumEntry("Green", 1.2));
- m_temperatureInput->setValue(config->readDoubleNumEntry("Temperature", 4750.0));
+ m_greenInput->setValue(config->readDoubleNumEntry("Green", 1.0));
+ m_temperatureInput->setValue(config->readDoubleNumEntry("Temperature", 6500.0));
slotTemperatureChanged(m_temperatureInput->value());
slotChannelChanged(m_channelCB->currentItem());
slotScaleChanged(m_scaleBG->selectedId());
Index: digikam/imageplugins/whitebalance/imageeffect_whitebalance.h
===================================================================
--- digikam/imageplugins/whitebalance/imageeffect_whitebalance.h (revision 778163)
+++ digikam/imageplugins/whitebalance/imageeffect_whitebalance.h (revision 778164)
@@ -7,7 +7,8 @@
* Description : a digiKam image editor plugin to correct
* image white balance
*
- * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2008 by Guillaume Castagnino <casta at xwing dot info>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -22,7 +23,6 @@
*
* ============================================================ */
-
#ifndef IMAGEEFFECT_WHITEBALANCE_H
#define IMAGEEFFECT_WHITEBALANCE_H
--- digikam/libs/whitebalance/whitebalance.cpp (revision 778163)
+++ digikam/libs/whitebalance/whitebalance.cpp (revision 778164)
@@ -6,7 +6,8 @@
* Date : 2007-16-01
* Description : white balance color correction.
*
- * Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2008 by Guillaume Castagnino <casta at xwing dot info>
*
* Some parts are inspired from RawPhoto implementation copyrighted
* 2004-2005 by Pawel T. Jochym <jochym at ifj edu pl>
@@ -39,7 +40,6 @@
#include "ddebug.h"
#include "imagehistogram.h"
-#include "blackbody.h"
#include "whitebalance.h"
namespace Digikam
@@ -69,8 +69,8 @@ public:
exposition = 0.0;
gamma = 1.0;
saturation = 1.0;
- green = 1.2;
- temperature = 4.750;
+ green = 1.0;
+ temperature = 6500.0;
}
bool clipSat;
@@ -127,7 +127,7 @@ void WhiteBalance::whiteBalance(uchar *d
if (d->clipSat) d->mg = 1.0;
setLUTv();
setRGBmult();
-
+
// Apply White balance adjustments.
adjustWhiteBalance(data, width, height, sixteenBit);
}
@@ -136,41 +136,33 @@ void WhiteBalance::autoWBAdjustementFrom
{
// Calculate Temperature and Green component from color picked.
- register int l, r, m;
- double sR, sG, sB, mRB, t;
+ double tmin, tmax, mBR;
+ float mr, mg, mb;
- 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(blackBodyWhiteBalance)/(sizeof(float)*3);
- m = (r + l) / 2;
+ DDebug() << "Sums: R:" << tc.red() << " G:" << tc.green() << " B:" << tc.blue() << endl;
- for (l = 0, r = sizeof(blackBodyWhiteBalance)/(sizeof(float)*3), m = (l+r)/2 ; r-l > 1 ; m = (l+r)/2)
+ /* This is a dichotomic search based on Blue and Red layers ratio
+ to find the matching temperature
+ Adapted from ufraw (0.12.1) RGB_to_Temperature
+ */
+ tmin = 2000.0;
+ tmax = 12000.0;
+ mBR = (double)tc.blue() / (double)tc.red();
+ green = 1.0;
+ for (temperature = (tmin+tmax)/2; tmax-tmin > 10; temperature = (tmin+tmax)/2)
{
- if (blackBodyWhiteBalance[m][0]/blackBodyWhiteBalance[m][2] > mRB)
- l = m;
+ DDebug() << "Intermediate Temperature (K):" << temperature << endl;
+ setRGBmult(temperature, green, mr, mg, mb);
+ if (mr/mb > mBR)
+ tmax = temperature;
else
- r = m;
-
- DDebug() << "L,M,R: " << l << " " << m << " " << r
- << " blackBodyWhiteBalance[m]=:" << blackBodyWhiteBalance[m][0]/blackBodyWhiteBalance[m][2]
- << endl;
+ tmin = temperature;
}
-
- DDebug() << "Temperature (K):" << m*10.0+2000.0 << endl;
-
- t = (blackBodyWhiteBalance[m][1]/blackBodyWhiteBalance[m][0]) / (sG/sR);
+ // Calculate the green level to neutralize picture
+ green = (mr / mg) / ((double)tc.green() / (double)tc.red());
- DDebug() << "Green component:" << t << endl;
-
- temperature = m*10.0+2000.0;
- green = t;
+ DDebug() << "Temperature (K):" << temperature << endl;
+ DDebug() << "Green component:" << green << endl;
}
void WhiteBalance::autoExposureAdjustement(uchar* data, int width, int height, bool sb,
@@ -207,25 +199,73 @@ void WhiteBalance::autoExposureAdjusteme
delete histogram;
}
-void WhiteBalance::setRGBmult()
+void WhiteBalance::setRGBmult(double &temperature, double &green, float &mr, float &mg, float &mb)
{
- int t;
float mi;
+ double xD, yD, X, Y, Z;
- if ( d->temperature > 7.0 ) d->temperature = 7.0;
+ if ( temperature > 12000 ) temperature = 12000.0;
- t = (int)(d->temperature * 100.0 - 200.0);
- d->mr = 1.0 / blackBodyWhiteBalance[t][0];
- d->mg = 1.0 / blackBodyWhiteBalance[t][1];
- d->mb = 1.0 / blackBodyWhiteBalance[t][2];
- d->mg *= d->green;
+ /* Here starts the code picked from ufraw (0.12.1)
+ to convert Temperature + green multiplier to RGB multipliers
+ */
+ /* Convert between Temperature and RGB.
+ * Base on information from http://www.brucelindbloom.com/
+ * The fit for D-illuminant between 4000K and 12000K are from CIE
+ * The generalization to 2000K < T < 4000K and the blackbody fits
+ * are my own and should be taken with a grain of salt.
+ */
+ const double XYZ_to_RGB[3][3] = {
+ { 3.24071, -0.969258, 0.0556352 },
+ {-1.53726, 1.87599, -0.203996 },
+ {-0.498571, 0.0415557, 1.05707 } };
+ // Fit for CIE Daylight illuminant
+ if (temperature <= 4000)
+ {
+ xD = 0.27475e9/(temperature*temperature*temperature)
+ - 0.98598e6/(temperature*temperature)
+ + 1.17444e3/temperature + 0.145986;
+ }
+ else if (temperature <= 7000)
+ {
+ xD = -4.6070e9/(temperature*temperature*temperature)
+ + 2.9678e6/(temperature*temperature)
+ + 0.09911e3/temperature + 0.244063;
+ }
+ else
+ {
+ xD = -2.0064e9/(temperature*temperature*temperature)
+ + 1.9018e6/(temperature*temperature)
+ + 0.24748e3/temperature + 0.237040;
+ }
+ yD = -3*xD*xD + 2.87*xD - 0.275;
+
+ X = xD/yD;
+ Y = 1;
+ Z = (1-xD-yD)/yD;
+ mr = X*XYZ_to_RGB[0][0] + Y*XYZ_to_RGB[1][0] + Z*XYZ_to_RGB[2][0];
+ mg = X*XYZ_to_RGB[0][1] + Y*XYZ_to_RGB[1][1] + Z*XYZ_to_RGB[2][1];
+ mb = X*XYZ_to_RGB[0][2] + Y*XYZ_to_RGB[1][2] + Z*XYZ_to_RGB[2][2];
+ /* End of the code picked to ufraw
+ */
+
+ // Apply green multiplier
+ mg = mg / green;
+
+ mr = 1.0 / mr;
+ mg = 1.0 / mg;
+ mb = 1.0 / mb;
// Normalize to at least 1.0, so we are not dimming colors only bumping.
- mi = QMIN(d->mr, d->mg);
- mi = QMIN(mi, d->mb);
- d->mr /= mi;
- d->mg /= mi;
- d->mb /= mi;
+ mi = QMIN(mr, QMIN(mg, mb));
+ mr /= mi;
+ mg /= mi;
+ mb /= mi;
+}
+
+void WhiteBalance::setRGBmult()
+{
+ setRGBmult(d->temperature, d->green, d->mr, d->mg, d->mb);
}
void WhiteBalance::setLUTv()
Index: digikam/libs/whitebalance/whitebalance.h
===================================================================
--- digikam/libs/whitebalance/whitebalance.h (revision 778163)
+++ digikam/libs/whitebalance/whitebalance.h (revision 778164)
@@ -6,7 +6,8 @@
* Date : 2007-16-01
* Description : white balance color correction.
*
- * Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2008 by Guillaume Castagnino <casta at xwing dot info>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -45,7 +46,7 @@ public:
void whiteBalance(uchar *data, int width, int height, bool sixteenBit,
double black=0.0, double exposition=0.0,
- double temperature=4.750, double green=1.2, double dark=0.5,
+ double temperature=6500.0, double green=1.0, double dark=0.5,
double gamma=1.0, double saturation=1.0);
static void autoExposureAdjustement(uchar* data, int width, int height, bool sb,
@@ -56,6 +57,7 @@ public:
private:
void setRGBmult();
+ static void setRGBmult(double &temperature, double &green, float &mr, float &mg, float &mb);
void setLUTv();
void adjustWhiteBalance(uchar *data, int width, int height, bool sixteenBit);
inline unsigned short pixelColor(int colorMult, int index, int value);
Index: digikam/utilities/setup/setupdcraw.cpp
===================================================================
--- digikam/utilities/setup/setupdcraw.cpp (revision 778163)
+++ digikam/utilities/setup/setupdcraw.cpp (revision 778164)
@@ -6,7 +6,7 @@
* Date : 2007-02-06
* Description : setup RAW decoding settings.
*
- * Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -89,8 +89,9 @@ void SetupDcraw::applySettings()
KConfig* config = kapp->config();
config->setGroup("ImageViewer Settings");
config->writeEntry("SixteenBitsImage", d->dcrawSettings->sixteenBits());
- config->writeEntry("CameraColorBalance", d->dcrawSettings->useCameraWB());
- config->writeEntry("AutomaticColorBalance", d->dcrawSettings->useAutoColorBalance());
+ config->writeEntry("WhiteBalance", d->dcrawSettings->whiteBalance());
+ config->writeEntry("CustomWhiteBalance", d->dcrawSettings->customWhiteBalance());
+ config->writeEntry("CustomWhiteBalanceGreen", d->dcrawSettings->customWhiteBalanceGreen());
config->writeEntry("RGBInterpolate4Colors", d->dcrawSettings->useFourColor());
config->writeEntry("DontStretchPixels", d->dcrawSettings->useDontStretchPixels());
config->writeEntry("EnableNoiseReduction", d->dcrawSettings->useNoiseReduction());
@@ -116,8 +117,11 @@ void SetupDcraw::readSettings()
d->dcrawSettings->setcaBlueMultiplier(config->readDoubleNumEntry("caBlueMultiplier", 1.0));
d->dcrawSettings->setDontStretchPixels(config->readBoolEntry("DontStretchPixels", false));
d->dcrawSettings->setUnclipColor(config->readNumEntry("UnclipColors", 0));
- d->dcrawSettings->setCameraWB(config->readBoolEntry("CameraColorBalance", true));
- d->dcrawSettings->setAutoColorBalance(config->readBoolEntry("AutomaticColorBalance", true));
+ d->dcrawSettings->setWhiteBalance((KDcrawIface::RawDecodingSettings::WhiteBalance)
+ config->readNumEntry("WhiteBalance",
+ KDcrawIface::RawDecodingSettings::CAMERA));
+ d->dcrawSettings->setCustomWhiteBalance(config->readNumEntry("CustomWhiteBalance", 6500));
+ d->dcrawSettings->setCustomWhiteBalanceGreen(config->readDoubleNumEntry("CustomWhiteBalanceGreen", 1.0));
d->dcrawSettings->setFourColor(config->readBoolEntry("RGBInterpolate4Colors", false));
d->dcrawSettings->setQuality((KDcrawIface::RawDecodingSettings::DecodingQuality)
config->readNumEntry("RAWQuality",
Index: digikam/utilities/setup/setupdcraw.h
===================================================================
--- digikam/utilities/setup/setupdcraw.h (revision 778163)
+++ digikam/utilities/setup/setupdcraw.h (revision 778164)
@@ -6,7 +6,7 @@
* Date : 2007-02-06
* Description : setup RAW decoding settings.
*
- * Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
Index: digikam/utilities/imageeditor/editor/editorwindow.cpp
===================================================================
--- digikam/utilities/imageeditor/editor/editorwindow.cpp (revision 778163)
+++ digikam/utilities/imageeditor/editor/editorwindow.cpp (revision 778164)
@@ -894,10 +894,12 @@ void EditorWindow::applyStandardSettings
m_IOFileSettings->rawDecodingSettings.outputColorSpace = KDcrawIface::RawDecodingSettings::SRGB;
m_IOFileSettings->rawDecodingSettings.sixteenBitsImage = config->readBoolEntry("SixteenBitsImage", false);
- m_IOFileSettings->rawDecodingSettings.automaticColorBalance = config->readBoolEntry("AutomaticColorBalance", true);
- m_IOFileSettings->rawDecodingSettings.cameraColorBalance = config->readBoolEntry("CameraColorBalance", true);
+ m_IOFileSettings->rawDecodingSettings.whiteBalance = (KDcrawIface::RawDecodingSettings::WhiteBalance)config->readNumEntry("WhiteBalance",
+ KDcrawIface::RawDecodingSettings::CAMERA);
+ m_IOFileSettings->rawDecodingSettings.customWhiteBalance = config->readNumEntry("CustomWhiteBalance", 6500);
+ m_IOFileSettings->rawDecodingSettings.customWhiteBalanceGreen = config->readDoubleNumEntry("CustomWhiteBalanceGreen", 1.0);
m_IOFileSettings->rawDecodingSettings.RGBInterpolate4Colors = config->readBoolEntry("RGBInterpolate4Colors", false);
- m_IOFileSettings->rawDecodingSettings.DontStretchPixels = config->readBoolEntry("DontStretchPixels", false);
+ m_IOFileSettings->rawDecodingSettings.DontStretchPixels = config->readBoolEntry("DontStretchPixels", false);
m_IOFileSettings->rawDecodingSettings.enableNoiseReduction = config->readBoolEntry("EnableNoiseReduction", false);
m_IOFileSettings->rawDecodingSettings.unclipColors = config->readNumEntry("UnclipColors", 0);
m_IOFileSettings->rawDecodingSettings.RAWQuality = (KDcrawIface::RawDecodingSettings::DecodingQuality)config->readNumEntry("RAWQuality",