From 7d3a764ba5800dcfbb29cfe4f33b218c80014988 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Mon, 20 Apr 2026 00:05:58 +0200 Subject: [PATCH] Fix triangulatePoints with 2-channel arrays. --- modules/3d/src/triangulate.cpp | 4 +-- modules/3d/test/test_cameras.cpp | 46 ++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/modules/3d/src/triangulate.cpp b/modules/3d/src/triangulate.cpp index 4d0c08d780..3a0809b303 100644 --- a/modules/3d/src/triangulate.cpp +++ b/modules/3d/src/triangulate.cpp @@ -71,7 +71,7 @@ void triangulatePoints( InputArray _P1, InputArray _P2, { npoints1 = points1.rows + points1.cols - 1; ystep1 = 1; - pstep1 = points1.rows == 1 ? 2 : (int)(points1.step/points1.elemSize()); + pstep1 = 2; } else { @@ -84,7 +84,7 @@ void triangulatePoints( InputArray _P1, InputArray _P2, { npoints2 = points2.rows + points2.cols - 1; ystep2 = 1; - pstep2 = points2.rows == 1 ? 2 : (int)(points2.step/points2.elemSize()); + pstep2 = 2; } else { diff --git a/modules/3d/test/test_cameras.cpp b/modules/3d/test/test_cameras.cpp index 966ecdc4c7..bfc2ff751c 100644 --- a/modules/3d/test/test_cameras.cpp +++ b/modules/3d/test/test_cameras.cpp @@ -1071,21 +1071,45 @@ TEST(Calib3d_Triangulate, accuracy) float x1data[] = { 200.f, 0.f }; float x2data[] = { 170.f, 1.f }; float Xdata[] = { 0.f, -5.f, 25/3.f }; - Mat x1(2, 1, CV_32F, x1data); - Mat x2(2, 1, CV_32F, x2data); - Mat res0(1, 3, CV_32F, Xdata); + constexpr int num_points = 5; + Mat1f res0(num_points, 3); + for(int i = 0; i < num_points; ++i) { + for(int j = 0; j < 3; ++j) { + res0(i, j) = Xdata[j]; + } + } + Mat res_, res; - triangulatePoints(P1, P2, x1, x2, res_); - cv::transpose(res_, res_); // TODO cvtest (transpose doesn't support inplace) - convertPointsFromHomogeneous(res_, res); - res = res.reshape(1, 1); + for(int test : {0, 1}) { + if (test == 0) { + // 2xN and 1xN 2-channel. + Mat1f x1(2, num_points); + Mat2f x2(1, num_points); + for(int i = 0; i < 2; ++i) { + for(int j = 0; j < num_points; ++j) { + x1(i, j) = x1data[i]; + x2(0, j)[i] = x2data[i]; + } + } + triangulatePoints(P1, P2, x1, x2, res_); + } else { + // Array and vector. + std::array x1; + x1.fill({x1data[0], x1data[1]}); + std::vector x2(num_points, {x2data[0], x2data[1]}); + triangulatePoints(P1, P2, x1, x2, res_); + } + cv::transpose(res_, res_); // TODO cvtest (transpose doesn't support inplace) + convertPointsFromHomogeneous(res_, res); + res = res.reshape(1, num_points); - cout << "[1]:" << endl; - cout << "\tres0: " << res0 << endl; - cout << "\tres: " << res << endl; + cout << "[1]:" << endl; + cout << "\tres0: " << res0 << endl; + cout << "\tres: " << res << endl; - ASSERT_LE(cvtest::norm(res, res0, NORM_INF), 1e-1); + ASSERT_LE(cvtest::norm(res, res0, NORM_INF), 1e-1); + } } // another testcase http://code.opencv.org/issues/3461