Crop-awareness of Lab curve histogram+cleanups; see issue #667

This commit is contained in:
Oliver Duis 2011-05-02 20:22:59 +02:00
parent 69f42cd8d4
commit 8ac9e46f4f
10 changed files with 71 additions and 53 deletions

View File

@ -396,7 +396,7 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::complexLCurve (double br, double contr, const std::vector<double>& curvePoints, \
LUTu & histogram, LUTf & outCurve, \
LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, \
LUTu & outBeforeCCurveHistogram, int skip) {
// curve without contrast
@ -422,21 +422,21 @@ namespace rtengine {
std::vector<double> brightcurvePoints;
brightcurvePoints.push_back((double)((CurveType)DCT_NURBS));
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
brightcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
brightcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
if(br>0) {
brightcurvePoints.push_back(0.1); //toe point
if (br>0) {
brightcurvePoints.push_back(0.1); // toe point
brightcurvePoints.push_back(0.1+br/150.0); //value at toe point
brightcurvePoints.push_back(0.7); //shoulder point
brightcurvePoints.push_back(0.7); // shoulder point
brightcurvePoints.push_back(MIN(1.0,0.7+br/300.0)); //value at shoulder point
} else {
brightcurvePoints.push_back(0.1-br/150.0); //toe point
brightcurvePoints.push_back(0.1); //value at toe point
brightcurvePoints.push_back(0.1-br/150.0); // toe point
brightcurvePoints.push_back(0.1); // value at toe point
brightcurvePoints.push_back(MIN(1.0,0.7-br/300.0)); //shoulder point
brightcurvePoints.push_back(0.7); //value at shoulder point
brightcurvePoints.push_back(MIN(1.0,0.7-br/300.0)); // shoulder point
brightcurvePoints.push_back(0.7); // value at shoulder point
}
brightcurvePoints.push_back(1); // white point
brightcurvePoints.push_back(1); // value at white point
@ -444,7 +444,7 @@ namespace rtengine {
DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for (int i=0; i<32768; i++) {//L values range up to 32767, higher values are for highlight overflow
for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow
// change to [0,1] range
float val = (float)i / 32767.0;
@ -478,14 +478,14 @@ namespace rtengine {
std::vector<double> contrastcurvePoints;
contrastcurvePoints.push_back((double)((CurveType)DCT_NURBS));
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
contrastcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
contrastcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
contrastcurvePoints.push_back(avg-avg*(0.6-contr/250.0)); //toe point
contrastcurvePoints.push_back(avg-avg*(0.6+contr/250.0)); //value at toe point
contrastcurvePoints.push_back(avg-avg*(0.6-contr/250.0)); // toe point
contrastcurvePoints.push_back(avg-avg*(0.6+contr/250.0)); // value at toe point
contrastcurvePoints.push_back(avg+(1-avg)*(0.6-contr/250.0)); //shoulder point
contrastcurvePoints.push_back(avg+(1-avg)*(0.6+contr/250.0)); //value at shoulder point
contrastcurvePoints.push_back(avg+(1-avg)*(0.6-contr/250.0)); // shoulder point
contrastcurvePoints.push_back(avg+(1-avg)*(0.6+contr/250.0)); // value at shoulder point
contrastcurvePoints.push_back(1); // white point
contrastcurvePoints.push_back(1); // value at white point
@ -502,7 +502,7 @@ namespace rtengine {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for (int i=0; i<32768; i++) {//L values go up to 32767, last stop is for highlight overflow
for (int i=0; i<32768; i++) { // L values go up to 32767, last stop is for highlight overflow
float val;
// apply custom/parametric/NURBS curve, if any
@ -510,7 +510,7 @@ namespace rtengine {
if (outBeforeCCurveHistogram) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi]+=histogram[i] ;
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ;
}
val = tcurve->getVal (dcurve[i]);
} else {

View File

@ -209,7 +209,8 @@ class CurveFactory {
LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1);
static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& acurvePoints, \
const std::vector<double>& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped,
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
};
class Curve {

View File

@ -237,7 +237,7 @@ Imagefloat::to16() const
}
void Imagefloat::CalcCroppedHistogram(const ProcParams &params, float scale, LUTu & hist) {
void Imagefloat::calcCroppedHistogram(const ProcParams &params, float scale, LUTu & hist) {
hist.clear();
// Set up factors to calc the lightness
@ -249,18 +249,13 @@ void Imagefloat::CalcCroppedHistogram(const ProcParams &params, float scale, LUT
// calc pixel size
int hx1 = 0, hx2 = width, hy1 = 0, hy2 = height;
if (params.crop.enabled) {
hx1 = MIN(width-1,MAX(0,params.crop.x / scale));
hy1 = MIN(height-1,MAX(0,params.crop.y / scale));
hx2 = MIN(width,MAX(0,(params.crop.x+params.crop.w) / scale));
hy2 = MIN(height,MAX(0,(params.crop.y+params.crop.h) / scale));
}
int x1, x2, y1, y2;
params.crop.mapToResized(width, height, scale, x1, x2, y1, y2);
#pragma omp parallel for
for (int y=hy1; y<hy2; y++) {
for (int y=y1; y<y2; y++) {
int i;
for (int x=hx1; x<hx2; x++) {
for (int x=x1; x<x2; x++) {
i = (int)(facRed * r[y][x] + facGreen * g[y][x] + facBlue * b[y][x]);
if (i<0) i=0; else if (i>65535) i=65535;
hist[i]++;

View File

@ -89,7 +89,7 @@ class Imagefloat : public ImageIO, public IImagefloat {
virtual float** getGPlane () { return g; }
virtual float** getBPlane () { return b; }
void CalcCroppedHistogram(const ProcParams &params, float scale, LUTu & hist);
void calcCroppedHistogram(const ProcParams &params, float scale, LUTu & hist);
void ExecCMSTransform(cmsHTRANSFORM hTransform, bool safe);
};

View File

@ -44,7 +44,7 @@ ImProcCoordinator::ImProcCoordinator ()
satcurve(65536,0);
vhist16(65536);
lhist16(65536);
lhist16(65536); lhist16Cropped(65536);
histCropped(65536);
histRed(256); histRedRaw(256);
@ -189,7 +189,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases);
if ((todo & M_RGBCURVE) || todo==CROP) {
if (hListener) oprevi->CalcCroppedHistogram(params, scale, histCropped);
if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
// complexCurve also calculated pre-curves histogram dependend on crop
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, \
@ -201,18 +201,30 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
// if it's just crop we just need the histogram, no image updates
if ( todo!=CROP ) {
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation);
}
// compute L channel histogram
lhist16.clear();
for (int i=0; i<pH; i++)
for (int j=0; j<pW; j++)
lhist16[CLIP((int)(oprevl->L[i][j]))]++;
int x1, y1, x2, y2, pos;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16.clear(); lhist16Cropped.clear();
for (int x=0; x<pH; x++)
for (int y=0; y<pW; y++) {
pos=CLIP((int)(oprevl->L[x][y]));
lhist16[pos]++;
if (y>=y1 && y<y2 && x>=x1 && x<x2) lhist16Cropped[pos]++;
}
}
readyphase++;
if ((todo & M_LUMACURVE) || todo==CROP) {
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
lumacurve, histLCurve, scale==1 ? 1 : 16);
}
if (todo & M_LUMACURVE) {
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale==1 ? 1 : 16);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
params.labCurve.acurve, params.labCurve.bcurve, chroma_acurve, chroma_bcurve, satcurve, scale==1 ? 1 : 16);
}
@ -296,14 +308,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
readyphase++;
if (hListener) {
int hx1 = 0, hx2 = pW, hy1 = 0, hy2 = pH;
if (params.crop.enabled) {
hx1 = MIN(pW-1,MAX(0,params.crop.x / scale));
hy1 = MIN(pH-1,MAX(0,params.crop.y / scale));
hx2 = MIN(pW,MAX(0,(params.crop.x+params.crop.w) / scale));
hy2 = MIN(pH,MAX(0,(params.crop.y+params.crop.h) / scale));
}
updateHistograms (hx1, hy1, hx2, hy2); // just RGBL, not the tone curves
updateLRGBHistograms ();
hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histRedRaw, histGreenRaw, histBlueRaw);
}
@ -386,7 +391,10 @@ if (settings->verbose) printf ("setscale before lock\n");
}
void ImProcCoordinator::updateHistograms (int x1, int y1, int x2, int y2) {
void ImProcCoordinator::updateLRGBHistograms () {
int x1, y1, x2, y2;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
histRed.clear();
histGreen.clear();

View File

@ -75,7 +75,7 @@ class ImProcCoordinator : public StagedImageProcessor {
LUTf satcurve;
LUTu vhist16;
LUTu lhist16;
LUTu lhist16,lhist16Cropped;
LUTu histCropped;
LUTu histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, bcabhist;
@ -98,7 +98,7 @@ class ImProcCoordinator : public StagedImageProcessor {
void progress (Glib::ustring str, int pr);
void reallocAll ();
void updateHistograms (int x1, int y1, int x2, int y2);
void updateLRGBHistograms ();
void setScale (int prevscale);
void updatePreviewImage (int todo, Crop* cropCall= NULL);

View File

@ -37,6 +37,17 @@ namespace procparams {
const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" };
const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"};
// Maps crop to resized width (e.g. smaller previews)
void CropParams::mapToResized(int resizedWidth, int resizedHeight, int scale, int &x1, int &x2, int &y1, int &y2) const {
x1 = 0, x2 = resizedWidth, y1 = 0, y2 = resizedHeight;
if (enabled) {
x1 = MIN(resizedWidth-1, MAX(0, x / scale));
y1 = MIN(resizedHeight-1, MAX(0, y / scale));
x2 = MIN(resizedWidth, MAX(0, (x+w) / scale));
y2 = MIN(resizedHeight, MAX(0, (y+h) / scale));
}
}
ProcParams::ProcParams () {
setDefaults ();

View File

@ -209,6 +209,8 @@ class CropParams {
Glib::ustring ratio;
Glib::ustring orientation;
Glib::ustring guide;
void mapToResized(int resizedWidth, int resizedHeight, int scale, int &x1, int &x2, int &y1, int &y2) const;
};
/**

View File

@ -739,7 +739,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
hist16[(int)(2*(labView->L[i][j]))]++;
// luminance processing
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, curve, dummy, 16);
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
hist16, hist16, curve, dummy, 16);
ipf.luminanceCurve (labView, labView, curve);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16);

View File

@ -169,7 +169,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16[CLIP((int)((labView->L[i][j])))]++;
// luminance processing
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, curve, dummy, 1);
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1);
ipf.luminanceCurve (labView, labView, curve);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1);