YOLOv5目标检测+KCF单目标跟踪c++ 实现(QT creator +tensort GPU加速)
单目标的识别跟踪kcf算法结合yolov5的目标检测模块
·
1.YOLov5的检测相关dill 导出 和模型文件.engine生成
这里参考我的另外一篇文章有详细说明
yolov5 windows 下训练+ c++ TensorRT 部署在qt (vs+qtcreator) 只要一篇文章即可_知新_ROL的博客-CSDN博客
2.qt creator +opencv 相关配置说明
1.版本说明
qt 的版本:5.12.10
opencv:4.5.3 --这里要用到其contrib的模块 tracking
OpenCV4.5.3+OpenCV_contrib4.5.3配置笔记_opencv4和opencvcontrib配置_lucky_yu_er的博客-CSDN博客
2.qt creator 的.pro 中的修改
这里根据大家自己的路径进行修改,如果改为之后还有问题,可能是环境变量没有配置,系统找不到dill 。
win32:CONFIG(release, debug|release): LIBS += -LD:/my_software/opencv/opencv/newbuil_with_contrib/x64/vc15/lib/ -lopencv_world453
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_software/opencv/opencv/newbuil_with_contrib/x64/vc15/lib/ -lopencv_world453d
INCLUDEPATH +=D:/my_software/opencv/opencv/newbuil_with_contrib/include
DEPENDPATH += D:/my_software/opencv/opencv/newbuil_with_contrib/include/opencv2
# 自己导出的dll 设置
INCLUDEPATH += "D:/my_code/my_yolov5_tensorrt"
DEPENDPATH += "D:/my_code/my_yolov5_tensorrt"
win32:CONFIG(release, debug|release): LIBS += -LD:/my_code/my_yolov5_tensorrt/build_dill/Release/ -lyolov5
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_code/my_yolov5_tensorrt/build_dill/Release/ -lyolov5d
### TensorRT-8.5.3.1设置
INCLUDEPATH +="D:/my_software/TensorRT-8.5.3.1/include"
DEPENDPATH +="D:/my_software/TensorRT-8.5.3.1/include"
win32:CONFIG(release, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvinfer
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvinferd
win32:CONFIG(release, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvinfer_plugin
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvinfer_plugind
win32:CONFIG(release, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvonnxparser
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvonnxparserd
win32:CONFIG(release, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvparsers
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/my_software/TensorRT-8.5.3.1/lib/ -lnvparsersd
## CUDA 设置
CUDA_SOURCES += yololayer.cu
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.7"
SYSTEM_NAME = Win64
SYSTEM_TYPE = 64
CUDA_ARCH = sm_86
NVCC_OPTIONS = --use_fast_math
## 头文件路径
INCLUDEPATH += "$$CUDA_DIR/include"
# 导入库文件路径
QMAKE_LIBDIR += "$$CUDA_DIR/lib/x64"
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
3.将相关dill 移入 运行生成的debug /release 文件夹中
找到releas/debug 文件夹中
将下面这些东西放进去
3.代码中的修改
1.ui 界面 -画两个label 两个按钮即可
2.mainwindow.h 下的配置
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
//c++的一些库
#include <iostream>
#include <string.h>
#include<iostream>
#include <stdio.h>
#include <windows.h>
#include <cmath>
#include <typeinfo>
//opencv的一些库
#include <opencv2/opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2\tracking\tracking.hpp>
//qt的一些库
#include <QMainWindow>
#include<QDebug>
#include<QMessageBox>
#include"QByteArray"
#include"QRect"
#include"QDateTime"
#include"QDir"
#include<QFileDialog>
#include<QTimer>
//qt 中和网络通信相关的一些库
#include<QJsonObject>
#include<QByteArray>
#include<QJsonDocument>
#include <QMetaObject>
#include <QEventLoop>
#include <QJsonDocument> //以下是json数据传送所需头文件
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include<QFileInfo>
#pragma execution_character_set("utf-8");//设置字体可中文显示
typedef unsigned char uchar;
using namespace std;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void ReadFrame();
void on_btnOpenVideo_clicked();
void on_btnCloseVideo_clicked();
private:
QTimer *timer;
cv::VideoCapture capture;
cv::Mat frame;
cv::Mat result_frame;
int frame_index=0;
bool is_checking=false;
int truck_num=0;
int car_id=0;
bool is_tracking_object;
void LabelDisplayMat(QLabel *label, cv::Mat &mat);
void recv_change_openvideo(bool isopen_video);
string QStr2Str(const QString qStr);
// 跟踪测试
cv::Ptr<cv::Tracker> tracker;
cv::TrackerKCF::Params tracker_params;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2.mainwindows.cpp
代码中融合了目标失败后可以继续跟踪, 其中只检测叉车car_forklift 这一类中的一个
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"yololayer.h"
#include "Detection.h"
Connect connect_yolo;
YOLOV5* yolo_dll = connect_yolo.Create_YOLOV5_Object();
std::vector<cv::Rect> Boxes; //检测的结果返回框框
std::vector<const char*>ClassLables; //检测的分类类型
cv::Rect bbox;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(ReadFrame()));
yolo_dll->Initialize("yolov5sexp14best.engine", 0); //读取yolo的模型
// bbox=cv::Rect(500, 500, 100, 100);
tracker_params.detect_thresh = 0.3f;
tracker = cv::TrackerKCF::create(tracker_params);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ReadFrame()
{
if(capture.isOpened())
{
capture >> frame;
if(!frame.empty())
{
result_frame=frame.clone();
cvtColor(frame, result_frame, cv::COLOR_BGR2RGB); // OpenCV中Mat读入的图像是BGR格式,要转换为RGB格式
if(car_id==1)
{
qDebug()<<"bbox不是空的";
is_checking=tracker->update(result_frame, bbox);
cv::rectangle(result_frame,bbox,cv::Scalar(0, 0, 255), 2, 8, 0) ;// result_frame
if(is_checking==false)
{
car_id=0;
tracker.release();
}
}else
{
qDebug()<<"is_checking "<<is_checking;
yolo_dll->Detecting(frame, Boxes, ClassLables);
for(unsigned i=0;i<Boxes.size();i++)
{
string str_ship="car_forklift";
qDebug()<<ClassLables.at(i);
qDebug()<<str_ship.c_str();
string str_class(ClassLables.at(i));
if(str_class==str_ship.c_str())
{
qDebug()<<"ClassLables.at(i)"<<Boxes.at(i).x<<" "<<Boxes.at(i).y;
if(car_id==0)
{
bbox=Boxes.at(i);
qDebug()<<"bbox"<<bbox.x<<" "<<bbox.y;
car_id=1;
tracker_params.detect_thresh = 0.3f;
tracker = cv::TrackerKCF::create(tracker_params);
tracker->init(result_frame,bbox);
}
}
}
}
cv::resize(frame, frame, cv::Size(640, 480));
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不同的摄像头用不同的格式。
QImage image((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
ui->label->resize( ui->label->pixmap()->size()); // 将label控件resize到fame的尺寸
cv::resize(result_frame, result_frame, cv::Size(640, 480));
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不同的摄像头用不同的格式。
QImage image2((const uchar*)result_frame.data, result_frame.cols, result_frame.rows, QImage::Format_RGB888);
ui->label_3->setPixmap(QPixmap::fromImage(image2)); // 将图片显示到label上
ui->label_3->resize( ui->label_3->pixmap()->size()); // 将label控件resize到fame的尺寸
Boxes.clear();
ClassLables.clear();
}
}
}
void MainWindow::on_btnOpenVideo_clicked()
{
QString file_name = QFileDialog::getOpenFileName(this, tr("Open Video"), ".", tr("Video File(*.avi *.mp4 *.h264)"));
capture.open(file_name.toStdString());
timer->start(25); // 开始计时,每隔25毫秒更新一次,超时则发出timeout()信号
}
void MainWindow::on_btnCloseVideo_clicked()
{
timer->stop(); // 停止读取数据。
// 释放内存;
capture.release();
frame.release();
}
void MainWindow::on_pushButton_clicked()
{
on_btnOpenVideo_clicked();
}
void MainWindow::on_pushButton_2_clicked()
{
on_btnCloseVideo_clicked();
}
4 .效果展示
叉车跟踪的效果如下

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)