社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

踩坑记录 | 发现了OpenCV-Python执行比C++慢几百倍的原因

OpenCV学堂 • 2 月前 • 249 次点击  

点击上方蓝字关注我们

微信公众号:OpenCV学堂

关注获取更多计算机视觉与深度学习知识

联通组件算子(CCL)

连接组件标记算法(connected component labeling algorithm)是图像分析中最常用的算法之一,算法的实质是扫描一幅图像的每个像素,对于像素值相同的分为相同的组(group),最终得到图像中所有的像素连通组件。扫描的方式可以是从上到下,从左到右,对于一幅有N个像素的图像来说,最大连通组件个数为N/2。扫描是基于每个像素单位,对于二值图像而言,连通组件集合可以是V={1|白色}或者V={0|黑色}, 取决于前景色与背景色的不同。对于灰度图像来说,连图组件像素集合可能是一系列在0 ~ 255之间k的灰度值。OpenCV中相关的两个函数分别是:
int cv::connectedComponents(  InputArray  image, // 输入二值图像,黑色背景  OutputArray     labels, // 输出的标记图像,背景index=0  int     connectivity = 8, // 连通域,默认是8连通  int     ltype = CV_32S // 输出的labels类型,默认是CV_32S)

 带统计信息的联通组件标记函数

int cv::connectedComponentsWithStats(InputArray  image, // 输入二值图像,黑色背景OutputArray     labels, // 输出的标记图像,背景index=0OutputArray     stats, // 统计信息,包括每个组件的位置、宽、高与面积OutputArray     centroids, // 每个组件的中心位置坐标cx, cyint     connectivity, // 寻找连通组件算法的连通域,默认是8连通int     ltype, // 输出的labels的Mat类型CV_32Sint     ccltype // 连通组件算法)

在OpenCV实验大师中封装的第二个函数支持。

不同速度 现象对比

最近用户群里有个人跟我说,它有个二值化的图像,然用了OpenCV实验大师的联通组件算子,发现特别耗时,3200x3200大小的图像,耗时居然是几十秒,然后我让他把图发我,我自己测试了一下,发现的确是的。

然后我就把这个保存为流程文件,到的C++引擎库中又测试了一下,发现速度很快,截图如下:

只需要不到50毫秒,而Python版本的居然比C++版本慢了几百倍,我觉得肯定是Python版本哪里实现有不合理的代码,于是我开启了端点执行,单步打印调试….

查找问题与代码修改

通过我一通对比自己实现的C++ 与Python代码发现,无论是C++ 还是Python里面调用OpenCV函数都在十几毫秒可以完成,所以Python实现中20多秒的时间损耗肯定来自于Python代码本身,应该与OpenCV无关,一通DEBUG之后我发现是我最后给标签图像赋值颜色的代码造成的,代码如下:

执行耗时如下:
ccl time :  22649.269342422485  ms
然后我看了一下代码,发现了最可能的原因是
result[labels==t] = colors[t]
这行代码导致的,因为我有很多标签,每个标签它都要全图搜索一次,几百个标签,它就全图搜索几百次了,想想在3200x3200的图上遍历搜索几百次,能不成瓶颈吗?我哭,我最初写这个代码觉得这个语法很高大上,鬼斧神工,现在是回旋镖打自己。然后我改成下面这样:

执行时间变成:
ccl time :  4321.542501449585  ms
没办法,Python里面遍历数组就是慢,我有限水平已经尽力,想快还是用C++吧。最后上传一下我的测试图像:


OpenCV4系统化学习


深度学习系统化学习

推荐阅读

OpenCV4.8+YOLOv8对象检测C++推理演示

ZXING+OpenCV打造开源条码检测应用

攻略 | 学习深度学习只需要三个月的好方法

三行代码实现 TensorRT8.6 C++ 深度学习模型部署

实战 | YOLOv8+OpenCV 实现DM码定位检测与解析

对象检测边界框损失 – 从IOU到ProbIOU

初学者必看 | 学习深度学习的五个误区


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/173767
 
249 次点击