OpenCV将cv::Mat做为函数返回值的使用总结

前置知识

1、Mat 类包含两部分,一是 矩阵头 (matrix header),二是 矩阵指针 (pointer to matrix)

2、 Mat 类中的赋值算子 "=" 和 拷贝构造函数,涉及的是浅拷贝,当执行这两个操作时,仅仅是复制了矩阵头。

参考链接:OpenCV 之 Mat 类 - 飞鸢逐浪 - 博客园

场景一

直接在函数里创建一个cv::Mat对象,并返回。这里借助了C11的返回值优化技术,只会有一个拷贝构造。

cv::Mat bgr = cv::imread("lena.jpg")  // 使用拷贝构造函数

// OpenCV 4.5.2 imread源码
// modules/imgcodecs/src/loadsave.cpp
Mat imread( const String& filename, int flags )
{
    CV_TRACE_FUNCTION();

    /// create the basic container
    Mat img;

    /// load the data
    imread_( filename, flags, img );

    /// return a reference to the data
    return img;
}

场景二

将现有的对象,赋予新值,减少代码变量。

cv::Mat bgr_to_rgb(const cv::Mat& bgr)                                                                                                                                                        
{ 
  Mat rgb;
  cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
  return rgb;
}

cv::Mat image = cv::imread("lena.jpg");
image = bgr_to_rgb(image);  // 使用赋值函数

// OpenCV 4.5.2 cv::Mat的赋值操作符重载源码,添加了说明注释
// modules/core/src/matrix.cpp
Mat& Mat::operator=(const Mat& m)
{
    if( this != &m )
    {
        if( m.u )
            CV_XADD(&m.u->refcount, 1);
        release();  // 释放现有对象,如果无其它引用,会释放数据块内存空间
        flags = m.flags;
        if( dims <= 2 && m.dims <= 2 )
        {
            dims = m.dims;
            rows = m.rows;
            cols = m.cols;
            step[0] = m.step[0];
            step[1] = m.step[1];
        }
        else
            copySize(m);
        data = m.data;  // 与赋值的Mat共享数据块,浅复制只复制指针
        datastart = m.datastart;
        dataend = m.dataend;
        datalimit = m.datalimit;
        allocator = m.allocator;
        u = m.u;
    }
    return *this;
}

总结

1、加深对C++里拷贝构造函数和赋值函数的理解

2、查看OpenCV源码,可以加深使用的认识,写出安全又优雅的代码

你可能感兴趣的:(OpenCV,opencv)