2016-09-27 69 views
1

我需要创建一个类型的对象CV_32FC2来存储包含在KeyPoint结构中的坐标点。为了清晰起见,我想在一个函数内部完成它。无法为函数内的cv :: Mat分配值

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; 
    } 
} 

编译器在for循环中强调要求指向该Mat的“p1_dist”。 如果我在主函数内写入这段代码,错误将不会发生。 你能帮我指出这个问题吗?

+0

你一定要明白,一旦你退出功能'p1_dist'将被销毁,所有你在循环内做什么会没有理由对吗?如果你想保持'Mat'对象存活,你必须把它作为一个指针传递给你的函数,这样发生在函数体内部的变化实际上就会保留下来。 – rbaleksandar

+0

'p1_dist.at (0,i)'应该返回一个双引用,它不能像数组那样访问。你可能意指'p1_dist.at (0,i)'。否则,我不会跟随你的问题与主。 –

+0

你应该发布确切的编译器消息,你已经有确切的答案。 – gia

回答

1

首先你需要返回你创建的矩阵。为了符合OpenCV的,你可以传递一个参考Mat

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

然后你需要用正确的模板来访问数据值。如果你需要一个CV_32FC2矩阵,即float有2个通道的矩阵,你需要访问它:p1_dist.at<Vec2f>(row, col)[channel],即:

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

它通常是更清晰的使用Mat_<Tp>当你已经知道了矩阵的类型。为CV_32FC2相当于将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; 
    ... 
} 

把所有在一起:

#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; 
} 
+0

非常感谢您的帮助,我使用错误的模板访问矩阵。 –

+0

很高兴帮助; D – Miki