mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
geometry: fix boundingRect throwing for boolean masks
In 5.0 cv::Mat_<bool>::depth() returns CV_Bool instead of CV_8U, so boundingRect routed boolean masks into pointSetBoundingRect, which expects a CV_32S/CV_32F point set and threw. CV_Bool is a 1-byte 0/1 mask type, so handle it like CV_8U/CV_8S via the byte-wise maskBoundingRect path.
This commit is contained in:
@@ -504,7 +504,7 @@ double arcLength( InputArray _curve, bool is_closed )
|
||||
|
||||
static Rect maskBoundingRect( const Mat& img )
|
||||
{
|
||||
CV_Assert( img.depth() <= CV_8S && img.channels() == 1 );
|
||||
CV_Assert( (img.depth() <= CV_8S || img.depth() == CV_Bool) && img.channels() == 1 );
|
||||
|
||||
Size size = img.size();
|
||||
int xmin = size.width, ymin = -1, xmax = -1, ymax = -1, i, j, k;
|
||||
@@ -709,7 +709,10 @@ cv::Rect boundingRect(InputArray array)
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat m = array.getMat();
|
||||
return m.depth() <= CV_8U ? maskBoundingRect(m) : pointSetBoundingRect(m);
|
||||
// CV_Bool is a 1-byte mask type (added in 5.0); route it through the
|
||||
// byte-wise mask path, same as CV_8U/CV_8S. See #29578.
|
||||
int depth = m.depth();
|
||||
return (depth <= CV_8U || depth == CV_Bool) ? maskBoundingRect(m) : pointSetBoundingRect(m);
|
||||
}
|
||||
|
||||
cv::Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale)
|
||||
|
||||
@@ -96,4 +96,31 @@ TEST(Imgproc_BoundingRect, bug_24217)
|
||||
}
|
||||
}
|
||||
|
||||
// See https://github.com/opencv/opencv/issues/29578
|
||||
// cv::Mat_<bool>::depth() returns CV_Bool in 5.0, which regressed boundingRect
|
||||
// (it used to be treated as CV_8U in 4.x). A boolean mask must be handled as a
|
||||
// byte-wise mask, matching the CV_8UC1 result.
|
||||
TEST(Imgproc_BoundingRect, bool_mask_29578)
|
||||
{
|
||||
for (int image_width = 3; image_width < 20; image_width++)
|
||||
{
|
||||
for (int image_height = 1; image_height < 15; image_height++)
|
||||
{
|
||||
cv::Rect rect(0, image_height - 1, 3, 1);
|
||||
|
||||
cv::Mat_<bool> mask(cv::Size(image_width, image_height), false);
|
||||
mask(rect).setTo(true);
|
||||
|
||||
cv::Mat_<uchar> ref(cv::Size(image_width, image_height), (uchar)0);
|
||||
ref(rect).setTo(255);
|
||||
|
||||
EXPECT_EQ(mask.depth(), CV_Bool);
|
||||
cv::Rect result;
|
||||
ASSERT_NO_THROW(result = boundingRect(mask));
|
||||
EXPECT_EQ(result, rect);
|
||||
EXPECT_EQ(result, boundingRect(ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user