OpenCV的Python或C ++编码的性能是否不同?

问题描述 投票:56回答:4

我的目标是一点一点地启动opencv,但首先我需要确定哪个OpenCV API更有用。我预测Python实现会更短,但与本机C ++实现相比,运行时间会更加密集和缓慢。有没有人知道可以评论这两种观点之间的性能和编码差异?

c++ python performance opencv
4个回答
134
投票

如前面的答案中所提到的,与C ++或C相比,Python速度较慢.Python的构建原因在于其简单性,可移植性以及创造性,用户只需要担心算法,而不是编程问题。

但是在OpenCV中,有一些不同的东西。 Python-OpenCV只是原始C / C ++代码的包装器。它通常用于组合两种语言的最佳功能,C / C ++的性能和Python的简单性。

因此,当您从Python调用OpenCV中的函数时,实际运行的是底层C / C ++源代码。因此,性能上没有太大差异。(我记得我在某处看过性能损失<1%,不记得在哪里。对OpenCV中一些基本功能的粗略估计显示了<4%的最坏情况惩罚。即penalty = [maximum time taken in Python - minimum time taken in C++]/minimum time taken in C++)。

当您的代码具有大量本机python代码时会出现问题。例如,如果您正在创建自己的OpenCV中没有的函数,事情会变得更糟。这些代码在Python中本地运行,这大大降低了性能。

但新的OpenCV-Python界面完全支持Numpy。 Numpy是Python中的科学计算软件包。它也是本机C代码的包装器。它是一个高度优化的库,支持各种矩阵操作,非常适合图像处理。因此,如果您可以正确组合OpenCV函数和Numpy函数,您将获得非常高速的代码。

要记住的是,总是尽量避免Python中的循环和迭代。相反,使用Numpy(和OpenCV)中提供的数组操作工具。使用C = A+B简单地添加两个numpy数组比使用双循环快很多倍。

例如,您可以查看这些文章:

  1. Fast Array Manipulation in Python
  2. Performance comparison of OpenCV-Python interfaces, cv and cv2

8
投票

openCV的所有google结果都是相同的:python只会稍微慢一点。但是,我没有看过任何关于此的分析。所以我决定做一些并发现:

即使对于琐碎的程序,Python也比使用opencv的C ++慢得多。

我能想到的最简单的例子是在屏幕上显示网络摄像头的输出并显示每秒的帧数。使用python,我达到了50FPS(在Intel原子上)。使用C ++,我获得了65FPS,增加了25%。在这两种情况下,CPU使用率都使用单核,据我所知,受CPU性能的限制。此外,这个测试案例与我在过去从一个项目移植到另一个项目中看到的情况一致。

这种差异来自哪里?在python中,所有openCV函数都返回图像矩阵的新副本。无论何时捕获图像,或者调整图像大小 - 在C ++中,您都可以重用现有内存。在python你不能。我怀疑这段时间分配内存是主要区别,因为正如其他人所说:openCV的底层代码是C ++。

在将python抛出窗口之前:python的开发速度要快得多,只要你没有遇到硬件限制,或者开发速度比性能更重要,那就使用python。在我使用openCV的许多应用程序中,我已经开始使用python,后来只将计算机视觉组件转换为C ++(例如,使用python的ctype模块并将CV代码编译成共享库)。

Python代码:

import cv2
import time

FPS_SMOOTHING = 0.9

cap = cv2.VideoCapture(2)
fps = 0.0
prev = time.time()
while True:
    now = time.time()
    fps = (fps*FPS_SMOOTHING + (1/(now - prev))*(1.0 - FPS_SMOOTHING))
    prev = now

    print("fps: {:.1f}".format(fps))

    got, frame = cap.read()
    if got:
        cv2.imshow("asdf", frame)
    if (cv2.waitKey(2) == 27):
        break

C ++代码:

#include <opencv2/opencv.hpp>
#include <stdint.h>

using namespace std;
using namespace cv;

#define FPS_SMOOTHING 0.9

int main(int argc, char** argv){
    VideoCapture cap(2);
    Mat frame;

    float fps = 0.0;
    double prev = clock(); 
    while (true){
        double now = (clock()/(double)CLOCKS_PER_SEC);
        fps = (fps*FPS_SMOOTHING + (1/(now - prev))*(1.0 - FPS_SMOOTHING));
        prev = now;

        printf("fps: %.1f\n", fps);

        if (cap.isOpened()){
            cap.read(frame);
        }
        imshow("asdf", frame);
        if (waitKey(2) == 27){
            break;
        }
    }
}

可能的基准限制:

  • 相机帧率
  • 定时器测量精度
  • 花在打印格式上的时间

3
投票

你是对的,Python几乎总是比C ++慢很多,因为它需要一个解释器,而C ++却没有。但是,这确实要求C ++是强类型的,这会留下更小的错误余量。有些人更喜欢严格编码,而其他人喜欢Python的内在宽容。

如果您想要对Python编码样式与C ++编码样式进行全面讨论,那么这不是最佳选择,请尝试查找文章。

编辑:因为Python是一种解释型语言,而C ++被编译成机器代码,一般来说,使用C ++可以获得性能优势。但是,关于使用OpenCV,核心OpenCV库已经编译成机器代码,因此围绕OpenCV库的Python包装器正在执行编译代码。换句话说,当谈到从Python执行计算上昂贵的OpenCV算法时,您不会看到很多性能损失,因为它们已经针对您正在使用的特定体系结构进行了编译。


3
投票

answer from sdfgeoff错过了你可以在Python中重用数组的事实。预先分配它们并传递它们,它们将被使用。所以:

    image = numpy.zeros(shape=(height, width, 3), dtype=numpy.uint8)
    #....
    retval, _ = cv.VideoCapture.read(image)
© www.soinside.com 2019 - 2024. All rights reserved.