Opencv 图像元素的存取方法和效果对比:
#include<iostream>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
//-------------------------------------【全局函数声明】------------------------------------------
// 描述:全局函数声明
//-------------------------------------------------------------------------------------------
void colorReduceAt(const Mat &srcImage, Mat &dstImage, int div);
void colorReducePtr(const Mat &srcImage, Mat & dstImage, int div);
void colorReduceIte(const Mat &srcImage, Mat & dstImage, int div);
//-------------------------------------【int main()】------------------------------------------
// 描述:主函数接口
//-------------------------------------------------------------------------------------------
int main(int argc,char ** argv)
{
//输入图像
Mat srcImage = imread("G:\\VS_File\\Picture\\lena.jpg");
if (srcImage.empty())
{
return -1;
}
imshow("原始图像", srcImage);
//按照原始图的参数规格创建效果图
Mat dstImage;
double time_s;
/****************************【用迭代器计算】**************************************/
//记录时间
time_s = static_cast<double>(getTickCount());
//调用颜色空间缩减函数
colorReduceIte(srcImage, dstImage, 32);
//计算运行时间并输出
time_s = ((double)getTickCount() - time_s) / getTickFrequency();
cout << "迭代器计算 运行时间: " << time_s << endl;
imshow("迭代器计算 效果图", dstImage);
/****************************【动态地址计算】****************************************/
//记录时间
time_s = static_cast<double>(getTickCount());
//调用颜色空间缩减函数
colorReduceAt(srcImage, dstImage, 32);
//计算运行时间并输出
time_s = ((double)getTickCount() - time_s) / getTickFrequency();
cout << "动态地址计算 运行时间: " << time_s << endl;
imshow("动态地址计算 效果图", dstImage);
/****************************【指针访问像素】****************************************************/
//记录时间
time_s = static_cast<double>(getTickCount());
//调用颜色空间缩减函数
colorReducePtr(srcImage, dstImage, 32);
//计算运行时间并输出
time_s = ((double)getTickCount() - time_s) / getTickFrequency();
cout << "指针访问像素 运行时间: " << time_s << endl;
imshow("指针访问像素 效果图", dstImage);
/*********************************************************************************/
waitKey(0);
cv::destroyAllWindows();
return 0;
}
//-------------------------------------【colorReduce】---------------------------------------
// 描述:colorReduce颜色空间缩减
//-------------------------------------------------------------------------------------------
//【1】使用动态地址运算配合at
void colorReduceAt(const Mat &srcImage, Mat &dstImage, int div)
{
dstImage = srcImage.clone();
//遍历图像
for (int i = 0; i < srcImage.rows; i++)
{
for (int j = 0; j < srcImage.cols; j++)
{
dstImage.at<Vec3b>(i, j)[0] = srcImage.at<Vec3b>(i, j)[0] / div * div + div / 2;
dstImage.at<Vec3b>(i, j)[1] = srcImage.at<Vec3b>(i, j)[1] / div * div + div / 2;
dstImage.at<Vec3b>(i, j)[2] = srcImage.at<Vec3b>(i, j)[2] / div * div + div / 2;
}
}
}
//【2】用指针访问像素
void colorReducePtr(const Mat &srcImage, Mat & dstImage, int div)
{
//参数准备
dstImage = srcImage.clone();
int nrows = dstImage.rows;
int ncols = dstImage.cols*dstImage.channels();
//双重循环遍历所有像素值
for (int i = 0; i < nrows; i++)//行循环
{
uchar * data = dstImage.ptr<uchar>(i); //获得第i行的首地址
for (int j = 0; j < ncols; j++) //列循环
{
//开始处理每个像素
data[j] = data[j] / div * div + div / 2;
//处理结束
}
}
}
//【3】用迭代器操作像素
void colorReduceIte(const Mat &srcImage, Mat & dstImage, int div)
{
//参数准备
dstImage = srcImage.clone();
//获取迭代器
Mat_<Vec3b>::iterator it = dstImage.begin<Vec3b>();//初始位置
Mat_<Vec3b>::iterator itend = dstImage.end<Vec3b>();//结束位置
//存取彩色图像像素
for (; it != itend; it++)
{
(*it)[0] = (*it)[0] / div * div + div / 2;
(*it)[0] = (*it)[0] / div * div + div / 2;
(*it)[0] = (*it)[0] / div * div + div / 2;
}
}