Riccardo Giubilato
Riccardo Giubilato

Reputation: 110

Can't assign values to cv::Mat inside function

I need to create a Mat object of type CV_32FC2 to store coordinate points contained in a KeyPoint structure. I want to do it inside a function for clarity.

void myfun(vector<KeyPoint>& k){
    Mat p1_dist(1, k.size(), CV_32FC2);

    for(int i=0; i<k.size(); i++){
       p1_dist.at<double>(0, i)[0] = k1[i].pt.x;
       p1_dist.at<double>(0, i)[1] = k1[i].pt.y;
    }
}

The compiler underlines the "p1_dist" inside the for loop asking for a pointer to that Mat. If I write that piece of code inside the main function the error won't happen. Can you help me pointing out the issue?

Upvotes: 1

Views: 1194

Answers (1)

Miki
Miki

Reputation: 41765

First you need to return the matrix you create. To conform to OpenCV, you can pass a reference to Mat:

void myfun(const vector<KeyPoint>& k, Mat& p1_dist){ ... }

Then you need to access the data values with the correct template. If you need a CV_32FC2 matrix, i.e. a matrix of float with 2 channels, you need to access it with: p1_dist.at<Vec2f>(row, col)[channel], i.e.:

p1_dist.at<Vec2f>(0, i)[0] = k[i].pt.x;
p1_dist.at<Vec2f>(0, i)[1] = k[i].pt.y;

It's usually clearer to use the Mat_<Tp> when you already know the type of the matrix. The equivalent for CV_32FC2 would be Mat2f:

void myfun(const vector<KeyPoint>& k, Mat2f& p1_dist){  
    ...
    p1_dist(0, i)[0] = k[i].pt.x;
    p1_dist(0, i)[1] = k[i].pt.y;
    ...  
}

Putting all together:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

void myfun(const vector<KeyPoint>& k, Mat2f& p1){
    p1 = Mat2f(1, k.size()); // Set proper size

    for(size_t i=0; i<k.size(); i++){
       p1(0, i)[0] = k[i].pt.x;
       p1(0, i)[1] = k[i].pt.y;
    }
}

int main()
{
    vector<KeyPoint> k = ...;
    Mat2f p1_dist;
    myfun(k, p1_dist);   

    // Use p1_dist

    return 0;
}

Upvotes: 1

Related Questions