OpenCV-Python11:程序性能检测及优化

目录

背景说明

学习目标及环境

Python程序性能检测方法及说明介绍

OpenCV 检测程序效率 

OpenCV 中的默认优化 

在IPython 中检测程序效率

更多IPython 的魔法命令

效率优化技术


背景说明

        在实际图像处理中程式每秒都要做大量的运算,为了体现程序的实用性,程序不仅要能给出正确的结果,同时还必须足够快。这就要求我们在同一硬体保证实现程序功能的前提下,能够对程式进行检测和优化,从而实现程式的最优化。

学习目标及环境

  • 学会检测程序的效率
  • 掌握能够提高程序效率的技巧
  • 学习函数cv2.getTickCount,cv2.getTickFrequency
  • Python =3.6.8      OpenCV-Python=3.4.2.16

Python程序性能检测方法及说明介绍

        在Python中,可以使用一些工具和技术来检测和优化程序的性能。以下是几种常用的方法及其简要介绍:

  • 时间测量

        使用Python的time模块可以测量程序的执行时间。可以使用time.time()函数来获取当前时间戳,从而计算代码块的执行时间。

  • cProfile模块

        cProfile是Python的内置模块,可以用于分析程序的性能。它可以提供函数级别的统计信息,包括每个函数的执行时间和调用次数。

  • line_profiler模块        

        line_profiler是一个第三方模块,可以用于分析代码的行级别性能。它可以显示每行代码的执行时间和调用次数,帮助找到代码中的瓶颈。

  • memory_profiler模块

        memory_profiler是一个第三方模块,可以用于分析程序的内存使用情况。它可以显示每个函数的内存占用量,帮助找到内存泄漏或过度分配的问题。

  • 性能分析工具

        除了Python内置的模块,还有一些第三方工具可以用于性能分析。例如,使用Py-Spy可以直接采样Python进程的堆栈,以获得函数调用的时间分布情况。

  • 可视化工具

        有一些可视化工具可以帮助分析程序的性能。例如,使用SnakeViz可以将cProfile和line_profiler的输出结果可视化,以便更直观地分析程序的性能。

        在进行性能优化时,可以使用这些工具来找到程序的瓶颈,并进行相应的优化。然而,需要注意的是,性能优化并不是一种简单的任务,需要综合考虑算法、数据结构、并行化等多个方面的因素。因此,在进行性能优化时,需要综合考虑各种方法和工具,并进行合理的权衡和取舍。

OpenCV 检测程序效率 

cv2.getTickCount() :该函数返回从参考点到这个函数被执的时钟数。所以当你在一个函数执行前后都调用它的话,你就会得到这个函数的执行时间(时钟数)。
cv2.getTickFrequency(): 返回时钟频率或者说每秒钟的时钟数目。所以你可以按照下列的方式得到一个函数运行了多少秒:

# -*- coding: utf-8 -*-
"""
@author: Pegasus
"""

import cv2
import numpy as np

e1 = cv2.getTickCount()
# 在这里调用hello函数测试
print('hello world!')
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()
print('运行时间为:',time)

注意:也可以用time 模块实现以上功能,但是调用函数是time.time() 而不是cv2.getTickCount()

OpenCV 中的默认优化 

OpenCV 中的很多函数都被优化过(使用SSE2,AVX 等)。也包含一些没有优化的代码。如果我们的系统支持优化的尽量利用这一点。在编译时优化是默认开启的。因此OpenCV 运行的就是优化后的代码,如果你把优化关闭的话就只能执行低效的代码了。你可以使用函数cv2.useOptimized()
来查看优化是否开启了,使用函数cv2.setUseOptimized() 来开启优化。我们来看一个简单的例子吧。

# -*- coding: utf-8 -*-
"""
Created on Thu Jan 9 21:08:41 2014
@author: duan
"""
import cv2
import numpy as np
# check if optimization is enabled
In [5]: cv2.useOptimized()
Out[5]: True
In [6]: %timeit res = cv2.medianBlur(img,49)
10 loops, best of 3: 34.9 ms per loop
# Disable it
In [7]: cv2.setUseOptimized(False)
In [8]: cv2.useOptimized()
Out[8]: False
In [9]: %timeit res = cv2.medianBlur(img,49)
10 loops, best of 3: 64.1 ms per loop

结果显示,优化后中值滤波的速度是原来的两倍。如果你查看源代码的话你会发现中值滤波是被SIMD 优化的。所以你可以在代码的开始处开启优化(你要记住优化是默认开启的)。

在IPython 中检测程序效率

        有时你需要比较两个相似操作的效率,这时你可以使用IPython 为你提供的魔法命令%time。他会让代码运行好几次从而得到一个准确的运行时间,它也可以用来测试单行代码的。例如:你想知以下同一个数学运算用哪种方式的代码会执行的更快。
x = 5; y = x ∗ ∗2
x = 5; y = x ∗ x
x = np.uint([5]); y = x ∗ x
y = np.squre(x)
我们可以在IPython 的Shell 中使用魔法命令找到答案。

import cv2
import numpy as np
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

竟然是第一种写法,它居然比Nump 快了20 倍。如果考虑到数组构建的话能提高到100 倍的差。

注意:Python 的标量运算比Nump 的标量运算快。对于仅包含一两个元素的操作,Python 标量比Numpy 的数组快。但是当数组稍微大一点时Numpy 就会胜出了。 

我们来比较一下cv2.countNonZero() 和np.count_nonzero()。

import cv2
import numpy as np
In [35]: %timeit z = cv2.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 的魔法命令

还有几个魔法命令可以用来检测程序的效率,如profiling,line profiling,内存使用等。他们都有完善的文档。所以只提供了链接。感兴的可以自己学习一下。

效率优化技术

        有些技术和编程方法可以帮助我们最大的发挥Python 和Numpy 的威力。在这里我们仅仅提一下相关的,你可以通过链接查找更多详细信息。

Python优化技术: https://wiki.python.org/moin/PythonSpeed/PerformanceTips

Scipy和Numpy:http://scipy-lectures.org/advanced/advanced_numpy/index.html#advanced-numpy

我要说的最重要的一点是,要先用最简单的方式实现你的算法(因为结果正确最重要),当结果正确后,再使用上面的提到的方法找到程序的瓶颈来优它。面给出一些建议:

  1. 尽量避免使用循环,尤其双层三层循环,它们天生就是非常慢的。
  2. 算法中尽量使用向量操作,因为Numpy 和OpenCV 都对向量操作进行了优化。
  3. 利用高速缓存的一致性。
  4.  没有必要的话就不要复制数组,使用视图来代替复制。数组复制是非常浪费源的。
  5. 如果进行了上诉优化,程序依然很慢或者有些需要无法避免,应该尝试一下使用其它的包比如 Cython来加速你的程序,或者从新设计一下算法流程及思路

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【linux】SSH终端Putty配置:文件上传/下载、显示中文字体、自动登录

文章目录 写在前面putty上传/下载文件1. 下载2. 解压和配置3. 使用sz/rz3.1 下载文件:sz3.2 上传文件:rz 显示中文字体1. 下载合适的字体2. 解压和安装3. putty配置 putty自动登录1. putty配置2. putty快捷方式配置3. 使用putty 写在后面 写在前面 一篇博客介绍了12种SSH终端工…

D3132|贪心算法

435.无重叠区间 初始思路&#xff1a; 我的思路就是如果有两个区间重叠&#xff0c;保留end比较小的那个区间&#xff0c;删除end比较大的区间。 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>…

恐怖题材黑马大作,艾尔莎B760M-E D5和你玩转《心灵杀手2》

说起恐怖题材的游戏&#xff0c;相信不少朋友都会第一时间想到《生化危机》、《寂静岭》、《死亡空间》等经典系列与作品。而在最近这几年&#xff0c;恐怖题材游戏也有不少黑马出现&#xff0c;比如最近推出的《心灵杀手2》就是2010年《心灵杀手》的续作&#xff0c;它是由开发…

iPhone16:首款AI iPhone?

随着科技水平的不断发展&#xff0c;智能手机逐渐成为人们最依赖的电子产品之一。为能够满足用户需求&#xff0c;手机的硬件、外观设计与性能飞速提升&#xff0c;这也导致智能手机市场快速进入到瓶颈期。 为了能够带来更优秀的表现&#xff0c;苹果可能会为iPhone 16系列带来…

中国首家!腾讯云入选Gartner®视频平台服务市场指南代表厂商

近日&#xff0c; Gartner正式发布《Market Guide for Video Platform Services》&#xff08;《视频平台服务市场指南》&#xff0c;下称“《指南》”&#xff09;&#xff0c;凭借领先的音视频技术和产品组合优势&#xff0c;腾讯云成为中国首家且唯一入选的代表厂商。 腾讯…

GZ015 机器人系统集成应用技术样题8-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题8 选手须知&#xff1a; 本任务书共 25页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…

Vue学习笔记-Vue3中的customRef

作用 创建一个自定义的ref&#xff0c;并对其依赖项的更新和触发进行显式控制 案例 描述&#xff1a;向输入框中输入内容&#xff0c;在下方延迟1秒展示输入内容 代码&#xff1a; <template><input type"text" v-model"keyword"><h3&…

力扣刷题记录(15)LeetCode:509、70、746

目录 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯 总结 ​​​​​​ 用一个数组来存储前两个数的值&#xff0c;然后根据前两个数的值来确定当前的值。 class Solution { public:int fib(int n) {if(n<2) return n;vector<int> v;v.push_back(0);v.push…

3 使用postman批量创建测试数据

上一篇:2 使用postman进行接口测试-CSDN博客 在软件测试实际工作中,因测试需要,我们要批量创建测试数据。如果某些接口不允许输入重复数据,我们在做批量请求时就要做参数处理了。 比如在上一篇介绍的用户注册接口,一般注册的时候用户名是不允许重复的,如果要批量创…

8.完成任务实现的SDK封装及插件式加载

1.设计 任务的实现目前完成了Modbus RTU、Modbus TCP、Virtule。任务实现应该是任意的&#xff0c;比如打印一段话&#xff0c;执行一句SQL等&#xff0c;所以系统内部的必然要做到可扩展。 要做到可扩展&#xff0c;首先第一步就是定义标准&#xff0c;所以我们首先需要封装…

FA1210AN (MHz范围晶体单元超小型低轮廓贴片)

FA1210AN体积小&#xff0c;高度低&#xff0c;设计人员可以在不影响性能的情况下节省板空间。这对于那些限制功能和尺寸的设备和模块来说是必不可少的。 宽MHz范围的频率服务于流行的&#xff0c;无线通信协议&#xff0c;理想的消费者和工业物联网应用。应用程序&#xff1a…

第15章 《乐趣》Page375~379定时器,定时回调,定时回调线程id, 停止后续定时

运行效果&#xff1a;在骏马窗口中&#xff0c;按下ctrl t 键&#xff0c;就可以看到定时回调&#xff0c;同时可以看出timer_callback和main()真的不在同一线程中运行 代码如下&#xff1a;仅给出main.cpp, 其他的头文件和源文件和Page355~375的代码一样&#xff0c;可参看上…

【C语言】数组(一维)详解,手把手教你,保姆级!!!

目录 数组的概念 数组的创建 数组的初始化 数组的类型 数组使用下标 数组的打印 数组的输入 数组的储存 总结 数组的概念 数组是⼀组相同类型元素的集合&#xff1b; 从这个概念中我们有3点拓展&#xff1a; 1&#xff0c;数组中存放的是1个或者多个数据&#xff0c;但…

4.raft协议及简化版raft协议

1.Raft协议介绍 这篇文章&#xff1a;百度安全验证 讲的比较详细了&#xff0c;我再以我的方式汇总一下&#xff1a; Raft协议是一种分布式一致性协议&#xff0c;比Pasox简单&#xff0c;旨在解决数据的一致性和高可用性Raft在选举中的方式&#xff1a; 所有节点相互建立连…

什么是磁钢的工作点和Pc值?如何计算Pc值?

永磁体是在开路状态下工作的&#xff0c;由于开路状态的磁体是在退磁场的作用下&#xff0c;所以工作状态下的永磁体的磁感应强度不在闭路状态的Br点上&#xff0c;而是在比Br低的退磁曲线上的某一点&#xff0c;这一点称为永磁体的工作点&#xff0c;如下图D点。 工作点与退磁…

【C语言】操作符详解(四):结构成员访问操作符

目录 结构成员访问操作符 结构体 结构体的声明 结构体变量的定义和初始化 结构成员访问操作符 结构体成员的直接访问 结构体成员的间接访问 结构成员访问操作符 结构体 ⭐C语言已经提供了内置类型&#xff0c;如: char、short、int、long、float、double等&#xff0c;但…

备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项——任务2:离线数据处理

MySQLhttps://www.mysql.com/ 将下发的ds_db01.sql数据库文件放置mysql中 12、编写Scala代码&#xff0c;使用Spark将MySQL的ds_db01库中表user_info的全量数据抽取到Hive的ods库中表user_info。字段名称、类型不变&#xff0c;同时添加静态分区&#xff0c;分区字段为etl_da…

提高软件交付速度的6种架构策略

本文向您展示如何评估软件交付性能&#xff0c;并向您介绍可用于提高软件交付性能的六种策略。 如何评估软件的交付速度 软件交付速度能够促进业务发展&#xff0c;那么我们如何评估软件的交付速度呢&#xff1f;主要有以下4个指标 一个功能从开发到上线运营使用需要多久&#…

代码随想Day39 | 62.不同路径、63. 不同路径 II

62.不同路径 每次向右或者向下走两个选择&#xff0c;定义dp数组dp[i][j] 为到达索引ij的路径和&#xff0c;状态转移公式为 dp[i][j]dp[i-1][j]dp[i][j-1]&#xff0c;初始状态的第一行和第一列为1&#xff0c;从左上到右下开始遍历即可。详细代码如下&#xff1a; class Sol…

问卷调查结果分析指南:方法与技巧解析

问卷调查是一种常见的数据收集方式&#xff0c;广泛用于市场调研、科研、员工幸福评估等各个领域。但是&#xff0c;问卷的数据收集只是第一步&#xff0c;分析这种数据至关重要。问卷调查该怎么分析结果&#xff1f;首先要进行数据清理&#xff0c;然后对数据展开叙述&#xf…
最新文章