Stepan Yakovenko
Stepan Yakovenko

Reputation: 9226

How to convert cv::Mat to cv::Vec3f?

I'd like to convert Mat tov Vec3f elegantly. Currently I do it like that:

            Mat line;
            Vec3f ln;
            ln[0] = line.at<float>(0, 0);
            ln[1] = line.at<float>(0, 1);
            ln[2] = line.at<float>(0, 2);

Is there a better way to do it?

Upvotes: 2

Views: 4964

Answers (2)

Quang Hoang
Quang Hoang

Reputation: 150815

One easy way

Mat m = Mat::zeros(3,1,CV_32F);
Vec3f xyz((float*)m.data);
cout<<xyz<< endl;

Upvotes: 0

Dan Mašek
Dan Mašek

Reputation: 19071

In your comment, you specify that this is a single channel floating point matrix with size 3x1. I'd be explicit about the data type in the code, so I'd represent it with cv::Mat1f.

Now, since it's a single channel matrix, we can't directly access elements as Vec3f, since if the input Mat was a submatrix we'd get incorrect results. We can use cv::Mat::reshape to efficiently turn the input into a 3-channel Mat, and then use cv::Mat::at to access the first element.


Sample code:

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat1f m(3, 1);
    m << 1.0f , 2.0f , 3.0f;

    cv::Vec3f v(m.reshape(3).at<cv::Vec3f>());

    std::cout << "m=" << m << "\n";
    std::cout << "v=" << v << "\n";

    return 0;
}

Output:

m=[1;
 2;
 3]
v=[1, 2, 3]

To be honest, it might be more efficient to just write a short utility function to do this. Something like

cv::Vec3f to_vec3f(cv::Mat1f const& m)
{
    CV_Assert((m.rows == 3) && (m.cols == 1));
    return cv::Vec3f(m.at<float>(0), m.at<float>(1), m.at<float>(2));
}

Upvotes: 5

Related Questions