zoukankan      html  css  js  c++  java
  • oencv学习(6)Mat学习(1)

    首先,Mat不仅可以存图像,也可以用来存放其他高维的数据。数据存在data指针所指向的地址中的,对于高维数据(dim维),每个数据的地址是用上面式子算的;它的一个特例是2维数据(图像),式子简化成了下面的那个公式。

    1、关于行列问题

    1 Mat img1 = imread("C:/Users/Administrator/Desktop/lena_b_512_512.bmp",0);//灰度图像
    2     cout<<img1.rows<<endl;
    3     cout<<img1.cols<<endl;
    4     cout<<img1.size[0]<<endl;//与img1.rows相等
    5     cout<<img1.size[1]<<endl;//与img1.cols相等
    2、取出前8*8个元素的灰度值
    1 Mat img1 = imread("C:/Users/Administrator/Desktop/lena_b_512_512.bmp",0);//灰度图像
    2     int i,j;
    3     for(i=0;i<8;i++)
    4     {
    5     for(j=0;j<8;j++)
    6     cout<<(double)img1.at<uchar>(i,j)<<"  ";//(1,2)点的灰度值
    7     cout<<endl;
    8     }

     
    cout<<(int)(*(img1.data + img1.step[0] * 1 + img1.step[1] * 2))<<endl;//(1,2)点的灰度值

    Mat img2 = imread("D:/picture/images/baboon1.jpg");//彩色图像
    cout<<(int)img2.at<Vec3b>(1,2)[1]<<endl;//(1,2)点的G分量
    cout<<(int)(*(img2.data + img2.step[0] * 1 + img2.step[1] * 2  + sizeof(uchar)))<<endl;//(1,2)点的G分量
    return 0;
    }
    因为8bit图像对应的像素值为0~255,所以opencv使用了uchar类型,这样非常节省空间;但是如果想看到具体的像素值,
     
    for(i=0;i<8;i++)
     {
        for(j=0;j<8;j++)
     {
      R=img1.at<Vec3b>(i,j)[0];
      G=img1.at<Vec3b>(i,j)[1];
      B=img1.at<Vec3b>(i,j)[2];
     }
     
     cout<<endl;
     }
    3、数组拷贝

    Mat这个类有两部分数据。一个是matrix header,这部分的大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等等。另一个部分是一个指向矩阵包含像素值的指针

    1 Mat A, C; // creates just the header parts
    2 A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we’ll know the method used (allocate matrix)
    3 Mat B(A); // Use the copy constructor
    4 C = A; // Assignment operator

    4、创建

    Mat_<uchar>对应的是CV_8U,

    Mat_<char>对应的是CV_8S,

    Mat_<int>对应的是CV_32S,

    Mat_<float>对应的是CV_32F,

    Mat_<double>对应的是CV_64F,

    还有个需要注意的问题,就是流操作符<<对于Mat的操作,仅限于Mat是2维的情况。

    对应的数据深度如下:

    • CV_8U - 8-bit unsigned integers ( 0..255 )

    • CV_8S - 8-bit signed integers ( -128..127 )

    • CV_16U - 16-bit unsigned integers ( 0..65535 )

    • CV_16S - 16-bit signed integers ( -32768..32767 )

    • CV_32S - 32-bit signed integers ( -2147483648..2147483647 )

    • CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )

    • CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN

    再说说Mat的创建,方式有两种,罗列一下:1.调用create(行,列,类型)2.Mat(行,列,类型(值))。

    1 // make a 7x7 complex matrix filled with 1+3j.
    2 Mat M(7,7,CV_32FC2,Scalar(1,3));
    3 // and now turn M to a 100x60 15-channel 8-bit matrix.
    4 // The old content will be deallocated
    5 M.create(100,60,CV_8UC(15));
    需要注意的是,copy这样的操作只是copy了矩阵的matrix header和那个指针,而不是矩阵的本身,也就意味着两个矩阵的数据指针指向的是同一个地址,需要开发者格外注意。比如上面这段程序,A、B、C指向的是同一块数据,他们的header不同,但对于A的操作同样也影响着B、C的结果。刚刚提高了内存自动释放的问题,那么当我不再使用A的时候就把内存释放了,那时候再操作B和C岂不是很危险。不用担心,OpenCV的大神为我们已经考虑了这个问题,是在最后一个Mat不再使用的时候才会释放内存,咱们就放心用就行了。
     

    如果想建立互不影响的Mat,是真正的复制操作,需要使用函数clone()或者copyTo()

     
    我抬头仰望星空不是为了摘取流星,而是为了一个永不屈服的梦想。
  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/happycaoyue/p/3093276.html
Copyright © 2011-2022 走看看