OpenCV入门教程(5)-Mat类之Mat_类

本文介绍了OpenCV中Mat_类的设计目的与使用方法。通过使用Mat_类可以在声明变量时就确定矩阵元素的类型,简化了后续操作,并降低了类型错误的风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mat_类是对 Mat 类的一个包装,其定义如下:

template<typename _Tp> class Mat_ : public Mat
{
public:
    //只定义了几个方法
    //没有定义新的属性
};

这是一个非常轻量级的包装,既然已经有 Mat 类,为何还要定义一个 Mat_?下面我们看这段代码:

Mat M(600, 800, CV_8UC1);
for( int i = 0; i < M.rows; ++i)
{
    uchar * p = M.ptr<uchar>(i);
    for( int j = 0; j < M.cols; ++j )
    {
        double d1 = (double) ((i+j)%255);
        M.at<uchar>(i,j) = d1;
        double d2 = M.at<double>(i,j);//此行有错
    }
}

在读取矩阵元素时,以及获取矩阵某行的地址时,需要指定数据类型。这样首先需要不停地写“”,让人感觉很繁琐,在繁琐和烦躁中容易犯错,如上面代码中的错误,用 at()获取矩阵元素时错误的使用了 double 类型。这种错误不是语法错误,因此在编译时编译器不会提醒。在程序运行时,at()函数获取到的不是期望的(i,j)位置处的元素,数据已经越界,但是运行时也未必会报错。这样的错误使得你的程序忽而看上去正常,忽而弹出“段错误”,特别是在代码规模很大时,难以查错。
如果使用 Mat_类,那么就可以在变量声明时确定元素的类型,访问元素时不再需要指定元素类型,即使得代码简洁,又减少了出错的可能性。上面代码可以用 Mat_实现,实现代码如下面例程里的第二个双重 for 循环。

#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
    Mat M(600, 800, CV_8UC1);
    for( int i = 0; i < M.rows; ++i)
    {
        //获取指针时需要指定类型
        uchar * p = M.ptr<uchar>(i);
        for( int j = 0; j < M.cols; ++j )
        {
            double d1 = (double) ((i+j)%255);
            //用 at()读写像素时,需要指定类型
            M.at<uchar>(i,j) = d1;
            //下面代码错误,应该使用 at<uchar>()
            //但编译时不会提醒错误
            //运行结果不正确,d2 不等于 d1
            double d2 = M.at<double>(i,j);
        }
    }
    //在变量声明时指定矩阵元素类型
    Mat_<uchar> M1 = (Mat_<uchar>&)M;
    for( int i = 0; i < M1.rows; ++i)
    {
        //不需指定元素类型,语句简洁
        uchar * p = M1.ptr(i);
        for( int j = 0; j < M1.cols; ++j )
        {
            double d1 = (double) ((i+j)%255);
            //直接使用 Matlab 风格的矩阵元素读写,简洁
            M1(i,j) = d1;
            double d2 = M1(i,j);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值