Home > OS >  OpenCV::Mat how to efficiently add a column of ones?
OpenCV::Mat how to efficiently add a column of ones?

Time:06-24

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.

  • Related