美文网首页图像处理Learn OpenCV程序员
2015-04-30-确定 OpenCV 矩阵元素的数据类型

2015-04-30-确定 OpenCV 矩阵元素的数据类型

作者: YimianDai | 来源:发表于2015-08-25 10:53 被阅读5524次

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

    • 使用 at 方法访问数据元素的时候要指明数据类型
    • 做数值运算的时候,比如究竟是整数除法还是浮点数除法。

    但面对一大堆代码,我们有时并不清楚当前的矩阵元素究竟是什么类型,这篇文章就是以 cv::Mat 类为例来解决这个问题。

    cv::Mat 类的对象有一个成员函数 type() 用来返回矩阵元素的数据类型,返回值是 int 类型,不同的返回值代表不同的类型。OpenCV Reference Manual 中对 type() 的解释如下所示:

    Mat::type
    C++: int Mat::type() const
    The method returns a matrix element type. This is an identifier compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.

    实际的代码如下所示:

    cv::Mat haha = cv::Mat::zeros(3,3,CV_64F);
    int hahaType = haha.type();
    std::cout<<"hahaType = "<<hahaType<<std::endl;
    
    

    至此,知道了 type() 函数,下一步更关键的就是返回值和具体类型之间的对应关系了。文章《[LIST OF MAT TYPE IN OPENCV][LIST OF MAT TYPE IN OPENCV]》对此整理得非常清楚,具体如下表所示:

    C1 C2 C3 C4
    CV_8U 0 8 16 24
    CV_8S 1 9 17 25
    CV_16U 2 10 18 26
    CV_16S 3 11 19 27
    CV_32S 4 12 20 28
    CV_32F 5 13 21 29
    CV_64F 6 14 22 30

    表头的 C1, C2, C3, C4 指的是通道(Channel)数,比如灰度图像只有 1 个通道,是 C1;JPEG格式 的 RGB 彩色图像就是 3 个通道,是 C3;PNG 格式的彩色图像除了 RGB 3个通道外,还有一个透明度通道,所以是 C4。大家还会发现 7 怎么没有被定义类型,这个可以看 OpenCV 源码,有如下所示的一行,说明 7 是用来给用户自定义的:

    #define CV_USRTYPE1 7
    

    如果仅仅是为了在数值计算前明确数据类型,那么看到这里就可以了;如果是要使用 at 方法访问数据元素,那么还需要下面一步。因为以单通道为例,at 方法接受的是 uchar 这样的数据类型,而非 CV_8U。在已知通道数和每个通道数据类型的情况下,指定给 at 方法的数据类型如下表所示:

    C1 C2 C3 C4 C6
    uchar uchar cv::Vec2b cv::Vec3b cv::Vec4b
    short short cv::Vec2s cv::Vec3s cv::Vec4s
    int int cv::Vec2i cv::Vec3i cv::Vec4i
    float float cv::Vec2f cv::Vec3f cv::Vec4f cv::Vec6f
    double double cv::Vec2d cv::Vec3d cv::Vec4d cv::Vec6d

    至此,我们就可以像《OpenCV for Matlab Users (2)》中演示的一样采用如下方式访问图像(矩阵)了

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

    初写于 2015-04-30.
    首发于 Yimian Dai's Homepage,转载请注明出处。

    参考资料

    • [LIST OF MAT TYPE IN OPENCV][LIST OF MAT TYPE IN OPENCV]

    附录

    数据类型及其取值范围
    数值 具体类型 取值范围
    CV_8U 8 位无符号整数 (0…..255)
    CV_8S 8 位符号整数 (-128…..127)
    CV_16U 16 位无符号整数 (0……65535)
    CV_16S 16 位符号整数 (-32768…..32767)
    CV_32S 32 位符号整数 (-2147483648……2147483647)
    CV_32F 32 位浮点数 (-FLT_MAX ………FLT_MAX,INF,NAN)
    CV_64F 64 位浮点数 (-DBL_MAX ……….DBL_MAX,INF,NAN)
    Vec 类的定义
    template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};
    
    typedef Vec<uchar, 2> Vec2b;
    typedef Vec<uchar, 3> Vec3b;
    typedef Vec<uchar, 4> Vec4b;
    
    typedef Vec<short, 2> Vec2s;
    typedef Vec<short, 3> Vec3s;
    typedef Vec<short, 4> Vec4s;
    
    typedef Vec<int, 2> Vec2i;
    typedef Vec<int, 3> Vec3i;
    typedef Vec<int, 4> Vec4i;
    
    typedef Vec<float, 2> Vec2f;
    typedef Vec<float, 3> Vec3f;
    typedef Vec<float, 4> Vec4f;
    typedef Vec<float, 6> Vec6f;
    
    typedef Vec<double, 2> Vec2d;
    typedef Vec<double, 3> Vec3d;
    
    typedef Vec<double, 4> Vec4d;
    typedef Vec<double, 6> Vec6d;
    
    


    [LIST OF MAT TYPE IN OPENCV]: http://ninghang.blogspot.jp/2012/11/list-of-mat-type-in-opencv.html

    相关文章

      网友评论

      本文标题:2015-04-30-确定 OpenCV 矩阵元素的数据类型

      本文链接:https://www.haomeiwen.com/subject/fklqcttx.html