本文参考《Opencv3 入门》 作者毛星云
//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间//-----------------------------------------------------------------------------------------
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
//---------------------------------【用指针访问像素colorReduce1()函数部分】----------------------------
// 描述:用指针访问像素
//-----------------------------------------------------------------------------------------
void colorReduce1(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<uchar>(i);
for (int j = 0; j < colNumber; j++)
{
data[j] = data[j] / div*div + div / 2;
}
}
}
//---------------------------------【用迭代器操作像素colorReduce2()函数部分】----------------------------
// 描述:用迭代器操作像素
//-----------------------------------------------------------------------------------------
void colorReduce2(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)
{
(*it)[0] = (*it)[0] / div*div + div / 2;
(*it)[1] = (*it)[1] / div*div + div / 2;
(*it)[2] = (*it)[2] / div*div + div / 2;
}
}
//---------------------------------【用动态地址计算来操作像素colorReduce3()函数部分】----------------------------
// 描述:用动态地址计算来操作像素
//-----------------------------------------------------------------------------------------
void colorReduce3(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<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;
}
}
}
//---------------------------------【主函数main()部分】----------------------------
// 描述:main()主函数部分
//-----------------------------------------------------------------------------------------
int main()
{
for (int i = 1; i <= 3; i++)
{
Mat inputImage = imread("E:/3.jpg");
Mat outputImage;
imshow("源图", inputImage);
if (i == 1)
{
double time_1= static_cast<double>(getTickCount());
colorReduce1(inputImage, outputImage, 50);
time_1 = ((double)getTickCount() - time_1) / getTickFrequency();
imshow("指针访问像素", outputImage);
cout << "用指针访问像素用时" << time_1 << "secends" << endl;
waitKey(5000);
}
if (i == 2)
{
double time_2 = static_cast<double>(getTickCount());
colorReduce2(inputImage, outputImage, 50);
time_2 = ((double)getTickCount() - time_2) / getTickFrequency();
imshow("用迭代器操作元素", outputImage);
waitKey(5000);
cout << "用迭代器操作元素用时" << time_2 << "secends" << endl;
}
if (i == 3)
{
double time_3 = static_cast<double>(getTickCount());
colorReduce3(inputImage, outputImage, 50);
time_3 = ((double)cvGetTickCount() - time_3) / getTickFrequency();
imshow("使用动态地址操作元素", outputImage);
cout << "使用动态地址操作元素用时" << time_3 << "secend" << endl;
waitKey(0);
}
}
system("pause");
}
调试结果:
可以清楚的看书,用指针访问像素的方法用时最小。