zoukankan      html  css  js  c++  java
  • opencv之Mat数据类型

    data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data)

     

    dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维


    channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。


    depth:深度,即每一个像素的位数(bits),在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 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;


    step:是一个数组,定义了矩阵的布局,具体见下面图片分析,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(m-1)总是等于 channels;


    elemSize : 矩阵中每一个元素的数据大小,如果Mat中的数据的数据类型是 CV_8U 那么 elemSize = 1,CV_8UC3 那么 elemSize = 3,CV_16UC2 那么 elemSize = 4;记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小


    这是一个二维矩阵,那么维度为 2 (M.dims == 2);
    M.rows == 3; M.cols == 4;
    sizeof(uchar) = 1,那么每一个数据元素大小为 1 (M.elemSize() == 1, M.elemSize1() == 1);
    CV_8U 得到 M.depth() == 0, M.channels() == 1;
    因为是二维矩阵,那么 step 数组只有两个值, step[0] 和 step[1] 分别代表一行的数据大小和一个元素的数据大小,则 M.step[0] == 4, M.step[1] == 1;
    M.step1(0) == M.cols = 4; M.step1(1) == 1;


    假设上面的矩阵数据类型是 CV_8UC3,也就是三通道

    M.dims == 2; M.channels() == 3;M.depth() == 0;
    M.elemSize() == 3 (每一个元素包含3个uchar值) M.elemSize1() == 1 (elemSize / channels)
    M.step[0] == M.cols * M.elemSize() == 12, M.step[1] == M.channels() * M.elemSize1() == M.elemSize() == 3;
    M.step(0) == M.cols * M.channels() == 12 ; M.step(1) == M.channels() == 3;

    Mat::clone()  创建一个全拷贝

    Mat::copyTo();  不止表示拷贝数据,还表示n=m.col(0)

    Mat矩阵中数据指针Mat.data是uchar类型指针,CV_8U系列可以通过计算指针位置快速地定位矩阵中的任意元素。

    Mat M(7,7,CV_32F,Scalar(1,3));

    解释如下:创建一个M矩阵,7行7列,类型为CV_32F,C2表示有2个通道。Scalar(1,3)是对矩阵进行初始化赋值。第一个通道全为1,第2个通道全为3。

    Mat_<uchar>对应的是CV_8U,

    Mat_<char>对应的是CV_8S,

    Mat_<int>对应的是CV_32S,

    Mat_<float>对应的是CV_32F,

    Mat_<double>对应的是CV_64F

     cv::Mat是一个n维矩阵类,声明在<opencv2/core/core.hpp>中。(using namespace cv)

     cv::Mat_是一个模板类,声明在<opencv2/core/core.hpp>中。

     由于cv::Mat类中含有很多模板方法,这些参数类型要到运行期才能确定,但是这种灵活性却使得简单的调用代码复杂,因此就有了cv::Mat_类来简化代码。

    cv::Mat image = cv::imread('img.jpg');
    image.at<uchar>(j, i) = 255;
    
    cv::Mat_<uchar> im2 = image;
    im2(j, i) = 255;

    Mat有3个重要的方法:

             1、Mat mat = imread(const String* filename);        读取图像

             2、imshow(const string frameName, InputArray mat);     显示图像

             3、imwrite (const string& filename, InputArray img);   储存图像

    at<>和ptr<>的区分

    image.at<uchar>(i,j):取出灰度图像中i行j列的点。

    image.at<Vec3b>(i,j)[k]:取出彩色图像中i行j列第k通道的颜色点。其中uchar,Vec3b都是图像像素值的类型,Vec3b通过typedef Vec<T,N>来定义的,N代表元素的个数,T代表类型。

    更简单一些的方法:OpenCV定义了一个Mat的模板子类为Mat_,它重载了operator()让我们可以更方便的取图像上的点。

    Mat_<uchar> im=image;

    im(i,j)=255;

    取出图像中第i行数据的指针:image.ptr<uchar>(i);’

    opencv遍历的详细介绍:http://www.cnblogs.com/ronny/p/3482202.html

    http://www.cnblogs.com/zjgtan/archive/2013/04/06/3002962.html

  • 相关阅读:
    mode
    文件操作
    深浅拷贝
    基础数据类型补充
    再谈编码 decode和encode
    Python练习题 015:一颗自由落地的球
    Python练习题 014:完数
    Python练习题 013:求解a+aa+aaa……
    Python练习题 012:字符统计
    Python练习题 011:成绩打分
  • 原文地址:https://www.cnblogs.com/feifanrensheng/p/8681014.html
Copyright © 2011-2022 走看看