From fc18abefc46ccb839a5cf6c122469ac17b9339f8 Mon Sep 17 00:00:00 2001 From: Huijun Liu/John Liu Date: Fri, 31 May 2024 11:28:29 +0800 Subject: [PATCH 1/2] use norm_l1 to replace absdiff --- modules/ximgproc/src/thinning.cpp | 36 +++---------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/modules/ximgproc/src/thinning.cpp b/modules/ximgproc/src/thinning.cpp index 76e8ad15425..43d00de46ca 100644 --- a/modules/ximgproc/src/thinning.cpp +++ b/modules/ximgproc/src/thinning.cpp @@ -110,9 +110,6 @@ static void thinningIteration(Mat img, int iter, int thinningType){ auto ptr = img.ptr(i, j); // p1 - // p9 p2 p3 - // p8 p1 p4 - // p7 p6 p5 uchar p2 = ptr[-cols]; uchar p3 = ptr[-cols + 1]; uchar p4 = ptr[1]; @@ -128,16 +125,6 @@ static void thinningIteration(Mat img, int iter, int thinningType){ value = lut_zhang_iter0[neighbors]; else value = lut_zhang_iter1[neighbors]; - - //int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + - // (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + - // (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) + - // (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1); - //int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9; - //int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8); - //int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8); - //if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0) value = 0; - // else value = 1; }); } if(thinningType == THINNING_GUOHALL){ @@ -149,9 +136,6 @@ static void thinningIteration(Mat img, int iter, int thinningType){ auto ptr = img.ptr(i, j); // p1 - // p9 p2 p3 - // p8 p1 p4 - // p7 p6 p5 uchar p2 = ptr[-cols]; uchar p3 = ptr[-cols + 1]; uchar p4 = ptr[1]; @@ -167,15 +151,6 @@ static void thinningIteration(Mat img, int iter, int thinningType){ value = lut_guo_iter0[neighbors]; else value = lut_guo_iter1[neighbors]; - - //int C = ((!p2) & (p3 | p4)) + ((!p4) & (p5 | p6)) + - // ((!p6) & (p7 | p8)) + ((!p8) & (p9 | p2)); - //int N1 = (p9 | p2) + (p3 | p4) + (p5 | p6) + (p7 | p8); - //int N2 = (p2 | p3) + (p4 | p5) + (p6 | p7) + (p8 | p9); - //int N = N1 < N2 ? N1 : N2; - //int m = iter == 0 ? ((p6 | p7 | (!p9)) & p8) : ((p2 | p3 | (!p5)) & p4); - //if ((C == 1) && ((N >= 2) && ((N <= 3)) & (m == 0))) value = 0; - // else value = 1; }); } @@ -188,21 +163,16 @@ void thinning(InputArray input, OutputArray output, int thinningType){ CV_CheckTypeEQ(processed.type(), CV_8UC1, ""); // Enforce the range of the input image to be in between 0 - 255 processed /= 255; - Mat prev = processed.clone(); - Mat diff; - do { thinningIteration(processed, 0, thinningType); thinningIteration(processed, 1, thinningType); - absdiff(processed, prev, diff); - if (!hasNonZero(diff)) break; + const auto res = cv::norm(processed, prev, cv::NORM_L1); + if (res <= 0) { break; } processed.copyTo(prev); - } - while (true); + } while (true); processed *= 255; - output.assign(processed); } From e881f951ef39ada490a181988c8463b0a03b1a25 Mon Sep 17 00:00:00 2001 From: Huijun Liu/John Liu Date: Fri, 31 May 2024 11:42:13 +0800 Subject: [PATCH 2/2] remove marker form thinningIteration and remove "if" from forEach --- modules/ximgproc/src/thinning.cpp | 81 ++++++++++--------------------- 1 file changed, 25 insertions(+), 56 deletions(-) diff --git a/modules/ximgproc/src/thinning.cpp b/modules/ximgproc/src/thinning.cpp index 43d00de46ca..abd71e76e27 100644 --- a/modules/ximgproc/src/thinning.cpp +++ b/modules/ximgproc/src/thinning.cpp @@ -92,8 +92,7 @@ static uint8_t lut_guo_iter1[] = { 1, 1, 1, 1}; // Applies a thinning iteration to a binary image -static void thinningIteration(Mat img, int iter, int thinningType){ - Mat marker = Mat::zeros(img.size(), CV_8UC1); +static void thinningIteration(Mat &img, Mat &marker, const uint8_t* const lut) { int rows = img.rows; int cols = img.cols; marker.col(0).setTo(1); @@ -101,60 +100,27 @@ static void thinningIteration(Mat img, int iter, int thinningType){ marker.row(0).setTo(1); marker.row(rows - 1).setTo(1); - if(thinningType == THINNING_ZHANGSUEN){ - marker.forEach([=](uchar& value, const int postion[]) { - int i = postion[0]; - int j = postion[1]; - if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1) - return; - - auto ptr = img.ptr(i, j); // p1 - - uchar p2 = ptr[-cols]; - uchar p3 = ptr[-cols + 1]; - uchar p4 = ptr[1]; - uchar p5 = ptr[cols + 1]; - uchar p6 = ptr[cols]; - uchar p7 = ptr[cols - 1]; - uchar p8 = ptr[-1]; - uchar p9 = ptr[-cols - 1]; - - int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7); - - if (iter == 0) - value = lut_zhang_iter0[neighbors]; - else - value = lut_zhang_iter1[neighbors]; - }); - } - if(thinningType == THINNING_GUOHALL){ - marker.forEach([=](uchar& value, const int postion[]) { - int i = postion[0]; - int j = postion[1]; - if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1) - return; - - auto ptr = img.ptr(i, j); // p1 - - uchar p2 = ptr[-cols]; - uchar p3 = ptr[-cols + 1]; - uchar p4 = ptr[1]; - uchar p5 = ptr[cols + 1]; - uchar p6 = ptr[cols]; - uchar p7 = ptr[cols - 1]; - uchar p8 = ptr[-1]; - uchar p9 = ptr[-cols - 1]; - - int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7); - - if (iter == 0) - value = lut_guo_iter0[neighbors]; - else - value = lut_guo_iter1[neighbors]; - }); - } + marker.forEach([=](uchar& value, const int postion[]) { + int i = postion[0]; + int j = postion[1]; + if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1) { return; } + + auto ptr = img.ptr(i, j); // p1 + uchar p2 = ptr[-cols]; + uchar p3 = ptr[-cols + 1]; + uchar p4 = ptr[1]; + uchar p5 = ptr[cols + 1]; + uchar p6 = ptr[cols]; + uchar p7 = ptr[cols - 1]; + uchar p8 = ptr[-1]; + uchar p9 = ptr[-cols - 1]; + + int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7); + value = lut[neighbors]; + }); img &= marker; + marker.setTo(0); } // Apply the thinning procedure to a given image @@ -164,9 +130,12 @@ void thinning(InputArray input, OutputArray output, int thinningType){ // Enforce the range of the input image to be in between 0 - 255 processed /= 255; Mat prev = processed.clone(); + Mat marker = Mat::zeros(processed.size(), CV_8UC1); + const auto lutIter0 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter0 : lut_zhang_iter0; + const auto lutIter1 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter1 : lut_zhang_iter1; do { - thinningIteration(processed, 0, thinningType); - thinningIteration(processed, 1, thinningType); + thinningIteration(processed, marker, lutIter0); + thinningIteration(processed, marker, lutIter1); const auto res = cv::norm(processed, prev, cv::NORM_L1); if (res <= 0) { break; } processed.copyTo(prev);