访问图像中的像素
方法一: 指针访问:C操作符[]
方法二: 迭代器iterator
方法三: 动态地址计算
方法一:指针访问像素
速度最快但是有点抽象
void color_look(Mat & inputImage, Mat& outputImage, int div)
{
//参数准备
outputImage = inputImage.clone(); // 复制实参到临时变量
int rowNumber = outputImage.row; // 行数
int colNumber = outputImage.cols*outputImage.channels(); // 列数*通道数=每行元素个数
//双重循环,便利所有的像素值
for(int i = 0;i < rowNumber;i++) // 行循环
{
uchar* data = outputImage.ptr<uchar>(i); //获取第i行的首地址
for(int j = 0;j < colNumber; j++) //列循环
{
// 查看并操作每个元素
data[j] = data[j]/div*div + div/2; // 颜色空间缩减
// 操作完成
}
}
}
方法二:用迭代器操作像素
在迭代法中,我们所需要做的仅仅是获得图像矩阵的begin和end,然后增加迭代直至从begin到end。将*操作符添加在迭代指针前,即可访问当前指向的内容。相比用指针直接访问可能出现的越界问题,迭代器绝对是非常安全的方法。
void color_look(Mat& inputImage, Mat& outputImage, int div)
{
// 参数准备
outputImage = inputImage.clone(); // 复制实参到临时变量
// 获取迭代器
Mat_<Vec3b>::iteartor it = outputImage.begin<Vec3b>(); // 初始位置的迭代器
Mat_<Vec3b>::iteartor 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;
}
}
方法三:动态地址计算
比较简洁,符合对像素的直接认识
void color_look(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;
}
}
}