zoukankan      html  css  js  c++  java
  • Mat类对象的分析与应用

    1 Mat对象的构造方法

    Mat类提供了构造函数、复制构造函数与赋值构造函数来初始化一个对象。下面选取了Opencv中的部分源代码:

     1  //! default constructor
     2     Mat();
     3     //! constructs 2D matrix of the specified size and type
     4     // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
     5     Mat(int rows, int cols, int type);
     6     Mat(Size size, int type);
     7     //! constucts 2D matrix and fills it with the specified value _s.
     8     Mat(int rows, int cols, int type, const Scalar& s);
     9     Mat(Size size, int type, const Scalar& s);
    10 
    11     //! constructs n-dimensional matrix
    12     Mat(int ndims, const int* sizes, int type);
    13     Mat(int ndims, const int* sizes, int type, const Scalar& s);
    14 
    15     //! copy constructor
    16     Mat(const Mat& m);
    17     //! constructor for matrix headers pointing to user-allocated data
    18     Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
    19     Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
    20     Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
    21 
    22     //! creates a matrix header for a part of the bigger matrix
    23     Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
    24     Mat(const Mat& m, const Rect& roi);
    25     Mat(const Mat& m, const Range* ranges);
    26     //! converts old-style CvMat to the new matrix; the data is not copied by default
    27     Mat(const CvMat* m, bool copyData=false);
    28     //! converts old-style CvMatND to the new matrix; the data is not copied by default
    29     Mat(const CvMatND* m, bool copyData=false);
    30     //! converts old-style IplImage to the new matrix; the data is not copied by default
    31     Mat(const IplImage* img, bool copyData=false);
    32     //! builds matrix from std::vector with or without copying the data
    33     template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
    34     //! builds matrix from cv::Vec; the data is copied by default
    35     template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
    36     //! builds matrix from cv::Matx; the data is copied by default
    37     template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
    38     //! builds matrix from a 2D point
    39     template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
    40     //! builds matrix from a 3D point
    41     template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
    42     //! builds matrix from comma initializer
    43     template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
    44 
    45     //! download data from GpuMat
    46     explicit Mat(const gpu::GpuMat& m);
    47 
    48     //! destructor - calls release()
    49     ~Mat();
    50     //! assignment operators
    51     Mat& operator = (const Mat& m);
    52     Mat& operator = (const MatExpr& expr);

    我们可以采用上述函数构造Mat对象,如

    1 Mat A, C;   //缺省构造函数,只创建了头部分,没有实际数据
    2 A = imread("1.jpg", CV_LOAD_IMAGE_COLOR);//将图片1数据读入A中
    3 Mat B(A);        //使用复制构造函数使B指向A的数据
    4 C=A;              //使用赋值构造函数使C指向A的数据
    5 Mat D(2,2, CV_8UC3, Scalar(0,0,255))  //利用带参数的构造函数创建对象

    Mat对象采用了引用计算的方法,A,C,B只是头不同,但都指向相同的数据,每当复制一个Mat对象的头时,引用计数加1,当清除一个头时,引用计数减1,当引用计数为0时,释放资源。为了复制数据,可以采用Mat类中的clone()copyTo()方法。

    2 用Mat类中的方法处理图像

    利用at方法改变图像中每一个位置的像素值

    Process(Mat & image)
    {
    for(int i=0;i<image.rows;i++)
    for(int j=0;j<image.cols;j++)
    {
    if (image.channels() == 1) { // gray-level image image.at<uchar>(j,i)= 255; } else if (image.channels() == 3) { // color image image.at<cv::Vec3b>(j,i)[0]= 255; image.at<cv::Vec3b>(j,i)[1]= 255; image.at<cv::Vec3b>(j,i)[2]= 255; }
    } }

    利用ptr方法可以进行同样的操作

    Process(Mat & image)
    {  
       int row=image.rows;
       int cn=image.cols*image.channel();//每一行的数据
       for(int i=0;i<row;i++)
      {
          //得到第i行的地址
         uchar* data= image.ptr<uchar>(j);
         for(int j=0;j<cn;j++)
         {
           data[j]=255;
         }
      }
    }

     使用迭代器

    Process(Mat & image)
    { 
    if (image.channels() == 1) { // gray-level image Mat_<uchar>::iterator it=image.begin<uchar>();
    Mat_<uchar>::iterator itend=image.end<uchar>();
    for(;it!=itend;it++)
    *it=255; }
    else if (image.channels() == 3) { // color image Mat_<Vec3b>::iterator it=image.begin<Vec3b>();
    Mat_<Vec3b>::iterator itend=image.end<Vec3b>();
    for(;it!=itend;it++)
    {
    (*it)[0]=255;
    (*it)[1]=255;
    (*it)[2]=255;
    }

    }
    }

    利用邻域像素点作处理,如图像的锐化

    void sharpen(const cv::Mat &image, cv::Mat &result) 
    {
    // allocate if necessary result.create(image.size(), image.type()); for (int j= 1; j<image.rows-1; j++)
    {
    const uchar* previous= image.ptr<const uchar>(j-1); // 前一行 const uchar* current= image.ptr<const uchar>(j); // 当前行 const uchar* next= image.ptr<const uchar>(j+1); // 下一行 uchar* output= result.ptr<uchar>(j); // 输出行 for (int i=1; i<image.cols-1; i++)
    {
    *output++= cv::saturate_cast<uchar>( 5*current[i]-current[i-1] -current[i+1]-previous[i]-next[i]); } } // 将未处理的像素设为0 result.row(0).setTo(cv::Scalar(0)); result.row(result.rows-1).setTo(cv::Scalar(0)); result.col(0).setTo(cv::Scalar(0)); result.col(result.cols-1).setTo(cv::Scalar(0)); }

    上述过程实际是利用一个3×3的模板对原始图像作卷积,opencv中的函数filter2D可以实现该过程

    void sharpen2D(const cv::Mat &image, cv::Mat &result) 
    {
    // 创建卷积核 cv::Mat kernel(3,3,CV_32F,cv::Scalar(0)); // 设置卷积核的值 kernel.at<float>(1,1)= 5.0; kernel.at<float>(0,1)= -1.0; kernel.at<float>(2,1)= -1.0; kernel.at<float>(1,0)= -1.0; kernel.at<float>(1,2)= -1.0; //实现卷积计算 cv::filter2D(image,result,image.depth(),kernel); }
     
  • 相关阅读:
    TFTP服务器的使用
    SecureCRT Ver 8.1.4 整合汉化绿色版一体包
    SecureCRT Ver 8.1.4 整合汉化绿色版一体包
    深度好贴,mark一下!
    DataSnap——利用TParams进行多表事务更新
    临时表经典使用范例
    PHP对文件的操作方法
    中国银行支付接口(ecshop版)
    常用支付接口实例php版
    PHPCMS网站二次开发配置要点
  • 原文地址:https://www.cnblogs.com/zhulong890816/p/4600681.html
Copyright © 2011-2022 走看看