/*
trace contour until certain point is met.
- returns 1 if met, 0 else.
+ returns 1 if met and this is the last contour
+ encountered by a raster scan reaching the point, 0 else.
*/
static int
icvTraceContour( schar *ptr, int step, schar *stop_ptr, int is_hole )
break;
}
- if( i3 == stop_ptr || (i4 == i0 && i3 == i1) )
+ if (i3 == stop_ptr) {
+ if (!(*i3 & 0x80)) {
+ /* it's the only contour */
+ return 1;
+ }
+
+ /* check if this is the last contour */
+ /* encountered during a raster scan */
+ schar *i5;
+ int t = s;
+ while (true)
+ {
+ t = (t - 1) & 7;
+ i5 = i3 + deltas[t];
+ if (*i5 != 0)
+ break;
+ if (t == 0)
+ return 1;
+ }
+ }
+
+ if( (i4 == i0 && i3 == i1) )
break;
i3 = i4;
s = (s + 4) & 7;
} /* end of border following loop */
}
- return i3 == stop_ptr;
+ else {
+ return i3 == stop_ptr;
+ }
+
+ return 0;
}
ASSERT_EQ(0, cvtest::norm(img, img_draw_contours, NORM_INF));
}
+TEST(Imgproc_FindContours, regression_4363_shared_nbd)
+{
+ // Create specific test image
+ Mat1b img(12, 69, (const uchar&)0);
+
+ img(1, 1) = 1;
+
+ // Vertical rectangle with hole sharing the same NBD
+ for (int r = 1; r <= 10; ++r) {
+ for (int c = 3; c <= 5; ++c) {
+ img(r, c) = 1;
+ }
+ }
+ img(9, 4) = 0;
+
+ // 124 small CCs
+ for (int r = 1; r <= 7; r += 2) {
+ for (int c = 7; c <= 67; c += 2) {
+ img(r, c) = 1;
+ }
+ }
+
+ // Last CC
+ img(9, 7) = 1;
+
+ vector< vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+ findContours(img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
+
+ bool found = false;
+ size_t index = 0;
+ for (vector< vector<Point> >::const_iterator i = contours.begin(); i != contours.end(); ++i)
+ {
+ const vector<Point>& c = *i;
+ if (!c.empty() && c[0] == Point(7, 9))
+ {
+ found = true;
+ index = (size_t)(i - contours.begin());
+ break;
+ }
+ }
+ EXPECT_TRUE(found) << "Desired result: point (7,9) is a contour - Actual result: point (7,9) is not a contour";
+
+ if (found)
+ {
+ EXPECT_LT(hierarchy[index][3], 0) << "Desired result: (7,9) has no parent - Actual result: parent of (7,9) is another contour. index = " << index;
+ }
+}
+
TEST(Imgproc_PointPolygonTest, regression_10222)
{
vector<Point> contour;