当前位置: 首页 > news >正文

海康摄像机SDK获取视频流转码显示

开发环境

vs2017+QT5.9+海康威视SDK+opencv

代码

该博主代码略加修改即可运行,存在问题:cpu占用率达50%;拖动窗口明显延迟

https://blog.csdn.net/2501_90502174/article/details/146361878?fromshare=blogdetail&sharetype=blogdetail&sharerId=146361878&sharerefer=PC&sharesource=weixin_44965579&sharefrom=from_linkhttps://blog.csdn.net/2501_90502174/article/details/146361878?fromshare=blogdetail&sharetype=blogdetail&sharerId=146361878&sharerefer=PC&sharesource=weixin_44965579&sharefrom=from_link

我的改动

SDK的导入由环境变量改为相对路径,即< >改为" "

Format_BGR888改为Format_RGB888,qt5不支持Format_BGR888

// 13. 生成 QImage(Qt5兼容写法)
// 先将BGR转为RGB,再用Format_RGB888构造cv::Mat rgbMat;cv::cvtColor(bgrMat, rgbMat, cv::COLOR_BGR2RGB);QImage img(rgbMat.data, rgbMat.cols, rgbMat.rows, rgbMat.step, QImage::Format_RGB888);

gpt给的改进方案

一、项目数据流与线程分析

目前视频流处理流程是:

HK SDK → RealDataCallback (SDK 内线程)↓
PlayM4 解码 → DecodeCallback↓
YUV → BGR → RGB → QImage↓
emit frameUpdated (HikCamera 对象)↓
CameraThread 捕获 newFrame↓
emit newFrame → VideoWidget.updateFrame()↓
paintEvent 绘制

特点:

  1. 多线程

    • SDK 内部线程(RealDataCallback) → PlayM4 解码 → DecodeCallback

    • CameraThread 继承 QThread,接收 frameUpdated 并发 newFrame 信号

    • VideoWidget 在 GUI 线程绘制

  2. 瓶颈点

    • DecodeCallback 每帧都进行 YUV→BGR→RGB → QImage → copy()

    • VideoWidget::updateFrame() 对 QImage 做了 scaled() + QPixmap::fromImage()

    • paintEvent 每次 update() 都重新绘制 QPixmap

    • 线程间通过信号传递每帧,Qt 信号默认是 QueuedConnection,每帧都进入事件队列

    • 对于高帧率(25~30fps)视频,可能导致 事件队列堆积 → CPU 占用高、UI 卡顿


二、主要性能问题分析

  1. CPU 占用高(50%)原因

    • 每帧都做 两次颜色转换

      cv::cvtColor(yuvMat, bgrMat, cv::COLOR_YUV2BGR_YV12);
      cv::cvtColor(bgrMat, rgbMat, cv::COLOR_BGR2RGB);
      
    • QImage img(rgbMat.data, ...) + img.copy() → 内存拷贝

    • VideoWidget::updateFrame 调用 scaled() → CPU 缩放

    • paintEvent 每次都重绘整个控件

  2. 拖动窗口卡顿原因

    • paintEvent 重绘与 updateFrame 信号频率高

    • QWidget 使用 Qt::WA_OpaquePaintEvent,每次重绘全屏消耗 CPU

    • 图像缩放是同步的,阻塞 GUI 线程

  3. 线程安全与锁

    • 每帧使用 QMutexLocker 对 m_currentFrame 上锁 → 如果锁等待时间过长,也可能拖慢 UI


三、优化方案

1️⃣ 减少颜色转换开销

  • 如果后续 YOLO 使用 OpenCV,可以保持 BGR 格式,不必转换为 RGB 再 QImage。

  • Qt 支持使用 QImage::Format_BGR888(Qt 5.9 支持较有限)或者直接绘制 OpenCV Mat:

cv::Mat bgrMat; // 已解码的 BGR
QImage img(bgrMat.data, bgrMat.cols, bgrMat.rows, bgrMat.step, QImage::Format_RGB888); // 不做 copy
emit frameUpdated(img); // 去掉 copy()
  • 避免重复 cvtColor,如果不必显示 RGB,可直接用 BGR Mat 做后续处理(YOLO)。


2️⃣ 优化 VideoWidget 渲染

  • 避免每帧做 scaled(),只在 resizeEvent 时做一次缩放:

void VideoWidget::updateFrame(const QImage& frame)
{if (frame.isNull()) return;QMutexLocker locker(&m_mutex);m_currentFrame = QPixmap::fromImage(frame); // 不缩放update();
}void VideoWidget::resizeEvent(QResizeEvent* event)
{QMutexLocker locker(&m_mutex);if (!m_currentFrame.isNull())m_currentFrame = m_currentFrame.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);QWidget::resizeEvent(event);
}
  • paintEvent 中直接绘制 m_currentFrame,无需每帧缩放。

  • 或者使用 QLabel + setPixmap,Qt 内部优化比手动 scaled 快。


3️⃣ 降低信号队列压力

  • 使用 Qt::DirectConnection 或在 DecodeCallback 内部 限制帧率

static QElapsedTimer timer;
static int fps = 30;
if (timer.elapsed() < 1000 / fps) return;
timer.restart();
emit camera->frameUpdated(img);
  • 或者在 CameraThread 内做 帧丢弃策略,保证 GUI 线程只处理 20~30 fps 即可。


4️⃣ 异步 YOLO 推理

  • 不要在 GUI 线程做 YOLO 推理

  • 可以在 CameraThread 或单独的推理线程做:

// CameraThread 收到 frameUpdated
if (!m_inferThread->isRunning())m_inferThread->enqueueFrame(frame); // 推理线程队列
  • 推理线程输出结果 → GUI 线程绘制标注 → 显示


5️⃣ 锁优化

  • DecodeCallbackVideoWidget::updateFrame 使用的锁可以考虑:

    • 使用 QAtomicPointer / std::atomic 替代 QMutex,避免每帧锁等待

    • 或者使用 双缓冲,一帧在后台解码,一帧在前台绘制


6️⃣ 其他小优化

  1. QImage::copy() → 只在必须时做

  2. paintEvent 填充背景可以省略 fillRect,如果 WA_OpaquePaintEvent 与 QPixmap 覆盖

  3. HikCamera 初始化阶段尽量复用 PlayM4 端口,不必频繁获取释放


四、总体优化建议

优化点方法预期效果
YUV → RGB → QImage避免多余转换,保持 BGRCPU 占用降低 10~20%
QImage → QPixmap 缩放只在 resize 时缩放UI 拖动卡顿明显改善
信号队列限制帧率 20~30 fpsCPU 占用下降,避免 GUI 阻塞
Mutex双缓冲或原子指针降低锁开销
YOLO 推理单独线程异步处理不阻塞 UI,保持视频流顺滑
paintEvent避免每帧 full repaintUI 响应更流畅
http://www.dtcms.com/a/610348.html

相关文章:

  • 事业单位网站登录模板景德镇陶瓷学院校友做网站的
  • 当消防安全遇见数字孪生:一场防患于未“燃”的科技革命
  • Day 43 复习日--Fashion Mnist数据集
  • Android线程池参数配置指南:理论与实战
  • 外贸网站建设科技公司logo是什么意思
  • 手机网站如何排版高端网站建设 恩愉科技
  • 广州手机建设网站小说网站80电子书怎么做
  • S型单级双吸水平中开式离心泵泵轴断裂原因
  • 网站制作怎么学用闲置的安卓手机做网站服务器
  • UE5中,导入的CAD的Actor为什么Simulate Physics无法被勾选?
  • 佛山网站seo合肥优化网站
  • 珠海专业网站制作网站建设举措
  • vue3使用‘js-audio-recorder‘插件实现录音功能,回传pcm文件
  • 关键词搜索引擎工具爱站什么叫网站空间
  • 成都好网站购物系统流程图
  • 基于crontab、sftp和SpringBoot命令行应用的数据定时上报方案
  • C/C++混合项目中的头文件管理:.h与.hpp的分工与协作
  • C语言最好的编译器 | 选择合适的编译器,提高开发效率
  • 【虚拟现实技术】在Unity里创建一个简单的AR项目
  • 第一章 家世
  • 评价指标MAE 、MSE 、R2
  • 珠海市律师网站建设怎么样wordpress教程 页面
  • 便利的合肥网站建设专业的医疗行业网站模板
  • PostgreSQL (零-1) Windows安装PostgreSQL
  • 宁波网站建设公司名单推荐景安备案域名购买
  • FPGA语法基础(三):Verilog 位选择语法详解
  • 【Linux笔记】网络部分——NAT-代理-网络穿透
  • 第二章:物理层
  • asp网站程序网页设计视频网站建设
  • 网站小图标怎么做网页制作设计思路