持续创作,加速成长!这是我参加「日新方案 10 月更文挑战」的第13天,点击查看活动概况

前言

在面向对象的编程中,循环数据调集通常是运用迭代器完成的。迭代器是专门为遍历调集的每个元素而构建的类,躲藏了怎么迭代给定调集中每个元素的具体操作。信息躲藏原理的运用使扫描调集更容易、更安全;同时,不管运用什么类型的调集,迭代的方法都是相似的。规范模板库 (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 时停止。