mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-18 08:44:11 +08:00
Merge pull request #3743 from vrabaud:thinning
Misc thinning fixes. #3743 - edges could be modified - 2 sets of iterations were always done even if the first set did not return any change - countNonZero is slow compared to hasNonZero ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name.
This commit is contained in:
@@ -96,6 +96,10 @@ static void thinningIteration(Mat img, int iter, int thinningType){
|
||||
Mat marker = Mat::zeros(img.size(), CV_8UC1);
|
||||
int rows = img.rows;
|
||||
int cols = img.cols;
|
||||
marker.col(0).setTo(1);
|
||||
marker.col(cols - 1).setTo(1);
|
||||
marker.row(0).setTo(1);
|
||||
marker.row(rows - 1).setTo(1);
|
||||
|
||||
if(thinningType == THINNING_ZHANGSUEN){
|
||||
marker.forEach<uchar>([=](uchar& value, const int postion[]) {
|
||||
@@ -133,6 +137,7 @@ static void thinningIteration(Mat img, int iter, int thinningType){
|
||||
//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){
|
||||
@@ -170,6 +175,7 @@ static void thinningIteration(Mat img, int iter, int thinningType){
|
||||
//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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -183,16 +189,17 @@ 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 = Mat::zeros(processed.size(), CV_8UC1);
|
||||
Mat prev = processed.clone();
|
||||
Mat diff;
|
||||
|
||||
do {
|
||||
thinningIteration(processed, 0, thinningType);
|
||||
thinningIteration(processed, 1, thinningType);
|
||||
absdiff(processed, prev, diff);
|
||||
if (!hasNonZero(diff)) break;
|
||||
processed.copyTo(prev);
|
||||
}
|
||||
while (countNonZero(diff) > 0);
|
||||
while (true);
|
||||
|
||||
processed *= 255;
|
||||
|
||||
|
@@ -6,9 +6,12 @@
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static int createTestImage(Mat& src)
|
||||
static int createTestImage(Mat1b& src)
|
||||
{
|
||||
src = Mat::zeros(Size(256, 256), CV_8UC1);
|
||||
src = Mat1b::zeros(Size(256, 256));
|
||||
// Create a corner point that should not be affected.
|
||||
src(0, 0) = 255;
|
||||
|
||||
for (int x = 50; x < src.cols - 50; x += 50)
|
||||
{
|
||||
cv::circle(src, Point(x, x/2), 30 + x/2, Scalar(255), 5);
|
||||
@@ -20,13 +23,14 @@ static int createTestImage(Mat& src)
|
||||
|
||||
TEST(ximgproc_Thinning, simple_ZHANGSUEN)
|
||||
{
|
||||
Mat src;
|
||||
Mat1b src;
|
||||
int src_pixels = createTestImage(src);
|
||||
|
||||
Mat dst;
|
||||
Mat1b dst;
|
||||
thinning(src, dst, THINNING_ZHANGSUEN);
|
||||
int dst_pixels = countNonZero(dst);
|
||||
EXPECT_LE(dst_pixels, src_pixels);
|
||||
EXPECT_EQ(dst(0, 0), 255);
|
||||
|
||||
#if 0
|
||||
imshow("src", src); imshow("dst", dst); waitKey();
|
||||
@@ -35,13 +39,14 @@ TEST(ximgproc_Thinning, simple_ZHANGSUEN)
|
||||
|
||||
TEST(ximgproc_Thinning, simple_GUOHALL)
|
||||
{
|
||||
Mat src;
|
||||
Mat1b src;
|
||||
int src_pixels = createTestImage(src);
|
||||
|
||||
Mat dst;
|
||||
Mat1b dst;
|
||||
thinning(src, dst, THINNING_GUOHALL);
|
||||
int dst_pixels = countNonZero(dst);
|
||||
EXPECT_LE(dst_pixels, src_pixels);
|
||||
EXPECT_EQ(dst(0, 0), 255);
|
||||
|
||||
#if 0
|
||||
imshow("src", src); imshow("dst", dst); waitKey();
|
||||
|
Reference in New Issue
Block a user