围院 2023-01-06 10:37 采纳率: 0%
浏览 227
已结题

QT使用Opencv进行KCF目标跟踪时无法关闭上次跟踪开始第二次跟踪(init)

在这种特定条件下有没有其他的方法能在MainWindow主体下重启在其他Class线程下的KCF跟踪器的init()函数与update()函数呢?

前提

项目采用QT使用FFmpeg线程拉取网络摄像头的RTSP流转入Opencv线程进行实时(100ms延迟内)的KCF算法跟踪,对于目标跟踪后的图像显示到主线程的ui界面上来。

部分代码
void MyThread::GotMatimg(cv::Mat img)  //目标跟踪显示画面
{
    targetstatus = "3";
    if(successTrack && !Tack) //鼠标框选判别
    {
        targetstatus = "2";
        tracker->init(img,SignPoint);
        Tack = true;
    }
    else if(Tack)
    {
        tracker->update(img,SignPoint);
        rectangle(img,SignPoint, Scalar(255, 0, 0), 2, 3);
        trackx = SignPoint.x + (SignPoint.width /2);
        tracky = SignPoint.y + (SignPoint.height /2);
        if(!tracker->update(img,SignPoint))
        {
            targetstatus = "丢失";
        }
        else
        {
            targetstatus = "跟踪";
        }
    }
    emit SendMatimg(img); //发送图片数据
}

void MainWindow::GainMatimg(cv::Mat img)
{
    showImage(img,QImage::Format_RGB888,ui->label); //显示视频
}

void MainWindow::on_btnsign_clicked()
{
    if(ui->btnsign->text() == "识别")
    {
        threeD->Track_Sign = true;//切换为opencv鼠标框选功能
        Tack = false;        
        targetstatus = "4";
        
        NET_DVR_StopRealPlay(IRealPlayHandle);
        struPlayInfo.hPlayWnd = NULL;//需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
        IRealPlayHandle = NET_DVR_RealPlay_V40(userID,&struPlayInfo,NULL,NULL);
        
        connect(m_trad, SIGNAL(SendMatimg(cv::Mat)), this, SLOT(GainMatimg(cv::Mat)),Qt::AutoConnection); //连接发送跟踪处理后的图片信号与接收图片显示槽
        connect(m_ffmpeg, SIGNAL(SigGetOneFrame(cv::Mat)), m_trad, SLOT(GotMatimg(cv::Mat)),Qt::AutoConnection);//连接发送原始图片信号与获取图片进行跟踪处理槽
        
        ui->btnsign->setText("定位");
    }
    else if(ui->btnsign->text() == "定位")
    {
        threeD->Track_Sign = false;//关闭opencv鼠标框选功能
        successTrack = false; //关闭跟踪处理
        
        struPlayInfo.hPlayWnd = hWnd;//需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
        IRealPlayHandle = NET_DVR_RealPlay_V40(userID,&struPlayInfo,NULL,NULL);
        
        disconnect(m_trad, SIGNAL(SendMatimg(cv::Mat)), this, SLOT(GainMatimg(cv::Mat)));//断开连接
        disconnect(m_ffmpeg, SIGNAL(SigGetOneFrame(cv::Mat)), m_trad, SLOT(GotMatimg(cv::Mat)));
        ui->btnsign->setText("识别");
    }
}
项目必备(无法改变与替换)
  1. 必须单独使用FFmpeg作为子线程拉取流来进行处理才能达到实时的要求,使用Opencv自带拉流(VideoCapture)无法做到实时要求

  2. 鼠标框选子线程来实现要求的目标框选功能,并该子线程需要具备多功能,所以该功能无法改变

  3. 在OpenCV子线程将获得到的FFmpeg框选的图像进行KCF初始化(init())后实时更新跟踪图像(update()),KCF跟踪算法对于项目的契合度更高

疑问难题

尝试过在父线程使用KCF算法中的release()、reset()函数进行关闭跟踪,但这两种函数都无法关闭跟踪;无法关闭跟踪就无法进行下一步的操作,请帮我解答一下如何C++下在父线程重新开启在子线程的KCF算法。

  • 写回答

7条回答 默认 最新

  • _leoatliang 2023-01-06 10:45
    关注
    获得5.40元问题酬金

    使用 OpenCV 进行 KCF 目标跟踪时如果想要在主线程中重新开始跟踪,可以在主线程中重新调用 KCF 跟踪器的 init() 函数。要确保跟踪器在主线程之外的线程中的 update() 函数是在安全的方式下被调用的。

    如果你使用的是 QThread 来运行 OpenCV 线程,可以使用 QMetaObject::invokeMethod() 函数来从主线程安全地调用 update() 函数。例如:

    QMetaObject::invokeMethod(opencvThread, "update", Qt::QueuedConnection);
    

    这样就可以在主线程中安全地调用 update() 函数了。

    如果你使用的是其他线程库,可以使用相应的同步机制来保证 update() 函数在安全的方式下被调用。

    评论

报告相同问题?

问题事件

  • 系统已结题 1月14日
  • 创建了问题 1月6日

悬赏问题

  • ¥100 请问我基于逐飞库写的这个有关于mp u6050传感器的函数,为什么输出的值是固定的?
  • ¥15 hadoop中启动hive报错如下怎么解决
  • ¥15 如何优化QWebEngineView 加载url的速度
  • ¥15 关于#hadoop#的问题,请各位专家解答!
  • ¥15 如何批量抓取网站信息
  • ¥15 Spring Boot离线人脸识别
  • ¥15 NRF24L01能发送但是不能接收
  • ¥15 想问一下这种情况怎么解决呢(关键词-file)
  • ¥15 python Flassk 模块部署 服务器时报错
  • ¥15 Opencv(C++)异常