OpenCV-图像像素遍历操作的三种方法对比(程序提速)

简介: OpenCV-图像像素遍历操作的三种方法对比(程序提速)

场景需求

      使用OpenCV,避免不了的就是对图像像素进行操作,遍历操作更是家常便饭,当图像数据不多时,各类方法的速度差不太多;但面对数据计算次数非常多,尤其在进行迭代、拟合、递归等数据反复计算的工作时,此时不得不面对的就是程序性能、算法提速和优化的问题了。


      在OpenCV中有三种最常用的像素操作方法,分别是动态地址操作法、迭代器操作法和指针操作法。下面简单介绍下该三种方法的优劣和使用场景:


  1. 动态地址操作法。最常用,比如直接A.at,操作Mat矩阵A第i行第j列的像素值,简洁明了,适合对某个或某几个值直接操作时使用,定位非常方便,也可以遍历计算使用,但是速度方面比其他两个方法都要慢;
  2. 迭代器操作法。运用了C++中STL的理念,通过迭代器的方式,获取矩信息的头尾(begin和end),然后依次操作,该方法适合连续计算时使用,速度和动态地址操作法差不多,比指针法慢,但是胜在安全性好;
  3. 指针法。我最喜欢的遍历法,一遇到遍历操作必用ptr,该方法缺点就是指针容易越界,编代码时要慎重,确保安全和稳定,但是速度没得说。

      三种方法一般情况在debug下运行差异性很明显,release下没那么明显;但是一旦遍历的函数复杂性加大了,release下的差异性就会体现出来了,指针法绝对是最快的,我在做图像迭代拟合计算时,用指针法替代动态地址法,速度至少提高5-10倍,一点不夸张。。。


     下面简单写了段测试代码,展示下三种方法的使用方式,顺便测试下debug和release下的运行时间情况。

C++实现代码

// 动态地址操作法
for (int i = 0; i < A.rows; i++)
{ 
  for (int j = 0; j < A.cols; j++)
  {
    P.at<float>(i, j) *= 2;
  }
}
// 迭代器操作法
Mat_<float>::iterator it = B1.begin<float>();
Mat_<float>::iterator itend = B1.end<float>();
for (; it!=itend; ++it)
{
  (*it)*= 2;
}
// 指针操作法
for (int i = 0; i < A.rows; i++)
{ 
  float *data = B2.ptr<float>(i);
  for (int j = 0; j < A.cols; j++)
  {
    data[j]*= 2;
  }
}

测试代码

#include<iostream>
#include<opencv2/opencv.hpp>
#include<ctime>
using namespace std;
using namespace cv;
int main(void)
{
  Mat A = Mat::zeros(10000, 10000, CV_32FC1);
  // 随意创建一个A矩阵
  for (int i = 0; i < A.rows; i++)
  {
    for (int j = 0; j < A.cols; j++)
    {
      A.at<float>(i, j) = rand()%100/100.f;
    }
  }
  Mat B0,B1,B2;
  B0 = A.clone();
  B1 = A.clone();
  B2 = A.clone();
  // 动态地址操作法
  double time0 = static_cast<double>(getTickCount());
  for (int i = 0; i < A.rows; i++)
  { 
    for (int j = 0; j < A.cols; j++)
    {
      B0.at<float>(i, j) *= 2;
    }
  }
  time0 = ((double)getTickCount() - time0) / getTickFrequency();
  cout << "    动态地址法运行时间为:" << time0 << "秒" << endl << endl;
  // 迭代器操作法
  double time1 = static_cast<double>(getTickCount());
  Mat_<float>::iterator it = B1.begin<float>();
  Mat_<float>::iterator itend = B1.end<float>();
  for (; it!=itend; ++it)
  {
    (*it)*= 2;
  }
  time1 = ((double)getTickCount() - time1) / getTickFrequency();
  cout << "    迭代器法运行时间为:" << time1 << "秒" << endl << endl;
  // 指针操作法
  double time2 = static_cast<double>(getTickCount());
  for (int i = 0; i < A.rows; i++)
  { 
    float *data = B2.ptr<float>(i);
    for (int j = 0; j < A.cols; j++)
    {
      data[j]*= 2;
    }
  }
  time2 = ((double)getTickCount() - time2) / getTickFrequency();
  cout << "    指针法运行时间为:" << time2<< "秒" << endl << endl;
  system("pause");
  return 0;
}

测试效果

     release下:

图1 release下运行时间对比

     debug下:

图2 debug下运行时间对比

图2 debug下运行时间对比

      综上所述,追求安全性就用迭代器,追求方便和便于定位就用动态地址at,追求极致速度就用ptr指针。

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
1月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
322 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
2月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
49 4
|
2月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
3月前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
WK
|
3月前
|
编解码 计算机视觉 Python
如何在OpenCV中进行图像转换
在OpenCV中,图像转换涉及颜色空间变换、大小调整及类型转换等操作。常用函数如`cvtColor`可实现BGR到RGB、灰度图或HSV的转换;`resize`则用于调整图像分辨率。此外,通过`astype`或`convertScaleAbs`可改变图像数据类型。对于复杂的几何变换,如仿射或透视变换,则可利用`warpAffine`和`warpPerspective`函数实现。这些技术为图像处理提供了强大的工具。
WK
108 1
|
3月前
|
存储 编解码 API
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
245 1
|
3月前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
497 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
|
4月前
|
机器学习/深度学习 传感器 算法
OpenCV4工业缺陷检测的六种方法
OpenCV4工业缺陷检测的六种方法
|
4月前
|
机器学习/深度学习 XML 计算机视觉
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它提供了大量的函数和工具,用于处理图像和视频数据。
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它提供了大量的函数和工具,用于处理图像和视频数据。
|
5月前
|
算法 计算机视觉
【Qt&OpenCV 图像的感兴趣区域ROI】
【Qt&OpenCV 图像的感兴趣区域ROI】
165 1