前言
在面向对象的编程中,循环数据集合通常是使用迭代器完成的。迭代器是专门为遍历集合的每个元素而构建的类,隐藏了如何迭代给定集合中每个元素的具体操作。信息隐藏原理的应用使扫描集合更容易、更安全;同时,无论使用什么类型的集合,迭代的形式都是相似的。标准模板库 (Standard Template Library, STL) 具有与其每个集合类相关联的迭代器类。而 OpenCV 同样提供了一个 cv::Mat 迭代器类,该类与 C++ STL 中的标准迭代器兼容。在本节中,我们使用继续减色任务讲解如何使用迭代器扫描图像。
使用迭代器扫描图像
Cv::Mat 实例的迭代器对象可以通过首先创建一个 cv::MatIterator_ 对象来获得。与 cv::Mat_ 的情况一样,下划线表示这是一个模板子类。实际上,由于图像迭代器用于访问图像元素,因此在编译时必须知道返回类型。迭代器声明如下:
cv::MatIterator_<cv::Vec3b> it;
或者,也可以使用 Mat_ 模板类中定义的迭代器类型:
cv::Mat_<cv::Vec3b>::iterator it;
接下来,我们将迭代器应用于颜色减少任务。
要将迭代器应用于颜色减少任务,需要执行以下步骤。
1、我们使用常见的开始和结束迭代器方法循环像素。首先,我们必须获得开始位置:
// 在初始位置获取迭代器
cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
2、然后,我们必须获得迭代器的结束位置:
// 获取结束位置
cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
3、接下来,我们必须循环迭代器直到结束位置:
// 循环所有像素
for ( ; it!= itend; ++it) {
4、最后,对像素应用颜色减少算法:
(*it)[0]= (*it)[0]/div*div + div/2;
(*it)[1]= (*it)[1]/div*div + div/2;
(*it)[2]= (*it)[2]/div*div + div/2;
由于我们正在处理彩色图像,以上代码中的迭代器会返回一个 cv::Vec3b 实例,使用解引用运算符 [] 可以访问每个颜色通道元素。
无论扫描哪种类型的集合,使用迭代器始终需要遵循相同的模式。首先,使用适当的专用类创建迭代器对象,在以上代码中,我们使用了 cv::Mat_<cv::Vec3b>::iterator (或cv::MatIterator_<cv::Vec3b>)。
然后,获取在起始位置(在以上代码中为图像的左上角)处使用 begin 方法初始化的迭代器。使用 cv::Mat 实例,可以通过 image.begin<cv::Vec3b>() 获取起始位置。我们也可以在迭代器上使用算术。例如,如果希望从图像的第二行开始迭代,可以在 image.begin<cv::Vec3b>()+image.cols 处初始化 cv::Mat 迭代器。集合的结束位置的获取方式类似,但使用的是 end 方法。也可以在结束迭代器上使用算术;例如,如果希望在最后一行之前停止,最终迭代将在迭代器到达 image.end<cv::Vec3b>()-image.cols 时停止。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。