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()函数,因为使用这个函数其效率不高,但是其可读性较好。

  • 相关阅读:
    mysql 加入列,改动列,删除列。
    C语言中的static 具体分析
    [Python网络编程]gevent httpclient以及网页编码
    iOS学习之 plist文件的读写
    数据库设计中的14个技巧
    最简单的基于FFMPEG的封装格式转换器(无编解码)
    一次重要的爱情婚姻抉择,您怎么看?
    2014年到期的myeclipse5.5.1注冊码
    24点经典算法
    使用val()方法设置表单中的默认选中项
  • 原文地址:https://www.cnblogs.com/cc111/p/9276411.html
Copyright © 2011-2022 走看看