迭代器是一种极为方便的可以遍历数组或集合的方法,使用opencv的自带的Mat中的迭代器,可以方便的进行遍历数组操作。
在迭代法中,你所需要做的仅仅是获得图像矩阵的begin和end,然后增加迭代直至从begin到end。将*操作符添加在迭代指针前,即可访问当前指向的内容。对于一个cv::Mat的实例,你可以通过image.begin<cv::Vec3b>()来得到图像左上角位置的迭代器。如果想从第二行开始,可以使用image.begin<cv::Vec3b>()+image.rows来初始化迭代器。
注意:如果你的操作对象是const cv::Mat,或者你想强调当前当前循环不会对CV::Mat的实例进行修改,那么你就因该创建常量迭代器。常量迭代器的声明如下:
cv::Mat ConstIterator_<cv::Vec3b>it;
或者:
cv::Mat_<cv::Vec3b> ::Const_Iterator it;
程序代码如下:
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
void colorReduce(cv::Mat& img, int div = 64);
int main()
{
cv::Mat img_orginal = cv::imread("8.jpg");
cv::Mat img_altered = img_orginal.clone();
colorReduce(img_altered);
cv::namedWindow("orignal");
cv::imshow("orignal", img_orginal);
cv::namedWindow("altered");
cv::imshow("altered", img_altered);
cv::waitKey();
return 0;
}
void colorReduce(cv::Mat& img, int div)
{
int n = cv::log(static_cast<double>(div)) / cv::log(2.0);
int mask = 0xFF << n; //使用位运算的颜色缩减公式,如果我们限制缩减因子为2的幂次,
//那么,只取像素值的前n位即可得到不大于改制的关于缩减因子的最大整数倍数。运算掩膜可以通过简单的移位操作。
// 方式一:
//cv::Mat_<cv::Vec3b>::iterator it = img.begin<cv::Vec3b>(); 定义在MAT-内部的迭代器类型
// 方式二:
cv::MatIterator_<cv::Vec3b> it = img.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b> itend = img.end<cv::Vec3b>();
for (; it != img.end<cv::Vec3b>(); it++)
{ //处理每个像素
(*it)[0] = (*it)[0] & mask + div / 2;
(*it)[1] = (*it)[1] & mask + div / 2;
(*it)[2] = (*it)[2] & mask + div / 2;
}
}
原始图像:
运行结果: