1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #27641 from Ma-gi-cian:subdiv2d-rect2f-clean

Subdiv2d rect2f clean #27641

Closes https://github.com/opencv/opencv/issues/27623

Changes:

- Added Subdiv2D(Rect2f) constructor overload
- Added initDelaunay(Rect2f) method overload

- No changes to the previous implementation to keep it backward compatible
- Added tests for init and testing with edge case of extremely small coordinates

- [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.
- [x] The feature is well documented and sample code can be built with the project CMake

See original pull request at : https://github.com/opencv/opencv/pull/27631
This commit is contained in:
Aditya Jha
2025-08-15 17:35:27 +05:30
committed by GitHub
parent 9909d0a7d2
commit 7a1ec54c43
3 changed files with 124 additions and 1 deletions
+15 -1
View File
@@ -1112,13 +1112,27 @@ public:
*/
CV_WRAP Subdiv2D(Rect rect);
/** @brief Creates a new empty Delaunay subdivision
/** @overload */
CV_WRAP Subdiv2D(Rect2f rect);
/** @overload
@brief Creates a new empty Delaunay subdivision
@param rect Rectangle that includes all of the 2D points that are to be added to the subdivision.
*/
CV_WRAP void initDelaunay(Rect rect);
/** @overload
@brief Creates a new empty Delaunay subdivision
@param rect Rectangle that includes all of the 2d points that are to be added to the subdivision.
*/
CV_WRAP void initDelaunay(Rect2f rect);
/** @brief Insert a single point into a Delaunay triangulation.
@param pt Point to insert.
+56
View File
@@ -118,6 +118,16 @@ Subdiv2D::Subdiv2D(Rect rect)
initDelaunay(rect);
}
Subdiv2D::Subdiv2D(Rect2f rect)
{
validGeometry = false;
freeQEdge = 0;
freePoint = 0;
recentEdge = 0;
initDelaunay(rect);
}
Subdiv2D::QuadEdge::QuadEdge()
{
@@ -535,6 +545,52 @@ void Subdiv2D::initDelaunay( Rect rect )
recentEdge = edge_AB;
}
void Subdiv2D::initDelaunay( Rect2f rect )
{
CV_INSTRUMENT_REGION();
float big_coord = 6.f * MAX( rect.width, rect.height );
float rx = rect.x;
float ry = rect.y;
vtx.clear();
qedges.clear();
recentEdge = 0;
validGeometry = false;
topLeft = Point2f( rx, ry );
bottomRight = Point2f( rx + rect.width, ry + rect.height );
Point2f ppA( rx + big_coord, ry );
Point2f ppB( rx, ry + big_coord );
Point2f ppC( rx - big_coord, ry - big_coord );
vtx.push_back(Vertex());
qedges.push_back(QuadEdge());
freeQEdge = 0;
freePoint = 0;
int pA = newPoint(ppA, false);
int pB = newPoint(ppB, false);
int pC = newPoint(ppC, false);
int edge_AB = newEdge();
int edge_BC = newEdge();
int edge_CA = newEdge();
setEdgePoints( edge_AB, pA, pB );
setEdgePoints( edge_BC, pB, pC );
setEdgePoints( edge_CA, pC, pA );
splice( edge_AB, symEdge( edge_CA ));
splice( edge_BC, symEdge( edge_AB ));
splice( edge_CA, symEdge( edge_BC ));
recentEdge = edge_AB;
}
void Subdiv2D::clearVoronoi()
{
@@ -64,4 +64,57 @@ TEST(Imgproc_Subdiv2D, issue_25696) {
ASSERT_EQ(static_cast<size_t>(2), triangles.size());
}
// Initialization test
TEST(Imgproc_Subdiv2D, rect2f_constructor_and_init)
{
cv::Rect2f rect_f(0.5f, 1.5f, 100.7f, 200.3f);
cv::Subdiv2D subdiv_f(rect_f);
cv::Point2f pt1(50.2f, 80.1f);
cv::Point2f pt2(75.8f, 120.9f);
cv::Point2f pt3(25.5f, 150.3f);
EXPECT_NO_THROW(subdiv_f.insert(pt1));
EXPECT_NO_THROW(subdiv_f.insert(pt2));
EXPECT_NO_THROW(subdiv_f.insert(pt3));
cv::Subdiv2D subdiv_init;
EXPECT_NO_THROW(subdiv_init.initDelaunay(rect_f));
EXPECT_NO_THROW(subdiv_init.insert(pt1));
EXPECT_NO_THROW(subdiv_init.insert(pt2));
EXPECT_NO_THROW(subdiv_init.insert(pt3));
std::vector<cv::Vec6f> triangles;
EXPECT_NO_THROW(subdiv_f.getTriangleList(triangles));
EXPECT_GT(triangles.size(), 0u);
}
// test with small coordinates
TEST(Imgproc_Subdiv2D, rect2f_edge_cases)
{
cv::Rect2f small_rect(0.0f, 0.0f, 0.1f, 0.1f);
cv::Subdiv2D subdiv_small(small_rect);
cv::Point2f small_pt(0.05f, 0.05f);
EXPECT_NO_THROW(subdiv_small.insert(small_pt));
cv::Rect2f float_rect(10.25f, 20.75f, 50.5f, 30.25f);
cv::Subdiv2D subdiv_float(float_rect);
cv::Point2f float_pt1(35.125f, 35.875f);
cv::Point2f float_pt2(45.375f, 25.625f);
cv::Point2f float_pt3(55.750f, 45.125f);
EXPECT_NO_THROW(subdiv_float.insert(float_pt1));
EXPECT_NO_THROW(subdiv_float.insert(float_pt2));
EXPECT_NO_THROW(subdiv_float.insert(float_pt3));
std::vector<cv::Vec6f> triangles;
subdiv_float.getTriangleList(triangles);
EXPECT_GT(triangles.size(), 0u);
}
}}