OpenCV迭代器扫描图像

OpenCV迭代器扫描图像,在面向对象编程时,我们通常用迭代器对数据集合进行循环遍历。迭代器是一种类,专门用于遍历集合的每个元素,并能隐藏遍历过程的具体细节。信息隐藏原则的应用,使扫描集合的过程变得更加容易和安全。并且不管被用于哪种类型的集合,它都能提供类似的形式。标准模板库(Standard Template Library, STL)对每个集合类都定义了对应的迭代器类,OpenCV也提供了cv::Mat的迭代器类,并且与C++ STL中的标准迭代器兼容。

准备工作

本文仍使用前面的减色程序作为例子。

如何实现

要得到cv::Mat实例的迭代器,首先要创建一个cv::MatIterator_对象。跟cv::Mat_类似,这个下划线表示它是一个模板子类。因为图像迭代器是用来访问图像元素的,所以必须在编译时就明确返回值的类型。可以这样定义彩色图像的迭代器:

cv::MatIterator_<cv::Vec3b> it;

也可以使用在Mat_模板类内部定义的iterator类型:

cv::Mat_<cv::Vec3b>::iterator it;

然后就可以使用常规的迭代器方法begin和end对像素进行循环遍历了。不同之处在于它们仍然是模板方法。现在,减色函数可以这样编写:

          void colorReduce(cv::Mat image, int div=64) {
            // div必须是2 的幂
            int n= staic_cast<int>(
          log(static_cast<double>(div))/log(2.0) + 0.5);

            // 用来截取像素值的掩码
            uchar mask= 0xFF<<n; // 如果div=16, mask=0xF0
            uchar div2 = div >> 1; // div2 = div/2
            // 迭代器
            cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
            cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

            // 扫描全部像素
            for ( ; it! = itend; ++it) {

              (*it)[0]&= mask;
              (*it)[0]+= div2;
              (*it)[1]&= mask;
              (*it)[1]+= div2;
              (*it)[2]&= mask;
              (*it)[2]+= div2;
            }
          }

请注意,这里处理的是一个彩色图像,因此迭代器返回cv::Vec3b实例。你可以用取值运算符[]访问每个颜色通道的元素。这里也可以使用cv::Vec3b的重载运算符,可简化为:

*it= *it/div*div+offset;

短向量的元素运算都可以使用这种方法。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!