用迭代器扫描图像 - sumpig/OpenCV GitHub Wiki

要得到cv::Mat 实例的迭代器,首先要创建一个cv::MatIterator_对象。

必须在编译时就明确返回值的类型。可以这样定义彩色图像的迭代器:

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

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

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

然后就可以使用常规的迭代器方法begin 和end 对像素进行循环遍历了。现在,减色函数可以这样编写:

void colorReduce(cv::Mat image, int div=64) {

    int n = staic_cast<int>(log(static_cast<double>(div))/log(2.0) + 0.5);
    uchar mask = 0xFF<<n; 
    uchar div2 = div >> 1; 

    // 迭代器
    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;
    }
}

还可以在迭代器上使用数学计算,例如若要从图像的第二行开始,可以用 image.begin<cv::Vec3b>()+image.cols 初始化 cv::Mat 迭代器。

结束的迭代器也能使用数学计算,例如你想在最后一行前就结束迭代,可使用 image.endcv::Vec3b()-image.cols

我们还可以用对cv::Mat_实例的引用来获取迭代器的开始位置和结束位置,这样就不需要在 begin 和 end 方法中指定迭代器的类型了:

cv::Mat_<cv::Vec3b> cimage(image);
cv::Mat_<cv::Vec3b>::iterator it = cimage.begin();
cv::Mat_<cv::Vec3b>::iterator itend = cimage.end();

cv::getTickCount() 函数会返回从最近一次计算机开机到当前的时钟周期数。

若想得到以秒为单位的代码运行时间,可使用另一个方法 cv::getTickFrequency(),它返回每秒的时钟周期数,这里假定CPU的频率是固定的。

为了获得某个函数(或代码段)的运行时间,通常需使用这样的程序模板:

const int64 start = cv::getTickCount();
colorReduce(image); // 调用函数
// 经过的时间(单位:秒)
double duration = (cv::getTickCount()-start) / cv::getTickFrequency();
⚠️ **GitHub.com Fallback** ⚠️