Added possibility to export profiling reference image without WB to make it possible to generate DNG profiles; also apply transform and scaling on profiling reference image

This commit is contained in:
torger
2015-03-21 21:11:36 +01:00
parent 1ec6ff068b
commit bf5aecab31
12 changed files with 131 additions and 88 deletions

View File

@@ -1410,6 +1410,7 @@ TP_ICM_NOICM;No ICM: sRGB Output
TP_ICM_OUTPUTPROFILE;Output Profile
TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling
TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile.
TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance
TP_ICM_TONECURVE;Use DCP's tone curve
TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve.
TP_ICM_WORKINGPROFILE;Working Profile

View File

@@ -956,7 +956,7 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &
}
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) {
MyMutex::MyLock lock(mProcessing);
@@ -969,7 +969,6 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
Imagefloat* im = new Imagefloat (fW, fH);
imgsrc->preprocess( ppar.raw, ppar.lensProf, ppar.coarse );
imgsrc->demosaic(ppar.raw );
//imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.toneCurve, ppar.icm, ppar.raw);
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
@@ -988,29 +987,46 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
}
currWB = autoWB;
}
params.wb.temperature = currWB.getTemp ();
params.wb.green = currWB.getGreen ();
if (!apply_wb) {
currWB = ColorTemp(); // = no white balance
}
imgsrc->getImage (currWB, 0, im, pp, ppar.toneCurve, ppar.icm, ppar.raw);
imgsrc->convertColorSpace(im, ppar.icm, currWB, params.raw);
if (params.crop.enabled) {
Imagefloat *tmpim = new Imagefloat (params.crop.w, params.crop.h);
int cx = params.crop.x;
int cy = params.crop.y;
int cw = params.crop.w;
int ch = params.crop.h;
ImProcFunctions ipf (&ppar, true);
if (ipf.needsTransform()) {
Imagefloat* trImg = new Imagefloat (fW, fH);
ipf.transform (im, trImg, 0, 0, 0, 0, fW, fH, fW, fH, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(),
imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), true);
delete im;
im = trImg;
}
if (params.crop.enabled) {
Imagefloat *tmpim = new Imagefloat (params.crop.w, params.crop.h);
int cx = params.crop.x;
int cy = params.crop.y;
int cw = params.crop.w;
int ch = params.crop.h;
#pragma omp parallel for
for (int i=cy; i<cy+ch; i++) {
for (int j=cx; j<cx+cw; j++) {
tmpim->r(i-cy, j-cx) = im->r(i, j);
tmpim->g(i-cy, j-cx) = im->g(i, j);
tmpim->b(i-cy, j-cx) = im->b(i, j);
}
}
delete im;
im = tmpim;
}
for (int i=cy; i<cy+ch; i++) {
for (int j=cx; j<cx+cw; j++) {
tmpim->r(i-cy, j-cx) = im->r(i, j);
tmpim->g(i-cy, j-cx) = im->g(i, j);
tmpim->b(i-cy, j-cx) = im->b(i, j);
}
}
delete im;
im = tmpim;
}
Image16* im16 = im->to16();
delete im;
int imw, imh;
double tmpScale = ipf.resizeScale(&params, fW, fH, imw, imh);
if (tmpScale != 1.0) {
Image16* tempImage = new Image16 (imw, imh);
ipf.resize (im16, tempImage, tmpScale);
delete im16;
im16 = tempImage;
}
im16->saveTIFF (fname,16,true);
delete im16;
//im->saveJPEG (fname, 85);

View File

@@ -233,7 +233,7 @@ class ImProcCoordinator : public StagedImageProcessor {
void setAutoChromaListener (AutoChromaListener* adn) {adnListener = adn; }
void setWaveletListener (WaveletListener* awa) {awavListener = awa; }
void saveInputICCReference (const Glib::ustring& fname);
void saveInputICCReference (const Glib::ustring& fname, bool apply_wb);
InitialImage* getInitialImage () { return imgsrc; }
};

View File

@@ -250,6 +250,7 @@ class ImProcFunctions {
void sharpeningcam (CieImage* ncie, float** buffer);
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh);
void lab2monitorRgb (LabImage* lab, Image8* image);
void resize (Image16* src, Image16* dst, float dScale);
// void Lanczoslab (LabImage* src, LabImage* dst, float scale);

View File

@@ -333,6 +333,65 @@ SSEFUNCTION static void Lanczos(const LabImage* src, LabImage* dst, float scale)
}
}
float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh) {
imw = fw;
imh = fh;
if (!params || !params->resize.enabled) {
return 1.0;
}
// get the resize parameters
int refw, refh;
double dScale;
if (params->crop.enabled && params->resize.appliesTo == "Cropped area") {
// the resize values applies to the crop dimensions
refw = params->crop.w;
refh = params->crop.h;
}
else {
// the resize values applies to the image dimensions
// if a crop exists, it will be resized to the calculated scale
refw = fw;
refh = fh;
}
switch(params->resize.dataspec) {
case (1):
// Width
dScale = (double)params->resize.width/(double)refw;
break;
case (2):
// Height
dScale = (double)params->resize.height/(double)refh;
break;
case (3):
// FitBox
if ((double)refw/(double)refh > (double)params->resize.width/(double)params->resize.height)
dScale = (double)params->resize.width/(double)refw;
else
dScale = (double)params->resize.height/(double)refh;
break;
default:
// Scale
dScale = params->resize.scale;
break;
}
if (fabs(dScale-1.0)<=1e-5) {
return 1.0;
}
if (params->crop.enabled && params->resize.appliesTo == "Full image") {
imw = params->crop.w;
imh = params->crop.h;
}
else {
imw = refw;
imh = refh;
}
imw = (int)( (double)imw * dScale + 0.5 );
imh = (int)( (double)imh * dScale + 0.5 );
return (float)dScale;
}
void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale) {
#ifdef PROFILE

View File

@@ -236,10 +236,17 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
// compute channel multipliers
double r, g, b;
float rm, gm, bm;
ctemp.getMultipliers (r, g, b);
rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
if (ctemp.getTemp() < 0) {
// no white balance, ie revert the pre-process white balance to restore original unbalanced raw camera color
rm = ri->get_pre_mul(0);
gm = ri->get_pre_mul(1);
bm = ri->get_pre_mul(2);
} else {
ctemp.getMultipliers (r, g, b);
rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
}
if (true) {
// adjust gain so the maximum raw value of the least scaled channel just hits max

View File

@@ -368,7 +368,7 @@ namespace rtengine {
virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) =0;
virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) =0;
virtual void saveInputICCReference (const Glib::ustring& fname) =0;
virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) =0;
virtual void setProgressListener (ProgressListener* l) =0;
virtual void setSizeListener (SizeListener* l) =0;

View File

@@ -1045,63 +1045,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
if (pl) pl->setProgress (0.70);
if (params.resize.enabled) {
// get the resize parameters
int refw, refh;
double tmpScale;
if (params.crop.enabled && params.resize.appliesTo == "Cropped area") {
// the resize values applies to the crop dimensions
refw = cw;
refh = ch;
}
else {
// the resize values applies to the image dimensions
// if a crop exists, it will be resized to the calculated scale
refw = fw;
refh = fh;
}
switch(params.resize.dataspec) {
case (1):
// Width
tmpScale = (double)params.resize.width/(double)refw;
break;
case (2):
// Height
tmpScale = (double)params.resize.height/(double)refh;
break;
case (3):
// FitBox
if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height)
tmpScale = (double)params.resize.width/(double)refw;
else
tmpScale = (double)params.resize.height/(double)refh;
break;
default:
// Scale
tmpScale = params.resize.scale;
break;
}
int imw, imh;
double tmpScale = ipf.resizeScale(&params, fw, fh, imw, imh);
if (tmpScale != 1.0) {
// resize image
if (fabs(tmpScale-1.0)>1e-5) {
int imw, imh;
if (params.crop.enabled && params.resize.appliesTo == "Full image") {
imw = cw;
imh = ch;
}
else {
imw = refw;
imh = refh;
}
imw = (int)( (double)imw * tmpScale + 0.5 );
imh = (int)( (double)imh * tmpScale + 0.5 );
Image16* tempImage = new Image16 (imw, imh);
ipf.resize (readyImg, tempImage, tmpScale);
delete readyImg;
readyImg = tempImage;
}
Image16* tempImage = new Image16 (imw, imh);
ipf.resize (readyImg, tempImage, tmpScale);
delete readyImg;
readyImg = tempImage;
}

View File

@@ -693,6 +693,13 @@ void ICMPanel::saveReferencePressed () {
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK);
Gtk::CheckButton applyWB(M("TP_ICM_SAVEREFERENCE_APPLYWB"));
applyWB.set_active(true);
Gtk::HBox* hbox = Gtk::manage( new Gtk::HBox() );
hbox->pack_end(applyWB, Gtk::PACK_SHRINK, 2);
Gtk::VBox *vbox = dialog.get_vbox();
vbox->pack_end(*hbox, Gtk::PACK_SHRINK, 2);
Gtk::FileFilter filter_tif;
filter_tif.set_name(M("SAVEDLG_TIFFFILTER"));
filter_tif.add_pattern("*.tif");
@@ -704,6 +711,7 @@ void ICMPanel::saveReferencePressed () {
filter_any.add_pattern("*");
dialog.add_filter(filter_any);
dialog.show_all_children();
//dialog.set_do_overwrite_confirmation (true);
bool done = false;
@@ -717,7 +725,7 @@ void ICMPanel::saveReferencePressed () {
if (ext != "tif" && ext != "tiff")
fname += ".tif";
if (confirmOverwrite(dialog, fname)) {
icmplistener->saveInputICCReference (fname);
icmplistener->saveInputICCReference (fname, applyWB.get_active());
lastRefFilename = Glib::path_get_basename (fname);
done = true;
}

View File

@@ -31,7 +31,7 @@ class ICMPanelListener {
public:
virtual ~ICMPanelListener() {}
virtual void saveInputICCReference (Glib::ustring fname) {}
virtual void saveInputICCReference (Glib::ustring fname, bool apply_wb) {}
};
class ICMPanel : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel {

View File

@@ -580,10 +580,10 @@ void ToolPanelCoordinator::cropSelectRequested () {
toolBar->setTool (TMCropSelect);
}
void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname) {
void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname, bool apply_wb) {
if (ipc)
ipc->saveInputICCReference (fname);
ipc->saveInputICCReference (fname, apply_wb);
}
int ToolPanelCoordinator::getSpotWBRectSize () {

View File

@@ -265,7 +265,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
void cropSelectRequested ();
// icmpanellistener interface
void saveInputICCReference (Glib::ustring fname);
void saveInputICCReference (Glib::ustring fname, bool apply_wb);
// imageareatoollistener interface
void spotWBselected (int x, int y, Thumbnail* thm=NULL);