09_opencv_遍历运行图像像素

指针访问图像像素

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

遍历每一个像素

//双重循环,遍历所有的像素值
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*256256256256
颜色空间缩减(color space reduction)便可以派上用场了,它在很多应用中可以大大降低运算复杂度。颜色空间缩减的做法是:将现有颜色空间值除以某个输入值,以获得较少的颜色数

在这里插入图片描述
在这里插入图片描述

//---------------------------------【头文件、命名空间包含部分】--------------------------
// 描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#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]);
        } //行处理结束
        }
        }

迭代器访问图像像素

//参数准备
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;
        // ------------------------【处理结束】----------------------------
        }

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

//---------------------------------【头文件、命名空间包含部分】---------------------------
// 描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#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 方法访问

//存取彩色图像像素
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方法对对象进行空间颜色缩减

//-----------------------------【头文件、命名空间包含部分】------------------------------
// 描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#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]);
                              } // 行处理结束
                              }
                              }

在这里插入图片描述

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

//---------------------------------【头文件、命名空间包含部分】-----------------------------
// 描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#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;
                                                          }

在这里插入图片描述
在这里插入图片描述

posted @ 2025-08-03 14:01  wzzkaifa  阅读(18)  评论(0)    收藏  举报