【问题标题】:strange results while returning a Mat from a function call从函数调用返回 Mat 时出现奇怪的结果
【发布时间】:2015-01-26 18:29:57
【问题描述】:

在下面的函数中,输入参数是一个 2 列的 Mat 矩阵, 我循环遍历它并返回一个只包含非零元素的新矩阵。

Mat LaneDetector::getHigherThanZero(const Mat& X)
{

vector<Vec2f> XX;

for(int i = 0; i < X.rows; ++i)
{
    if(X.at<float>(i,1) > 0)
        XX.push_back(Vec2f(X.at<float>(i,0), X.at<float>(i,1)));
}
Mat Y = Mat(XX).reshape(1);
return Y;

}

当我在主程序中运行它时,一切正常。当我从主要调用它时:

Mat Y = getHigherThanZero(X);
cout << Y << endl;

我得到了一些垃圾:

我在这里做错了什么?

【问题讨论】:

  • Mat 是什么?你检查过它的复制/移动构造函数吗?
  • 可能是因为您没有实现与“Mat Y = getHigherThanZero(X)”一起使用的复制构造函数
  • Mat 是 cv::Mat - 复制构造函数已隐式在基类中实现。
  • 顺便说一下,-1.5883997e+038 对应于0xFEEEFEEE,一个神奇的cookie(根据wikipedia)是“微软的调试HeapFree()用来标记释放的堆内存”
  • @SleuthEye - 谢谢,但这并不能帮助我解决我的问题 :-)

标签: c++ opencv


【解决方案1】:

试试

cv::Mat LaneDetector::getHigherThanZero(const cv::Mat& X)
{

    std::vector<cv::Vec2f> XX;

    for(int i = 0; i < X.rows; ++i)
    {
        if(X.at<float>(i,1) > 0)
            XX.push_back(cv::Vec2f(X.at<float>(i,0), X.at<float>(i,1)));
    }

    cv::Mat Y = cv::Mat(XX).reshape(1);

    return Y.clone();

}

您的XX 超出范围,cv::Mat(XX) 不会复制数据,因此您必须自己复制它,这是由.clone() 完成的

编辑:也许有一个标志可以从输入数组/向量中复制数据,因此您可以在 Mat 构造函数中使用它,而不是稍后调用 .clone,但不确定!

编辑 2:cv::Mat Y = cv::Mat(XX).reshape(1).clone(); 后跟 return Y; 也可以;)

【讨论】:

  • 更好return Mat(XX).reshape(1);,因为Y没有被使用,所以不需要克隆。
  • 恕我直言,它与 cv::Mat 的析构函数无关,但与 std::vector 的析构函数无关。由于.reshape 不复制值,cv::Mat(XX) 不复制值,它们只存在于超出范围的向量中。
  • 但也许有一个标志可以直接在 Mat 构造上复制数组/向量数据,不确定...
【解决方案2】:

正如here operator= 解释的那样,对矩阵进行了浅拷贝。尽管已经声明,存在某种引用计数,但很可能实现得不够好。你应该试试:

Mat Y(getHigherThanZero(X));

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 2012-12-09
    相关资源
    最近更新 更多