一利用指针进行图像遍历
#include <opencv2/highgui.hpp>
#include <cmath>
//速度最快
void colorReduce(cv::Mat &image,int div)
{
int nl=image.rows;
int nc=image.cols*image.channels();
//利用位运算
int n=log2(div);
uchar mask=0xFF<<n;
//判断矩阵的连续性
if(image.isContinuous())
{
nc*=nl;
nl=1;
}
for(int i=0;i<nl;i++)
{
uchar* data=image.ptr<uchar>(i);
for(int j=0;j<nc;j++)
{
*data=(*data&mask)+(div>>1);
data++;
}
}
}
二利用迭代器进行遍历
#include <opencv2/highgui.hpp>
void colorReduce(cv::Mat &image,int div)
{
//利用每一行迭代器进行遍历
auto it=image.begin<cv::Vec3b>();
auto itend=image.end<cv::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;
}
}
三利用运算符重载
#include <opencv2/highgui.hpp>
#include <cmath>
//实现简单,最为实用
void colorReduce(cv::Mat &image,int div)
{
//进行位运算
int n=log2(div);
uchar mask=0xFF<<n;
image=(image&cv::Scalar(mask,mask,mask)
+cv::Scalar(div/2,div/2,div/2));
}