Opencv3笔记5——访问图像中的元素

访问图像中像素

LUT函数:Look up table 操作

operationsOnArrays:LUT()<lut>函数来进行批量图像元素查找,扫描和操作图像

计时函数

getTickCount() 和 getTickFrequecny()
1. getTickCount() 函数返回CPU自某事情以来走过的始终周期
2. getTickFrequency() 函数返回CPU一秒返回所走过的时钟周期

1 指针访问

#include 
#include 
#include 
using namespace std;
using namespace cv;
//---------------【全局函数声明部分】---------------
//     描述:全局函数声明    
//-----------------------------------------------
void colorReduce(Mat & inputImage, Mat & outputImage, int div);
//----------------【main()函数】----------------------
//     描述:控制台应用程序的入口函数,我们的程序从这里开始
//---------------------------------------------------
int main()
{
       // 创建原始图并显示
       Mat srcImage = imread("1.jpg");
       imshow("原始图像", srcImage);
       // 按原始图的参数规格来创建效果图
       Mat dstImage;
       dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());
       // 记录起始时间
       double time0 = static_cast<double>(getTickCount());
       // 调用颜色空间缩减函数
       colorReduce(srcImage, dstImage, 32);
       //计算运行时间并输出
       time0 = ((double)getTickCount() - time0) / getTickFrequency();
       cout << "此方法运行时间为: " << time0 << "秒" << endl;
       //显示效果图
       imshow("效果图", dstImage);
       waitKey(0);
       return 0;
}
void colorReduce(Mat & inputImage, Mat & outputImage, int div)
{
       outputImage = inputImage.clone(); //复制实参到临时变量
       int rowNumber = outputImage.rows;
       int colNumber = outputImage.cols*outputImage.channels();      // 列数 × 通道 = 每一行元素的个数
       for (int i = 0; i < rowNumber; i++)
       {
              uchar * data = outputImage.ptr(i); //获取第i行的首地址
              for (int j = 0;j < colNumber; j++)
              {
                     data[j] = data[j] / div * div + div / 2;
              }
       }
}

Opencv3笔记5——访问图像中的元素_第1张图片

这里写图片描述

2 迭代器操作

void colorReduce(Mat & inputImage, Mat & outputImage, int div)
{
       outputImage = inputImage.clone(); //复制实参到临时变量
       Mat_::iterator it = outputImage.begin(); // 初始位置的迭代器
       Mat_::iterator itend = outputImage.end();       //z终止位置的迭代器
       //存取彩色图像像素
       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;
       }
}

这里写图片描述

3 动态地址计算

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++)
              {
                     outputImage.at(i, j)[0] = outputImage.at(i, j)[0] / div*div + div / 2;
                     outputImage.at(i, j)[1] = outputImage.at(i, j)[1] / div*div + div / 2;
                     outputImage.at(i, j)[2] = outputImage.at(i, j)[2] / div*div + div / 2;
              }
       }
}

这里写图片描述

其余14种方法

1 利用ptr 和[]
void colorReduce0(Mat &image, int div=64) {
         int nl= image.rows; //行数
         int nc= image.cols * image.channels(); //每行元素的总元素数量

      for (int j=0; j(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

                  data[i]= data[i]/div*div + div/2;

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

            } //单行处理结束                 
      }
}
2 使用ptr和 * ++
void colorReduce1(Mat &image, int div=64) {
         int nl= image.rows; //行数
         int nc= image.cols * image.channels(); //每行元素的总元素数量

      for (int j=0; j(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

                            *data++= *data/div*div + div/2;

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

            } //单行处理结束             
      }
}
3 使用模板
void colorReduce2(Mat &image, int div=64) {
         int nl= image.rows; //行数
         int nc= image.cols * image.channels(); //每行元素的总元素数量

      for (int j=0; jimage.ptr(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

                           int v= *data;
                  *data++= v - v%div + div/2;

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

            } //单行处理结束                  
      }
}
4 使用位操作
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<// e.g. 对于 div=16, mask= 0xF0

      for (int j=0; j(j);
          for (int i=0; i//------------开始处理每个像素-------------------

            *data++= *data&mask + div/2;

            //-------------结束像素处理------------------------
            }  //单行处理结束           
      }
}
5 指针运算
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<// e.g. 对于 div=16, mask= 0xF0

      //获取指向图像缓冲区的指针
         uchar *data= image.data;
      for (int j=0; jfor (int i=0; i//-------------开始处理每个像素-------------------

            *(data+i)= *data&mask + div/2;

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

            } //单行处理结束             
            data+= step;  // next line
      }
}
6 利用 .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<// e.g. 例如div=16, mask= 0xF0

      for (int j=0; j(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

            *data++= *data&mask + div/2;

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

            } //单行处理结束           
      }
}
7 利用.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<// e.g. 比如div=16, mask= 0xF0

      for (int j=0; j(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

            *data++= *data&mask + div/2;

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

            } //单行处理结束                  
      }
}
8 利用 .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<// e.g. 比如div=16, mask= 0xF0

      for (int j=0; j(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;

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

            } //单行处理结束                   
      }
}
9 利用Mat_ iterator
void colorReduce8(Mat &image, int div=64) {
         //获取迭代器
         Mat_::iterator it= image.begin();
         Mat_::iterator itend= image.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;
        //-------------结束像素处理------------------------
         }//单行处理结束 
}
10 利用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<// e.g. 比如 div=16, mask= 0xF0
         // 获取迭代器
         Mat_::iterator it= image.begin();
         Mat_::iterator itend= image.end();
         //扫描所有元素
         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;
        //-------------结束像素处理------------------------
         }//单行处理结束 
}
11 利用Mat Iterator_
void colorReduce10(Mat &image, int div=64) {
         //获取迭代器
         Mat_ cimage= image;
         Mat_::iterator it=cimage.begin();
         Mat_::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;
        //-------------结束像素处理------------------------
         }
}
12 利用动态地址计算配合at
void colorReduce11(Mat &image, int div=64) {
         int nl= image.rows; //行数
         int nc= image.cols; //列数

      for (int j=0; jfor (int i=0; i//-------------开始处理每个像素-------------------

                  image.at(j,i)[0]=       image.at(j,i)[0]/div*div + div/2;
                  image.at(j,i)[1]=       image.at(j,i)[1]/div*div + div/2;
                  image.at(j,i)[2]=       image.at(j,i)[2]/div*div + div/2;

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

            } //单行处理结束                
      }
}
13 利用图像的输入与输出
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<// e.g.比如div=16, mask= 0xF0

      for (int j=0; j(j);
                const uchar* idata= image.ptr(j);
          for (int i=0; i//-------------开始处理每个像素-------------------

            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;

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

          } //单行处理结束                  
      }
}
14 利用操作符重载
void colorReduce13(Mat &image, int div=64) {

         int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
         //掩码值
         uchar mask= 0xFF<// e.g. 比如div=16, mask= 0xF0
         //进行色彩还原
         image=(image&Scalar(mask,mask,mask))+Scalar(div/2,div/2,div/2);
}

你可能感兴趣的:(Opencv,机器视觉)