OpenCV: 使用C和C++开发到底哪个好?
C和C++都可以用来开发OPENCV,尽管OPENCV的源码是用C写的,但应用起来实际区别不大。我们看看老外的讨论。
菜鸟提问:
现在我正在使用OpenCV API(C++)开发一些应用程序。此应用程序使用视频进行处理。在电脑上,一切工作都很快。今天我决定把这个应用程序移植到Android上(用摄像头作为视频输入)。幸运的是,有了Android的opencv,所以我只是在示例Android应用程序中添加了我的本地代码。除了表演,一切都很好。我对我的应用程序进行了基准测试,发现该应用程序使用4-5fps,这实际上是不可接受的(我的设备有单核1GHz处理器),我希望它使用大约10fps。是否有必要在C上完全重写我的应用程序?我知道使用std::vector这样的东西对开发人员来说很舒服,但我不在乎。
OpenCV的C接口与C++接口具有相同的功能和方法。
我在谷歌上搜索了这个问题,但什么也没找到。
大神回答:
我在Android和优化方面做了很多工作(我写了一个视频处理应用程序,可以在4ms内处理一帧),所以我希望能给你一些相关的答案。C和C++接口在OpenCV没有太大的区别。有些代码是用C编写的,并且有一个C++包装器,还有一些例子。两者之间的任何显著差异(由Shervin Emami测量)要么是回归,要么是错误修复,要么是质量改进。你应该坚持使用最新的opencv版本。
为什么不重写?
你会花很多时间,你可以用得更好。C接口很麻烦,引入错误或内存泄漏的机会很高。我认为你应该避免。
优化建议
a.启用优化。
编译器优化和缺少调试断言都会对运行时间产生很大的影响。
b.介绍你的应用程序。
先在你的电脑上做,因为它容易得多。使用Visual Studio事件探查器来识别缓慢的部分。优化它们。永远不要优化,因为你认为是缓慢的,但因为你衡量它。从最慢的函数开始,尽可能地优化它,然后再慢一点。测量你的变化以确保它确实更快。
c.专注于算法。
一个更快的算法可以提高性能的数量级(100倍)。一个C++技巧会给你带来2X的性能提升。
经典技术:
调整视频帧的大小。通常,您可以从200x300px图像中提取信息,而不是从1024x768图像中提取信息。第一个的面积是10倍小。使用简单的操作而不是复杂的操作。使用整数而不是浮点。千万不要在执行数千次的矩阵或for循环中使用double。
尽量少计算。您是否可以只在图像的特定区域跟踪对象,而不是对所有帧都进行处理?你能在一个非常小的图像上做一个粗略的/近似的检测,然后在全帧的ROI上对它进行优化吗?
d.在重要的地方使用C开发
在循环中,使用C样式代替C++是有意义的。指向数据矩阵或浮点数组的指针比mat.at或std::vector<>快得多。瓶颈通常是一个嵌套循环。关注它。在整个地方替换vector<>并将代码临时化是没有意义的。
e.避免隐性成本
一些opencv函数将数据转换为double,处理它,然后转换回输入格式。当心它们,它们会破坏移动设备的性能。示例:扭曲、缩放、类型转换。另外,颜色空间转换是懒惰的。更喜欢直接从本地YUV获得的灰度。
f.使用矢量化
ARM处理器使用一种称为neon的技术实现矢量化。学会使用它。它是强大的!
MJ的意见:
1、尽量用C++开发,C++的接口和PYTHON接口非常接近,便于未来语言和AI技术过渡。
2、算法的优化远远大于语言的编译器的价值。
3、C的指针开发对于一般新手很容易出错,且不好追查问题,C的API的可读性也不如C++
4、别忘了利用硬件的特殊处理能力,这种提升完全可以碾压C和C++带来的编译提升价值。
更多相关文章
- Android系统的Root权限获取与检测
- Android(安卓)面试题(答案最全)
- Android(安卓)Service学习之AIDL, Parcelable和远程服务
- [置顶] Android系统体系结构分析
- Android权限之sharedUserId和签名
- Android中ListView的几种常见的优化方法
- 我的Android进阶之旅------>Android中的布局优化 include、merge
- DNS负载均衡,导致Android和iOS访问接口,导致导致时间相差很大
- 轻松理解 Android(安卓)Binder,只需要读这一篇