zoukankan      html  css  js  c++  java
  • opencv-图像遍历

    利用at

    单通道

         cv::Mat M(5, 4, CV_8UC1);  //单通道矩阵--灰度
         int ch=M.channels();
         std::cerr<<M<<std::endl;
         int r=M.rows;
         int c=M.cols;
         qDebug()<<"行数:"<<r<<";"<<"列数:"<<c<<Qt::endl;
        for(int i=0;i<r;i++){  //i是行号
            for(int j=0;j<c;j++){  //j是列号
                int t=M.at<uchar>(i,j); //返回指点坐标的数据
                //无符号数据用uchar;float数据用float
                std::cout<<t<<";";
            }
            std::cout<<std::endl;
        }
    
        M.at<uchar>(3,2)=99; //修改指点坐标的值
        std::cout<<M<<std::endl;
    
        qDebug()<<"通道数:"<<ch<<Qt::endl;

     3通道

         cv::Mat M(5, 4, CV_8UC3);  //3通道矩阵
         int ch=M.channels();
         std::cerr<<M<<std::endl;
         int r=M.rows;
         int c=M.cols;
         qDebug()<<"行数:"<<r<<";"<<"列数:"<<c<<Qt::endl;
        for(int i=0;i<r;i++){  //i是行号
            for(int j=0;j<c;j++){  //j是列号
                int t=M.at<cv::Vec3b>(i,j)[0]; //返回指点坐标的B值
                //注意:用cv::Vec3b;i和j确定像素点;[]里确定哪个通道
                int t1=M.at<cv::Vec3b>(i,j)[1]; //返回指点坐标的G值
                int t2=M.at<cv::Vec3b>(i,j)[2]; //返回指点坐标的R值
    
                std::cout<<t<<","<<t1<<","<<t2<<";";
            }
            std::cout<<std::endl;
        }
    
        M.at<cv::Vec3b>(3,2)[1]=99; //修改指点坐标的G值
        std::cout<<M<<std::endl;
    
        qDebug()<<"通道数:"<<ch<<Qt::endl;

    利用指针:优点效率高点 

         cv::Mat M(5, 4, CV_8UC3);  //3通道矩阵
    int ch=M.channels();
         int nr=M.rows;
         int c=M.cols;
         int nl=c*ch;  //nl是数据列数
         //注意:M.cols是像素点列数,而每个像素点分成RGB三个数据,所以数据列数=像素点列数*通道数
    
         std::cerr<<M<<std::endl;
    
         uchar p01 = M.ptr<uchar>(0)[2];  //返回指定行指定数据列的数值
         //()里是行号,[]里是列号
         uchar* p0 = M.ptr<uchar>(0);  //返回指定行的首地址
         uchar pp01=p0[2];   //返回指针指定行的指定数据列的数值
    
         M.ptr<uchar>(0)[2]=99;  //修改指定行指定数据列的数值
         p0[1]=88;       //修改指针指定行的指定数据列的数值
    
        std::cerr<<M<<std::endl;
    
        qDebug()<<"通道数:"<<ch<<Qt::endl;
        qDebug()<<p01<<Qt::endl;
        qDebug()<<pp01<<Qt::endl;

     连续矩阵

    一行数据肯定是连续的,但是行与行之间不一定是连续的
    一般用Mat::creat()创建的矩阵都是连续的,但是也不绝对,依然需要判断才可以进行连续性操作。而从图像中截取的图像通常是不连续的,如果想将其转换为连续存储,可以用clone进行拷贝一份
    m*n的数据就是需要判断连续性的。如果数据存储是连续的,可以将图像看出一个一维数组。否则只能用二维数据方式进行访问

         cv::Mat M(5, 4, CV_8UC3);
        bool b=M.isContinuous();  //判断行与行之间的储存是否连续
        
        std::cerr<<M<<std::endl;
    
        int nl=M.rows*M.cols*M.channels();  //连续矩阵可以看做一行;总列数=行数*像素点列数*通道
        if(b==true){
            for(int j=0;j<nl;j++){
                uchar t = M.ptr<uchar>(0)[j]; //返回指定位置的数据
                //连续矩阵看做一行,所以行号是0
                qDebug()<<t;
            }
            qDebug()<<Qt::endl;
        }
        M.ptr<uchar>(0)[1]=99;  //修改指定位置的值
        std::cerr<<M<<std::endl;
    
        qDebug()<<b<<Qt::endl;

    利用迭代器 

         cv::Mat M(5, 4, CV_8UC3);
         std::cerr<<M<<std::endl;
         cv::Mat MM(5, 4, CV_8UC3);
         std::cerr<<MM<<std::endl;
    
       //非常量迭代器--通过迭代器可以修改数据
         cv::Mat_<cv::Vec3b>::iterator it1 = M.begin<cv::Vec3b>(); //图像左上角位置的迭代器--方式一
    
         cv::MatIterator_<cv::Vec3b> it = M.begin<cv::Vec3b>();   //图像左上角位置的迭代器--方式二
         cv::MatIterator_<cv::Vec3b> itend = M.end<cv::Vec3b>();   //图像末尾位置的迭代器
    
         //常量迭代器--通过迭代器不能修改数据
          cv::Mat_<cv::Vec3b>::const_iterator itt1=MM.begin<cv::Vec3b>();//方式一
          cv::MatConstIterator_<cv::Vec3b> itt = MM.begin<cv::Vec3b>();   //方式二
          cv::MatConstIterator_<cv::Vec3b> ittend=MM.end<cv::Vec3b>();
    
    
    
         int i=0,i1=0,i2=0;
         for (; it != itend; it++,itt++){
             i=(*it)[0]; //返回迭代器所指像素点的B值
             //*it 表示迭代器所指的像素点
             i1=(*it)[1]; //返回迭代器所指像素点的G值
             i2=(*it)[2]; //返回迭代器所指像素点的R值
             std::printf("%u,%u,%u;",i,i1,i2);
             //修改M的值;把MM的值给M
             (*it)[0]=(*itt)[0];
             (*it)[1]=(*itt)[1];
             (*it)[2]=(*itt)[2];
            }
            std::cerr<<M<<std::endl;

     块操作

    行列操作

         cv::Mat M(5, 4, CV_8UC3);
         std::cerr<<M<<std::endl;
    
         cv::Mat mRow=M.row(0);  //创建一个矩阵头(浅拷贝,数据共享),指向指定行的数据
         //mRow是1行M.cols*M.channels()列的矩阵
         cv::Mat mCol=M.col(0);  //创建一个矩阵头(浅拷贝,数据共享),指向指定像素列的数据
         //mCol是M.rows行M.channels()列的矩阵
    
        cv::Mat mR = M.rowRange(1,3).clone();  //创建一个矩阵头(浅拷贝,数据共享),指向指定所有行的数据
        //参数是前闭后开;上面参数指向的是第二行和第三行的数据,不包括第四行
    
        cv::Mat mC = M.colRange(1,3); //创建一个矩阵头(浅拷贝,数据共享),指向指定所有像素列的数据
        //参数是前闭后开;上面参数指向的是第二像素列和第三像素列的数据,不包括第四像素列
    
        mRow.ptr<uchar>(0)[1]=99;
    
         std::cerr<<mRow<<std::endl;
         std::cerr<<M<<std::endl;

    区域操作

         cv::Mat M(10, 9, CV_8UC3);
         std::cerr<<M<<std::endl;
    
         cv::Mat MM=M(cv::Rect(1,2,3,5));//创建一个矩阵头(浅拷贝,数据共享),指向指定区域的数据
         /*参数1:起始像素点列号--从0开始
           参数2:起始像素点行号
           参数3:总像素点列数
           参数4:总像素点行数
    */
         std::cerr<<MM<<std::endl;
    
         MM.at<cv::Vec3b>(3,1)[1]=99;
    
         std::cerr<<MM<<std::endl;
         std::cerr<<M<<std::endl;

    指向对角线像素点 

         cv::Mat M(5, 4, CV_8UC3);
         std::cerr<<M<<std::endl;
    
         cv::Mat mD=M.diag(0);  //创建一个矩阵头(浅拷贝,数据共享),指向M对角线像素点
         //参数=0  表示主对角线
    
         std::cerr<<mD<<std::endl;
    
        mD.ptr<uchar>(0)[1]=99;
    
         std::cerr<<M<<std::endl;
         std::cerr<<mD<<std::endl;

         cv::Mat M(5, 4, CV_8UC3);
         std::cerr<<M<<std::endl;
    
         cv::Mat mD=M.diag(1);
         //参数n>0  表示对角线向右移动n像素点
    
         std::cerr<<mD<<std::endl;

         cv::Mat M(5, 4, CV_8UC3);
         std::cerr<<M<<std::endl;
    
         cv::Mat mD=M.diag(-1);
         //参数n<0  表示对角线向下移动n像素点
    
         std::cerr<<mD<<std::endl;



  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15370674.html
Copyright © 2011-2022 走看看