zoukankan      html  css  js  c++  java
  • <<视觉slam十四讲>>_ch5 实践部分之imageBasics.cpp的代码解释及总结

    1.关于int main(int argc,char** argv)中argc,argv参数的解释

       argc参数表示命令行中参数的个数,其值是在输入命令时由系统按实际参数的个数自动赋值的
          argv参数是字符串指针数组,存放命令行中的参数,长度即为参数个数argc
          其中的第0个参数是程序的全名,之后的参数由用户输入的参数确定

    2.关于 cv::waitKey(0)的解释:

      在inshow之后必须要有waitKey(k),以便给予足够的时间显示图像,功能是不断刷新图像。waitKey(k)仅对窗口机制起作用,其中k的单位为ms:如果k=0,表示无线等待下去,直到有按键按下,无返回值;如果k>0,表示等待的时间,若在这段时间内没有任何操作则等待结束后返回-1,如在期间输入了字符,则最终返回字符的ASCII码

    3.像素的表示:

      如果是灰度图,用8位整数(unsigned char)表示一个像素,即表示0~255的值.
           如果是RGB相机的深度图中,由于记录了各个像素与相机之间的距离(单位为毫米),而RGB相机的量程在十几米左右,超过了255,所以用16位整数(unsigned short)表示一个像素,即表示0~65536的值.
           如果是彩色图像,常见的是用三个通道(即red,blue,green三个颜色)表示任意一种色彩,而每个通道占8位,所以用24位表示一个像素.

    4.给算法计时:
        1).头文件为:#include<ctime>
            clock_t time_stt=clock();
            在执行相关算法处理之后计算用时: (clock()-time_stt)/(double)CLOCKS_PER_SEC(见p46)
        2).头文件为:#include <chrono>
              chrono::steady_clock::time_point t1=chrono::steady_clock::now();

        //...

        //program...

        //...

        chrono::steady_clock::time_point  t2=chrono::steady_clock::now();
           chrono::duration<double> time_used=chrono::duration_cast<chrono::duration<double>>(t2-t1);

      3)opencv计时函数:

         double t=static_cast<double> (getTickCount());

        //...

        //program...

        //...

        t = ((double)getTickCount()-t)/getTickFrequency();    

    5.复制图像的方式:
        1.直接赋值:在这种方式下的赋值,一旦对复制后的图像进行更改,则原图像也会改变
        2.使用clone函数赋值:对复制后的图像更改不会影响到原图像

    6. 遍历图像像素的方法:

      参考:https://blog.csdn.net/keith_bb/article/details/53071133

      对图像像素进行遍历时共有三种方法: 1). 动态地址计算
                        2). 迭代器iterator
                        3). C操作符[] (指针方式访问)

      我们给出一个综合例程:

      1 #include <iostream>
      2 #include <opencv2/core.hpp>
      3 #include <opencv2/highgui.hpp>
      4 
      5 using namespace std;
      6 using namespace cv;
      7 
      8 void colorReduceAt(Mat& dstImageAt,int div);
      9 void colorReduceIterator(Mat &dstImageIterator, int div);
     10 void colorReducePtr(Mat &dstImagePtr, int div);
     11 
     12 int main(int argc,char** argv)
     13 {
     14     Mat srcImg=imread(argv[1]);
     15     if(argc!=1)
     16     {
     17         cout<<"usage:./total lena.png"<<endl;
     18     }
     19     imshow("lena.png",srcImg);
     20 
     21     //声明处理后图像变量
     22     Mat dstImageAt,dstImageIterator,dstImagePtr;
     23     dstImageAt=srcImg.clone();
     24     dstImageIterator=srcImg.clone();
     25     dstImagePtr=srcImg.clone();
     26 
     27     int div=50;
     28 
     29     //声明时间变量
     30     double timeAt,timeIterator,timePtr;
     31 
     32     //at()
     33     timeAt=static_cast<double>(getTickCount());
     34     colorReduceAt(dstImageAt,div);
     35     timeAt=((double)getTickCount()-timeAt)/getTickFrequency();
     36     imshow("dstImageAt_lena.png",dstImageAt);
     37     cout<<"使用at()动态地址计算耗时:"<<timeAt<<"s"<<endl<<endl;
     38 
     39     //iterator
     40     timeIterator=static_cast<double>(getTickCount());
     41     colorReduceAt(dstImageIterator,div);
     42     timeIterator=((double)getTickCount()-timeIterator)/getTickFrequency();
     43     imshow("dstImageIterstor_lena.png",dstImageIterator);
     44     cout<<"使用iterator迭代器计算耗时:"<<timeIterator<<"s"<<endl<<endl;
     45 
     46     //ptr
     47     timePtr=static_cast<double>(getTickCount());
     48     colorReducePtr(dstImagePtr,div);
     49     timePtr=((double)getTickCount()-timePtr)/getTickFrequency();
     50     imshow("dstImagePtr_lena.png",dstImagePtr);
     51     cout<<"使用ptr指针计算耗时:"<<timePtr<<"s"<<endl<<endl;
     52 
     53     waitKey(0);
     54 }
     55 
     56 //使用at动态地址计算方式
     57 //用函数at()来实现对矩阵中某个像素值进行读取
     58 //以及进行赋值操作
     59 void colorReduceAt( Mat &dstImageAt, int div)
     60 {
     61     int rowNumber=dstImageAt.rows;//获取图像行数
     62     int colNumber=dstImageAt.cols;//获取图像列数
     63 
     64     //对每个像素进行处理
     65     for(int i=0;i<rowNumber;++i)
     66     {
     67         for(int j=0;j<colNumber;++j)
     68         {
     69             dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Blue
     70             dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Green
     71             dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Red
     72         }
     73     }
     74 }
     75 
     76 //使用iterator迭代器方式
     77 void colorReduceIterator(Mat &dstImageIterator, int div)
     78 {
     79     MatIterator_<Vec3b> imageIt=dstImageIterator.begin<Vec3b>();//获取迭代器初始位置
     80     MatIterator_<Vec3b> imageEnd=dstImageIterator.end<Vec3b>();//获取迭代器结束位置
     81 
     82     for(;imageIt!=imageEnd;++imageIt)
     83     {
     84         (*imageIt)[0]=(*imageIt)[0]/div*div;//Blue
     85         (*imageIt)[1]=(*imageIt)[1]/div*div;//Green
     86         (*imageIt)[2]=(*imageIt)[2]/div*div;//Red
     87     }
     88 }
     89 
     90 //使用ptr指针
     91 void colorReducePtr(Mat &dstImagePtr, int div)
     92 {
     93     int rowNumber=dstImagePtr.rows;
     94     int colNumber=dstImagePtr.cols;
     95 
     96     for(int i=0;i<rowNumber;++i)
     97     {
     98         uchar* pixelPtr=dstImagePtr.ptr<uchar>(i);//获取矩阵每行首地址
     99         for(int j=0;j<colNumber;++j)
    100         {
    101             pixelPtr[j]=pixelPtr[j]/div*div;
    102         }
    103     }
    104 } 

         运行结果:  

               

            

        三种遍历像素的方法对比:

             从上述的运行结果中,我们可以看出指针方式是最快的处理方式,而迭代器的方式相对最慢。但是使用迭代器是较为安全的访问方式。

            如果需要对图像像素进行遍历,不推荐使用at()函数,因为使用这个函数其效率不高,但是其可读性较好。

  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/cc111/p/9276411.html
Copyright © 2011-2022 走看看