opencv VideoCapture抓取RTSP高延迟,崩溃解决方法

目前项目需要对网络摄像头进行实时视觉算法检测。
遇到问题:
在使用抓取VideoCaptureRTSP流的过程中,若需要对图像进行处理,则最后的显示结果画面就会表现出高延迟,然后卡住,很快崩溃;
直观感受:
图像处理速度远不如VideoCapture抓取速度,然后感觉是有内置缓存的,导致卡顿,延迟;对VideoCapture进行等待处理,效果不佳;
解决思路:
采用多线程的方式,为VideoCapture单独开一个线程,自动抓取图像,并且存储到一个容器中,容器若满了自动更新容器,清理掉前面的图像,存储最新的图像;
然后主线程直接生成对象,调用get函数获取到容器中的数据;

实现代码: QT c++版
VideoCapture的线程类
opencvcap.h

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <QThread>
#include <QMutex>


using namespace cv;
using namespace std;

class OpencvCap :public QThread
{
    Q_OBJECT

public:
    OpencvCap(const char* url);
    ~OpencvCap();

    void put_frame(Mat frame);
    bool get_frame(Mat &frame);

private:
    void run() override;
    //缓存容器
    vector<Mat> m_vec_frame;
    //互斥锁
    QMutex m_mutex;
    //videocapture
    VideoCapture m_cap;
};

opencvcap.cpp

#include "opencvcap.h"

OpencvCap::OpencvCap(const char* url)
{
    m_cap.open(url);
}

OpencvCap::~OpencvCap()
{
    m_cap.release();
}

void OpencvCap::run()
{
    if(!m_cap.isOpened())
    {
        qDebug("cannot open the videocapture\n");
        return ;
    }
    Mat current_frame;
    while(true)
    {
        m_cap >> current_frame;
        if(current_frame.empty())
        {
            qDebug("frame empty\n");
            return ;
        }
        put_frame(current_frame);
        waitKey(20);

    }
}


void OpencvCap::put_frame(Mat frame)
{
    m_mutex.lock();
    // 这边采用的更简单粗暴的清理方式,可以根据实际情况自定义清理方式
    if(m_vec_frame.size() >5)
       m_vec_frame.clear();
    //存入容器
    m_vec_frame.push_back(frame);
    m_mutex.unlock();
    return;
}

bool OpencvCap::get_frame(Mat &frame)
{
    m_mutex.lock();
    if(m_vec_frame.size() < 1)
        return false;
    else
    {
   		 //从容器中取图像
        frame = m_vec_frame.back();
    }
    m_mutex.unlock();
    return true;
}

main
实际上,这部分是分散开来的,集中起来只是方便理解

int main()
{
		//创建对象,初始化
	 OpencvCap *m_opencvcap;
	 m_opencvcap = new OpencvCap("rtsp://admin:abc123456@192.168.1.64/h264/ch1/main/av_stream");
	
	//开始线程
	  m_opencvcap->start();
	
    Mat frame;
    while(true)
    {
         bool ret = m_opencvcap->get_frame(frame);
         if(ret == false || frame.empty())
            return 0;
        //处理图像······
        imshow("windows",frame);

    }
}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值