Merge pull request #19842 from gasparitiago:3.4

Update rotatedRectangleIntersection function to calculate near to origin

* Change type used in points function from RotatedRect

In the function that sets the points of a RotatedRect, the types

should be double in order to keep the precision when dealing with
RotatedRects that are defined far from the origin.

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* added proper type casts

* Update rotatedRectangleIntersection function to calculate near to origin

This commit changes the rotatedRectangleIntersection function in order
to calculate the intersection of two rectangles considering that they
are shifted near the coordinates origin (0, 0).

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* Revert type changes in types.cpp and adequate code to c++98

* Revert unnecessary casts on types.cpp

Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@gmail.com>
pull/20263/head
Tiago De Gaspari 3 years ago committed by GitHub
parent c1adbe3189
commit 3cf4375387
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 57
      modules/imgproc/src/intersection.cpp
  2. 17
      modules/imgproc/test/test_intersection.cpp

@ -47,24 +47,16 @@
namespace cv
{
int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion )
static int _rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, std::vector<Point2f> &intersection )
{
CV_INSTRUMENT_REGION();
// L2 metric
const float samePointEps = std::max(1e-16f, 1e-6f * (float)std::max(rect1.size.area(), rect2.size.area()));
if (rect1.size.empty() || rect2.size.empty())
{
intersectingRegion.release();
return INTERSECT_NONE;
}
Point2f vec1[4], vec2[4];
Point2f pts1[4], pts2[4];
std::vector <Point2f> intersection; intersection.reserve(24);
rect1.points(pts1);
rect2.points(pts2);
@ -92,8 +84,6 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r
intersection[i] = pts1[i];
}
Mat(intersection).copyTo(intersectingRegion);
return INTERSECT_FULL;
}
}
@ -300,7 +290,50 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r
}
intersection.resize(N);
Mat(intersection).copyTo(intersectingRegion);
return ret;
}
int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion )
{
CV_INSTRUMENT_REGION();
if (rect1.size.empty() || rect2.size.empty())
{
intersectingRegion.release();
return INTERSECT_NONE;
}
// Shift rectangles closer to origin (0, 0) to improve the calculation of the intesection region
// To do that, the average center of the rectangles is moved to the origin
const Point2f averageCenter = (rect1.center + rect2.center) / 2.0f;
RotatedRect shiftedRect1(rect1);
RotatedRect shiftedRect2(rect2);
// Move rectangles closer to origin
shiftedRect1.center -= averageCenter;
shiftedRect2.center -= averageCenter;
std::vector <Point2f> intersection; intersection.reserve(24);
const int ret = _rotatedRectangleIntersection(shiftedRect1, shiftedRect2, intersection);
// If return is not None, the intersection Points are shifted back to the original position
// and copied to the interesectingRegion
if (ret != INTERSECT_NONE)
{
for (size_t i = 0; i < intersection.size(); ++i)
{
intersection[i] += averageCenter;
}
Mat(intersection).copyTo(intersectingRegion);
}
else
{
intersectingRegion.release();
}
return ret;
}

@ -391,4 +391,21 @@ TEST(Imgproc_RotatedRectangleIntersection, regression_18520)
}
}
TEST(Imgproc_RotatedRectangleIntersection, regression_19824)
{
RotatedRect r1(
Point2f(246805.033f, 4002326.94f),
Size2f(26.40587f, 6.20026f),
-62.10156f);
RotatedRect r2(
Point2f(246805.122f, 4002326.59f),
Size2f(27.4821f, 8.5361f),
-56.33761f);
std::vector<Point2f> intersections;
int interType = cv::rotatedRectangleIntersection(r1, r2, intersections);
EXPECT_EQ(INTERSECT_PARTIAL, interType);
EXPECT_LE(intersections.size(), (size_t)7);
}
}} // namespace

Loading…
Cancel
Save