在opencv中,提供了三种访问像素点的方法:
- 1.指针访问
- 2.迭代器访问
- 3.动态地址计算
直接上代码:
//方法一:指针访问
void colorReduce(Mat& input, Mat& output, int div)
{
output = input.clone();
int rowNum = output.rows;
int colNum = output.cols * output.channels();
//像素遍历
for (int i = 0; i < rowNum; i++)
{
uchar* data = output.ptr<uchar>(i);
for (int j = 0; j < colNum; j++)
{
data[j] = data[j] / div * div + div / 2;
}
}
}
//方法2 迭代器
void colorReduce(Mat& input, Mat& output, int div)
{
output = input.clone();
Mat_<Vec3b>::iterator it = output.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = output.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;
}
}
//3.动态地址计算
void colorReduce(Mat& input, Mat& output, int div)
{
output = input.clone();
int rowNum = output.rows;
int colNum = output.cols;
//存取彩色图像像素
for (int i = 0; i < rowNum; i++)
{
for (int j = 0; j < colNum; j++)
{
output.at<Vec3b>(i, j)[0] = output.at<Vec3b>(i, j)[0] / div * div + div / 2;
output.at<Vec3b>(i, j)[1] = output.at<Vec3b>(i, j)[1] / div * div + div / 2;
output.at<Vec3b>(i, j)[2] = output.at<Vec3b>(i, j)[2] / div * div + div / 2;
}
}
}
附主程序:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
#include<core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
void colorReduce(Mat& input, Mat& output, int div);
int main(int argc,char **argv)
{
Mat srcImage = imread("F:/pic/img2.jpg",IMREAD_UNCHANGED);
if (!srcImage.data)
{
cout << "加载失败" << endl;
return -1;
}
namedWindow("原始图", CV_WINDOW_AUTOSIZE);
imshow("原始图", srcImage);
//创建效果图
Mat destImage;
destImage.create(srcImage.rows, destImage.cols, srcImage.type());
//记录起始时间
double time0 = static_cast<double>(getTickCount());
//调用颜色空间缩减函数
colorReduce(srcImage, destImage, 32);
//计算运行时间并输出
time0 = (getTickCount() - time0) / getTickFrequency();
cout << "此方法运行时间为:" << time0 << endl;
imshow("效果图", destImage);
waitKey(0);
//system("pause");
return 0;
}
参考opencv编程入门,文中还提到了其他的14种遍历像素方法,之后有机会会附上。