OpenCV文字叠加在FHD视频流上的CPU占用率过高

问题描述 投票:1回答:2

我想显示一个FHD直播(25 fps),并叠加一些(变化的)文本。为此,我基本上使用下面的代码。

基本上是这样的

  1. 加载框架
  2. (cv::putText 此处略过)
  3. 显示框,如果它是一个倍数 delay

但与e.g.相比,这段代码超级超级慢。mpv 消耗了大量的cpu时间(cv::useOptimized() == true).

到目前为止 delay 是我不方便的摆弄参数,以某种方式使其可行。

  • delay == 1 结果是 180%的CPU使用率 (全帧率)
  • delay == 5 导致80%的CPU使用率

但是 delay == 5 或5 fps真的很迟钝,实际上还是cpu负载太大。

我怎样才能让这段代码更快或者更好或者以其他方式解决这个任务(我不绑定opencv)?

P.s. 没有 cv::imshow 的CPU使用率低于30%,不管是 delay.

#include <opencv2/opencv.hpp>
#include <X11/Xlib.h>

// process ever delayth frame
#define delay 5

Display* disp = XOpenDisplay(NULL);
Screen*  scrn = DefaultScreenOfDisplay(disp);
int screen_height = scrn->height;
int screen_width  = scrn->width;

int main(int argc, char** argv){

  cv::VideoCapture cap("rtsp://url");
  cv::Mat frame;

  if (cap.isOpened())
    cap.read(frame);

  cv::namedWindow(  "PREVIEW", cv::WINDOW_NORMAL );
  cv::resizeWindow( "PREVIEW", screen_width, screen_height );

  int framecounter = 0;
  while (true){

    if (cap.isOpened()){

      cap.read(frame);
      framecounter += 1;

      // Display only delay'th frame
      if (framecounter % delay == 0){
        /*
         * cv::putText
         */
        framecounter = 0;
        cv::imshow("PREVIEW", frame);
      }

    }
    cv::waitKey(1);
  }
}
c++ opencv video-processing video-capture preview
2个回答
2
投票

我现在发现 valgrind (储存库)和 gprof2dot (pip3 install --user gprof2dot):

valgrind --tool=callgrind /path/to/my/binary    # Produced file callgrind.out.157532
gprof2dot --format=callgrind --output=out.dot callgrind.out.157532
dot -Tpdf out.dot -o graph.pdf

这产生了一个奇妙的图说 蒸发60%以上 关于 cvResize.而事实上,当我评论出 cv::resizeWindow,cpu使用率从180%降低到~60%。

由于屏幕的分辨率为1920×1200,而流媒体为1920×1080,所以除了烧CPU周期外,基本上什么都没做。

到目前为止,这还是很脆弱的。只要我把它切换到全屏模式,再切换回来,cpu负载就会回到180 %。

为了解决这个问题,原来我可以通过完全禁止调整大小,用 cv::WINDOW_AUTOSIZE ...

cv::namedWindow( "PREVIEW", cv::WINDOW_AUTOSIZE );

.或 -- -- 如 Micka 建议--在编译时支持OpenGL的OpenCV版本上(-DWITH_OPENGL=ON我的Debian仓库版本不是),使用......

    cv::namedWindow( "PREVIEW", cv::WINDOW_OPENGL );

...将渲染卸载到GPU上,结果发现调整大小的速度更快(55%的CPU比我的65%)。不似 协同工作 cv::WINDOW_KEEPRATIO.*

此外,事实证明 cv:UMat 可以用来替代 cv:Mat 额外提升了性能(由 ps -e -o pcpu,args):

Mat-UMat performance profile]


附录

[*]所以我们必须手动调整它的比例,并照顾到长宽比。

float screen_aspratio = (float) screen_width / screen_height;
float image_aspratio  = (float) image_width  / image_height;

if ( image_aspratio >= screen_aspratio ) { // width limited, center window vertically
  cv::resizeWindow("PREVIEW", screen_width, screen_width / image_aspratio );
  cv::moveWindow(  "PREVIEW", 0, (screen_height - image_height) / 2 );
}
else { // height limited, center window horizontally
  cv::resizeWindow("PREVIEW", screen_height * image_aspratio, screen_height );
  cv::moveWindow(  "PREVIEW", (screen_width - image_width) / 2, 0 );
}

1
投票

有一件事是你要创建一个新的窗口,每次你想显示什么东西时都要调整它的大小。

移动这些线条

cv::namedWindow( "PREVIEW", cv::WINDOW_NORMAL );
cv::resizeWindow( "PREVIEW", screen_width, screen_height );

到你之前 while(true) 并看到它,解决了这个

© www.soinside.com 2019 - 2024. All rights reserved.