OpenCV学习笔记(七):访问图像中像素的三类方法

该文章参考毛星云著《OpenCV3编程入门》,电子工业出版社。


图像是以像素为单位储存的,访问图像中的每个像素是处理图像的基础,一般有三种访问图像像素的方法:


方法一:指针访问:C操作符[ ]

方法二:迭代器iterator

方法三:动态地址计算


下面直接上代码,代码的目的是减少图像的颜色种类数,即减少颜色的细分。


[cpp]  view plain  copy
  1. #include<opencv2/opencv.hpp>  
  2. #include<iostream>  
  3.   
  4. using namespace cv;  
  5. using namespace std;  
  6.   
  7. void colorreduce(Mat& inputImage, Mat& outputImage, int div);  
  8.   
  9. int main()  
  10. {  
  11.     Mat srcimage = imread("1.jpg");  
  12.     imshow("srcimage", srcimage);  
  13.   
  14.     Mat dstimage;  
  15.     dstimage.create(srcimage.rows, srcimage.cols, srcimage.type());  
  16.       
  17.     double time0 = static_cast<double>(getTickCount());  
  18.   
  19.     colorreduce(srcimage, dstimage, 32);  
  20.   
  21.     time0 = ((double)getTickCount() - time0) / getTickFrequency();  
  22.     cout << "Time = " << time0 << "seconds" << endl;  
  23.     imshow("dstimage", dstimage);  
  24.     waitKey(0);  
  25. }  
  26.   
  27. void colorreduce(Mat & inputImage, Mat & outputImage, int div)  
  28. {  
  29.   
  30.     //方法一:使用指针  
  31.     outputImage = inputImage.clone();  
  32.     int rowNumber = outputImage.rows;  
  33.     int colNumber = outputImage.cols * outputImage.channels(); //每一行元素的个数  
  34.   
  35.     for (int i = 0; i < rowNumber; i++)  
  36.     {  
  37.         uchar* data = outputImage.ptr<uchar>(i); //获取行地址  
  38.         for (int j = 0; j < colNumber; j++)  
  39.         {  
  40.             data[j] = data[j] / div*div + div / 2;  
  41.         }  
  42.         //*data++ = *data / div*div + div / 2; //所有方法中最快的  
  43.     }  
  44.   
  45.   
  46.     /*  
  47.     //方法二:迭代器  
  48.     outputImage = inputImage.clone();  
  49.     Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();  
  50.     Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();  
  51.   
  52.     for (; it != itend; ++it)  
  53.     {  
  54.         (*it)[0] = (*it)[0] / div*div + div / 2;  
  55.         (*it)[1] = (*it)[1] / div*div + div / 2;  
  56.         (*it)[2] = (*it)[2] / div*div + div / 2;  
  57.     }  
  58.     */  
  59.   
  60.     /* 
  61.     //方法三:动态地址计算 
  62.     outputImage = inputImage.clone(); 
  63.     int rowNumber = outputImage.rows; 
  64.     int colNumber = outputImage.cols; 
  65.  
  66.     for (int i = 0; i < rowNumber; i++) 
  67.     { 
  68.         for (int j = 0; j < colNumber; j++) 
  69.         { 
  70.             outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div*div + div / 2; 
  71.             outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div*div + div / 2; 
  72.             outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div*div + div / 2; 
  73.         } 
  74.     } 
  75.     */  
  76. }  

程序运行的效果如下:






从结果上看,减小颜色种类后,图像变得更模糊了。


在程序中,需要注意的是colorreduce函数的形参是Mat&,而不是Mat,这是C++的知识,因为需要传入函数的图片在主函数中也发生变化,即函数外部的数据随函数内部的操作而变化。

版权声明:本文为博主原创文章,未经博主允许不得用于商业转载。 https://blog.csdn.net/wangxuwen2/article/details/52091827

猜你喜欢

转载自blog.csdn.net/a8039974/article/details/80554587