Skip to content

Commit 4d657c7

Browse files
committed
ansleliu's code (pull/3750)
1 parent c889698 commit 4d657c7

File tree

1 file changed

+28
-89
lines changed

1 file changed

+28
-89
lines changed

modules/ximgproc/src/thinning.cpp

+28-89
Original file line numberDiff line numberDiff line change
@@ -92,94 +92,35 @@ static uint8_t lut_guo_iter1[] = {
9292
1, 1, 1, 1};
9393

9494
// Applies a thinning iteration to a binary image
95-
static void thinningIteration(Mat img, int iter, int thinningType){
96-
Mat marker = Mat::zeros(img.size(), CV_8UC1);
95+
static void thinningIteration(Mat &img, Mat &marker, const uint8_t* const lut) {
9796
int rows = img.rows;
9897
int cols = img.cols;
9998
marker.col(0).setTo(1);
10099
marker.col(cols - 1).setTo(1);
101100
marker.row(0).setTo(1);
102101
marker.row(rows - 1).setTo(1);
103102

104-
if(thinningType == THINNING_ZHANGSUEN){
105-
marker.forEach<uchar>([=](uchar& value, const int postion[]) {
106-
int i = postion[0];
107-
int j = postion[1];
108-
if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1)
109-
return;
110-
111-
auto ptr = img.ptr(i, j); // p1
112-
113-
// p9 p2 p3
114-
// p8 p1 p4
115-
// p7 p6 p5
116-
uchar p2 = ptr[-cols];
117-
uchar p3 = ptr[-cols + 1];
118-
uchar p4 = ptr[1];
119-
uchar p5 = ptr[cols + 1];
120-
uchar p6 = ptr[cols];
121-
uchar p7 = ptr[cols - 1];
122-
uchar p8 = ptr[-1];
123-
uchar p9 = ptr[-cols - 1];
124-
125-
int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7);
126-
127-
if (iter == 0)
128-
value = lut_zhang_iter0[neighbors];
129-
else
130-
value = lut_zhang_iter1[neighbors];
131-
132-
//int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) +
133-
// (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) +
134-
// (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
135-
// (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
136-
//int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
137-
//int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
138-
//int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);
139-
//if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0) value = 0;
140-
// else value = 1;
141-
});
142-
}
143-
if(thinningType == THINNING_GUOHALL){
144-
marker.forEach<uchar>([=](uchar& value, const int postion[]) {
145-
int i = postion[0];
146-
int j = postion[1];
147-
if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1)
148-
return;
149-
150-
auto ptr = img.ptr(i, j); // p1
151-
152-
// p9 p2 p3
153-
// p8 p1 p4
154-
// p7 p6 p5
155-
uchar p2 = ptr[-cols];
156-
uchar p3 = ptr[-cols + 1];
157-
uchar p4 = ptr[1];
158-
uchar p5 = ptr[cols + 1];
159-
uchar p6 = ptr[cols];
160-
uchar p7 = ptr[cols - 1];
161-
uchar p8 = ptr[-1];
162-
uchar p9 = ptr[-cols - 1];
163-
164-
int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7);
165-
166-
if (iter == 0)
167-
value = lut_guo_iter0[neighbors];
168-
else
169-
value = lut_guo_iter1[neighbors];
170-
171-
//int C = ((!p2) & (p3 | p4)) + ((!p4) & (p5 | p6)) +
172-
// ((!p6) & (p7 | p8)) + ((!p8) & (p9 | p2));
173-
//int N1 = (p9 | p2) + (p3 | p4) + (p5 | p6) + (p7 | p8);
174-
//int N2 = (p2 | p3) + (p4 | p5) + (p6 | p7) + (p8 | p9);
175-
//int N = N1 < N2 ? N1 : N2;
176-
//int m = iter == 0 ? ((p6 | p7 | (!p9)) & p8) : ((p2 | p3 | (!p5)) & p4);
177-
//if ((C == 1) && ((N >= 2) && ((N <= 3)) & (m == 0))) value = 0;
178-
// else value = 1;
179-
});
180-
}
103+
marker.forEach<uchar>([=](uchar& value, const int postion[]) {
104+
int i = postion[0];
105+
int j = postion[1];
106+
if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1) { return; }
107+
108+
auto ptr = img.ptr(i, j); // p1
109+
uchar p2 = ptr[-cols];
110+
uchar p3 = ptr[-cols + 1];
111+
uchar p4 = ptr[1];
112+
uchar p5 = ptr[cols + 1];
113+
uchar p6 = ptr[cols];
114+
uchar p7 = ptr[cols - 1];
115+
uchar p8 = ptr[-1];
116+
uchar p9 = ptr[-cols - 1];
117+
118+
int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7);
119+
value = lut[neighbors];
120+
});
181121

182122
img &= marker;
123+
marker.setTo(0);
183124
}
184125

185126
// Apply the thinning procedure to a given image
@@ -188,21 +129,19 @@ void thinning(InputArray input, OutputArray output, int thinningType){
188129
CV_CheckTypeEQ(processed.type(), CV_8UC1, "");
189130
// Enforce the range of the input image to be in between 0 - 255
190131
processed /= 255;
191-
192132
Mat prev = processed.clone();
193-
Mat diff;
194-
133+
Mat marker = Mat::zeros(processed.size(), CV_8UC1);
134+
const auto lutIter0 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter0 : lut_zhang_iter0;
135+
const auto lutIter1 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter1 : lut_zhang_iter1;
195136
do {
196-
thinningIteration(processed, 0, thinningType);
197-
thinningIteration(processed, 1, thinningType);
198-
absdiff(processed, prev, diff);
199-
if (!hasNonZero(diff)) break;
137+
thinningIteration(processed, marker, lutIter0);
138+
thinningIteration(processed, marker, lutIter1);
139+
const auto res = cv::norm(processed, prev, cv::NORM_L1);
140+
if (res <= 0) { break; }
200141
processed.copyTo(prev);
201-
}
202-
while (true);
142+
} while (true);
203143

204144
processed *= 255;
205-
206145
output.assign(processed);
207146
}
208147

0 commit comments

Comments
 (0)