无法将值分配给函数内部的 cv::Mat

Posted

技术标签:

【中文标题】无法将值分配给函数内部的 cv::Mat【英文标题】:Can't assign values to cv::Mat inside function 【发布时间】:2016-09-27 18:19:27 【问题描述】:

我需要创建一个CV_32FC2 类型的Mat 对象来存储KeyPoint 结构中包含的坐标点。为了清楚起见,我想在函数中执行此操作。

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 循环内的“p1_dist”下划线,要求指向该 Mat 的指针。 如果我在 main 函数中编写那段代码,则不会发生错误。 你能帮我指出问题吗?

【问题讨论】:

您确实意识到,一旦您退出函数p1_dist 将被破坏,您在循环中所做的所有事情都将是徒劳的,对吧?如果你想让Mat 对象保持活动状态,你必须将它作为指针传递给你的函数,这样函数体内发生的更改才会真正保留。 p1_dist.at&lt;double&gt;(0, i) 应该返回一个双引用,它不能像数组一样被访问。你的意思可能是p1_dist.at&lt;double[2]&gt;(0, i)。否则,我不会关注你的 main 问题。 你应该发布确切的编译器消息,你已经有了确切的答案。 【参考方案1】:

首先,您需要返回您创建的矩阵。要符合 OpenCV,您可以传递对 Mat 的引用:

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

然后您需要使用正确的模板访问数据值。如果你需要一个CV_32FC2矩阵,即float的矩阵有2个通道,你需要使用:p1_dist.at&lt;Vec2f&gt;(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_&lt;Tp&gt; 通常会更清楚。 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;

【讨论】:

非常感谢您的帮助,我使用错误的模板访问矩阵。 很高兴它有帮助;D

以上是关于无法将值分配给函数内部的 cv::Mat的主要内容,如果未能解决你的问题,请参考以下文章

如何将 cv::mat 对象从 python 模块传递给 c++ 函数并返回返回的 cv::mat 类型的对象?

cv::Mat 分配给 'at<unsigned char>(0,0)' 时会导致崩溃

如何从函数返回多维 Mat 数组

用户定义函数中的子集以将值分配给目标列

如何将像素数据的所有权传递给 cv::Mat

mwArray和cv::Mat转化函数 20170812