From b4ef423acd943c972d1231d95a9a360e0db8ec38 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 25 Nov 2016 18:22:26 +0100 Subject: [PATCH] pixelshift: show mask only, Speedup for adaptive motion detection --- rtdata/languages/default | 1 + rtengine/pixelshift.cc | 114 +++++++++++++++++++++---------------- rtengine/procevents.h | 1 + rtengine/procparams.cc | 17 +++++- rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 2 +- rtengine/rawimagesource.h | 2 +- rtengine/refreshmap.cc | 3 +- rtgui/bayerprocess.cc | 30 +++++++++- rtgui/bayerprocess.h | 4 +- rtgui/paramsedited.cc | 6 ++ rtgui/paramsedited.h | 1 + 12 files changed, 127 insertions(+), 55 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 01d5270e1..2137092f2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1660,6 +1660,7 @@ TP_RAW_PIXELSHIFTMOTION_TOOLTIP;0 means no motion detection\n1 - 99 means motion TP_RAW_PIXELSHIFTMOTIONCORRECTION;Pixelshift motion correction TP_RAW_PIXELSHIFTMOTIONCORRECTION_TOOLTIP;1 = 2 pixels\n3 = 3x3 grid\n5 = 5x5 grid TP_RAW_PIXELSHIFTSHOWMOTION;Show motion +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show mask only TP_RAW_PIXELSHIFTSTDDEVFACTOR;StdDev factor TP_RAW_PIXELSHIFTEPERISO;e per ISO TP_RAW_PIXELSHIFTNREADISO;nRead diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index e2a59c314..215506811 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -36,20 +36,27 @@ namespace { -float greenDiff(float a, float b, bool adaptive, float scale, float stddevFactor, float eperIso, float nreadIso, float prnu) +float greenDiff(float a, float b, bool adaptive, float stddevFactor, float eperIso, float nreadIso, float prnu, bool showMotion) { // calculate the difference between to green samples - float gDiff = std::fabs(a - b); if(adaptive) { + float gDiff = a - b; + gDiff *= eperIso; + gDiff *= gDiff; float avg = (a + b) / 2.f; - avg *= scale; // revert the colour scaling avg *= eperIso; prnu *= avg; - float stddev = stddevFactor * sqrtf(avg + nreadIso * nreadIso + prnu * prnu); - gDiff *= scale; - gDiff *= eperIso; - return gDiff - stddev; + float stddev = stddevFactor * (avg + nreadIso + prnu * prnu); + float result = gDiff - stddev; + if(!showMotion) { + return result; + } else if(result > 0.f) { // for the motion mask + return std::fabs(a - b) / std::max(a, b) + 0.01f; + } else { + return 0.f; + } } else { + float gDiff = std::fabs(a - b); // add a small epsilon to avoid division by zero float maxVal = std::max(a, b) + 0.01f; return gDiff / maxVal; @@ -61,7 +68,7 @@ float greenDiff(float a, float b, bool adaptive, float scale, float stddevFactor using namespace std; using namespace rtengine; -void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, unsigned int frame, unsigned int gridSize, bool adaptive, float stddevFactor, float eperIso, float nreadIso, float prnu) +void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, bool showOnlyMask, unsigned int frame, unsigned int gridSize, bool adaptive, float stddevFactor, float eperIso, float nreadIso, float prnu) { BENCHFUN @@ -86,14 +93,18 @@ void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, b const float scaleGreen = 1.f / scale_mul[1]; eperIso *= (100.f / idata->getISOSpeed()); + eperIso *= scaleGreen; prnu /= 100.f; - + stddevFactor *= stddevFactor; + nreadIso *= nreadIso; + // If the values of two corresponding green pixels differ my more then motionThreshold %, the pixel will be treated as a badGreen pixel float motionThreshold = 1.f - (motion / 100.f); // For shades of green motion indicators const float blendFactor = (motion == 0.f ? 1.f : 1.f / (1.f - motionThreshold)); +// bool showOnlyMask = showMotion; // bool checkRedBlue = (gridSize == 5); // bool checkRedBlue = false; unsigned int offsX = 0, offsY = 0; @@ -141,39 +152,39 @@ void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, b if(detectMotion || adaptive) { if(gridSize == 3) { // compute maximum of differences for first two columns of 3x3 grid - greenDifMax[0] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[0] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); - greenDifMax[1] = max(greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[1] = max(greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); } else if(gridSize == 5) { // compute maximum of differences for first four columns of 5x5 grid - greenDifMax[0] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j-2], riFrames[3 - offset]->data[i + offset -2][j - 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 1][j-2], riFrames[3 - offset]->data[i + offset][j - 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 3][j-2], riFrames[3 - offset]->data[i + offset +2][j - 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset - 1][j-2], riFrames[2 + offset]->data[i - offset][j - 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset + 1][j-2], riFrames[2 + offset]->data[i - offset + 2][j - 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[0] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j-2], riFrames[3 - offset]->data[i + offset -2][j - 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j-2], riFrames[3 - offset]->data[i + offset][j - 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j-2], riFrames[3 - offset]->data[i + offset +2][j - 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j-2], riFrames[2 + offset]->data[i - offset][j - 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j-2], riFrames[2 + offset]->data[i - offset + 2][j - 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); - greenDifMax[1] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j - 1], riFrames[2 + offset]->data[i - offset - 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset+2][j - 1], riFrames[2 + offset]->data[i - offset + 3][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[1] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j - 1], riFrames[2 + offset]->data[i - offset - 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset+2][j - 1], riFrames[2 + offset]->data[i - offset + 3][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); - greenDifMax[2] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j], riFrames[3 - offset]->data[i + offset -2][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 3][j], riFrames[3 - offset]->data[i + offset +2][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[2] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j], riFrames[3 - offset]->data[i + offset -2][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j], riFrames[3 - offset]->data[i + offset +2][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); - greenDifMax[3] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j + 1], riFrames[2 + offset]->data[i - offset - 1][j+2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j+2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset+2][j + 1], riFrames[2 + offset]->data[i - offset + 3][j+2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j+2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 2][j +- 1], riFrames[3 - offset]->data[i + offset + 1][j+2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[3] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j + 1], riFrames[2 + offset]->data[i - offset - 1][j+2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j+2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset+2][j + 1], riFrames[2 + offset]->data[i - offset + 3][j+2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j+2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j +- 1], riFrames[3 - offset]->data[i + offset + 1][j+2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); } } @@ -191,22 +202,22 @@ void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, b float gridMax; if(gridSize == 1) { // compute difference for current pixel and skip next pixel, that's the method from dcrawps - gridMax = greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu); + gridMax = greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion); skipNext = !showMotion; } else if(gridSize == 3) { // compute maximum of differences for third column of 3x3 grid and save at position lastIndex - greenDifMax[lastIndex] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j + 2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j + 2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 2][j + 1], riFrames[3 - offset]->data[i + offset + 1][j + 2], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[lastIndex] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j + 2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j + 2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j + 1], riFrames[3 - offset]->data[i + offset + 1][j + 2], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); gridMax = max(greenDifMax[0],greenDifMax[1],greenDifMax[2]); } else if(gridSize == 5) { // compute maximum of differences for fifth column of 5x5 grid and save at position lastIndex - greenDifMax[lastIndex] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j+2], riFrames[3 - offset]->data[i + offset -2][j + 3], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 1][j+2], riFrames[3 - offset]->data[i + offset][j + 3], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[1 - offset]->data[i - offset + 3][j+2], riFrames[3 - offset]->data[i + offset +2][j + 3], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset - 1][j+2], riFrames[2 + offset]->data[i - offset][j + 3], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu), - greenDiff(riFrames[0 + offset]->data[i + offset + 1][j+2], riFrames[2 + offset]->data[i - offset + 2][j + 3], adaptive, scaleGreen, stddevFactor, eperIso, nreadIso, prnu) + greenDifMax[lastIndex] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j+2], riFrames[3 - offset]->data[i + offset -2][j + 3], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j+2], riFrames[3 - offset]->data[i + offset][j + 3], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j+2], riFrames[3 - offset]->data[i + offset +2][j + 3], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j+2], riFrames[2 + offset]->data[i - offset][j + 3], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j+2], riFrames[2 + offset]->data[i - offset + 2][j + 3], adaptive, stddevFactor, eperIso, nreadIso, prnu, showMotion) ); gridMax = max(greenDifMax[0],greenDifMax[1],greenDifMax[2],greenDifMax[3],greenDifMax[4]); } @@ -226,12 +237,16 @@ void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, b } if (gridMax > thresh - korr) { - float blend = (gridMax - thresh + korr) * blendFactor; // at least one of the tested pixels of the grid is detected as motion if(showMotion) { - // if showMotion is enabled make the pixel green - greenDest[j + offsX] = 1000.f + 25000.f * blend; - nonGreenDest0[j + offsX] = nonGreenDest1[j + offsX] = 0.f; + float blend = (gridMax - thresh + korr) * blendFactor; + if(!showOnlyMask) { + // if showMotion is enabled make the pixel green + greenDest[j + offsX] = 1000.f + 25000.f * blend; + nonGreenDest0[j + offsX] = nonGreenDest1[j + offsX] = 0.f; + } else { + greenDest[j + offsX] = nonGreenDest0[j + offsX] = nonGreenDest1[j + offsX] = 1000.f + 25000.f * blend; + } } if(skipNext) { @@ -241,6 +256,9 @@ void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, b } // do not set the motion pixel values. They have already been set by demosaicer or showMotion continue; + } else if(showOnlyMask) { + greenDest[j + offsX] = nonGreenDest0[j + offsX] = nonGreenDest1[j + offsX] = 0.f; + continue; } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 24469cead..72cbf781f 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -472,6 +472,7 @@ enum ProcEvent { EvOBPCompens = 442, EvRawImageNum = 443, EvDemosaicPixelshiftMotion = 444, + EvDemosaicPixelshiftMotionMaskOnly = 445, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 5da9f05fd..01f3f665b 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -889,10 +889,11 @@ void RAWParams::setDefaults() bayersensor.pixelshiftMotionCorrection = 3; bayersensor.pixelShiftStddevFactor = 5.0; bayersensor.pixelShiftEperIso = 0.75; - bayersensor.pixelShiftNreadIso = 5.0; + bayersensor.pixelShiftNreadIso = 3.45; bayersensor.pixelShiftPrnu = 1.0; bayersensor.pixelshiftShowMotion = false; - bayersensor.pixelShiftAutomatic = false; + bayersensor.pixelshiftShowMotionMaskOnly = false; + bayersensor.pixelShiftAutomatic = true; bayersensor.black0 = 0.0; bayersensor.black1 = 0.0; bayersensor.black2 = 0.0; @@ -3400,6 +3401,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelshiftShowMotion ); } + if (!pedited || pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly) { + keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelshiftShowMotionMaskOnly ); + } + if (!pedited || pedited->raw.bayersensor.pixelShiftAutomatic) { keyFile.set_boolean ("RAW Bayer", "pixelShiftAutomatic", raw.bayersensor.pixelShiftAutomatic ); } @@ -7518,6 +7523,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("RAW Bayer", "PixelShiftShowMotionMaskOnly")) { + raw.bayersensor.pixelshiftShowMotionMaskOnly = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotionMaskOnly"); + + if (pedited) { + pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly = true; + } + } + if (keyFile.has_key ("RAW Bayer", "pixelShiftAutomatic")) { raw.bayersensor.pixelShiftAutomatic = keyFile.get_boolean("RAW Bayer", "pixelShiftAutomatic"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 5bd3e4646..80c0af080 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1189,6 +1189,7 @@ public: double pixelShiftNreadIso; double pixelShiftPrnu; bool pixelshiftShowMotion; + bool pixelshiftShowMotionMaskOnly; bool pixelShiftAutomatic; bool dcb_enhance; //bool all_enhance; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d3e6b1881..a838b5a0a 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1966,7 +1966,7 @@ void RawImageSource::demosaic(const RAWParams &raw) amaze_demosaic_RT (0, 0, W, H); // for non pixelshift files use amaze if pixelshift is selected. We need it also for motion correction } if(numFrames == 4) { - pixelshift_simple(0, 0, W, H, raw.bayersensor.pixelshiftMotion > 0, raw.bayersensor.pixelshiftMotion, raw.bayersensor.pixelshiftShowMotion, currFrame, raw.bayersensor.pixelshiftMotionCorrection, raw.bayersensor.pixelShiftAutomatic, raw.bayersensor.pixelShiftStddevFactor, raw.bayersensor.pixelShiftEperIso, raw.bayersensor.pixelShiftNreadIso, raw.bayersensor.pixelShiftPrnu); + pixelshift(0, 0, W, H, raw.bayersensor.pixelshiftMotion > 0, raw.bayersensor.pixelshiftMotion, raw.bayersensor.pixelshiftShowMotion, raw.bayersensor.pixelshiftShowMotionMaskOnly, currFrame, raw.bayersensor.pixelshiftMotionCorrection, raw.bayersensor.pixelShiftAutomatic, raw.bayersensor.pixelShiftStddevFactor, raw.bayersensor.pixelShiftEperIso, raw.bayersensor.pixelShiftNreadIso, raw.bayersensor.pixelShiftPrnu); } } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::dcb] ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 75037710b..3529a28ec 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -263,7 +263,7 @@ protected: void xtransborder_interpolate (int border); void xtrans_interpolate (const int passes, const bool useCieLab); void fast_xtrans_interpolate (); - void pixelshift_simple(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, unsigned int frame, unsigned int gridSize, bool adaptive, float stddevFactor, float eperIso, float nreadIso, float prnu); + void pixelshift(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, bool showOnlyMask, unsigned int frame, unsigned int gridSize, bool adaptive, float stddevFactor, float eperIso, float nreadIso, float prnu); void hflip (Imagefloat* im); void vflip (Imagefloat* im); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 643c9e075..4452ae623 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -471,7 +471,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLskal OUTPUTPROFILE, // EvOBPCompens DARKFRAME, // EvRawImageNum - DEMOSAIC // EvDemosaicPixelshiftMotion + DEMOSAIC, // EvDemosaicPixelshiftMotion + DEMOSAIC // EvDemosaicPixelshiftMotionMaskOnly }; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 63705e472..0878403cf 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -86,6 +86,9 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pixelShiftShowMotion = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_PIXELSHIFTSHOWMOTION"))); pixelShiftOptions->pack_start(*pixelShiftShowMotion); + pixelShiftShowMotionMaskOnly = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY"))); + pixelShiftOptions->pack_start(*pixelShiftShowMotionMaskOnly); + pixelShiftAutomatic = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_PIXELSHIFTADAPTIVE"))); pixelShiftOptions->pack_start(*pixelShiftAutomatic); @@ -180,6 +183,7 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA imagenumberconn = imageNumber->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::imageNumberChanged) ); dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::dcbEnhanceChanged), true); pixelShiftShowMotionconn = pixelShiftShowMotion->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::pixelShiftShowMotionChanged), true); + pixelShiftShowMotionMaskOnlyconn = pixelShiftShowMotionMaskOnly->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::pixelShiftShowMotionMaskOnlyChanged), true); pixelShiftAutomaticconn = pixelShiftAutomatic->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::pixelShiftAutomaticChanged), true); //allEnhconn = allEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::allEnhanceChanged), true); } @@ -209,6 +213,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params dcbIterations->setEditedState ( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); dcbEnhance->set_inconsistent(!pedited->raw.bayersensor.dcbEnhance); pixelShiftShowMotion->set_inconsistent(!pedited->raw.bayersensor.pixelshiftShowMotion); + pixelShiftShowMotionMaskOnly->set_inconsistent(!pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly); pixelShiftAutomatic->set_inconsistent(!pedited->raw.bayersensor.pixelShiftAutomatic); //allEnhance->set_inconsistent(!pedited->raw.bayersensor.allEnhance); lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); @@ -232,6 +237,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params dcbIterations->setValue (pp->raw.bayersensor.dcb_iterations); dcbEnhance->set_active(pp->raw.bayersensor.dcb_enhance); pixelShiftShowMotion->set_active(pp->raw.bayersensor.pixelshiftShowMotion); + pixelShiftShowMotionMaskOnly->set_active(pp->raw.bayersensor.pixelshiftShowMotionMaskOnly); pixelShiftAutomatic->set_active(pp->raw.bayersensor.pixelShiftAutomatic); ccSteps->setValue (pp->raw.bayersensor.ccSteps); lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations); @@ -296,6 +302,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getValue(); pp->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getValue(); pp->raw.bayersensor.pixelshiftShowMotion = pixelShiftShowMotion->get_active(); + pp->raw.bayersensor.pixelshiftShowMotionMaskOnly = pixelShiftShowMotionMaskOnly->get_active(); pp->raw.bayersensor.pixelShiftAutomatic = pixelShiftAutomatic->get_active(); int currentRow = method->get_active_row_number(); @@ -324,6 +331,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getEditedState (); pedited->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getEditedState (); pedited->raw.bayersensor.pixelshiftShowMotion = !pixelShiftShowMotion->get_inconsistent(); + pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly = !pixelShiftShowMotionMaskOnly->get_inconsistent(); pedited->raw.bayersensor.pixelShiftAutomatic = !pixelShiftAutomatic->get_inconsistent(); } } @@ -490,12 +498,32 @@ void BayerProcess::pixelShiftShowMotionChanged () lastDCBen = pixelShiftShowMotion->get_active (); } - + pixelShiftShowMotionMaskOnly->set_sensitive(pixelShiftShowMotion->get_active ()); if (listener) { listener->panelChanged (EvDemosaicPixelshiftMotion, pixelShiftShowMotion->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); } } +void BayerProcess::pixelShiftShowMotionMaskOnlyChanged () +{ + if (batchMode) { + if (pixelShiftShowMotionMaskOnly->get_inconsistent()) { + pixelShiftShowMotionMaskOnly->set_inconsistent (false); + pixelShiftShowMotionMaskOnlyconn.block (true); + pixelShiftShowMotionMaskOnly->set_active (false); + pixelShiftShowMotionMaskOnlyconn.block (false); + } else if (lastDCBen) { + pixelShiftShowMotionMaskOnly->set_inconsistent (true); + } + + lastDCBen = pixelShiftShowMotionMaskOnly->get_active (); + } + + if (listener) { + listener->panelChanged (EvDemosaicPixelshiftMotionMaskOnly, pixelShiftShowMotionMaskOnly->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} + void BayerProcess::pixelShiftAutomaticChanged () { if (batchMode) { diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index b490f8c42..f13a0fb66 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -45,6 +45,7 @@ protected: Adjuster* pixelShiftMotion; Adjuster* pixelShiftMotionCorrection; Gtk::CheckButton* pixelShiftShowMotion; + Gtk::CheckButton* pixelShiftShowMotionMaskOnly; Gtk::CheckButton* pixelShiftAutomatic; Adjuster* pixelShiftStddevFactor; Adjuster* pixelShiftEperIso; @@ -53,7 +54,7 @@ protected: bool lastDCBen; int oldMethod; //bool lastALLen; - sigc::connection methodconn, imagenumberconn, dcbEnhconn, pixelShiftShowMotionconn, pixelShiftAutomaticconn; //,allEnhconn; + sigc::connection methodconn, imagenumberconn, dcbEnhconn, pixelShiftShowMotionconn, pixelShiftShowMotionMaskOnlyconn, pixelShiftAutomaticconn; //,allEnhconn; public: BayerProcess (); @@ -68,6 +69,7 @@ public: void adjusterChanged (Adjuster* a, double newval); void dcbEnhanceChanged(); void pixelShiftShowMotionChanged(); + void pixelShiftShowMotionMaskOnlyChanged(); void pixelShiftAutomaticChanged(); //void allEnhanceChanged(); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 87dab2311..3859ca1e6 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -377,6 +377,7 @@ void ParamsEdited::set (bool v) raw.bayersensor.pixelShiftNreadIso = v; raw.bayersensor.pixelShiftPrnu = v; raw.bayersensor.pixelshiftShowMotion = v; + raw.bayersensor.pixelshiftShowMotionMaskOnly = v; raw.bayersensor.pixelShiftAutomatic = v; raw.bayersensor.greenEq = v; raw.bayersensor.linenoise = v; @@ -881,6 +882,7 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.pixelShiftNreadIso = raw.bayersensor.pixelShiftNreadIso && p.raw.bayersensor.pixelShiftNreadIso == other.raw.bayersensor.pixelShiftNreadIso; raw.bayersensor.pixelShiftPrnu = raw.bayersensor.pixelShiftPrnu && p.raw.bayersensor.pixelShiftPrnu == other.raw.bayersensor.pixelShiftPrnu; raw.bayersensor.pixelshiftShowMotion = raw.bayersensor.pixelshiftShowMotion && p.raw.bayersensor.pixelshiftShowMotion == other.raw.bayersensor.pixelshiftShowMotion; + raw.bayersensor.pixelshiftShowMotionMaskOnly = raw.bayersensor.pixelshiftShowMotionMaskOnly && p.raw.bayersensor.pixelshiftShowMotionMaskOnly == other.raw.bayersensor.pixelshiftShowMotionMaskOnly; raw.bayersensor.pixelShiftAutomatic = raw.bayersensor.pixelShiftAutomatic && p.raw.bayersensor.pixelShiftAutomatic == other.raw.bayersensor.pixelShiftAutomatic; raw.bayersensor.greenEq = raw.bayersensor.greenEq && p.raw.bayersensor.greenthresh == other.raw.bayersensor.greenthresh; raw.bayersensor.linenoise = raw.bayersensor.linenoise && p.raw.bayersensor.linenoise == other.raw.bayersensor.linenoise; @@ -2322,6 +2324,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelshiftShowMotion = mods.raw.bayersensor.pixelshiftShowMotion; } + if (raw.bayersensor.pixelshiftShowMotionMaskOnly) { + toEdit.raw.bayersensor.pixelshiftShowMotionMaskOnly = mods.raw.bayersensor.pixelshiftShowMotionMaskOnly; + } + if (raw.bayersensor.pixelShiftAutomatic) { toEdit.raw.bayersensor.pixelShiftAutomatic = mods.raw.bayersensor.pixelShiftAutomatic; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c116350a8..ae1fae218 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -699,6 +699,7 @@ public: bool pixelShiftNreadIso; bool pixelShiftPrnu; bool pixelshiftShowMotion; + bool pixelshiftShowMotionMaskOnly; bool pixelShiftAutomatic; //bool allEnhance; bool greenEq;