持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,减色任务讲解如何使用迭代器扫描图像。
使用迭代器扫描图像
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
时停止。