09_opencv_遍历操作图像像素

指针访问图像像素

c 复制代码
uchar* data = outputImage.ptr<uchar>(i);  //获取第i行的首地址

遍历每一个像素

c 复制代码
 //双重循环,遍历所有的像素值
    for(int i = 0;i < rowNumber;i++)  //行循环
    {
        uchar* data = outputImage.ptr<uchar>(i);  //获取第i行的首地址
        for(int j = 0;j < colNumber;j++)   //列循环
        {
            printf("data[%d]= %d\n",j,data[j]);
            // ---------【开始处理每个像素】-------------
            data[j] = data[j]/div*div + div/2;
            // int 类型除法操作会自动截余。例如 lold=14;Inew=(lold/10)*10=(14/10)*10=1*10=10;
            // ----------【处理结束】---------------------
            printf("颜色空间缩减后的data[%d]= %d\n",j,data[j]);
        }  //行处理结束
    }

利用指针对图像像素进行颜色空间缩减

若矩阵元素存储的是单通道像素,使用C或 C++的无符号字符类型,那么像素可有 256 个不同值。

若是三通道图像,这种存储格式的颜色数就太多了(确切地说,有一千六百多万种)256∗256∗256256*256*256256∗256∗256。

颜色空间缩减(color space reduction)便可以派上用场了,它在很多应用中可以大大降低运算复杂度。颜色空间缩减的做法是:将现有颜色空间值除以某个输入值,以获得较少的颜色数


c 复制代码
//---------------------------------【头文件、命名空间包含部分】--------------------------
//        描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;

//-----------------------------------【全局函数声明部分】-----------------------------------
//          描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//--------------------------------------【main( )函数】---------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
    //【1】创建原始图并显示
    Mat srcImage = imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/21.jpg");
    imshow("原始图像",srcImage);

    //【2】按原始图的参数规格来创建创建效果图
    Mat dstImage;
    dstImage.create(srcImage.rows,
                    srcImage.cols,
                    srcImage.type());//效果图的大小、类型与原图片相同

    cout<<"srcImage_rows = " << srcImage.rows << endl;
    cout<<"srcImage_cols = " << srcImage.cols << endl;
    cout<<"srcImage_type = " << srcImage.type() << endl << endl;
    
    cout<< "srcImage = " << srcImage << endl << "-------------------"<< endl;
    
    //【3】记录起始时间
    double time0 = static_cast<double>(getTickCount());

    //【4】调用颜色空间缩减函数
    colorReduce(srcImage,dstImage,32);

    //【5】计算运行时间并输出
    time0 = ((double)getTickCount() - time0)/getTickFrequency();
    cout<<"\t此方法运行时间为: "<<time0<<"秒"<<endl;  //输出运行时间

    //【6】显示效果图
    imshow("效果图",dstImage);
    waitKey(0);
}

//---------------------------------【colorReduce( )函数】---------------------------------
//          描述:使用【指针访问:C操作符[ ]】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
    //参数准备
    outputImage = inputImage.clone();  //拷贝实参到临时变量
    int rowNumber = outputImage.rows;  //行数
    int colNumber = outputImage.cols*outputImage.channels();  //列数 x 通道数=每一行元素的个数

    //双重循环,遍历所有的像素值
    for(int i = 0;i < rowNumber;i++)  //行循环
    {
        uchar* data = outputImage.ptr<uchar>(i);  //获取第i行的首地址
        for(int j = 0;j < colNumber;j++)   //列循环
        {
            printf("data[%d]= %d\n",j,data[j]);
            // ---------【开始处理每个像素】-------------
            data[j] = data[j]/div*div + div/2;
            // int 类型除法操作会自动截余。例如 lold=14;Inew=(lold/10)*10=(14/10)*10=1*10=10;
            // ----------【处理结束】---------------------
            printf("颜色空间缩减后的data[%d]= %d\n",j,data[j]);
            
        }  //行处理结束
    }
}

迭代器访问图像像素

c 复制代码
//参数准备
    outputImage = inputImage.clone();  //拷贝实参到临时变量
    //获取迭代器
    Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();  //初始位置的迭代器
    Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();  //终止位置的迭代器

    //存取彩色图像像素
    for(;it != itend;++it)
    {
        // ------------------------【开始处理每个像素】--------------------
        (*it)[0] = (*it)[0]/div*div + div/2;
        (*it)[1] = (*it)[1]/div*div + div/2;
        (*it)[2] = (*it)[2]/div*div + div/2;
        // ------------------------【处理结束】----------------------------
    }

利用迭代器对图像进行颜色空间缩减

c 复制代码
//---------------------------------【头文件、命名空间包含部分】---------------------------
//        描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//-----------------------------------【全局函数声明部分】-----------------------------------
//        描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//--------------------------------------【main( )函数】--------------------------------------
//        描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
    //【1】创建原始图并显示
    Mat srcImage = imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/21.jpg");
    imshow("原始图像",srcImage);

    //【2】按原始图的参数规格来创建创建效果图
    Mat dstImage;
    dstImage.create(srcImage.rows,srcImage.cols,srcImage.type());//效果图的大小、类型与原图片相同







   //【3】记录起始时间
    double time0 = static_cast<double>(getTickCount());

    //【4】调用颜色空间缩减函数
    colorReduce(srcImage,dstImage,32);

    //【5】计算运行时间并输出
    time0 = ((double)getTickCount() - time0)/getTickFrequency();
    cout<<"此方法运行时间为: "<<time0<<"秒"<<endl;  //输出运行时间

    //【6】显示效果图
    imshow("效果图",dstImage);
    waitKey(0);
}

//-------------------------------------【colorReduce( )函数】-----------------------------
//        描述:使用【迭代器】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
    //参数准备
    outputImage = inputImage.clone();  //拷贝实参到临时变量
    //获取迭代器
    Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();  //初始位置的迭代器
    Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();  //终止位置的迭代器

    //存取彩色图像像素
    for(;it != itend;++it)
    {
        printf("iterator = %d,%d,%d \n",(*it)[0],(*it)[1],(*it)[2]);
        // ------------------------【开始处理每个像素】--------------------
        (*it)[0] = (*it)[0]/div*div + div/2;
        (*it)[1] = (*it)[1]/div*div + div/2;
        (*it)[2] = (*it)[2]/div*div + div/2;
        // ------------------------【处理结束】----------------------------
        printf("颜色空间减缩后的iterator = %d,%d,%d \n",(*it)[0],(*it)[1],(*it)[2]);
    }
}


动态地址配合at 方法访问

c 复制代码
//存取彩色图像像素
    for(int i = 0;i < rowNumber;i++)
    {
        for(int j = 0;j < colNumber;j++)
        {
            // ------------------------【开始处理每个像素】--------------------
            outputImage.at<Vec3b>(i,j)[0] =  outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;  //蓝色通道
            outputImage.at<Vec3b>(i,j)[1] =  outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;  //绿色通道
            outputImage.at<Vec3b>(i,j)[2] =  outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;  //红是通道
            // -------------------------【处理结束】----------------------------
        }  // 行处理结束
    }

利用动态地址at方法对对象进行空间颜色缩减

c 复制代码
//-----------------------------【头文件、命名空间包含部分】------------------------------
//          描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;

//-----------------------------------【全局函数声明部分】-----------------------------------
//          描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//--------------------------------------【main( )函数】---------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
    system("color 9F");
    //【1】创建原始图并显示
    Mat srcImage = imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/21.jpg");
    imshow("原始图像",srcImage);

    //【2】按原始图的参数规格来创建创建效果图
    Mat dstImage;
    dstImage.create(srcImage.rows,srcImage.cols,srcImage.type());//效果图的大小、类型与原图片相同

    //【3】记录起始时间
    double time0 = static_cast<double>(getTickCount());

    //【4】调用颜色空间缩减函数
    colorReduce(srcImage,dstImage,32);

    //【5】计算运行时间并输出
    time0 = ((double)getTickCount() - time0)/getTickFrequency();
    cout<<"此方法运行时间为: "<<time0<<"秒"<<endl;  //输出运行时间

    //【6】显示效果图
    imshow("效果图",dstImage);
    waitKey(0);
}


//----------------------------------【colorReduce( )函数】-------------------------------
//          描述:使用【动态地址运算配合at】方法版本的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
    //参数准备
    outputImage = inputImage.clone();  //拷贝实参到临时变量
    int rowNumber = outputImage.rows;  //行数
    int colNumber = outputImage.cols;  //列数

    //存取彩色图像像素
    for(int i = 0;i < rowNumber;i++)
    {
        for(int j = 0;j < colNumber;j++)
        {
            printf("%d行,%d列 的三通道像素为 %d,%d,%d\n",i,j,outputImage.at<Vec3b>(i,j)[0],
                   outputImage.at<Vec3b>(i,j)[1],outputImage.at<Vec3b>(i,j)[2]);
            // ------------------------【开始处理每个像素】--------------------
            outputImage.at<Vec3b>(i,j)[0] =  outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;  //蓝色通道
            outputImage.at<Vec3b>(i,j)[1] =  outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;  //绿色通道
            outputImage.at<Vec3b>(i,j)[2] =  outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;  //红是通道
            // -------------------------【处理结束】----------------------------
            printf("%d行,%d列 的三通道像素颜色空间缩减成 %d,%d,%d\n",i,j,outputImage.at<Vec3b>(i,j)[0],
                   outputImage.at<Vec3b>(i,j)[1],outputImage.at<Vec3b>(i,j)[2]);
        }  // 行处理结束
    }
}

其他十四种遍历图像的方法

c 复制代码
//---------------------------------【头文件、命名空间包含部分】-----------------------------
//        描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
//---------------------------------【宏定义部分】---------------------------------------------
//        描述:包含程序所使用宏定义
//-------------------------------------------------------------------------------------------------
#define NTESTS 14
#define NITERATIONS 20
//----------------------------------------- 【方法一】-------------------------------------------
//        说明:利用.ptr 和 []
//-------------------------------------------------------------------------------------------------
void colorReduce0(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量
              
      for (int j=0; j<nl; j++)
      {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++)
          {
 
            //-------------开始处理每个像素-------------------
                 
                  data[i]= data[i]/div*div + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

//-----------------------------------【方法二】-------------------------------------------------
//        说明:利用 .ptr 和 * ++
//-------------------------------------------------------------------------------------------------
void colorReduce1(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量
              
      for (int j=0; j<nl; j++)
      {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++)
          {
 
            //-------------开始处理每个像素-------------------
                 
                 *data++= *data/div*div + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

//-----------------------------------------【方法三】-------------------------------------------
//        说明:利用.ptr 和 * ++ 以及模操作
//-------------------------------------------------------------------------------------------------
void colorReduce2(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量
              
      for (int j=0; j<nl; j++)
      {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++)
          {
 
            //-------------开始处理每个像素-------------------
       
                  int v= *data;
                  *data++= v - v%div + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

//----------------------------------------【方法四】---------------------------------------------
//        说明:利用.ptr 和 * ++ 以及位操作
//----------------------------------------------------------------------------------------------------
void colorReduce3(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 对于 div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            //------------开始处理每个像素-------------------
                 
            *data++= *data&mask + div/2;
 
            //-------------结束像素处理------------------------
            }  //单行处理结束
      }
}


//----------------------------------------【方法五】----------------------------------------------
//        说明:利用指针算术运算
//---------------------------------------------------------------------------------------------------
void colorReduce4(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      int step= image.step; //有效宽度
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 对于 div=16, mask= 0xF0
              
      //获取指向图像缓冲区的指针
      uchar *data= image.data;

      for (int j=0; j<nl; j++)
      {

          for (int i=0; i<nc; i++)
          {
 
            //-------------开始处理每个像素-------------------
                 
            *(data+i)= *data&mask + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束

            data+= step;  // next line
      }
}

//---------------------------------------【方法六】----------------------------------------------
//        说明:利用 .ptr 和 * ++以及位运算、image.cols * image.channels()
//-------------------------------------------------------------------------------------------------
void colorReduce5(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 例如div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++)
      {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<image.cols * image.channels(); i++)
          {
 
            //-------------开始处理每个像素-------------------
                 
            *data++= *data&mask + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

// -------------------------------------【方法七】----------------------------------------------
//        说明:利用.ptr 和 * ++ 以及位运算(continuous)
//-------------------------------------------------------------------------------------------------
void colorReduce6(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols * image.channels(); //每行元素的总元素数量

      if (image.isContinuous())
      {
          //无填充像素
          nc= nc*nl;
          nl= 1;  // 为一维数列
       }

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 比如div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            //-------------开始处理每个像素-------------------
                 
            *data++= *data&mask + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

//------------------------------------【方法八】------------------------------------------------
//        说明:利用 .ptr 和 * ++ 以及位运算 (continuous+channels)
//-------------------------------------------------------------------------------------------------
void colorReduce7(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols ; //列数

      if (image.isContinuous())
      {
          //无填充像素
          nc= nc*nl;
          nl= 1;  // 为一维数组
       }

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 比如div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            //-------------开始处理每个像素-------------------
                 
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}


// -----------------------------------【方法九】 ------------------------------------------------
//        说明:利用Mat_ iterator
//-------------------------------------------------------------------------------------------------
void colorReduce8(Mat &image, int div=64) {

      //获取迭代器
      Mat_<Vec3b>::iterator it= image.begin<Vec3b>();
      Mat_<Vec3b>::iterator itend= image.end<Vec3b>();

      for ( ; it!= itend; ++it) {
        
        //-------------开始处理每个像素-------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        //-------------结束像素处理------------------------
      }//单行处理结束
}

//-------------------------------------【方法十】-----------------------------------------------
//        说明:利用Mat_ iterator以及位运算
//-------------------------------------------------------------------------------------------------
void colorReduce9(Mat &image, int div=64) {

      // div必须是2的幂
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 比如 div=16, mask= 0xF0

      // 获取迭代器
      Mat_<Vec3b>::iterator it= image.begin<Vec3b>();
      Mat_<Vec3b>::iterator itend= image.end<Vec3b>();

      //扫描所有元素
      for ( ; it!= itend; ++it)
      {
        
        //-------------开始处理每个像素-------------------

        (*it)[0]= (*it)[0]&mask + div/2;
        (*it)[1]= (*it)[1]&mask + div/2;
        (*it)[2]= (*it)[2]&mask + div/2;

        //-------------结束像素处理------------------------
      }//单行处理结束
}

//------------------------------------【方法十一】---------------------------------------------
//        说明:利用Mat Iterator_
//-------------------------------------------------------------------------------------------------
void colorReduce10(Mat &image, int div=64) {

      //获取迭代器
      Mat_<Vec3b> cimage= image;
      Mat_<Vec3b>::iterator it=cimage.begin();
      Mat_<Vec3b>::iterator itend=cimage.end();

      for ( ; it!= itend; it++) {
        
        //-------------开始处理每个像素-------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        //-------------结束像素处理------------------------
      }
}

//--------------------------------------【方法十二】--------------------------------------------
//        说明:利用动态地址计算配合at
//-------------------------------------------------------------------------------------------------
void colorReduce11(Mat &image, int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols; //列数
              
      for (int j=0; j<nl; j++)
      {
          for (int i=0; i<nc; i++)
          {
 
            //-------------开始处理每个像素-------------------
                 
                  image.at<Vec3b>(j,i)[0]=     image.at<Vec3b>(j,i)[0]/div*div + div/2;
                  image.at<Vec3b>(j,i)[1]=     image.at<Vec3b>(j,i)[1]/div*div + div/2;
                  image.at<Vec3b>(j,i)[2]=     image.at<Vec3b>(j,i)[2]/div*div + div/2;
 
            //-------------结束像素处理------------------------
 
            } //单行处理结束
      }
}

//----------------------------------【方法十三】-----------------------------------------------
//        说明:利用图像的输入与输出
//-------------------------------------------------------------------------------------------------
void colorReduce12(const Mat &image, //输入图像
                 Mat &result,      // 输出图像
                 int div=64) {

      int nl= image.rows; //行数
      int nc= image.cols ; //列数

      //准备好初始化后的Mat给输出图像
      result.create(image.rows,image.cols,image.type());

      //创建无像素填充的图像
      nc= nc*nl;
      nl= 1;  //单维数组

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g.比如div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= result.ptr<uchar>(j);
          const uchar* idata= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            //-------------开始处理每个像素-------------------
                 
            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;
 
            //-------------结束像素处理------------------------
 
          } //单行处理结束
      }
}

//--------------------------------------【方法十四】-------------------------------------------
//        说明:利用操作符重载
//-------------------------------------------------------------------------------------------------
void colorReduce13(Mat &image, int div=64) {
    
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      //掩码值
      uchar mask= 0xFF<<n; // e.g. 比如div=16, mask= 0xF0

      //进行色彩还原
      image=(image&Scalar(mask,mask,mask))+Scalar(div/2,div/2,div/2);
}

//-----------------------------------【main( )函数】--------------------------------------------
//        描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main( )
{
    int64 t[NTESTS],tinit;
    Mat image0;
    Mat image1;
    Mat image2;

    system("color 4F");

    image0= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
    if (!image0.data)
        return 0;

    //时间值设为0
    for (int i=0; i<NTESTS; i++)
        t[i]= 0;


    // 多次重复测试
    int n=NITERATIONS;
    for (int k=0; k<n; k++)
    {
        cout << k << " of " << n << endl;

        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        //【方法一】利用.ptr 和 []
        tinit= getTickCount();
        colorReduce0(image1);
        t[0]+= getTickCount()-tinit;

        //【方法二】利用 .ptr 和 * ++
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce1(image1);
        t[1]+= getTickCount()-tinit;

        //【方法三】利用.ptr 和 * ++ 以及模操作
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce2(image1);
        t[2]+= getTickCount()-tinit;

        //【方法四】 利用.ptr 和 * ++ 以及位操作
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce3(image1);
        t[3]+= getTickCount()-tinit;

        //【方法五】 利用指针的算术运算
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce4(image1);
        t[4]+= getTickCount()-tinit;

        //【方法六】利用 .ptr 和 * ++以及位运算、image.cols * image.channels()
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce5(image1);
        t[5]+= getTickCount()-tinit;

        //【方法七】利用.ptr 和 * ++ 以及位运算(continuous)
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce6(image1);
        t[6]+= getTickCount()-tinit;

        //【方法八】利用 .ptr 和 * ++ 以及位运算 (continuous+channels)
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce7(image1);
        t[7]+= getTickCount()-tinit;

        //【方法九】 利用Mat_ iterator
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce8(image1);
        t[8]+= getTickCount()-tinit;

        //【方法十】 利用Mat_ iterator以及位运算
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce9(image1);
        t[9]+= getTickCount()-tinit;

        //【方法十一】利用Mat Iterator_
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce10(image1);
        t[10]+= getTickCount()-tinit;

        //【方法十二】 利用动态地址计算配合at
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce11(image1);
        t[11]+= getTickCount()-tinit;

        //【方法十三】 利用图像的输入与输出
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        Mat result;
        colorReduce12(image1, result);
        t[12]+= getTickCount()-tinit;
        image2= result;
        
        //【方法十四】 利用操作符重载
        image1= imread("/Volumes/Macintosh HD - 数据/Code/opencv_code/MyFirstOpenCV01/in_picture/24.png");
        tinit= getTickCount();
        colorReduce13(image1);
        t[13]+= getTickCount()-tinit;

        //------------------------------
    }
     //输出图像
    imshow("原始图像",image0);
    imshow("结果",image2);
    imshow("图像结果",image1);

    // 输出平均执行时间
    cout << endl << "-------------------------------------------" << endl << endl;
    cout << "\n【方法一】利用.ptr 和 []的方法所用时间为 " << 1000.*t[0]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法二】利用 .ptr 和 * ++ 的方法所用时间为" << 1000.*t[1]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法三】利用.ptr 和 * ++ 以及模操作的方法所用时间为" << 1000.*t[2]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法四】利用.ptr 和 * ++ 以及位操作的方法所用时间为" << 1000.*t[3]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法五】利用指针算术运算的方法所用时间为" << 1000.*t[4]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法六】利用 .ptr 和 * ++以及位运算、channels()的方法所用时间为" << 1000.*t[5]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法七】利用.ptr 和 * ++ 以及位运算(continuous)的方法所用时间为" << 1000.*t[6]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法八】利用 .ptr 和 * ++ 以及位运算 (continuous+channels)的方法所用时间为" << 1000.*t[7]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法九】利用Mat_ iterator 的方法所用时间为" << 1000.*t[8]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法十】利用Mat_ iterator以及位运算的方法所用时间为" << 1000.*t[9]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法十一】利用Mat Iterator_的方法所用时间为" << 1000.*t[10]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法十二】利用动态地址计算配合at 的方法所用时间为" << 1000.*t[11]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法十三】利用图像的输入与输出的方法所用时间为" << 1000.*t[12]/getTickFrequency()/n << "ms" << endl;
    cout << "\n【方法十四】利用操作符重载的方法所用时间为" << 1000.*t[13]/getTickFrequency()/n << "ms" << endl;
    
    waitKey();
    return 0;
}


相关推荐
中年程序员一枚9 分钟前
cv.drawChessboardCorners 是 OpenCV 中用于可视化棋盘格角点检测
人工智能·opencv·计算机视觉
深圳市快瞳科技有限公司21 分钟前
基于计算机视觉的鸟类数量统计技术原理解析
人工智能·计算机视觉
智驱力人工智能26 分钟前
超越识别 将光学字符识别(OCR)技术转化为可靠业务能力的交付思维 光学字符识别 金融票据OCR识别系统 物流单据自动识别技术
人工智能·opencv·算法·目标检测·ocr·边缘计算
Shiyuan71 小时前
【IEEE冠名EI会议】2026年IEEE第三届深度学习与计算机视觉国际会议
人工智能·深度学习·计算机视觉
mixboot1 小时前
OpenCV 源码编译并启用 .pc 文件生成
opencv
编码小哥1 小时前
OpenCV图像金字塔与图像拼接技术
人工智能·opencv·计算机视觉
cnnews1 小时前
用OpenCV实现烟花动画
开发语言·python·opencv·pygame·cv2
Rabi'1 小时前
Windows系统 Qt 整合 OpenCV4.12.0
开发语言·windows·qt·opencv
棒棒的皮皮1 小时前
【OpenCV】Python图像处理之形态学梯度运算
图像处理·python·opencv·计算机视觉
棒棒的皮皮2 小时前
【OpenCV】Python图像处理之开/闭运算
图像处理·python·opencv·计算机视觉