zoukankan      html  css  js  c++  java
  • OpenCv 2.4.9 (一) Mat基础结构&如何遍历图片

    前言


      因为对图像方面感兴趣,所以有空学学OpenCV的使用,并且希望以此为引子,带领自己入门图像领域。

      先post上几个参考网站,上面有完整源码:

      因为这么多资源,所以就不贴完整代码,这重点讲解某部分,方便自己以后回来查询。

    Mat - 基本的图像容器


    Mat

      在以前,opencv使用的是C结构,IplImage。但是使用这个结构有一个缺点就是你需要注意内存的申请和销毁。幸运的是,在C++我们可以使用一种更智能的结构,Mat。Mat会自动申请内存和销毁。

      Mat由基本的两部分组成:矩阵头(包含图片信息,例如矩阵大小,存储方法等)和一个指向包含像素点信息的指针。矩阵头部大小是常数,但是矩阵的大小却各不相同。

    1 Mat A, C;  // 只建立头部
    2 A = imread(fname, CV_LOAD_IMAGE_COLOR); 3 4 Mat B(A); // 调用copy构造函数 5 C = A; // 调用assign函数

      上面的所有对象都指向同一个矩阵,只是头部不一样而已。如果使用其中一个对象改变图像内容,所有指向这个矩阵的对象都会受影响。copy和assign只是复制头部的一些信息。

      我们可以调用其它方法实现深复制:

    1 Mat F = A.clone();
    2 Mat G;
    3 A.copyTo(G);

    显式创建Mat

      我们可以使用 imwrite() 函数来把一个矩阵写入到图片文件。但是为了调试方便,我们还可以使用<<输出(仅适用于二维矩阵)。

      下面是创建Mat对象的各种方法:

    • Mat()构造器
      1 Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255)); // CV_[多少位][有符号or无符号][类型前缀]C[通道数]
      2 cout << M <<endl;
      3 // [0, 0, 255, 0, 0, 255;
      4 //  0, 0, 255, 0, 0, 255
    • 使用CC++数组构造
      1 int sz[3] = {2, 2,2};
      2 Mat L(3, sz, CV_8UC(1), Scalar::all(0)); // 3维的[2, 2, 2]的图像
    • 为已存在IplImage指针构建头部
      1 IplImage* img = cvLoadImage(fname);
      2 Mat mtx(img);
    • Create() 函数
      1 M.create(4, 4, CV_8UC(2)); // 这种方法不能赋初值,只在中心分配内存时使用
      2 cout<< M << endl
    • Matlab风格的初始化
      1 Mat E = Mat::eye(4, 4, CV_64F);
      2 Mat O = Mat::ones(2, 2, CV_32F);
      3 Mat Z = Mat::zeros(3, 3, CV_8UC1);
    • 逗号分隔的初始化小矩阵
      1 Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    • 使用clone或copyTo。
      1 Mat RowClone = C.row(1).clone(); // randu(RowClone, Scalar::all(0), Scalar::all(255))可以在low和high之间随机

        

    怎样遍历图片


      首先,我们可以使用一段代码计算程序执行的时间:

    1 double t = (double)getTickCount();
    2 // do something
    3 t = ((double)getTickCount() - t) / getTickFrequency();

      

    图像的存储

      在RGB系统中,图像是这样存储的:(注意是BGR的形式,可以使用 isContinunous() 函数查看是否连续存放)

    (下面以颜色空间缩减为例子说明)

    C风格的读法

    先用指针p指向一行,然后再p[j]形式读取

    复制代码
     1 int channels = I.channels();
     2 int nRows = I.rows;
     3 int nCols = I.cols * channels;
     4 
     5 if (I.isContinuous()) {
     6     nCols = nCols * nRows;
     7     nRows = 1;
     8 }
     9 
    10 int i, j;
    11 uchar* p;
    12 for (i=0; i<nRows; ++i) {
    13     for (j=0; j<nCols; ++j) {
    14         p = I.ptr<uchar>(i);
    15         p[j] = table[p[j]]; //查表替换
    16     }
    17 }
    复制代码

    迭代(安全)方法

    迭代器从begin到end,使用(*it)[0]形式读取

    复制代码
    const int channels = I.channels();
    switch(channels)
    {
    case 1: {
        MatIterator_<uchar> it, end;
        for (it = I.begin<uchar>(), end=I.end<uchar>(); it != end; ++it)
            *it = table[*it];
        break;
        }
    case 3: {
        MatIterator_<Vec3b> it, end;
        for (it = I.begin<Vec3b>(), end=I.end<Vec3b>(); it != end; ++it)
            (*it)[0] = table[(*it)[0]];
            (*it)[1] = table[(*it)[1]];
            (*it)[2] = table[(*it)[2]];
        }
    }
    复制代码

     通过相关返回值的On-the-fly地址计算

    先把矩阵转换成Mat_,再用_I(i, j)[0]形式读取

    复制代码
    const int channels = I.channels();
    switch(channels)
    {
    case 1:
        {
            for (int i=0; i<I.rows; ++i)
                for (int j=0; j<I.cols; ++j)
                    I.at<uchar>(i, j) = table[I.at<uchar>(i, j)];
            break;
        }
    case 3:
        {
            Mat_<Vec3b> _I = I;
            for (int i=0; i<I.rows; ++i)
                for (int j=0; j<I.cols; ++j) {
                    _I(i, j)[0] = table[_I(i, j)[0]];
                    _I(i, j)[1] = table[_I(i, j)[1]];
                    _I(i, j)[2] = table[_I(i, j)[2]];
                }
            I = _I;
            break;
        }
    }
    复制代码

    快速实现表替换

    Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.data;
    for (int i=0; i < 256; ++i)
        p[i] = table[i];
    LUT(I, lookUpTable, I);
  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/zhengxingpeng/p/6685778.html
Copyright © 2011-2022 走看看