介绍一下OpenCV中forEach的用法,在需要遍历一张图像的所有像素的时候,使用Mat提供的方法forEach是个不错的选择,该方法可以实现并行处理像素值,该方法的原型如下:
void cv::Mat::forEach(const Functor &operation);
参数接收一个函数符,格式为
void fun(PixelType val, const int *position);
这里的PixelType 指的是像素的类型。如果需要修改像素值,就要在变量声明之前加上&引用。
传入参数可以使用lambda表达式,也可以自己编写函数或函数对象
cv::Mat src = cv::imread("1.jpg");
cv::Mat tmp;
src.convertTo(tmp, CV_32FC1);
tmp.forEach<float>(
[](float &val, const int *position){
val /= 255;
});
需要注意的是,因为是并行编程,所以如果对像素的处理涉及到对同一个内存空间进行修改的话,需要考虑互斥访问(有一次我不小心忘了设置互斥访问,计算出来的结果比真实结果少了,由此可以侧面反映出forEach函数真的实现了并行计算)此时需要使用到的是STL提供的mutex类,该类实现了互斥锁操作
#include <mutex>
cv::Mat src = cv::imread("1.jpg");
cv::Mat tmp;
src.convertTo(tmp, CV_32FC1);
float sum;
std::mutex mtx;
tmp.forEach<float>(
[&mutex, &sum](float &val, const int *position){
val /= 255;
mtx.lock();
sum += val;
mtx.unlock();
});