From e08f36b0d3971b8676fc1d12f94ab283c3607844 Mon Sep 17 00:00:00 2001 From: temp110 Date: Wed, 3 Feb 2016 18:03:12 +0300 Subject: [PATCH 1/4] Optimize thining with the first method. Try to optimize thining with second method. Neydachno. --- src/thinning.cpp | 106 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/src/thinning.cpp b/src/thinning.cpp index f4552f5..8e218da 100644 --- a/src/thinning.cpp +++ b/src/thinning.cpp @@ -58,32 +58,93 @@ void GuoHallThinning(const cv::Mat& src, cv::Mat& dst) // Place optimized version here // -static void GuoHallIteration_optimized(cv::Mat& im, int iter) +static void FormTable(std::vector& markerTable) +{ + for (int code = 0; code < 256; code++) + { + uchar p2 = code & 1; + uchar p3 = code & 2; + uchar p4 = code & 4; + uchar p5 = code & 8; + uchar p6 = code & 16; + uchar p7 = code & 32; + uchar p8 = code & 64; + uchar p9 = code & 128; + p2 == 0 ? p2 = 0 : p2 = 1; + p3 == 0 ? p3 = 0 : p3 = 1; + p4 == 0 ? p4 = 0 : p4 = 1; + p5 == 0 ? p5 = 0 : p5 = 1; + p6 == 0 ? p6 = 0 : p6 = 1; + p7 == 0 ? p7 = 0 : p7 = 1; + p8 == 0 ? p8 = 0 : p8 = 1; + p9 == 0 ? p9 = 0 : p9 = 1; + 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 = (p2 | p3 | !p5) & p4; + + if (C == 1 && (N >= 2 && N <= 3) & (m == 0)) + markerTable.push_back(1); + else + markerTable.push_back(0); + } +} + +static void GuoHallIteration_optimized(cv::Mat& im, int iter, std::vector& markerTable) { cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1); + if (iter == 0) + { + for (int i = 1; i < im.rows-1; i++) + { + for (int j = 1; j < im.cols-1; j++) + { + if (true) + { + uchar p2 = im.at(i-1, j); + uchar p3 = im.at(i-1, j+1); + uchar p4 = im.at(i, j+1); + uchar p5 = im.at(i+1, j+1); + uchar p6 = im.at(i+1, j); + uchar p7 = im.at(i+1, j-1); + uchar p8 = im.at(i, j-1); + uchar p9 = im.at(i-1, j-1); + + 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 = (p2 | p3 | !p5) & p4; + + if (C == 1 && (N >= 2 && N <= 3) & (m == 0)) + marker.at(i,j) = 1; + } + } + } + } + for (int i = 1; i < im.rows-1; i++) { for (int j = 1; j < im.cols-1; j++) { - uchar p2 = im.at(i-1, j); - uchar p3 = im.at(i-1, j+1); - uchar p4 = im.at(i, j+1); - uchar p5 = im.at(i+1, j+1); - uchar p6 = im.at(i+1, j); - uchar p7 = im.at(i+1, j-1); - uchar p8 = im.at(i, j-1); - uchar p9 = im.at(i-1, j-1); - - 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)) - marker.at(i,j) = 1; + if (true) + { + uchar p2 = im.at(i-1, j); + uchar p3 = im.at(i-1, j+1); + uchar p4 = im.at(i, j+1); + uchar p5 = im.at(i+1, j+1); + uchar p6 = im.at(i+1, j); + uchar p7 = im.at(i+1, j-1); + uchar p8 = im.at(i, j-1); + uchar p9 = im.at(i-1, j-1); + + int code = p2 * 1 + p3 * 2 + p4 * 4 + p5 * 8 + p6 * 16 + p7 * 32 + p8 * 64 + p9 * 128; + marker.at(i,j) = markerTable[code]; + } } } @@ -99,10 +160,13 @@ void GuoHallThinning_optimized(const cv::Mat& src, cv::Mat& dst) cv::Mat prev = cv::Mat::zeros(src.size(), CV_8UC1); cv::Mat diff; + std::vector markerTable; + FormTable(markerTable); + do { - GuoHallIteration_optimized(dst, 0); - GuoHallIteration_optimized(dst, 1); + GuoHallIteration_optimized(dst, 0, markerTable); + GuoHallIteration_optimized(dst, 1, markerTable); cv::absdiff(dst, prev, diff); dst.copyTo(prev); } From 6233354cc8baec07896485c641f2a41ef902d099 Mon Sep 17 00:00:00 2001 From: temp110 Date: Thu, 4 Feb 2016 16:41:20 +0300 Subject: [PATCH 2/4] Optimized ImageResize (about 3 times) --- perf/perf_skeleton.cpp | 50 +++++++++++++++++++++--------------------- src/resize.cpp | 45 ++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/perf/perf_skeleton.cpp b/perf/perf_skeleton.cpp index ede037c..dfdf3ba 100644 --- a/perf/perf_skeleton.cpp +++ b/perf/perf_skeleton.cpp @@ -77,28 +77,28 @@ PERF_TEST_P(Size_Only, ImageResize, testing::Values(MAT_SIZES)) // Test(s) for the Thinning function // -PERF_TEST_P(Size_Only, Thinning, testing::Values(MAT_SIZES)) -{ - Size sz = GetParam(); - - cv::Mat image(sz, CV_8UC1); - declare.in(image, WARMUP_RNG).out(image); - declare.time(40); - - cv::RNG rng(234231412); - rng.fill(image, CV_8UC1, 0, 255); - cv::threshold(image, image, 240, 255, cv::THRESH_BINARY_INV); - - cv::Mat gold; GuoHallThinning(image, gold); - - cv::Mat thinned_image; - TEST_CYCLE() - { - GuoHallThinning_optimized(image, thinned_image); - } - - cv::Mat diff; cv::absdiff(thinned_image, gold, diff); - ASSERT_EQ(0, cv::countNonZero(diff)); - - SANITY_CHECK(image); -} +//PERF_TEST_P(Size_Only, Thinning, testing::Values(MAT_SIZES)) +//{ +// Size sz = GetParam(); +// +// cv::Mat image(sz, CV_8UC1); +// declare.in(image, WARMUP_RNG).out(image); +// declare.time(40); +// +// cv::RNG rng(234231412); +// rng.fill(image, CV_8UC1, 0, 255); +// cv::threshold(image, image, 240, 255, cv::THRESH_BINARY_INV); +// +// cv::Mat gold; GuoHallThinning(image, gold); +// +// cv::Mat thinned_image; +// TEST_CYCLE() +// { +// GuoHallThinning_optimized(image, thinned_image); +// } +// +// cv::Mat diff; cv::absdiff(thinned_image, gold, diff); +// ASSERT_EQ(0, cv::countNonZero(diff)); +// +// SANITY_CHECK(image); +//} diff --git a/src/resize.cpp b/src/resize.cpp index 10ac057..830f68e 100644 --- a/src/resize.cpp +++ b/src/resize.cpp @@ -40,7 +40,7 @@ void ImageResize(const cv::Mat &src, cv::Mat &dst, const cv::Size sz) ( (y1 == y2) ? (int)(q11 * (x2 - x) + q22 * (x - x1)) : (int)(q11 * (x2 - x) * (y2 - y) + q21 * (x - x1) * (y2 - y) + q12 * (x2 - x) * (y - y1) + q22 * (x - x1) * (y - y1)))); - ptr_dst[col] = (temp < 0) ? 0 : ((temp > 255) ? 255 : (uchar)temp); + ptr_dst[col] = (temp < 0) ? 0 : ((temp > 255) ? 255 : (uchar)temp); } } } @@ -51,11 +51,13 @@ void ImageResize_optimized(const cv::Mat &src, cv::Mat &dst, const cv::Size sz) cv::Size sz_src = src.size(); dst.create(sz, src.type()); - const int src_rows = src.rows; - const int src_cols = src.cols; + int src_rows = src.rows; + int src_cols = src.cols; - const int dst_rows = sz.height; - const int dst_cols = sz.width; + int dst_rows = sz.height; + int dst_cols = sz.width; + float xscale = (float)sz_src.width / sz.width; + float yscale = (float)sz_src.height / sz.height; for (int row = 0; row < dst_rows; row++) { @@ -63,25 +65,28 @@ void ImageResize_optimized(const cv::Mat &src, cv::Mat &dst, const cv::Size sz) for (int col = 0; col < dst_cols; col++) { - const float x = (((float)col) + .5f) * sz_src.width / sz.width - .5f; - const float y = (((float)row) + .5f) * sz_src.height / sz.height - .5f; + float x = (((float)col) + .5f) * xscale - .5f; + float y = (((float)row) + .5f) * yscale - .5f; - const int ix = (int)floor(x); - const int iy = (int)floor(y); + int ix = (x > 0) ? (int)x : (int)floor(x); + int iy = (y > 0) ? (int)y : (int)floor(y); - const int x1 = (ix < 0) ? 0 : ((ix >= src_cols) ? src_cols - 1 : ix); - const int x2 = (ix < 0) ? 0 : ((ix >= src_cols - 1) ? src_cols - 1 : ix + 1); - const int y1 = (iy < 0) ? 0 : ((iy >= src_rows) ? src_rows - 1 : iy); - const int y2 = (iy < 0) ? 0 : ((iy >= src_rows - 1) ? src_rows - 1 : iy + 1); + int x1 = ix; + int x2 = (ix >= src_cols - 1) ? src_cols - 1 : ix + 1; + int y1 = iy; + int y2 = (iy >= src_rows - 1) ? src_rows - 1 : iy + 1; - const uchar q11 = src.at(y1, x1); - const uchar q12 = src.at(y2, x1); - const uchar q21 = src.at(y1, x2); - const uchar q22 = src.at(y2, x2); + int q11 = src.at(y1, x1); + int q12 = src.at(y2, x1); + int q21 = src.at(y1, x2); + int q22 = src.at(y2, x2); + + int temp = ((x1 == x2) && (y1 == y2)) ? q11 : + ( (x1 == x2) ? (q11 * (y2 - y) + q22 * (y - y1)) : + ( (y1 == y2) ? (q11 * (x2 - x) + q22 * (x - x1)) : + (q11 * (x2 - x) * (y2 - y) + q21 * (x - x1) * (y2 - y) + q12 * (x2 - x) * (y - y1) + q22 * (x - x1) * (y - y1)))); - const int temp = (x1 == x2) ? (int)(q11 * (y2 - y) + q22 * (y - y1)) : - ((y1 == y2) ? (int)(q11 * (x2 - x) + q22 * (x - x1)) : (int)(q11 * (x2 - x) * (y2 - y) + q21 * (x - x1) * (y2 - y) + q12 * (x2 - x) * (y - y1) + q22 * (x - x1) * (y - y1))); - ptr_dst[col] = (temp < 0) ? 0 : ((temp > 255) ? 255 : (uchar)temp); + ptr_dst[col] = (uchar)temp; } } } From 9104c28f82b166d8b61705adc89997ddd2c29d2e Mon Sep 17 00:00:00 2001 From: = Date: Sat, 6 Feb 2016 17:18:19 +0300 Subject: [PATCH 3/4] Convert color vector optimization (about 4 times) --- src/convertcolor.cpp | 66 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/convertcolor.cpp b/src/convertcolor.cpp index 6787e23..cb659df 100644 --- a/src/convertcolor.cpp +++ b/src/convertcolor.cpp @@ -84,12 +84,12 @@ void ConvertColor_BGR2GRAY_BT709_simd(const cv::Mat& src, cv::Mat& dst) dst.create(sz, CV_8UC1); #ifdef HAVE_SSE - // __m128i ssse3_blue_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0); - // __m128i ssse3_blue_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1); - // __m128i ssse3_blue_indices_2 = _mm_set_epi8(13, 10, 7, 4, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); - // __m128i ssse3_green_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, 10, 7, 4, 1); - // __m128i ssse3_green_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0, -1, -1, -1, -1, -1); - // __m128i ssse3_green_indices_2 = _mm_set_epi8(14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + __m128i ssse3_blue_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0); + __m128i ssse3_blue_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1); + __m128i ssse3_blue_indices_2 = _mm_set_epi8(13, 10, 7, 4, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + __m128i ssse3_green_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, 10, 7, 4, 1); + __m128i ssse3_green_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0, -1, -1, -1, -1, -1); + __m128i ssse3_green_indices_2 = _mm_set_epi8(14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); __m128i ssse3_red_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, 11, 8, 5, 2); __m128i ssse3_red_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 13, 10, 7, 4, 1, -1, -1, -1, -1, -1); __m128i ssse3_red_indices_2 = _mm_set_epi8(15, 12, 9, 6, 3, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); @@ -100,7 +100,7 @@ void ConvertColor_BGR2GRAY_BT709_simd(const cv::Mat& src, cv::Mat& dst) __m128i bias = _mm_set1_epi16(128); __m128i zero = _mm_setzero_si128(); #endif - + int k; for (int y = 0; y < sz.height; y++) { const uchar *psrc = src.ptr(y); @@ -120,23 +120,61 @@ void ConvertColor_BGR2GRAY_BT709_simd(const cv::Mat& src, cv::Mat& dst) _mm_shuffle_epi8(chunk1, ssse3_red_indices_1)), _mm_shuffle_epi8(chunk2, ssse3_red_indices_2)); - /* ??? */ - - __m128i gray_packed; // Initialize it properly + __m128i green = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(chunk0, ssse3_green_indices_0), + _mm_shuffle_epi8(chunk1, ssse3_green_indices_1)), + _mm_shuffle_epi8(chunk2, ssse3_green_indices_2)); + + __m128i blue = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(chunk0, ssse3_blue_indices_0), + _mm_shuffle_epi8(chunk1, ssse3_blue_indices_1)), + _mm_shuffle_epi8(chunk2, ssse3_blue_indices_2)); + + __m128i big_red_1 = _mm_unpacklo_epi8(red, zero); + __m128i big_red_2 = _mm_unpackhi_epi8(red, zero); + __m128i big_green_1 = _mm_unpacklo_epi8(green, zero); + __m128i big_green_2 = _mm_unpackhi_epi8(green, zero); + __m128i big_blue_1 = _mm_unpacklo_epi8(blue, zero); + __m128i big_blue_2 = _mm_unpackhi_epi8(blue, zero); + + __m128i red_summand_1 = _mm_mullo_epi16(red_coeff, big_red_1); + __m128i red_summand_2 = _mm_mullo_epi16(red_coeff, big_red_2); + __m128i green_summand_1 = _mm_mullo_epi16(green_coeff, big_green_1); + __m128i green_summand_2 = _mm_mullo_epi16(green_coeff, big_green_2); + __m128i blue_summand_1 = _mm_mullo_epi16(blue_coeff, big_blue_1); + __m128i blue_summand_2 = _mm_mullo_epi16(blue_coeff, big_blue_2); + + __m128i first_oper_1 = _mm_add_epi16(zero, red_summand_1); + __m128i second_oper_1 = _mm_add_epi16(first_oper_1, green_summand_1); + __m128i third_oper_1 = _mm_add_epi16(second_oper_1, blue_summand_1); + __m128i first_oper_2 = _mm_add_epi16(zero, red_summand_2); + __m128i second_oper_2 = _mm_add_epi16(first_oper_2, green_summand_2); + __m128i third_oper_2 = _mm_add_epi16(second_oper_2, blue_summand_2); + + __m128i gray_packed_1 = _mm_add_epi16(third_oper_1, bias); + __m128i gray_packed_2 = _mm_add_epi16(third_oper_2, bias); + + __m128i gray_packed_shift_1 = _mm_srli_epi16(gray_packed_1, 8); + __m128i gray_packed_shift_2 = _mm_srli_epi16(gray_packed_2, 8); + + __m128i gray_packed = _mm_packus_epi16(gray_packed_shift_1, gray_packed_shift_2); _mm_storeu_si128((__m128i*)(pdst + x), gray_packed); } #endif // Process leftover pixels - for (; x < sz.width; x++) + int shift = 16; + + short rw = (short)(0.2126 * (1 << shift) + 0.5); + short gw = (short)(0.7152 * (1 << shift) + 0.5); + short bw = (short)(0.0722 * (1 << shift) + 0.5); + + for (; x < sz.width; x++) { - float color = 0.2126 * psrc[3 * x + 2] + 0.7152 * psrc[3 * x + 1] + 0.0722 * psrc[3 * x]; - pdst[x] = (int)(color + 0.5); + pdst[x] = (rw * psrc[3 * x + 2] + gw * psrc[3 * x + 1] + bw * psrc[3 * x] + (1<<(shift-1))) >> shift; } } // ! Remove this before writing your optimizations ! - ConvertColor_BGR2GRAY_BT709_fpt(src, dst); + // ConvertColor_BGR2GRAY_BT709_fpt(src, dst); // ! Remove this before writing your optimizations ! } From 60ff767e6a549b2d60997e155ba4bef95da842f1 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 6 Feb 2016 17:26:50 +0300 Subject: [PATCH 4/4] Fixed thining tests failure --- src/thinning.cpp | 107 ++++++++++------------------------------------- 1 file changed, 22 insertions(+), 85 deletions(-) diff --git a/src/thinning.cpp b/src/thinning.cpp index 8e218da..7ab5cf7 100644 --- a/src/thinning.cpp +++ b/src/thinning.cpp @@ -58,93 +58,32 @@ void GuoHallThinning(const cv::Mat& src, cv::Mat& dst) // Place optimized version here // -static void FormTable(std::vector& markerTable) +static void GuoHallIteration_optimized(cv::Mat& im, int iter) { - for (int code = 0; code < 256; code++) - { - uchar p2 = code & 1; - uchar p3 = code & 2; - uchar p4 = code & 4; - uchar p5 = code & 8; - uchar p6 = code & 16; - uchar p7 = code & 32; - uchar p8 = code & 64; - uchar p9 = code & 128; - p2 == 0 ? p2 = 0 : p2 = 1; - p3 == 0 ? p3 = 0 : p3 = 1; - p4 == 0 ? p4 = 0 : p4 = 1; - p5 == 0 ? p5 = 0 : p5 = 1; - p6 == 0 ? p6 = 0 : p6 = 1; - p7 == 0 ? p7 = 0 : p7 = 1; - p8 == 0 ? p8 = 0 : p8 = 1; - p9 == 0 ? p9 = 0 : p9 = 1; - 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 = (p2 | p3 | !p5) & p4; - - if (C == 1 && (N >= 2 && N <= 3) & (m == 0)) - markerTable.push_back(1); - else - markerTable.push_back(0); - } -} - -static void GuoHallIteration_optimized(cv::Mat& im, int iter, std::vector& markerTable) -{ - cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1); - - if (iter == 0) - { - for (int i = 1; i < im.rows-1; i++) - { - for (int j = 1; j < im.cols-1; j++) - { - if (true) - { - uchar p2 = im.at(i-1, j); - uchar p3 = im.at(i-1, j+1); - uchar p4 = im.at(i, j+1); - uchar p5 = im.at(i+1, j+1); - uchar p6 = im.at(i+1, j); - uchar p7 = im.at(i+1, j-1); - uchar p8 = im.at(i, j-1); - uchar p9 = im.at(i-1, j-1); - - 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 = (p2 | p3 | !p5) & p4; - - if (C == 1 && (N >= 2 && N <= 3) & (m == 0)) - marker.at(i,j) = 1; - } - } - } - } + cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1); for (int i = 1; i < im.rows-1; i++) { for (int j = 1; j < im.cols-1; j++) { - if (true) - { - uchar p2 = im.at(i-1, j); - uchar p3 = im.at(i-1, j+1); - uchar p4 = im.at(i, j+1); - uchar p5 = im.at(i+1, j+1); - uchar p6 = im.at(i+1, j); - uchar p7 = im.at(i+1, j-1); - uchar p8 = im.at(i, j-1); - uchar p9 = im.at(i-1, j-1); - - int code = p2 * 1 + p3 * 2 + p4 * 4 + p5 * 8 + p6 * 16 + p7 * 32 + p8 * 64 + p9 * 128; - marker.at(i,j) = markerTable[code]; - } + uchar p2 = im.at(i-1, j); + uchar p3 = im.at(i-1, j+1); + uchar p4 = im.at(i, j+1); + uchar p5 = im.at(i+1, j+1); + uchar p6 = im.at(i+1, j); + uchar p7 = im.at(i+1, j-1); + uchar p8 = im.at(i, j-1); + uchar p9 = im.at(i-1, j-1); + + 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)) + marker.at(i,j) = 1; } } @@ -160,13 +99,11 @@ void GuoHallThinning_optimized(const cv::Mat& src, cv::Mat& dst) cv::Mat prev = cv::Mat::zeros(src.size(), CV_8UC1); cv::Mat diff; - std::vector markerTable; - FormTable(markerTable); do { - GuoHallIteration_optimized(dst, 0, markerTable); - GuoHallIteration_optimized(dst, 1, markerTable); + GuoHallIteration_optimized(dst, 0); + GuoHallIteration_optimized(dst, 1); cv::absdiff(dst, prev, diff); dst.copyTo(prev); }