/*OpenCv学习之 使用迭代器遍历图像
首先通俗的百度介绍一下什么是迭代器(iterator)
迭代器 其实就是一个指针,用来读取数组或者集合中的一个元素。读取完毕之后,迭代器又指向了下一个元素的地址。
感觉这个解释比较通俗易懂
课本上说:迭代器是一种特殊的类,专门用来遍历集合中的各个元素,同时隐藏了在给定的集合上元素迭代的具体实现方式?这句话是啥意思呢
咱也不知道,咱也不敢问 哈哈
实现方法: 哎呀 我根本不太理解这段话的机理啊 希望可以找个大神带我一下下
一个cv::Mat实例的迭代器可以通过创建一个cv::Mat Iterator_的实例来得到;类似Mat的子类 cv::Mat_
下划线意味着cv::Mat Iterator_是一个模板类 奶奶的请问模板类又是什么呢 和普通的类 子类 有什么区别呢??、
之所以如此是由于通过迭代器来存取图像的元素,就必须在编译时期知道图像元素的数据类型 卧槽
我咋感觉这说的牛头不对马嘴呢 ?啥玩意是 啊 通过迭代器读取元素,必须知道元素类型 为啥就得那样声明一个模板类呢???
cv::Mat Iterator _<Vec3b> it //声明一个图像的迭代器
另一种方式是使用定义在Mat_内部的迭代器类型
cv::Mat_<cv:: Vec3b> :: iterator it; //奶奶的 根本不明白 不过还是暂时记下吧
*/
# include <opencv.hpp>
# include <iostream>
using namespace cv;
using namespace std;
/*颜色缩减函数 使用迭代器 来遍历像素*/
void colorReduce(Mat &image, int div = 64)
{
//得到初始位置的迭代器 这里 Opencv2 和OpenCv3 定义迭代的语法有所不同 请注意一下 这里是OpenCv3 的定义方式
//难道这就是所谓的“通过迭代器来存取图像的元素,就必须在编译时期知道图像元素的数据类型”
//这应该就是相当于定义了 一个头指针 一个尾指针
MatIterator_<Vec3b> It_Start;
/*begin函数return语句是先将当前对象转化为Mat模板类对象,然后再调用Mat迭代器模板的构造函数初始化一个迭代器对象,
再返回给调用者,所以用这个函数初始化迭代器对象时,会有image.begin<Vec3b>()这么奇怪的写法。*/
It_Start = image.begin<Vec3b>();
MatIterator_<Vec3b> It_End;
It_End = image.end<Vec3b>();
cout << typeid(It_End).name() << endl;
cout << *It_Start << endl;
cout << *It_End << endl;
for (; It_Start != It_End; It_Start++)
{
//感觉这里理解的非常不好 描述不出来 就是没有掌握 对C++迭代器的知识了解不好
//感觉这个博客写的不错 https://www.cnblogs.com/maluning/p/8570717.html
(*It_Start)[0] = (*It_Start)[0] / div *div + div / 2;
(*It_Start)[1] = (*It_Start)[1] / div *div + div / 2;
(*It_Start)[2] = (*It_Start)[2] / div *div + div / 2;
}
}
int main()
{
Mat image;
int Array1[4] = { 1,2,3,4};
cout << Array1 << endl;
//这里一定要放入 工程文件夹下面 才可以
image = imread("Test2.jpg", IMREAD_UNCHANGED);
/*老是 犯一些低级的错误 本来 事项判断是否读入成功了 可是两个= 少写了一个 成了赋值号了 悲哀啊 */
if(image.data == NULL )
{
cout << "图片读取失败" << endl;
}
colorReduce(image, 64);
namedWindow("迭代器");
imshow("迭代器",image);
waitKey(0);
return 0;
}