GIVEN:
A matrix (N, 3) build from a point cloud, i.e. a vector<Point3d>
std::vector<cv::Point3d> pcVector = ... // from somewhere
cv::Mat pcMat = cv::Mat(pcVector).reshape(1);
Thus having pcMat
to be something like:
[ 0.1, 1.3, 4.5 ]
[ 3.1, 1.4, 7.6 ]
...
[ 1.1, 3.4, 4.1 ]
GOAL:
An efficient method to get a column of ones added to the matrix. That is to receive a matrix like the following from the above.
[ 0.1, 1.3, 4.5, 1.0 ]
[ 3.1, 1.4, 7.6, 1.0 ]
...
[ 1.1, 3.4, 4.1, 1.0 ]
CURRENTLY:
cv::Mat result(N, 4);
cv::Mat ones = cv::Mat_<double>::ones(N, 1);
cv::hconcat(pcMat, ones, result);
QUESTION:
This seems to be inefficient since a temporary matrix full of ones needs to be created. Are there any tricks to get this done faster?
CodePudding user response:
Use cv::convertPointsToHomogeneous
The function converts points from Euclidean to homogeneous space by appending 1's to the tuple of point coordinates. That is, each point (x1, x2, ..., xn) is converted to (x1, x2, ..., xn, 1).
// given
std::vector<cv::Point3d> pcVector = ... // from somewhere
cv::Mat pcMat = cv::Mat(pcVector).reshape(1);
// I did not run this
cv::Mat dst;
cv::convertPointsToHomogeneous(pcMat, dst); // pcVector oughta work too
As always, these things will accept both Nx1 K-channel Mats as well as NxK 1-channel Mats. The result seems to always be Nx1 (K 1)-channel though.
And... you can imagine what convertPointsFromHomogeneous
would do.