用迭代器扫描图像 - 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();