opencv图像处理教程C++(四)Mat的介绍和使用

之前我们已经使用到了Mat,但是还没有对它进行介绍。。。。。
Mat:基本图像容器
在以前的老式opencv中使用的是C结构,很烦人,需要注意内存的申请和销毁,后来转为C++接口,使用Mat对象,自动申请和销毁内存,很方便。
Mat由基本的两部分组成:矩阵头(包含图片信息,例如矩阵大小,存储方法等)和一个指向包含像素点信息的指针。矩阵头部大小是常数,但是矩阵的大小却各不相同。
Mat中重要的几个成员:

 size_t elemSize() const; 
 int type() const;
 int depth() const;
 int channels() const;
 size_t step1(int i=0) const
 int dims
 int rows, cols

channels:我们熟悉的是彩色图像三通道RGB,也就是矩阵中每一个元素值的个数,就像一个彩色像素点它由R、G、B三个混合而成。处于某行某列的像素点有三个值分别为RGB。
depth:深度是用来度量每一个像素的精度,每个像素的位数(bit)也就是深度越深,精度越高。在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3,CV_32S=4, CV_32F=5, CV_64F=6 }; 其中U表示unsigned的意思,S表示signed,也就是有无符号。我们可以看作以8U为基本单位
dim:矩阵维度
rows/cols(size):行列数。
type :表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_ + (位数)+(数据类型)+(通道数)。
data: uchar型的指针。Mat类分为了两个部分:矩阵头和指向矩阵数据部分的指针,data就是指向矩阵数据的指针。
Mat对象构造函数:(常用)
Mat();
Mat(int rows, int cols, int type);
Mat(Size size, int type);
Mat(int rows, int cols, int type, const Scalar& s);
Mat(Size size, int type, const Scalar& s);
Mat(int ndims, const int* sizes, int type);
Mat(int ndims, const int* sizes, int type, const Scalar& s);
常用方法:
void copyTo(Mat mat) //完全复制一份
void convertTo(Mat dst, int type) //转换,比如8位的转换为float
Mat clone() //完全复制一份
int channels() //通道数
int depth() //深度
bool empty(); //是否空
at(int i0,int i1) //访问矩阵元素
Mat对象使用-四个要点:
输出图像的内存是自动分配的
使用OpenCV的C++接口,不需要考虑内存分配问题
赋值操作和拷贝构造函数只会复制头部分
使用clone与copyTo两个函数实现数据完全复制
代码实现:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<opencv2/face.hpp>
#include<iostream>
#include<math.h>
#include <string> 
#include<fstream> 
using namespace cv::face;
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main()
{
    Mat src;
    double time, timeconsume;
    src = imread("C:/Users/Administrator/Desktop/pic/5.jpg");
    imshow("input", src);

    Mat dst = Mat(src.size(), src.type());
    dst = Scalar(127, 0, 255);//给矩阵所有的像素点设置颜色数据,绯红,这里的 = 号运算符重载了 Scalar参数顺序是 B G R
//Mat dst = src.clone();//完全拷贝
  /*Mat dst;
    src.copyTo(dst);//完全拷贝*/
 //Mat dst = imread("...");//只是复制部分,Mat对象头部与数据的指针,不会复制数据
//Mat dst(src);//只是复制部分,Mat对象头部与数据的指针,不会复制数据
    imshow("output image", dst);

    cvtColor(src, dst, CV_BGR2GRAY);//dst对象输出图像的内存是自动分配的
    printf("rgb.channels=%d, gray.channels=%d,%d,%d\n", src.channels(), dst.channels(), src.type(), dst.type());//rgb通道数为3,gray通道数为1,16,0

    const uchar* firstRow = dst.ptr<uchar>(0);//图像第一行颜色数据
    printf("first pixel value : %d\n", *firstRow);
    printf("dst.cols=%d, dst.rows=%d\n", dst.cols, dst.rows);

    // CV_8UC1 8表示8位,UC表示unsigned char,1表示1个通道, Scalar表示向量长度,要与通道数目一致
    Mat m(3, 3, CV_8UC3, Scalar(0, 0, 255));//3*3个像素点,CV_8UC3表示像素点为三个通道颜色数据,CV_8UC1表示像素点为单通道,对应的传 Scalar(255) 
    cout << "m = " << endl << m << endl;//打印每个通道颜色数据
    imshow("scalar", m);

    Mat m1;
    m1.create(src.size(), src.type());//以create方式创建Mat
    m1 = Scalar(0, 0, 255);//Scalar参数顺序是 B G R
    imshow("create", m1);
    //Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); //定义小数组,以 << 运算符重载 创建Mat
    Mat zeros = Mat::zeros(2, 2, CV_8UC1);//初始值0
    cout << "zeros = " << endl << zeros << endl;
    Mat eye = Mat::eye(3, 2, CV_8UC1);//沿着主对角线的像素点(不是通道)的第一个通道的数据设置为1,其他都为0,对于CV_8UC1的方阵可以生成单一矩阵
    cout << "eye = " << endl << eye << endl;
    waitKey(0);
}

结果:
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_26907755/article/details/81665414