【slam十四讲_相机与图像】—ch5.mageBasics.cpp的代码解释及总结

文章目录

    • 1. 关于int main(int argc,char** argv)中argc,argv参数的解释
    • 2.关于 cv::waitKey(0)的解释:
    • 3.像素的表示:
    • 4.给算法计时:
        • 1. 头文件为:#include
        • 2. 头文件为:#include
        • 3.opencv计时函数:
        • 4.复制图像的方式:
        • 5. 遍历图像像素的方法:
        • 示例:
      • 三种遍历像素的方法对比:

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

            clock_t time_stt=clock();
            在执行相关算法处理之后计算用时: (clock()-time_stt)/(double)CLOCKS_PER_SEC(见p46)

2. 头文件为:#include

              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();    

4.复制图像的方式:

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

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

  参考:1.https://blog.csdn.net/keith_bb/article/details/53071133
  对图像像素进行遍历时共有三种方法: 1). 动态地址计算
                    2). 迭代器iterator 
                    3). C操作符[] (指针方式访问)

示例:

  #include 
#include 
#include 

using namespace std;
using namespace cv;

void colorReduceAt(Mat& dstImageAt,int div);
void colorReduceIterator(Mat &dstImageIterator, int div);
void colorReducePtr(Mat &dstImagePtr, int div);

int main(int argc,char** argv)
{
    Mat srcImg=imread(argv[1]);
    if(argc!=1)
    {
        cout<<"usage:./total lena.png"<<endl;
    }
    imshow("lena.png",srcImg);

    //声明处理后图像变量
    Mat dstImageAt,dstImageIterator,dstImagePtr;
    dstImageAt=srcImg.clone();
    dstImageIterator=srcImg.clone();
    dstImagePtr=srcImg.clone();

    int div=50;

    //声明时间变量
    double timeAt,timeIterator,timePtr;

    //at()
    timeAt=static_cast<double>(getTickCount());
    colorReduceAt(dstImageAt,div);
    timeAt=((double)getTickCount()-timeAt)/getTickFrequency();
    imshow("dstImageAt_lena.png",dstImageAt);
    cout<<"使用at()动态地址计算耗时:"<<timeAt<<"s"<<endl<<endl;

    //iterator
    timeIterator=static_cast<double>(getTickCount());
    colorReduceAt(dstImageIterator,div);
    timeIterator=((double)getTickCount()-timeIterator)/getTickFrequency();
    imshow("dstImageIterstor_lena.png",dstImageIterator);
    cout<<"使用iterator迭代器计算耗时:"<<timeIterator<<"s"<<endl<<endl;

    //ptr
    timePtr=static_cast<double>(getTickCount());
    colorReducePtr(dstImagePtr,div);
    timePtr=((double)getTickCount()-timePtr)/getTickFrequency();
    imshow("dstImagePtr_lena.png",dstImagePtr);
    cout<<"使用ptr指针计算耗时:"<<timePtr<<"s"<<endl<<endl;

    waitKey(0);
}

//使用at动态地址计算方式
//用函数at()来实现对矩阵中某个像素值进行读取
//以及进行赋值操作
void colorReduceAt( Mat &dstImageAt, int div)
{
    int rowNumber=dstImageAt.rows;//获取图像行数
    int colNumber=dstImageAt.cols;//获取图像列数

    //对每个像素进行处理
    for(int i=0;i<rowNumber;++i)
    {
        for(int j=0;j<colNumber;++j)
        {
            dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Blue
            dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Green
            dstImageAt.at<Vec3b>(i,j)[0]=dstImageAt.at<Vec3b>(i,j)[0]/div*div;//Red
        }
    }
}

//使用iterator迭代器方式
void colorReduceIterator(Mat &dstImageIterator, int div)
{
    MatIterator_<Vec3b> imageIt=dstImageIterator.begin<Vec3b>();//获取迭代器初始位置
    MatIterator_<Vec3b> imageEnd=dstImageIterator.end<Vec3b>();//获取迭代器结束位置

    for(;imageIt!=imageEnd;++imageIt)
    {
        (*imageIt)[0]=(*imageIt)[0]/div*div;//Blue
        (*imageIt)[1]=(*imageIt)[1]/div*div;//Green
        (*imageIt)[2]=(*imageIt)[2]/div*div;//Red
    }
}

//使用ptr指针
void colorReducePtr(Mat &dstImagePtr, int div)
{
    int rowNumber=dstImagePtr.rows;
    int colNumber=dstImagePtr.cols;

    for(int i=0;i<rowNumber;++i)
    {
        uchar* pixelPtr=dstImagePtr.ptr<uchar>(i);//获取矩阵每行首地址
        for(int j=0;j<colNumber;++j)
        {
            pixelPtr[j]=pixelPtr[j]/div*div;
        }
    }
}

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

从上述的运行结果中,我们可以看出指针方式是最快的处理方式,而迭代器的方式相对最慢。但是使用迭代器是较为安全的访问方式。
如果需要对图像像素进行遍历,不推荐使用at()函数,因为使用这个函数其效率不高,但是其可读性较好。

参考:1.https://www.cnblogs.com/cc111/p/9276411.html

声明:本人写博客只为记录学习点滴,加深印象。

你可能感兴趣的:(SLAM)