【问题标题】:OpenCV based programs optimization on minimal linux embedded systems在最小的 linux 嵌入式系统上基于 OpenCV 的程序优化
【发布时间】:2017-11-30 16:32:21
【问题描述】:

我正在使用 Buildroot 为 Raspberry PI3 构建自己的嵌入式 Linux 操作系统。该操作系统将用于处理多个应用程序,其中之一基于 OpenCV (v3.3.0) 执行对象检测。

我从 Raspbian Jessy + Python 开始,但结果证明执行一个简单的示例需要很多时间,所以我决定设计自己的 RTOS,具有优化的特性 + C++ 开发而不是 Python。

我认为通过这些优化,RPI 的 4 个内核 + 1GB RAM 将处理此类应用程序。问题是,即使有了这些东西,最简单的计算机视觉程序也需要很多时间。

PC 与 Raspberry PI3 比较

这是我编写的一个简单程序,用于了解程序每个部分的执行时间的数量级。

#include <stdio.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

#include <time.h>       /* clock_t, clock, CLOCKS_PER_SEC */

using namespace cv;
using namespace std;

int main()
{
    setUseOptimized(true);
    clock_t t_access, t_proc, t_save, t_total;

    // Access time.
    t_access = clock();
    Mat img0 = imread("img0.jpg", IMREAD_COLOR);// takes ~90ms
    t_access = clock() - t_access;

    // Processing time
    t_proc = clock();
    cvtColor(img0, img0, CV_BGR2GRAY); 
    blur(img0, img0, Size(9,9));// takes ~18ms
    t_proc = clock() - t_proc;

    // Saving time
    t_save = clock();
    imwrite("img1.jpg", img0);
    t_save = clock() - t_save;

    t_total = t_access + t_proc + t_save;

    //printf("CLOCKS_PER_SEC = %d\n\n", CLOCKS_PER_SEC);

    printf("(TEST 0) Total execution time\t %d cycles \t= %f ms!\n", t_total,((float)t_total)*1000./CLOCKS_PER_SEC);
    printf("---->> Accessing  in\t %d cycles \t= %f ms.\n", t_access,((float)t_access)*1000./CLOCKS_PER_SEC);
    printf("---->> Processing in\t %d cycles \t= %f ms.\n", t_proc,((float)t_proc)*1000./CLOCKS_PER_SEC);
    printf("---->> Saving     in\t %d cycles \t= %f ms.\n", t_save,((float)t_save)*1000./CLOCKS_PER_SEC);

    return 0;
}

在 i7 PC 上的执行结果

在 Raspberry PI 上的执行结果(从 Buildroot 生成的操作系统)

如您所见,存在巨大差异。我需要优化每一个细节,以便此示例 处理 步骤以“近”实时的方式进行,处理时间最长为 15 毫秒,而不是 44 毫秒。所以这些是我的问题:

  • 如何优化我的操作系统以使其能够处理密集计算应用程序以及如何控制每个部分的优先级?
  • 如何充分利用 RPI3 的 4 核来满足要求?
  • 除了 OpenCV,还有其他可能吗?
  • 我应该使用 C 而不是 C++?
  • 您有什么推荐的硬件改进吗?

【问题讨论】:

  • 我认为你有不切实际的期望。只要考虑一下 i7(如果它是低端的)成本大约比整个 Raspberry 高出一个数量级——这一定是有原因的。 (与电源使用类似)。你还没有具体说明你有哪个 i7,但我敢打赌时钟速度更高,它有更多的缓存,更宽更快的内存接口,更宽的 SIMD 寄存器......做研究,运行一些标准基准......跨度>
  • Looking at blur 代码中的现有优化可以利用 OpenCL(不确定 RPi 上的状态)、OpenVX(不熟悉)或 IPP(可能不在 ARM 上) .如果您可以用它构建 OpenCV,也许 OCL 可能是可行的。使用FilterEngine 的回退实现看起来并不并行。因此,也许您可​​以将 4 个较小的重叠 ROI 与线程并行模糊。但是需要支付一些开销。
  • 顺便说一句,当您对这样的功能进行计时时,请在一个循环中进行多次测量。第一次调用某些函数可能会导致一些开销(例如,按需加载库)。
  • 您的代码是单线程的,因此不会利用 4 个内核。尝试在一个线程中获取,并立即将图像传递给第二个线程,将下一个图像传递给第三个线程,然后以循环方式传递给第四个线程,那么你的 44ms 可能会变成那个的 1/3 ,即你寻求的 15 毫秒。
  • 你可以考虑看看针对 ARM 架构优化的东西:FastCV(至少在高通设备上),或者ComputeLibrary

标签: c++ opencv raspberry-pi embedded-linux buildroot


【解决方案1】:

据我了解,您希望获得大约 30-40fps。如果是您的 I7:它速度很快,并且 itel 默认启用了加速技术的音调。对于树莓派:嗯,我们喜欢它,但它很慢,尤其是对于图像处理程序。

如何优化我的操作系统以使其能够处理密集计算应用程序以及如何控制每个部分的优先级?

You should include some acceleration library for arm and re-compiled opencv again with those features enabled. 

如何充分利用 RPI3 的 4 个核心来满足要求?

Paralleling your code so it could run on 4 cores 

除了OpenCV还有其他可能吗?

Ask your self first, what features do you need from OpenCV.

我应该使用 C 而不是 C++?

Changing language will not help you at all, stay and love C++. It is a beautiful language and very fast

您有什么推荐的硬件改进吗?

How about other board with mali GPU supported. So you could run opencv code directly on GPU, that will boost up your speed a lot.

【讨论】:

  • 谢谢@gachiemchiep 我发现那些 OpenVX 和 ComputeLibrary 非常有趣。但是,我仍在记录如何使用它们。关于GPU,这些非常昂贵,这就是为什么我试图将我手中的东西推到极限^^
  • 嗯,我明白了。所以在这种情况下,你应该先尝试启用一些硬件优化。例如,如果您使用 opencv 2.4,请参阅此链接 docs.opencv.org/2.4/doc/tutorials/introduction/crosscompilation/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 2012-09-12
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 2015-01-23
相关资源
最近更新 更多