opencv入门到精通——OpenCV4.1.2之性能衡量与优化方法

目录

目标

使用OpenCV衡量性能

OpenCV中的默认优化

在IPython中衡量性能

更多IPython魔术命令

性能优化技术


目标

在图像处理中,由于每秒要处理大量操作,因此必须使代码不仅提供正确的解决方案,而且还必须以最快的方式提供。因此,在本章中,你将学习

  • 衡量代码的性能。

  • 一些提高代码性能的技巧。

  • 你将看到以下功能:cv.getTickCountcv.getTickFrequency等。

除了OpenCV,Python还提供了一个模块time,这有助于衡量执行时间。另一个模块profile有助于获取有关代码的详细报告,例如代码中每个函数花费了多少时间,调用了函数的次数等。但是,如果你使用的是IPython,则所有这些功能都集成在用户友好的界面中方式。我们将看到一些重要的信息,有关更多详细信息,请查看“ 其他资源”部分中的链接。

使用OpenCV衡量性能

cv.getTickCount函数返回从参考事件(如打开机器的那一刻)到调用此函数那一刻之间的时钟周期数。因此,如果在函数执行之前和之后调用它,则会获得用于执行函数的时钟周期数。

cv.getTickFrequency函数返回时钟周期的频率或每秒的时钟周期数。因此,要找到执行时间(以秒为单位),你可以执行以下操作:

 

e1 = cv.getTickCount()
# 你的执行代码
e2 = cv.getTickCount()
time = (e2 - e1)/ cv.getTickFrequency()

我们将通过以下示例进行演示。下面的示例应用中位数过滤,其内核的奇数范围为5到49。(不必担心结果会是什么样,这不是我们的目标):

 

img1 = cv.imread('messi5.jpg')
e1 = cv.getTickCount()
for i in range(5,49,2):
    img1 = cv.medianBlur(img1,i)
e2 = cv.getTickCount()
t = (e2 - e1)/cv.getTickFrequency()
print( t )
# 我得到的结果是0.521107655秒

注意
你可以使用时间模块执行相同的操作。代替cv.getTickCount,使用time.time()函数。然后取两次相差。

OpenCV中的默认优化

许多 OpenCV 函数都是使用 SSE2、 AVX 等进行优化的。它还包含未优化的代码。因此,如果我们的系统支持这些特性,我们就应该利用它们(几乎所有现代的处理器都支持它们)。在编译时默认启用它。因此,如果启用了 OpenCV,它将运行优化的代码,否则它将运行未优化的代码。你可以使用 cvUseoptimized 检查是否启用 / 禁用和 cvSetuseoptimized 以启用 / 禁用它。让我们看一个简单的例子。

#检查是否启用了优化

 

# 检查是否启用了优化
In [5]: cv.useOptimized()
Out[5]: True
In [6]: %timeit res = cv.medianBlur(img,49)
10 loops, best of 3: 34.9 ms per loop
# 关闭它
In [7]: cv.setUseOptimized(False)
In [8]: cv.useOptimized()
Out[8]: False
In [9]: %timeit res = cv.medianBlur(img,49)
10 loops, best of 3: 64.1 ms per loop

看,优化的中值滤波比未优化的版本快2倍。如果你检查其来源,你可以看到中值滤波是 SIMD 优化。因此,你可以使用它在代码顶部启用优化(请记住,它是默认启用的)

在IPython中衡量性能

有时你可能需要比较两个类似操作的性能。IPython为你提供了一个神奇的命令计时器来执行此操作。它会多次运行代码以获得更准确的结果。同样,它们适用于测量单行代码。

例如,你知道以下哪个加法运算更好,x = 5; y = x**2, x = 5; y = x*x, x = np.uint8([5]); y = x*xy = np.square(x)?我们将在IPython shell中使用timeit得到答案。

 

In [10]: x = 5

In [11]: %timeit y=x**2
10000000 loops, best of 3: 73 ns per loop

In [12]: %timeit y=x*x
10000000 loops, best of 3: 58.3 ns per loop

In [15]: z = np.uint8([5])

In [17]: %timeit y=z*z
1000000 loops, best of 3: 1.25 us per loop

In [19]: %timeit y=np.square(z)
1000000 loops, best of 3: 1.16 us per loop

你可以看到x = 5; y = x * x最快,比Numpy快20倍左右。如果你还考虑阵列的创建,它可能会快100倍。酷吧?(大量开发人员正在研究此问题)

注意
Python标量操作比Numpy标量操作快。因此,对于包含一两个元素的运算,Python标量比Numpy数组好。当数组大小稍大时,Numpy会占优势。

我们将再尝试一个示例。这次,我们将比较cv.countNonZeronp.count_nonzero对于同一张图片的性能。

 

In [35]: %timeit z = cv.countNonZero(img)
100000 loops, best of 3: 15.8 us per loop
In [36]: %timeit z = np.count_nonzero(img)
1000 loops, best of 3: 370 us per loop

看,OpenCV 函数比 Numpy 函数快近25倍。

注意
通常,OpenCV函数比Numpy函数要快。因此,对于相同的操作,首选OpenCV功能。但是,可能会有例外,尤其是当Numpy处理视图而不是副本时。

更多IPython魔术命令

还有其他一些魔术命令可以用来测量性能,性能分析,行性能分析,内存测量等。它们都有很好的文档记录。因此,此处仅提供指向这些文档的链接。建议有兴趣的读者尝试一下。

性能优化技术

有几种技术和编码方法可以充分利用 Python 和 Numpy 的最大性能。这里只注明相关信息,并提供重要信息来源的链接。这里要注意的主要事情是,首先尝试以一种简单的方式实现算法。一旦它运行起来,分析它,找到瓶颈并优化它们。

1.尽量避免在Python中使用循环,尤其是双/三重循环等。它们本来就很慢。

2.由于Numpy和OpenCV已针对向量运算进行了优化,因此将算法/代码向量化到最大程度。

3.利用缓存一致性。

4.除非需要,否则切勿创建数组的副本。尝试改用视图。数组复制是一项昂贵的操作。

即使执行了所有这些操作后,如果你的代码仍然很慢,或者不可避免地需要使用大循环,请使用Cython等其他库来使其更快。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/295447.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14、Qt使用Eigen3

一、下载Eigen Eigen 二、创建项目 创建一个"Qt Widget Application"项目,基类选择“QMainWindow“,把Eigen拷贝到项目中 三、更改代码 在.pro中添加 INCLUDEPATH $$PWD\Eigen 在界面上添加一个pushButton,并转到槽&#xff0…

零成本搭建一款博客网站(基于Vercel+Hexo完美实现)【保姆级教程】

文章目录 🐸基于VercelHexo零成本搭建博客网站🐻实现思路 🐮Hexo的配置与安装🐒Hexo的美化与使用🐫Github的推送与部署🐼Vercel部署与网站上线🐛总结 🐸基于VercelHexo零成本搭建博客…

神经网络:机器学习基础

【一】什么是模型的偏差和方差? 误差(Error) 偏差(Bias) 方差(Variance) 噪声(Noise),一般地,我们把机器学习模型的预测输出与样本的真实label…

Spring Boot Admin对SpringBoot服务进行监控

Spring Boot Admin对SpringBoot服务进行监控 前面文章使用 Spring Boot Actuator 监控应用介绍了 Spring Boot Actuator 的使用,Spring Boot Actuator 提供 了对单个 Spring Boot 的监控,信息包含:应用状态、内存、线程、堆栈等等&#xff…

【Proteus仿真】【Arduino单片机】智能垃圾桶设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使用报警模块、LCD1602液晶模块、按键模块、人体红外传感器、HCSR04超声波、有害气体传感器、SG90舵机等。 主要功能: 系统运行后&am…

网络爬虫之Ajax动态数据采集

动态数据采集 规则 有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面教据,但是使用 requests 得到的结果并没有,这是因为requests 获取的都是原始的 HTML 文档…

本地websocket服务端结合cpolar内网穿透实现公网访问

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

融资项目——swagger2接口分类配置

在一般开发中,各种Controller可能会被分为两种:后台管理员的相关Controller与用户的相关Controller。所以在使用swagger2的时候,我们也希望其分为两个大类。其解决方法如下: Configuration EnableSwagger2 public class Swagger2…

window10下载与安装Dubbo Admin,图文说明

0,前言 在学习这篇文章之前,可以先把zookeeper安装一下 安装教程指路:window10下载与安装zookeeper,图文说明 1,下载 拉取代码,一般教程都会让我去github官网拉取,但是因为该网站经常打不开…

关键字:protected关键字

在 Java 中,protected 是一个访问修饰符,用于修饰类成员(成员变量、成员方法和构造方法)。当一个类成员被声明为 protected 时,它可以在同一包中的其他类以及子类中被访问。 以下是 protected 关键字的解析&#xff1a…

【案例】图片预览

效果图 如何让图片放大,大多数的UI组件都带有这种功能,今天给大家介绍的这个插件除了放大之外,还可以旋转、移动、翻转、旋转、二次放大(全屏) 实现 npm i v-viewer -Smain.js 中引入 import viewerjs/dist/viewer.c…

创新固定资产管理方式:易点易动集成企业微信的全新解决方案

在当今竞争激烈的商业环境中,高效的固定资产管理对于企业的成功至关重要。然而,传统的资产管理方式往往繁琐、容易出错,并且缺乏实时性和准确性。为了解决这些挑战,易点易动与企业微信进行了集成合作,推出了一种全新的…