【学习OpenCV】—— 深入了解 cv::Mat

  • rows:行数,或者高度;cols:列数,或者宽度

实现原理

cv::Mat 有两个必不可少的组成部分,一个头部,一个数据块。

class CV_EXPORTS Mat
{
public:

    int flags;
    //! the matrix dimensionality, >= 2
    int dims;
    //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
    int rows, cols;

    //! pointer to the data
    uchar* data;

}

cv::Mat 头部属性主要有:cols、rows 或 channels,而数据块(uchar* data)包含了图像中所有像素的值。

cv::Mat 有一个很重要的特性,就是只有在明确要求时((copyTo、clone)),内存块才会被复制。实际上,大多数操作都只仅仅复制了 cv::Mat 的头部信息,因此多个对象会同时指向同一个数据块。这种内存管理模式可以提高应用程序的运行效率,避免内存泄露。

cv::Mat image1(240, 320, CV_8U, 100);

我们需要指定每个矩阵元素的类型,CV_8U 表示每个像素对应一个字节,U表示无符号,字母S则是有符号。对于彩色图像,可用 CV_8UC3(C表示channel)

我们可以随时用 create 方法分配或重新分配图像的数据块,如果图像已经分配,首先其原来的内容会被释放。出于对性能的考虑,如果新的大小和类型与原来的相同,就不会重新分配内存(可以想象,会直接覆盖)。

// 重新分配一个新图像
// (仅在大小或类型不同时)
image1.create(200, 200, CV_8U);

一旦没有了指向 cv::Mat 对象的引用,分配的内存就会被自动释放。这一点可避免 C++ 动态内存分配(new)中常常发生的内存泄露问题。这是 OpenCV2 中的一个关键机制,通过 cv::Mat 实现引用计数(reference count)和浅复制。当在两个图像之间赋值时,图像数据(也即像素)并不会被复制,此时两个图像指向同一个内存块。

一些细节

cv::Mat image = cv::imread("...");
  • (1)Mat 类型

    if (image.type() == CV_8U)
        image.at<uchar>(i, j) = ...;
    
    if (image.type() == CV_8UC3)
        image.at<cv::Vec3b>(i, j)[0] = ...;
        image.at<cv::Vec3b>(i, j)[1] = ...;
        image.at<cv::Vec3b>(i, j)[2] = ...;     
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五道口纳什

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值