opencv Mat 操作

Mat初始化
  为空不赋值
    cv::Mat skeleton3D(4, 17, CV_64F);
  直接赋值:
    double a[] = {1,2,3,4};
    Mat test(2,2,CV_64_F);     cv::Mat mtest(
3, 1, CV_64F, cv::Scalar::all(0));     cv::Mat mtest(3, 1, CV_64F, cv::Scalar(1,2,3));   特殊矩阵     cv::Mat mz = cv::Mat::zeros(cv::Size(w,h), CV_8UC1); // 全零矩阵       【或者:Mat tmpdata = Mat::zeros(h, w, CV_8UC1);//h行w列的全0矩阵】     cv::Mat mo = cv::Mat::ones(cv::Size(w,h),CV_8UC1); // 全1矩阵       【或者:Mat tmpdata = Mat::ones(h, w, CV_8UC1);//h行w列的全1矩阵】     cv::Mat me = cv::Mat::eye(cv::Size(w,h),CV_32FC1); // 对角线为1的对角矩阵       【或者:Mat tmpdata = Mat::eye(h, w, CV_32FC1);//h行w列的对角矩阵
数据格式
  CV_8UC1\CV_8UC2\CV_8UC3\CV_8UC4
  CV_8S\--------
  CV_16U\----------
  CV_16S\-----------
  CV_32S\----------
  CV_32F\-----------
  CV_64F\----------
  8\16\32\64:表示位数
  S:符号,
  U:无符号整形
  F:浮点型
  表头的 C1, C2, C3, C4 指的是通道(Channel)数,
  比如灰度图像只有 1 个通道,是 C1;
  JPEG格式 的 RGB 彩色图像就是 3 个通道,是 C3;
  PNG 格式的彩色图像除了 RGB 3个通道外,还有一个透明度通道,所以是 C4。
  大家还会发现 7 怎么没有被定义类型,这个可以看 OpenCV 源码,有如下所示的一行,说明 7 是用来给用户自定义的
片选
  某一行
    cv::Mat m0 = m.row(i)
  某一列
    cv::Mat m0 = m.col(j)
  某几行
    cv::Mat m0 = m.rowRange(i0, i1)
  某几列
    cv::Mat m0 = m.colRange(j0, j1)
  行列同时选择
    cv::Mat m0 = m.colRange(cv::Range(j0, j1))
拼接
  cv::hconcat(intrinsicCam, mtest, intrinsicCam);
乘除法
  点乘
    AB= A*B;//返回值是Mat类型的
    AB=A.dot(B);//返回值是double类型的
  对应位置相乘
    AB = A.mul(B);
转置
  cv::transpose(m1, m3);
翻转
  cv::flip(m1, m2,1);
遍历
  方式一 :最慢,最容易理解
    for (int j = 0; j< image.rows; j++){  
      
for (int i = 0; i< image.cols; i++)   { 
        image.at<cv::Vec3b>(j, i)[0] = image.at<cv::Vec3b>(j, i)[0] / div*div + div / 2;  
        image.at<cv::Vec3b>(j, i)[1] = image.at<cv::Vec3b>(j, i)[1] / div*div + div / 2;  
        image.at<cv::Vec3b>(j, i)[2] = image.at<cv::Vec3b>(j, i)[2] / div*div + div / 2;  
      } // end of line        

    }  

    at <>里面对应关系

        

  方式二:使用Mat的成员函数ptr<>()

    cv::Mat中提供ptr函数访问任意一行像素的首地址,特别方便图像的一行一行的横向访问,如果需要一列一列的纵向访问图像,就稍微麻烦一点。但是ptr访问效率比较高,程序也比较安全,有越界判断

push back出错, 浅拷贝、深拷贝

  Mat 的各种运算,包括加减乘除、.t(),.inv()等都会创造一个临时结果变量,但仍然存在大量的成员函数返回的只是一个Mat头指针比如A.rowrange(0,3)。因此初次使用时需要注意甄别,对后者使用clone()深度拷贝一份。

    Mat m(1,1);

    vector<Mat>vecMatrix;

    for(int i = 0; i < 10; i++){

        m.at<float>(0) = float(i);

        vecMatrix.push_back(m);

    }

  正确的

    Mat m(1,1);

    vector<Mat>vecMatrix;     for(int i = 0; i < N; i++){     m.at<float>(0) = float(i);     vecMatrix.push_back(m.clone());     }

  

方法一

 

 

 

 

:使用Mat的成员函数ptr<>()

cv::Mat中提供ptr函数访问任意一行像素的首地址,特别方便图像的一行一行的横向访问,如果需要一列一列的纵向访问图像,就稍微麻烦一点。但是ptr访问效率比较高,程序也比较安全,有越界判断。

posted @ 2020-08-27 16:10  yunshangyue  阅读(328)  评论(0编辑  收藏  举报