Opencv中这样操作图像像素值才最快

科技   科技   2024-10-05 07:47   北京  

获取像素值的方法有许多种,常见的有如下两种。


一  使用at方法


Mat 类有一个方便的方法调用 at 来访问图像中位置(行、列)的像素

具体代码如下

    cv::Mat Img = cv::Mat::zeros(5000, 50000, CV_8UC1);  for (int r = 0; r < Img.rows; r++)  {    for (int c = 0; c < Img.cols; c++)    {      Img.at<uchar>(r, c) = 128;          }  }

二 使用图像指针


通过访问图像像素指针来进行操作值修改,具体代码如下所示

cv::Mat Img = cv::Mat::zeros(5000, 50000, CV_8UC1);  for (int r = 0; r < Img.rows; r++)  {    for (int c = 0; c < Img.cols; c++)    {      Img.data[r * Img.cols + c] = 128;    }  }

由于才疏学浅,我一直以为根据图像指针操作是速度最快的像素操作方法。


经过测试,对于尺寸5000*50000的图像像素操作时间分别为253ms和199ms。


显然第二种方法的运行速度确实快于at的方法,以至于我在许多算法中运用该方法,但是该方法的速度提升确实非常有限。


直到我遇到了第三种方法。。。


三 使用图像foreach方法


曾有人将该方法比喻为Opencv隐藏的宝石,我结合C++Lambda进行了算法性能测试,具体代码如下。


cv::Mat Img = cv::Mat::zeros(5000, 50000, CV_8UC1);  Img.forEach<uchar>    (      [](uchar& pixel, const int* position) -> void      {        pixel = 128;      }  );


对同样大小的图像进行相同操作,检测时间竟然为18ms,基本下降为原来的十分之一。


究其根本原因是Mat中foreach方法为Mat像素并行操作方法,而我的测试电脑为10核CPU,因此采用foreach进行测试时检测时间基本降低为原来的十分之一,充分发挥了CPU性能。


个人感觉该方法非常受用,瑾此分享!


机器视觉课堂
OpenCV、Halcon等机器视觉专业学习交流平台,服务于工业自动化、先进机器人技术、人工智能等相关专业技术人才。定期发布最新机器视觉相关新闻、应用案例、技术资料、展会信息等信息。
 最新文章