OpenCV(JavaCV)与 OpenCV(C/C++ 接口)
Posted
技术标签:
【中文标题】OpenCV(JavaCV)与 OpenCV(C/C++ 接口)【英文标题】:OpenCV (JavaCV) vs OpenCV (C/C++ interfaces) 【发布时间】:2014-02-08 01:45:58 【问题描述】:我只是想知道在给定的一组机器上,相对于 OpenCV 的 C/C++ 实现而言,使用 JavaCV 是否会有显着的速度性能优势。
如果我错了,请纠正我,但我的理解是 opencv 的 c/c++ 实现更接近机器,因为 OpenCV 的 Java 实现 JavaC 会在速度性能方面有轻微的劣势(以毫秒为单位)会有一个虚拟机将您的源代码转换为字节码,然后再转换为机器码。然而,使用 c/c++,它直接转换为机器代码,因此不承担虚拟机开销的中间步骤。
如果我犯了错误,请不要在这里杀了我;我只是在学习,欢迎提出建设性的批评。
谢谢
【问题讨论】:
但是 Java 是平台无关的,而 C/C++ 是平台相关的。 让opencv lib与maven一起工作的问题更少:p 【参考方案1】:我想在@ejbs 的回答中添加一些内容。
首先,你关心两个不同的问题:
-
Java 与 C++ 的性能
OpenCV 与 JavaCV
Java 与 C++ 性能是一个很长很长的故事。一方面,C++ 程序被编译成高度优化的原生代码。它们可以快速启动并始终快速运行,而不会因垃圾收集或其他 VM 职责而暂停(就像 Java 那样)。另一方面,一旦编译,C++ 中的程序就不能改变,无论它们在什么机器上运行,而 Java 字节码 是“即时”编译的并且始终针对它们运行的处理器架构进行了优化。在现代世界中,有这么多不同的设备(和处理器架构),这可能非常重要。此外,一些 JVM(例如 Oracle Hotspot)甚至可以优化已经编译为本机代码的代码! VM 收集有关程序执行的数据,并不时尝试重写代码,使其针对此特定执行进行优化。因此,在如此复杂的情况下,比较不同编程语言的实现性能的唯一真正方法就是运行它们并查看结果。
OpenCV 与 JavaCV 是另一回事。首先,您需要了解这些库背后的技术堆栈。
OpenCV 最初于 1999 年在英特尔研究实验室中创建,使用 C 语言编写。从那时起,它多次更换维护者,成为开源并达到第三版(即将发布)。目前,该库的核心是用 C++ 编写的,具有 Python 中的流行接口和其他编程语言中的许多包装器。
JavaCV 就是这样的包装器之一。因此,在大多数情况下,当您使用 JavaCV 运行程序时,您实际上也使用了 OpenCV,只需通过另一个接口调用它。但是 JavaCV 提供的不仅仅是 OpenCV 的一对一包装器。事实上,它捆绑了所有图像处理库,包括 FFmpeg、OpenKinect 等。 (注意,在 C++ 中,您也可以绑定这些库)。
因此,一般来说,无论您使用的是 OpenCV 还是 JavaCV,都将获得几乎相同的性能。它更多地取决于您的主要任务 - 是 Java 还是 C++ 更适合您的需求。
关于性能还有一点很重要。使用 OpenCV(直接或通过包装器),您有时会发现 OpenCV 函数通过几个顺序克服了其他实现。这是因为在其核心中大量使用了低级优化。例如,OpenCV 的filter2D 函数是SIMD-加速的,因此可以并行处理多组数据。而在计算机视觉方面,对常用功能的这种优化可能很容易导致显着的加速。
【讨论】:
非常深入的解释,感谢您抽出宝贵时间。 这是很棒的东西,我的意思是,这很好解释,你刚刚回答了我的问题,节省了我寻找这种可以理解的解释的时间。【参考方案2】:JavaCV 是 OpenCV 的接口,因此当您调用与 OpenCV 相关的内容时会产生一些开销,但通常大部分繁重的工作仍将在 C++ 端进行,因此不会有很大的性能损失。
您必须进行性能基准测试才能了解更多信息。
附言。我在这里很新,但我很确定这不是 *** 的合适问题。
【讨论】:
为什么你认为它不适合SO? 我不敢给你一个充分的理由,恐怕这更像是一种直觉。 是的,我知道这种感觉 :) 不过,这个问题是具体的,可能有具体的答案,所以我相信没关系。 也感谢 ffriend 和 ejbs;例如,在实时应用程序中,您正在检测高速公路上高速行驶的汽车,JavaCV 接口是否仍然足够快,可以捕获该汽车并增加计数?我知道我很傻,我知道 java 的速度非常快,但他们为什么要为我们提供这个库的 c/c++ 实现呢?与其他任何东西(Java,Python)相比,它不是 b/c 真的那么快吗?如果我错了,请纠正我 很确定最初的实现是用 C++ 编写的,所以这都是历史原因。我不确定它是否足够快,可能吗?如果您满意,请不要忘记接受我的回答;)【参考方案3】:我想添加一些关于 java 作为 c++ 库接口的更多见解...
A) 开发中:
1)虽然java可能更容易管理大型项目并且编译速度极快,但它非常非常困难,而且几乎不可能从java调试本机代码......
当代码在本机端崩溃...或内存泄漏(经常发生的事情...)时,您会感到有些无助...
2)除非您自己构建绑定(即使使用 swig 或其他任何东西都不是一件容易的事...)您依赖于绑定构建者的善意/健康/时间...。 所以在这种情况下,我更喜欢官方的“桌面 java”绑定而不是 javacv...
B) 性能。
1) 虽然可以优化绑定(使用 neobuffer 进行内存传输),因为在 javacv 情况下,每个本机函数调用仍然有非常非常小的 jni 开销 - 这在我们的例子中是没有意义的,因为与这个 jni 开销相比,大多数 opencv 函数消耗 X100000++ cpu 周期......
2) 大问题----停止世界 GARBAGE COLLECTIOR(GC)
java 使用一个垃圾收集器来停止所有 cpu 的线程,使其不适合实时应用程序,我听说过一些解决方法,比如重新设计你的应用程序不产生垃圾,使用 spaciel gc,或使用实时 java (花钱...)他们似乎都是额外的工作(而你想要的只是一条通往opencv的好方法......)
结论 - 如果你想创建一个专业的实时应用程序 - 然后使用 c++ 除非你有一个庞大的模块化项目需要管理——只要坚持使用 c++ 和预编译的头文件(让事情编译得更快......) 虽然使用 java 是一种乐趣,但当涉及到原生绑定时,HELL 就会崩溃......我知道我去过那里......
【讨论】:
以上是关于OpenCV(JavaCV)与 OpenCV(C/C++ 接口)的主要内容,如果未能解决你的问题,请参考以下文章