• C++ cv::Mat数据类型 + 提取某些行或列


    简介

    1、cv::Mat 数据类型

    2、cv::Mat 提取某些行或列

    cv::Mat 数据类型

    在以下两个场景中使用OpenCV时,我们必须事先知道矩阵元素的数据类型:

    1、使用 at 方法访问数据元素的时候要指明数据类型

    2、做数值运算的时候,比如究竟是整数除法还是浮点数除法。

    cv::Mat 类的对象有一个成员函数type()用来返回矩阵元素的数据类型,返回值是 int 类型,不同的返回值代表不同的类型,具体对应关系如下所示:

     表头的 C1, C2, C3, C4 指的是通道(Channel)数,例如:

    1、灰度图像只有 1 个通道,是 C1;

    2、JPEG格式 的 RGB 彩色图像就是 3 个通道,是 C3

    3、PNG 格式的彩色图像除了 RGB 3个通道外,还有一个透明度通道,所以是 C4。

    如果仅仅是为了在数值计算前明确数据类型,那么看到这里就可以了

    如果是要使用 at 方法访问数据元素,那么还需要下面一步

    因为以单通道为例,at 方法接受的是 uchar 这样的数据类型,而非 CV_8U。

    在已知通道数和每个通道数据类型的情况下,指定给 at 方法的数据类型如下表所示:

     现在,就可以使用at来访问图像的像素了:

    1 cv::Vec3b vec3b = img.at<cv::Vec3b>(0,0);
    2 uchar vec3b0 = img.at<cv::Vec3b>(0,0)[0];
    3 uchar vec3b1 = img.at<cv::Vec3b>(0,0)[1];
    4 uchar vec3b2 = img.at<cv::Vec3b>(0,0)[2];
    5 std::cout<<"vec3b = "<<vec3b<<std::endl;
    6 std::cout<<"vec3b0 = "<<(int)vec3b0<<std::endl;
    7 std::cout<<"vec3b1 = "<<(int)vec3b1<<std::endl;
    8 std::cout<<"vec3b2 = "<<(int)vec3b2<<std::endl;

    上述数据类型以及取值范围

    Vec类的定义

     1 template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};
     2 
     3 typedef Vec<uchar, 2> Vec2b;
     4 typedef Vec<uchar, 3> Vec3b;
     5 typedef Vec<uchar, 4> Vec4b;
     6 
     7 typedef Vec<short, 2> Vec2s;
     8 typedef Vec<short, 3> Vec3s;
     9 typedef Vec<short, 4> Vec4s;
    10 
    11 typedef Vec<int, 2> Vec2i;
    12 typedef Vec<int, 3> Vec3i;
    13 typedef Vec<int, 4> Vec4i;
    14 
    15 typedef Vec<float, 2> Vec2f;
    16 typedef Vec<float, 3> Vec3f;
    17 typedef Vec<float, 4> Vec4f;
    18 typedef Vec<float, 6> Vec6f;
    19 
    20 typedef Vec<double, 2> Vec2d;
    21 typedef Vec<double, 3> Vec3d;
    22 
    23 typedef Vec<double, 4> Vec4d;
    24 typedef Vec<double, 6> Vec6d;

    cv::Mat 提取某些行或列

    Mat::rowRange

    Creates a matrix header for the specified row span.

    C++:  Mat  Mat:: rowRange (int  startrow, int  endrow )  const
    C++:  Mat  Mat:: rowRange (const Range&  r )  const
    
    Parameters:    
    startrow – An inclusive 0-based start index of the row span.
    endrow – An exclusive 0-based ending index of the row span.
    r – Range structure containing both the start and the end indices.

    The method makes a new header for the specified row span of the matrix. Similarly to Mat::row() and Mat::col() , this is an O(1) operation.

    Mat::colRange

    Creates a matrix header for the specified column span.

    C++:  Mat  Mat:: colRange (int  startcol, int  endcol )  const
    C++:  Mat  Mat:: colRange (const Range&  r )  const
    Parameters:    
    startcol – An inclusive 0-based start index of the column span.
    endcol – An exclusive 0-based ending index of the column span.
    r – Range structure containing both the start and the end indices.

    The method makes a new header for the specified column span of the matrix. Similarly to Mat::row() and Mat::col() , this is an O(1) operation.

    由于这两个函数返回的是指向原矩阵内部位置的指针,所以最好再利用clone()函数进行数据拷贝创建新的矩阵,代码如下:

     1 #include <opencv2/core/core.hpp>  
     2 #include <opencv2/highgui/highgui.hpp>  
     3 #include <iostream>  
     4   
     5 using namespace cv;  
     6 using namespace std;  
     7   
     8 int main(){  
     9      Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);  
    10      cout << "Total matrix:" << endl;  
    11      cout << C << endl;  
    12   
    13      Mat row = C.rowRange(1,3).clone();  
    14      cout << "Row range:" << endl;  
    15      cout << row << endl;  
    16       
    17      Mat col = C.colRange(1,3).clone();  
    18      cout << "Col range:" << endl;  
    19      cout << col << endl;  
    20 }
    结果如下:
    Total matrix
    [0, -1, 0;
      -1, 5, -1;
      0, -1, 0]
    Row range:
    [-1, 5, -1;
      0, -1, 0]
    Col range:
    [-1, 0;
      5, -1;
      -1, 0]

    这两个函数很有趣,它们让我实现不用调用opencv特有函数来实现相应功能,而是自己可以写函数随机应变地实现自己所需的任何图像方面功能

    附录:

  • 相关阅读:
    ID3决策树---Java
    Static、final、abstract、接口、构造方法及java语法总结
    集合类 Collection
    String、StringBuilder
    java基础类:Object类和Math类
    如何快速定位TempDB产生问题
    教你实现图片的惰性加载
    如何在 apache 中开启 gzip 压缩服务
    Data URI 应用场景小结
    获取图片base64编码的几种方法
  • 原文地址:https://www.cnblogs.com/citrus/p/16235385.html
Copyright © 2020-2023  润新知