guyuealian
pan_jinquan
2018-05-09 03:22
采纳率: 75%
浏览 1.6k

OpenCV函数返回的简单问题

下面是一个OpenCV的小程序:

 #include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

template<typename _Tp>
vector<_Tp> convertMat2Vector(const Mat &_t1f)
{
    //_t1f.convertTo(t1f, CV_64F);
    return (vector<_Tp>)(_t1f.reshape(1, 1));//通道数不变,按行转为一行
}


template<typename _Tp>
cv::Mat convertVector2Mat(vector<_Tp> v,int cn,int rows)
{
    cv::Mat mat = cv::Mat(v);//将vector变成一列的mat
    cv::Mat dest=mat.reshape(cn, rows);
    cout << "dest=\n" << dest << endl;
    return dest;
}


int main()

{
    int arr[4][3] = { { 1, 1,1 },{ 2, 2,2 },{ 3, 3,3 },{ 4,4, 4 } };
    cv::Mat srcData(4, 3, CV_8UC1, arr);
    cout << "srcData=\n"<< srcData<< endl;
    vector<uchar> v = convertMat2Vector<uchar>(srcData);
    cv::Mat dest =convertVector2Mat<uchar>(v,1, 4);//函数里的dest和还回dest的结果为什么不一样的呀?
    cout << "dest=\n" << dest << endl;



    system("pause");
    waitKey();
    return 0;
}

运行结果:
图片说明

问题是:各位大神啊,我这哪里出问题?为什么函数里的dest和还回的dest的结果值为什么不一样的呀?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • feelcycle_07
    默默悟问 2018-05-09 07:40
    已采纳

    因为第2个方法的mat对象会释放,而dest引用的数据是来自于mat,并没有拷贝数据,因此在mat没有释放的情况下是正常的,
    之后引用的内存就被释放而成为野数据。另外你srcData也不对。修改如下:

     #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    template<typename _Tp>
    vector<_Tp> convertMat2Vector(const Mat &_t1f)
    {
        //_t1f.convertTo(t1f, CV_64F);
        return (vector<_Tp>)(_t1f.reshape(1, 1));//通道数不变,按行转为一行
    }
    
    
    template<typename _Tp>
    cv::Mat convertVector2Mat(vector<_Tp> v,int cn,int rows)
    {
        cv::Mat mat = cv::Mat(v);//将vector变成一列的mat
        cv::Mat dest=mat.reshape(cn, rows).clone();
        cout << "dest=\n" << dest << endl;
        return dest;
    }
    
    
    int main()
    
    {
        char arr[4][3] = { {1, 1, 1 },{ 2, 2, 2 },{ 3, 3, 3 },{ 4, 4, 4 } };
        cv::Mat srcData(4, 3, CV_8UC1, arr);
        cout << "srcData=\n"<< srcData<< endl;
        vector<uchar> v = convertMat2Vector<uchar>(srcData);
        cout << v.size() << endl;
        cv::Mat dest =convertVector2Mat<uchar>(v,1, 4);//函数里的dest和还回dest的结果为什么不一样的呀?
        cout << "dest=\n" << dest << endl;
    
        system("pause");
        waitKey();
        return 0;
    }
    
    点赞 2 评论
  • weixin_41986182
    weixin_41986182 2018-05-09 03:54

    return dest1;
    cv::Mat dest2 =convertVector2Mat
    这句话的执行顺序是:
    1、默认构造DEST2
    2、以DEST1为源,赋值(operater=) 给DEST2
    3、析构DEST1
    不过大部份编译器为将其优化为:
    1、以DEST1为源,拷贝构造给DEST2
    2、析构DEST1

    所以原因应该是CV:MAT未定义合适的拷贝构造函数所致。

    如是这个原因,还会发生更有趣的事情:
    在convertVector2Mat函数内部增加如下代码:
    cv::Mat dest=mat.reshape(cn, rows);
    cout << "dest=\n" << dest << endl;
    cv::Mat dest2=dest
    cout << "dest2=\n" << dest2 << endl;
    这两个结果都应该不一样了。

    解决办法有两个:
    1、定义合适的拷贝构造函数与赋值函数。
    2、改变实现形式,不再靠return赋值,而将结果能过 指针或引用 的参数返回。

    点赞 评论
  • phenix2009
    白色一大坨 2018-05-09 04:18

    我试了几次,如果convertVector2Mat里面是这样设置dest,可以返回:
    Mat dest = (Mat_(4, 3) << 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4);
    但如果这样设置,就返回不了:
    int arr[4][3] = { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 }, { 4, 4, 4 } };
    cv::Mat dest(4, 3, CV_8UC1, arr);
    跟mat.reshape(cn, rows);是一个效果
    我觉得应该跟动态分配有关系,这个是在接口内做的,建议你涉及动态分配的这些函数还是别用返回值来做。

    点赞 评论
  • feelcycle_07
    默默悟问 2018-05-09 07:41

    输出如下:

    srcData=
    [  1,   1,   1;
       2,   2,   2;
       3,   3,   3;
       4,   4,   4]
    12
    dest=
    [  1,   1,   1;
       2,   2,   2;
       3,   3,   3;
       4,   4,   4]
    dest=
    [  1,   1,   1;
       2,   2,   2;
       3,   3,   3;
       4,   4,   4]
    
    
    点赞 评论

相关推荐