OpenCV -Python 性能衡量和提升技术 | 十二
目标
在图像处理中,由于每秒要处理大量操作,因此必须使代码不仅提供正确的解决方案,而且还必须以最快的方式提供。因此,在本章中,你将学习
- 衡量代码的性能。
- 一些提高代码性能的技巧。
- 你将看到以下功能:cv.getTickCount,cv.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*x或y = 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.countNonZero和np.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 的最大性能。这里只注明相关信息,并提供重要信息来源的链接。这里要注意的主要事情是,首先尝试以一种简单的方式实现算法。一旦它运行起来,分析它,找到瓶颈并优化它们。
- 尽量避免在Python中使用循环,尤其是双/三重循环等。它们本来就很慢。
- 由于Numpy和OpenCV已针对向量运算进行了优化,因此将算法/代码向量化到最大程度。
- 利用缓存一致性。
- 除非需要,否则切勿创建数组的副本。尝试改用视图。数组复制是一项昂贵的操作。
即使执行了所有这些操作后,如果你的代码仍然很慢,或者不可避免地需要使用大循环,请使用Cython等其他库来使其更快。
其他资源
- Python优化技术:http://wiki.python.org/moin/PythonSpeed/PerformanceTips
- Scipy讲义- 高级Numpy:http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#advanced-numpy
- IPython中的时序和性能分析:http://pynash.org/2013/03/06/timing-and-profiling/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/
欢迎关注PyTorch官方中文教程站:
http://pytorch.panchuang.net/
OpenCV -Python 性能衡量和提升技术 | 十二的更多相关文章
- 【阿里聚安全·安全周刊】阿里双11技术十二讲直播预约|AWS S3配置错误曝光NSA陆军机密文件
关键词:阿里双11技术十二讲直播丨雪人计划丨亚马逊AWS S3配置错误丨2018威胁预测丨MacOS漏洞丨智能风控平台MTEE3丨黑客窃取<权利的游戏>剧本|Android 8.1 本 ...
- python成长之路【第十二篇】:RabbitMQ入门
一.RabbitMQ介绍 解释RabbitMQ,就不得不提到AMQP(Advanced Message Queuing Protocol)协议. AMQP协议是一种基于网络的消息传输协议,它能够在应用 ...
- Python成长笔记 - 基础篇 (十二)
本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 主题:学员管理系统 需求: 用户角色,讲师\学员, 用户登陆后根据角色不同,能做的 ...
- 《Python 学习手册4th》 第十二章 if测试和语法规则
''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...
- Python学习之旅(三十二)
Python基础知识(31):图形界面(Ⅱ) Python内置了turtle库,可以在计算机上绘图 运动控制: 1.画笔定位到坐标(x,y):turtle.goto(x,y) 2.向正方向运动 dis ...
- Python小白学习之路(十二)—【前向引用】【风湿理论】
前向引用 风湿理论(函数即变量) 理论总是很抽象,我个人理解: 代码从上到下执行,一旦遇到定义的函数体,内存便为其开辟空间,并用该函数的名字作为一个标识但是该函数体内具体是什么内容,这个时候并不着急去 ...
- Go语言核心36讲(Go语言进阶技术十二)--学习笔记
18 | if语句.for语句和switch语句 现在,让我们暂时走下神坛,回归民间.我今天要讲的if语句.for语句和switch语句都属于 Go 语言的基本流程控制语句.它们的语法看起来很朴素,但 ...
- python nose测试框架全面介绍十二 ----用例执行顺序打乱
在实际执行自动化测试时,发现我们的用例在使用同一个资源的操作时,用例的执行顺序对测试结果有影响,在手工测试时是完全没法覆盖的. 但每一次都是按用例名字来执行,怎么打乱来执行的. 在网上看到一个有意思的 ...
- Python之路【第三十二篇】:django 分页器
Django的分页器paginator 文件为pageDemo models.py from django.db import models # Create your models here. cl ...
随机推荐
- oracle监控参数
Sar –u 检查CPU的繁忙程度列说明Usr用户模式下cpu运行所占的百分比Sys系统模式下cpu运行所占的百分比Wio因为有进程等待块I/O而使cpu处于闲置状态所占百分比IdleCpu为闲置状态 ...
- [开源福利] Arithmetic Generator
Arithmetic Generator Built with ❤︎ by Simon Ma ✨ A powerful arithmetic generator
- Hibernate和Mybatis的工作原理以及区别
一.Mybatis的工作流程图 (1).原理详见: MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一 ...
- overflow-y:auto/hidden/scroll和overflow-x:visible组合渲染异常
最近做项目想做一个这样的效果:就是我想要内部div x轴溢出div则显示y轴溢出div则出现滚动条于是用到了overflow-y 和 overflow-x 这个css属性原来以为css中直接设置就ok ...
- Vue进阶课堂之《从HTML到Pug》
是啥 Pug听起来或许比较陌生,但是如果说起她的前生,相信各位多少会有耳闻:Jade.每当你不停的敲打<><><><></></> ...
- CSS+DIV自适应布局
CSS+DIV自适应布局 1.两列布局(左右两侧,左侧固定宽度200px;右侧自适应占满) 代码如下: <!doctype html> <html> <head> ...
- 前端面试题-HTML语义化标签
一.HTML5语义化标签 标签 描述 <article> 页面独立的内容区域. <aside> 页面的侧边栏内容. <bdi> 允许您设置一段文本,使其脱离其父元素 ...
- 个人理解TCP中SYN Cookie
说起SYN Cookie还是得从TCP3次握手开始说起,先给出计网的体系结构图 然后解释一下SYN,seq,ack,ACK的相关名词 SYN(建立连接) ACK(确认后全部为1) PSH(传送) FI ...
- springcloud gateway整合sentinel
1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spri ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...