From d82956bbe5df9cba8366f00660c8ac356e1e9a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Tue, 21 Jun 2016 20:50:42 +0200 Subject: [PATCH] Add optimized median25 and kill old macros (#3346) --- rtengine/FTblockDN.cc | 320 +++++--------- rtengine/ipwavelet.cc | 25 +- rtengine/median.h | 833 +++++++++++++++++++++++++++---------- rtengine/rawimagesource.cc | 30 +- 4 files changed, 723 insertions(+), 485 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 9f74d9f2c..03e1f15b4 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -49,54 +49,6 @@ #define epsilon 0.001f/(TS*TS) //tolerance -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - -#define med5(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; pp[9]=a9; pp[10]=a10; pp[11]=a11; pp[12]=a12; \ -pp[13]=a13; pp[14]=a14; pp[15]=a15; pp[16]=a16; pp[17]=a17; pp[18]=a18; pp[19]=a19; pp[20]=a20; pp[21]=a21; pp[22]=a22; pp[23]=a23; pp[24]=a24; \ -PIX_SORT(pp[0], pp[1]) ; PIX_SORT(pp[3], pp[4]) ; PIX_SORT(pp[2], pp[4]) ;\ -PIX_SORT(pp[2], pp[3]) ; PIX_SORT(pp[6], pp[7]) ; PIX_SORT(pp[5], pp[7]) ;\ -PIX_SORT(pp[5], pp[6]) ; PIX_SORT(pp[9], pp[10]) ; PIX_SORT(pp[8], pp[10]) ;\ -PIX_SORT(pp[8], pp[9]) ; PIX_SORT(pp[12], pp[13]) ; PIX_SORT(pp[11], pp[13]) ;\ -PIX_SORT(pp[11], pp[12]) ; PIX_SORT(pp[15], pp[16]) ; PIX_SORT(pp[14], pp[16]) ;\ -PIX_SORT(pp[14], pp[15]) ; PIX_SORT(pp[18], pp[19]) ; PIX_SORT(pp[17], pp[19]) ;\ -PIX_SORT(pp[17], pp[18]) ; PIX_SORT(pp[21], pp[22]) ; PIX_SORT(pp[20], pp[22]) ;\ -PIX_SORT(pp[20], pp[21]) ; PIX_SORT(pp[23], pp[24]) ; PIX_SORT(pp[2], pp[5]) ;\ -PIX_SORT(pp[3], pp[6]) ; PIX_SORT(pp[0], pp[6]) ; PIX_SORT(pp[0], pp[3]) ;\ -PIX_SORT(pp[4], pp[7]) ; PIX_SORT(pp[1], pp[7]) ; PIX_SORT(pp[1], pp[4]) ;\ -PIX_SORT(pp[11], pp[14]) ; PIX_SORT(pp[8], pp[14]) ; PIX_SORT(pp[8], pp[11]) ;\ -PIX_SORT(pp[12], pp[15]) ; PIX_SORT(pp[9], pp[15]) ; PIX_SORT(pp[9], pp[12]) ;\ -PIX_SORT(pp[13], pp[16]) ; PIX_SORT(pp[10], pp[16]) ; PIX_SORT(pp[10], pp[13]) ;\ -PIX_SORT(pp[20], pp[23]) ; PIX_SORT(pp[17], pp[23]) ; PIX_SORT(pp[17], pp[20]) ;\ -PIX_SORT(pp[21], pp[24]) ; PIX_SORT(pp[18], pp[24]) ; PIX_SORT(pp[18], pp[21]) ;\ -PIX_SORT(pp[19], pp[22]) ; PIX_SORT(pp[8], pp[17]) ; PIX_SORT(pp[9], pp[18]) ;\ -PIX_SORT(pp[0], pp[18]) ; PIX_SORT(pp[0], pp[9]) ; PIX_SORT(pp[10], pp[19]) ;\ -PIX_SORT(pp[1], pp[19]) ; PIX_SORT(pp[1], pp[10]) ; PIX_SORT(pp[11], pp[20]) ;\ -PIX_SORT(pp[2], pp[20]) ; PIX_SORT(pp[2], pp[11]) ; PIX_SORT(pp[12], pp[21]) ;\ -PIX_SORT(pp[3], pp[21]) ; PIX_SORT(pp[3], pp[12]) ; PIX_SORT(pp[13], pp[22]) ;\ -PIX_SORT(pp[4], pp[22]) ; PIX_SORT(pp[4], pp[13]) ; PIX_SORT(pp[14], pp[23]) ;\ -PIX_SORT(pp[5], pp[23]) ; PIX_SORT(pp[5], pp[14]) ; PIX_SORT(pp[15], pp[24]) ;\ -PIX_SORT(pp[6], pp[24]) ; PIX_SORT(pp[6], pp[15]) ; PIX_SORT(pp[7], pp[16]) ;\ -PIX_SORT(pp[7], pp[19]) ; PIX_SORT(pp[13], pp[21]) ; PIX_SORT(pp[15], pp[23]) ;\ -PIX_SORT(pp[7], pp[13]) ; PIX_SORT(pp[7], pp[15]) ; PIX_SORT(pp[1], pp[9]) ;\ -PIX_SORT(pp[3], pp[11]) ; PIX_SORT(pp[5], pp[17]) ; PIX_SORT(pp[11], pp[17]) ;\ -PIX_SORT(pp[9], pp[17]) ; PIX_SORT(pp[4], pp[10]) ; PIX_SORT(pp[6], pp[12]) ;\ -PIX_SORT(pp[7], pp[14]) ; PIX_SORT(pp[4], pp[6]) ; PIX_SORT(pp[4], pp[7]) ;\ -PIX_SORT(pp[12], pp[14]) ; PIX_SORT(pp[10], pp[14]) ; PIX_SORT(pp[6], pp[7]) ;\ -PIX_SORT(pp[10], pp[12]) ; PIX_SORT(pp[6], pp[10]) ; PIX_SORT(pp[6], pp[17]) ;\ -PIX_SORT(pp[12], pp[17]) ; PIX_SORT(pp[7], pp[17]) ; PIX_SORT(pp[7], pp[10]) ;\ -PIX_SORT(pp[12], pp[18]) ; PIX_SORT(pp[7], pp[12]) ; PIX_SORT(pp[10], pp[18]) ;\ -PIX_SORT(pp[12], pp[20]) ; PIX_SORT(pp[10], pp[20]) ; PIX_SORT(pp[10], pp[12]) ;\ -median=pp[12];} - -#define ELEM_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } - namespace rtengine { @@ -120,72 +72,6 @@ namespace rtengine extern const Settings* settings; -// Median calculation using quicksort -float fq_sort2(float arr[], int n) -{ - int low = 0; - int high = n - 1; - int median = (low + high) / 2; - - for (;;) { - if (high <= low) { - return arr[median] ; - } - - if (high == low + 1) { - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; - } - - return arr[median] ; - } - - int middle = (low + high) / 2; - - if (arr[middle] > arr[high]) { - ELEM_FLOAT_SWAP(arr[middle], arr[high]) ; - } - - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; - } - - if (arr[middle] > arr[low]) { - ELEM_FLOAT_SWAP(arr[middle], arr[low]) ; - } - - ELEM_FLOAT_SWAP(arr[middle], arr[low + 1]) ; - int ll = low + 1; - int hh = high; - - for (;;) { - do { - ll++; - } while (arr[low] > arr[ll]) ; - - do { - hh--; - } while (arr[hh] > arr[low]) ; - - if (hh < ll) { - break; - } - - ELEM_FLOAT_SWAP(arr[ll], arr[hh]) ; - } - - ELEM_FLOAT_SWAP(arr[low], arr[hh]) ; - - if (hh <= median) { - low = ll; - } - - if (hh >= median) { - high = hh - 1; - } - } -} - float media(float *elements, int N) { @@ -211,7 +97,7 @@ float media(float *elements, int N) void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, const int height, const mediantype medianType, const int iterations, const int numThreads, float **buffer) { - int border = 1, numElements, middleElement; + int border = 1; switch(medianType) { case MED_3X3SOFT: @@ -229,14 +115,10 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, case MED_7X7: border = 3; - numElements = 49; - middleElement = 24; break; default: // includes MED_9X9 border = 4; - numElements = 81; - middleElement = 40; } float **allocBuffer = NULL; @@ -280,7 +162,6 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, for (int i = border; i < height - border; i++) { if(medianType == MED_3X3SOFT) { - float pp[5], temp; int j; for (j = 0; j < border; j++) { @@ -288,7 +169,7 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } for (; j < width - border; j++) { - med2(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1], medianOut[i][j]); + medianOut[i][j] = median(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1]); } for(; j < width; j++) { @@ -309,7 +190,6 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, medianOut[i][j] = medianIn[i][j]; } } else if(medianType == MED_5X5SOFT) { - float pp[13]; int j; for (j = 0; j < border; j++) { @@ -317,28 +197,27 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } for (; j < width - border; j++) { - pp[0] = medianIn[i][j]; - pp[1] = medianIn[i - 1][j]; - pp[2] = medianIn[i + 1][j]; - pp[3] = medianIn[i][j + 1]; - pp[4] = medianIn[i][j - 1]; - pp[5] = medianIn[i - 1][j - 1]; - pp[6] = medianIn[i - 1][j + 1]; - pp[7] = medianIn[i + 1][j - 1]; - pp[8] = medianIn[i + 1][j + 1]; - pp[9] = medianIn[i + 2][j]; - pp[10] = medianIn[i - 2][j]; - pp[11] = medianIn[i][j + 2]; - pp[12] = medianIn[i][j - 2]; - fq_sort2(pp, 13); - medianOut[i][j] = pp[6]; + medianOut[i][j] = median( + medianIn[i][j], + medianIn[i - 1][j], + medianIn[i + 1][j], + medianIn[i][j + 1], + medianIn[i][j - 1], + medianIn[i - 1][j - 1], + medianIn[i - 1][j + 1], + medianIn[i + 1][j - 1], + medianIn[i + 1][j + 1], + medianIn[i + 2][j], + medianIn[i - 2][j], + medianIn[i][j + 2], + medianIn[i][j - 2] + ); } for(; j < width; j++) { medianOut[i][j] = medianIn[i][j]; } } else if(medianType == MED_5X5STRONG) { - float pp[25], temp; int j; for (j = 0; j < border; j++) { @@ -346,17 +225,16 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } for (; j < width - border; j++) { - med5(medianIn[i][j], medianIn[i - 1][j], medianIn[i + 1][j], medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], + medianOut[i][j] = median(medianIn[i][j], medianIn[i - 1][j], medianIn[i + 1][j], medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], medianIn[i - 2][j], medianIn[i + 2][j], medianIn[i][j + 2], medianIn[i][j - 2], medianIn[i - 2][j - 2], medianIn[i - 2][j + 2], medianIn[i + 2][j - 2], medianIn[i + 2][j + 2], - medianIn[i - 2][j + 1], medianIn[i + 2][j + 1], medianIn[i - 1][j + 2], medianIn[i - 1][j - 2], medianIn[i - 2][j - 1], medianIn[i + 2][j - 1], medianIn[i + 1][j + 2], medianIn[i + 1][j - 2], - medianOut[i][j]); + medianIn[i - 2][j + 1], medianIn[i + 2][j + 1], medianIn[i - 1][j + 2], medianIn[i - 1][j - 2], medianIn[i - 2][j - 1], medianIn[i + 2][j - 1], medianIn[i + 1][j + 2], medianIn[i + 1][j - 2]); } for(; j < width; j++) { medianOut[i][j] = medianIn[i][j]; } - } else {// includes MED_7X7 and MED_9X9 - float pp[81]; + } else if (medianType == MED_7X7) { + std::array pp = {}; int j; for (j = 0; j < border; j++) { @@ -373,8 +251,31 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } } - fq_sort2(pp, numElements); - medianOut[i][j] = pp[middleElement]; + medianOut[i][j] = median(pp); + } + + for(; j < width; j++) { + medianOut[i][j] = medianIn[i][j]; + } + } else { // includes MED_9X9 + std::array pp = {}; + int j; + + for (j = 0; j < border; j++) { + medianOut[i][j] = medianIn[i][j]; + } + + for (; j < width - border; j++) { + int kk = 0; + + for (int ii = -border; ii <= border; ii++) { + for (int jj = -border; jj <= border; jj++) { + kk++; + pp[kk] = medianIn[i + ii][j + jj]; + } + } + + medianOut[i][j] = median(pp); } for(; j < width; j++) { @@ -1853,11 +1754,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - if(methmed == 0) for (int j = 1; j < wid - 1; j++) { - med2(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), tm[i][j]); //3x3 soft + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1)); //3x3 soft } else for (int j = 1; j < wid - 1; j++) { @@ -1869,34 +1768,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef for (int i = 2; i < hei - 2; i++) { - float pp[25]; - if(methmed == 3) { - float temp; - for (int j = 2; j < wid - 2; j++) { - med5(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), source->r(i - 2, j), source->r(i + 2, j), source->r(i, j + 2), source->r(i, j - 2), source->r(i - 2, j - 2), source->r(i - 2, j + 2), source->r(i + 2, j - 2), source->r(i + 2, j + 2), - source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2), - tm[i][j]);//5x5 + source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2));//5x5 } } else for (int j = 2; j < wid - 2; j++) { - pp[0] = source->r(i, j); - pp[1] = source->r(i - 1, j); - pp[2] = source->r(i + 1, j); - pp[3] = source->r(i, j + 1); - pp[4] = source->r(i, j - 1); - pp[5] = source->r(i - 1, j - 1); - pp[6] = source->r(i - 1, j + 1); - pp[7] = source->r(i + 1, j - 1); - pp[8] = source->r(i + 1, j + 1); - pp[9] = source->r(i + 2, j); - pp[10] = source->r(i - 2, j); - pp[11] = source->r(i, j + 2); - pp[12] = source->r(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + tm[i][j] = median( + source->r(i, j), + source->r(i - 1, j), + source->r(i + 1, j), + source->r(i, j + 1), + source->r(i, j - 1), + source->r(i - 1, j - 1), + source->r(i - 1, j + 1), + source->r(i + 1, j - 1), + source->r(i + 1, j + 1), + source->r(i + 2, j), + source->r(i - 2, j), + source->r(i, j + 2), + source->r(i, j - 2) + ); // 5x5 soft } } } @@ -1916,11 +1810,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - if(methmed == 0) for (int j = 1; j < wid - 1; j++) { - med2(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), tm[i][j]); + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1)); } else for (int j = 1; j < wid - 1; j++) { @@ -1932,34 +1824,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef for (int i = 2; i < hei - 2; i++) { - float pp[25]; - if(methmed == 3) { - float temp; - for (int j = 2; j < wid - 2; j++) { - med5(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), source->b(i - 2, j), source->b(i + 2, j), source->b(i, j + 2), source->b(i, j - 2), source->b(i - 2, j - 2), source->b(i - 2, j + 2), source->b(i + 2, j - 2), source->b(i + 2, j + 2), - source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2), - tm[i][j]);//5x5 + source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2)); // 5x5 } } else for (int j = 2; j < wid - 2; j++) { - pp[0] = source->b(i, j); - pp[1] = source->b(i - 1, j); - pp[2] = source->b(i + 1, j); - pp[3] = source->b(i, j + 1); - pp[4] = source->b(i, j - 1); - pp[5] = source->b(i - 1, j - 1); - pp[6] = source->b(i - 1, j + 1); - pp[7] = source->b(i + 1, j - 1); - pp[8] = source->b(i + 1, j + 1); - pp[9] = source->b(i + 2, j); - pp[10] = source->b(i - 2, j); - pp[11] = source->b(i, j + 2); - pp[12] = source->b(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + tm[i][j] = median( + source->b(i, j), + source->b(i - 1, j), + source->b(i + 1, j), + source->b(i, j + 1), + source->b(i, j - 1), + source->b(i - 1, j - 1), + source->b(i - 1, j + 1), + source->b(i + 1, j - 1), + source->b(i + 1, j + 1), + source->b(i + 2, j), + source->b(i - 2, j), + source->b(i, j + 2), + source->b(i, j - 2) + ); // 5x5 soft } } } @@ -1981,11 +1868,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - if(methmed == 0) for (int j = 1; j < wid - 1; j++) { - med2(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), tm[i][j]); + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1)); } else for (int j = 1; j < wid - 1; j++) { @@ -1997,34 +1882,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef for (int i = 2; i < hei - 2; i++) { - float pp[25]; - if(methmed == 3) { - float temp; - for (int j = 2; j < wid - 2; j++) { - med5(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), source->g(i - 2, j), source->g(i + 2, j), source->g(i, j + 2), source->g(i, j - 2), source->g(i - 2, j - 2), source->g(i - 2, j + 2), source->g(i + 2, j - 2), source->g(i + 2, j + 2), - source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2), - tm[i][j]);//5x5 + source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2)); // 5x5 } } else for (int j = 2; j < wid - 2; j++) { - pp[0] = source->g(i, j); - pp[1] = source->g(i - 1, j); - pp[2] = source->g(i + 1, j); - pp[3] = source->g(i, j + 1); - pp[4] = source->g(i, j - 1); - pp[5] = source->g(i - 1, j - 1); - pp[6] = source->g(i - 1, j + 1); - pp[7] = source->g(i + 1, j - 1); - pp[8] = source->g(i + 1, j + 1); - pp[9] = source->g(i + 2, j); - pp[10] = source->g(i - 2, j); - pp[11] = source->g(i, j + 2); - pp[12] = source->g(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + tm[i][j] = median( + source->g(i, j), + source->g(i - 1, j), + source->g(i + 1, j), + source->g(i, j + 1), + source->g(i, j - 1), + source->g(i - 1, j - 1), + source->g(i - 1, j + 1), + source->g(i + 1, j - 1), + source->g(i + 1, j + 1), + source->g(i + 2, j), + source->g(i - 2, j), + source->g(i, j + 2), + source->g(i, j - 2) + ); // 5x5 soft } } } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 4e433b453..c1535dd38 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -37,6 +37,7 @@ #include "mytime.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" #include "EdgePreservingDecomposition.h" #ifdef _OPENMP @@ -50,26 +51,6 @@ #define fTS ((TS/2+1)) // second dimension of Fourier tiles #define blkrad 1 // radius of block averaging -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - - #define epsilon 0.001f/(TS*TS) //tolerance @@ -827,11 +808,9 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int #endif for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - for (int j = 1; j < wid - 1; j++) { if((varhue[i][j] < -1.3f && varhue[i][j] > - 2.5f) && (varchro[i][j] > 15.f && varchro[i][j] < 55.f) && labco->L[i][j] > 6000.f) { //blue sky + med3x3 ==> after for more effect use denoise - med3(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1], tmL[i][j]); //3x3 + tmL[i][j] = median(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1]); //3x3 } } } diff --git a/rtengine/median.h b/rtengine/median.h index 36794f87b..13a79e381 100644 --- a/rtengine/median.h +++ b/rtengine/median.h @@ -36,227 +36,630 @@ inline T median(std::array array) : ((*middle + *std::max_element(array.begin(), middle)) / static_cast(2)); } +template +inline T median(std::array array) +{ + return std::max(std::min(array[0], array[1]), std::min(array[2], std::max(array[0], array[1]))); +} + +template<> +inline vfloat median(std::array array) +{ + return vmaxf(vminf(array[0], array[1]), vminf(array[2], vmaxf(array[0], array[1]))); +} + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = std::max(array[0], tmp); + array[1] = std::min(array[1], array[4]); + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[2], array[3]); + return std::max(array[1], tmp); +} + +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = vmaxf(array[0], tmp); + array[1] = vminf(array[1], array[4]); + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[2], array[3]); + return vmaxf(array[1], tmp); +} + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[5]); + array[5] = std::max(array[0], array[5]); + array[0] = tmp; + tmp = std::min(array[0], array[3]); + array[3] = std::max(array[0], array[3]); + array[0] = tmp; + tmp = std::min(array[1], array[6]); + array[6] = std::max(array[1], array[6]); + array[1] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + array[1] = std::max(array[0], array[1]); + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[3] = std::max(tmp, array[3]); + array[3] = std::min(array[3], array[6]); + tmp = std::min(array[4], array[5]); + array[4] = std::max(array[1], tmp); + tmp = std::min(array[1], tmp); + array[3] = std::max(tmp, array[3]); + return std::min(array[3], array[4]); +} + +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[5]); + array[5] = vmaxf(array[0], array[5]); + array[0] = tmp; + tmp = vminf(array[0], array[3]); + array[3] = vmaxf(array[0], array[3]); + array[0] = tmp; + tmp = vminf(array[1], array[6]); + array[6] = vmaxf(array[1], array[6]); + array[1] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + array[1] = vmaxf(array[0], array[1]); + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[3] = vmaxf(tmp, array[3]); + array[3] = vminf(array[3], array[6]); + tmp = vminf(array[4], array[5]); + array[4] = vmaxf(array[1], tmp); + tmp = vminf(array[1], tmp); + array[3] = vmaxf(tmp, array[3]); + return vminf(array[3], array[4]); +} + +template +inline T median(std::array array) +{ + T tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[7] = tmp; + tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[3] = std::max(array[0], array[3]); + array[5] = std::min(array[5], array[8]); + array[7] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[6] = std::max(array[3], array[6]); + array[4] = std::max(array[1], tmp); + array[2] = std::min(array[2], array[5]); + array[4] = std::min(array[4], array[7]); + tmp = std::min(array[4], array[2]); + array[2] = std::max(array[4], array[2]); + array[4] = std::max(array[6], tmp); + return std::min(array[4], array[2]); +} + +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[7] = tmp; + tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[3] = vmaxf(array[0], array[3]); + array[5] = vminf(array[5], array[8]); + array[7] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[6] = vmaxf(array[3], array[6]); + array[4] = vmaxf(array[1], tmp); + array[2] = vminf(array[2], array[5]); + array[4] = vminf(array[4], array[7]); + tmp = vminf(array[4], array[2]); + array[2] = vmaxf(array[4], array[2]); + array[4] = vmaxf(array[6], tmp); + return vminf(array[4], array[2]); +} + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = std::min(tmp, array[6]); + array[6] = std::max(tmp, array[6]); + tmp = std::min(array[9], array[10]); + array[10] = std::max(array[9], array[10]); + array[9] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = std::min(tmp, array[9]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[12], array[13]); + array[13] = std::max(array[12], array[13]); + array[12] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[15], array[16]); + array[16] = std::max(array[15], array[16]); + array[15] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = std::min(tmp, array[15]); + array[15] = std::max(tmp, array[15]); + tmp = std::min(array[18], array[19]); + array[19] = std::max(array[18], array[19]); + array[18] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = std::min(tmp, array[18]); + array[18] = std::max(tmp, array[18]); + tmp = std::min(array[21], array[22]); + array[22] = std::max(array[21], array[22]); + array[21] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[23], array[24]); + array[24] = std::max(array[23], array[24]); + array[23] = tmp; + tmp = std::min(array[2], array[5]); + array[5] = std::max(array[2], array[5]); + array[2] = tmp; + tmp = std::min(array[3], array[6]); + array[6] = std::max(array[3], array[6]); + array[3] = tmp; + tmp = std::min(array[0], array[6]); + array[6] = std::max(array[0], array[6]); + array[0] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[4], array[7]); + array[7] = std::max(array[4], array[7]); + array[4] = tmp; + tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = std::min(tmp, array[4]); + array[4] = std::max(tmp, array[4]); + tmp = std::min(array[11], array[14]); + array[14] = std::max(array[11], array[14]); + array[11] = tmp; + tmp = std::min(array[8], array[14]); + array[14] = std::max(array[8], array[14]); + array[8] = std::min(tmp, array[11]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[15]); + array[15] = std::max(array[12], array[15]); + array[12] = tmp; + tmp = std::min(array[9], array[15]); + array[15] = std::max(array[9], array[15]); + array[9] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[16]); + array[16] = std::max(array[13], array[16]); + array[13] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = std::min(tmp, array[13]); + array[13] = std::max(tmp, array[13]); + tmp = std::min(array[20], array[23]); + array[23] = std::max(array[20], array[23]); + array[20] = tmp; + tmp = std::min(array[17], array[23]); + array[23] = std::max(array[17], array[23]); + array[17] = std::min(tmp, array[20]); + array[20] = std::max(tmp, array[20]); + tmp = std::min(array[21], array[24]); + array[24] = std::max(array[21], array[24]); + array[21] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[19], array[22]); + array[22] = std::max(array[19], array[22]); + array[19] = tmp; + array[17] = std::max(array[8], array[17]); + tmp = std::min(array[9], array[18]); + array[18] = std::max(array[9], array[18]); + array[9] = tmp; + tmp = std::min(array[0], array[18]); + array[18] = std::max(array[0], array[18]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[10], array[19]); + array[19] = std::max(array[10], array[19]); + array[10] = tmp; + tmp = std::min(array[1], array[19]); + array[19] = std::max(array[1], array[19]); + array[1] = std::min(tmp, array[10]); + array[10] = std::max(tmp, array[10]); + tmp = std::min(array[11], array[20]); + array[20] = std::max(array[11], array[20]); + array[11] = tmp; + tmp = std::min(array[2], array[20]); + array[20] = std::max(array[2], array[20]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[21]); + array[21] = std::max(array[12], array[21]); + array[12] = tmp; + tmp = std::min(array[3], array[21]); + array[21] = std::max(array[3], array[21]); + array[3] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[22]); + array[22] = std::max(array[13], array[22]); + array[4] = std::min(array[4], array[22]); + array[13] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[4] = tmp; + tmp = std::min(array[14], array[23]); + array[23] = std::max(array[14], array[23]); + array[14] = tmp; + tmp = std::min(array[5], array[23]); + array[23] = std::max(array[5], array[23]); + array[5] = std::min(tmp, array[14]); + array[14] = std::max(tmp, array[14]); + tmp = std::min(array[15], array[24]); + array[24] = std::max(array[15], array[24]); + array[15] = tmp; + array[6] = std::min(array[6], array[24]); + tmp = std::min(array[6], array[15]); + array[15] = std::max(array[6], array[15]); + array[6] = tmp; + tmp = std::min(array[7], array[16]); + array[7] = std::min(tmp, array[19]); + tmp = std::min(array[13], array[21]); + array[15] = std::min(array[15], array[23]); + tmp = std::min(array[7], tmp); + array[7] = std::min(tmp, array[15]); + array[9] = std::max(array[1], array[9]); + array[11] = std::max(array[3], array[11]); + array[17] = std::max(array[5], array[17]); + array[17] = std::max(array[11], array[17]); + array[17] = std::max(array[9], array[17]); + tmp = std::min(array[4], array[10]); + array[10] = std::max(array[4], array[10]); + array[4] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[14]); + array[14] = std::max(array[7], array[14]); + array[7] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[7] = std::max(tmp, array[7]); + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + array[10] = std::min(array[10], array[14]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = std::max(array[6], tmp); + tmp = std::min(array[6], tmp); + array[17] = std::max(tmp, array[17]); + tmp = std::min(array[12], array[17]); + array[17] = std::max(array[12], array[17]); + array[12] = tmp; + array[7] = std::min(array[7], array[17]); + tmp = std::min(array[7], array[10]); + array[10] = std::max(array[7], array[10]); + array[7] = tmp; + tmp = std::min(array[12], array[18]); + array[18] = std::max(array[12], array[18]); + array[12] = std::max(array[7], tmp); + array[10] = std::min(array[10], array[18]); + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[10], array[20]); + return std::max(tmp, array[12]); +} + +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = vminf(tmp, array[6]); + array[6] = vmaxf(tmp, array[6]); + tmp = vminf(array[9], array[10]); + array[10] = vmaxf(array[9], array[10]); + array[9] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = vminf(tmp, array[9]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[12], array[13]); + array[13] = vmaxf(array[12], array[13]); + array[12] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[15], array[16]); + array[16] = vmaxf(array[15], array[16]); + array[15] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = vminf(tmp, array[15]); + array[15] = vmaxf(tmp, array[15]); + tmp = vminf(array[18], array[19]); + array[19] = vmaxf(array[18], array[19]); + array[18] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = vminf(tmp, array[18]); + array[18] = vmaxf(tmp, array[18]); + tmp = vminf(array[21], array[22]); + array[22] = vmaxf(array[21], array[22]); + array[21] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[23], array[24]); + array[24] = vmaxf(array[23], array[24]); + array[23] = tmp; + tmp = vminf(array[2], array[5]); + array[5] = vmaxf(array[2], array[5]); + array[2] = tmp; + tmp = vminf(array[3], array[6]); + array[6] = vmaxf(array[3], array[6]); + array[3] = tmp; + tmp = vminf(array[0], array[6]); + array[6] = vmaxf(array[0], array[6]); + array[0] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[4], array[7]); + array[7] = vmaxf(array[4], array[7]); + array[4] = tmp; + tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = vminf(tmp, array[4]); + array[4] = vmaxf(tmp, array[4]); + tmp = vminf(array[11], array[14]); + array[14] = vmaxf(array[11], array[14]); + array[11] = tmp; + tmp = vminf(array[8], array[14]); + array[14] = vmaxf(array[8], array[14]); + array[8] = vminf(tmp, array[11]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[15]); + array[15] = vmaxf(array[12], array[15]); + array[12] = tmp; + tmp = vminf(array[9], array[15]); + array[15] = vmaxf(array[9], array[15]); + array[9] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[16]); + array[16] = vmaxf(array[13], array[16]); + array[13] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = vminf(tmp, array[13]); + array[13] = vmaxf(tmp, array[13]); + tmp = vminf(array[20], array[23]); + array[23] = vmaxf(array[20], array[23]); + array[20] = tmp; + tmp = vminf(array[17], array[23]); + array[23] = vmaxf(array[17], array[23]); + array[17] = vminf(tmp, array[20]); + array[20] = vmaxf(tmp, array[20]); + tmp = vminf(array[21], array[24]); + array[24] = vmaxf(array[21], array[24]); + array[21] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[19], array[22]); + array[22] = vmaxf(array[19], array[22]); + array[19] = tmp; + array[17] = vmaxf(array[8], array[17]); + tmp = vminf(array[9], array[18]); + array[18] = vmaxf(array[9], array[18]); + array[9] = tmp; + tmp = vminf(array[0], array[18]); + array[18] = vmaxf(array[0], array[18]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[10], array[19]); + array[19] = vmaxf(array[10], array[19]); + array[10] = tmp; + tmp = vminf(array[1], array[19]); + array[19] = vmaxf(array[1], array[19]); + array[1] = vminf(tmp, array[10]); + array[10] = vmaxf(tmp, array[10]); + tmp = vminf(array[11], array[20]); + array[20] = vmaxf(array[11], array[20]); + array[11] = tmp; + tmp = vminf(array[2], array[20]); + array[20] = vmaxf(array[2], array[20]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[21]); + array[21] = vmaxf(array[12], array[21]); + array[12] = tmp; + tmp = vminf(array[3], array[21]); + array[21] = vmaxf(array[3], array[21]); + array[3] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[22]); + array[22] = vmaxf(array[13], array[22]); + array[4] = vminf(array[4], array[22]); + array[13] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[4] = tmp; + tmp = vminf(array[14], array[23]); + array[23] = vmaxf(array[14], array[23]); + array[14] = tmp; + tmp = vminf(array[5], array[23]); + array[23] = vmaxf(array[5], array[23]); + array[5] = vminf(tmp, array[14]); + array[14] = vmaxf(tmp, array[14]); + tmp = vminf(array[15], array[24]); + array[24] = vmaxf(array[15], array[24]); + array[15] = tmp; + array[6] = vminf(array[6], array[24]); + tmp = vminf(array[6], array[15]); + array[15] = vmaxf(array[6], array[15]); + array[6] = tmp; + tmp = vminf(array[7], array[16]); + array[7] = vminf(tmp, array[19]); + tmp = vminf(array[13], array[21]); + array[15] = vminf(array[15], array[23]); + tmp = vminf(array[7], tmp); + array[7] = vminf(tmp, array[15]); + array[9] = vmaxf(array[1], array[9]); + array[11] = vmaxf(array[3], array[11]); + array[17] = vmaxf(array[5], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[17] = vmaxf(array[9], array[17]); + tmp = vminf(array[4], array[10]); + array[10] = vmaxf(array[4], array[10]); + array[4] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[14]); + array[14] = vmaxf(array[7], array[14]); + array[7] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[7] = vmaxf(tmp, array[7]); + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + array[10] = vminf(array[10], array[14]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = vmaxf(array[6], tmp); + tmp = vminf(array[6], tmp); + array[17] = vmaxf(tmp, array[17]); + tmp = vminf(array[12], array[17]); + array[17] = vmaxf(array[12], array[17]); + array[12] = tmp; + array[7] = vminf(array[7], array[17]); + tmp = vminf(array[7], array[10]); + array[10] = vmaxf(array[7], array[10]); + array[7] = tmp; + tmp = vminf(array[12], array[18]); + array[18] = vmaxf(array[12], array[18]); + array[12] = vmaxf(array[7], tmp); + array[10] = vminf(array[10], array[18]); + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[10], array[20]); + return vmaxf(tmp, array[12]); +} + template inline T median(T arg, ARGS... args) { return median(std::array{std::move(arg), std::move(args)...}); } -template -inline T median(T a, T b, T c) -{ - return std::max(std::min(a, b), std::min(c, std::max(a, b))); -} - -template<> -inline vfloat median(vfloat a, vfloat b, vfloat c) -{ - return vmaxf(vminf(a, b), vminf(c, vmaxf(a, b))); -} - -// See http://stackoverflow.com/questions/480960/code-to-calculate-median-of-five-in-c-sharp -template -inline T median(T a, T b, T c, T d, T e) -{ - if (b < a) { - std::swap(a, b); - } - if (d < c) { - std::swap(c, d); - } - - if (c < a) { - std::swap(b, d); - c = a; - } - - a = e; - - if (b < a) { - std::swap(a, b); - } - - if (a < c) { - std::swap(b, d); - a = c; - } - - return std::min(a, d); -} - -template<> -inline vfloat median(vfloat a, vfloat b, vfloat c, vfloat d, vfloat e) -{ - const vfloat f = vmaxf(vminf(a, b), vminf(c, d)); - const vfloat g = vminf(vmaxf(a, b), vmaxf(c, d)); - return median(e, f, g); -} - -// See http://www.cs.hut.fi/~cessu/selection/V_7_4 -// Hand unrolled algorithm by Flössie ;) -template -inline T median(T a, T b, T c, T d, T e, T f, T g) -{ - if (b < a) { - std::swap(a, b); - } - - if (d < c) { - std::swap(b, c); - std::swap(b, d); - } else { - std::swap(b, c); - } - - if (b < a) { - std::swap(a, b); - } else { - std::swap(c, d); - } - - if (e < d) { - std::swap(c, d); - std::swap(c, e); - - if (c < b) { - std::swap(b, c); - - if (g < f) { - std::swap(d, g); - std::swap(e, g); - std::swap(f, g); - } else { - std::swap(d, f); - std::swap(e, f); - } - - if (g < c) { - std::swap(a, d); - - if (d < b) { - std::swap(a, b); - } else { - std::swap(a, d); - b = d; - } - - if (g < f) { - return std::max(a, g); - } - - return std::max(b, f); - } - - if (f < d) { - std::swap(d, f); - } - - if (d < c) { - return std::min(c, f); - } - - return std::min(d, e); - } - - if (d < c) { - std::swap(c, e); - - if (f < b) { - if (g < b) { - return b; - } - - return std::min(d, g); - } - - if (g < f) { - std::swap(e, g); - std::swap(f, g); - } else { - std::swap(e, f); - } - - if (e < d) { - return std::min(d, g); - } - - return std::min(e, f); - } - - if (g < f) { - std::swap(f, g); - } - - std::swap(e, f); - - if (e < c) { - if (g < b) { - return b; - } - - return std::min(c, g); - } - - if (d < e) { - return std::min(d, f); - } - - return std::min(e, f); - } - - if (d < b) { - std::swap(b, d); - } else { - std::swap(c, e); - } - - if (e < d) { - std::swap(d, e); - - if (f < b) { - if (g < b) { - return b; - } - - return std::min(d, g); - } - - if (g < f) { - std::swap(e, g); - std::swap(f, g); - } else { - std::swap(e, f); - } - - if (e < d) { - return std::min(d, g); - } - - return std::min(e, f); - } - - if (g < f) { - std::swap(c, g); - std::swap(f, g); - } else { - std::swap(c, f); - } - - if (c < d) { - if (g < b) { - return b; - } - - return std::min(d, g); - } - - if (e < c) { - return std::min(e, f); - } - - return std::min(c, f); -} - // middle 4 of 6 elements, #define MIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \ {\ diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 7be671560..fa05e34c3 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -422,18 +422,6 @@ extern const Settings* settings; #define ABS(a) ((a)<0?-(a):(a)) #define DIST(a,b) (ABS(a-b)) -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ -PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ -PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ -PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median - RawImageSource::RawImageSource () : ImageSource() , plistener(NULL) @@ -1333,12 +1321,10 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres #endif for (int i = 2; i < H - 2; i++) { - float p[9], temp; // we need this for med3x3 macro - for (int j = 2; j < W - 2; j++) { - med3x3(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], - rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], - rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2], temp); + const float& temp = median(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], + rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], + rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2]); cfablur[i * W + j] = rawData[i][j] - temp; } } @@ -3039,9 +3025,6 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur jnext = j + 2; } - //med3x3(riFlatFile->data[iprev][jprev], riFlatFile->data[iprev][j], riFlatFile->data[iprev][jnext], - // riFlatFile->data[i][jprev], riFlatFile->data[i][j], riFlatFile->data[i][jnext], - // riFlatFile->data[inext][jprev], riFlatFile->data[inext][j], riFlatFile->data[inext][jnext], cfatmp[i*W+j]); med = median(riFlatFile->data[iprev][j], riFlatFile->data[i][jprev], riFlatFile->data[i][j], riFlatFile->data[i][jnext], riFlatFile->data[inext][j]); // if (riFlatFile->data[i][j]>hotdeadthresh*median || median>hotdeadthresh*riFlatFile->data[i][j]) { @@ -5148,11 +5131,4 @@ void RawImageSource::cleanup () delete phaseOneIccCurveInv; } -#undef PIX_SORT -#undef med3x3 - } /* namespace */ - -#undef PIX_SORT -#undef med3x3 -