diff --git a/README.md b/README.md index 0982a6c..6698317 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,18 @@ -## Yolov5s+SORT(卡尔曼+匈牙利) +## 机器人检测算法开发 -利用目标跟踪对检测框进行预测的技术,对目标检测任务进行加速,在yolov5检测的帧之间穿插使用卡尔曼滤波进行目标检测框的预测,减少对模型的调用,实现目标检测帧率提升的目的。 +目标检测是机器人的主要功能之一,目前机器人的目标检测主要存在以下问题: -#### 代码运行环境: +1.检测**速度慢**,无法做到实时检测; -| 开发环境 | Visual Studio 2022 | -| -------- | -------------------- | -| OpenCV | opencv-4.8.0-windows | -| 调用模型 | YOLOv5s 6.0 | +2.模型**性能差**,检测不稳定。 +针对检测速度慢,可以适当减少检测模型的使用,使用跟踪技术来预测目标框的位置,实现间隔几帧进行检测,中间使用跟踪算法进行预测检测框的技术,以解决检测速度慢的问题。 +针对模型性能差,检测不稳定的问题,目前嵌入式使用的主流模型是yolov5s,已经满足绝大多数场景的检测问题,同样适用跟踪算法来预测目标框的位置,可以做到防止目标框丢失情况的发生。 -#### 主要代码设置: +综上,本项目使用一些跟踪算法实现对检测的加速和稳定,代码的配置见具体文件中。 -main.py中 - -![img1](./images/img1.png) - -使用到的模型以及检测视频的路径。 - -![img2](./images/img2.png) - -模型的调用频率设置,设置为3表示帧率为3的倍数时进行模型的目标检测,其他时候使用预测的目标框。 +###### 使用到的模型及测试视频: +链接: https://pan.baidu.com/s/1XFdLT_7WT2SwQmmmzlakFA 提取码: z9qu +###### 附:此路径下每个文件夹均为一个单独的项目 diff --git a/yolo+ByteTrack/README.md b/yolo+ByteTrack/README.md new file mode 100644 index 0000000..5151b3b --- /dev/null +++ b/yolo+ByteTrack/README.md @@ -0,0 +1,39 @@ +## Yolov5s+ByteTrack + +ByteTrack提出于2022ECCV,是目前最主流的跟踪器之一,主要特点包括: + +1. 当目标逐渐被遮挡时,跟踪目标与低置信度检测目标匹配。 +2. 当目标遮挡逐渐重现时,跟踪目标与高置信度检测目标匹配。 + +同时ByteTrack消耗的计算资源较少,很适合用于嵌入式设备中,经过调研是机器人进行检测加速的最适合的跟踪算法。 + +#### 代码运行环境: + +| 开发环境 | Visual Studio 2022 | +| -------- | -------------------- | +| OpenCV | opencv-4.8.0-windows | +| 调用模型 | YOLOv5s 6.0 | +| TensorRT | TensorRT-8.5.1.7 | +| Eigen | eigen-3.4.0 | + +ByteTrack的代码配置更加复杂,尤其注意TensorRT的配置和cuda的配置,详细配置过程可以参考这个博客:[Win10+TensorRT 8.5安装+VS2022配置_tensorrt-8.5.2.2-CSDN博客](https://blog.csdn.net/gulingfengze/article/details/108425949) + +除了上述环境之外,代码配置过程中会出现dirent.h文件不存在的错误,这是因为windows库中没有这个文件,linux中存在,只需将项目中这个文件添加到项目中即可,同理,linux环境下可以将这个文件删除。 + +![img1](./images/img1.png) + +#### 主要代码设置: + +main.py中 + + string img_path = "D:/VS/yoloTest/images/detect.mp4"; + string model_path = "D:/VS/yoloTest/models/yolov5s.onnx"; + +使用到的模型以及检测视频的路径。 + +``` +int detect_interval = 3; +``` + +模型的调用频率设置,设置为3表示帧率为3的倍数时进行模型的目标检测,其他时候使用预测的目标框。 + diff --git a/yolo+ByteTrack/images/img1.png b/yolo+ByteTrack/images/img1.png new file mode 100644 index 0000000..afa3c1f Binary files /dev/null and b/yolo+ByteTrack/images/img1.png differ diff --git a/yolo+ByteTrack/x64/Debug/yoloTest.exe b/yolo+ByteTrack/x64/Debug/yoloTest.exe new file mode 100644 index 0000000..b8950e3 Binary files /dev/null and b/yolo+ByteTrack/x64/Debug/yoloTest.exe differ diff --git a/yolo+ByteTrack/x64/Debug/yoloTest.pdb b/yolo+ByteTrack/x64/Debug/yoloTest.pdb new file mode 100644 index 0000000..ea52078 Binary files /dev/null and b/yolo+ByteTrack/x64/Debug/yoloTest.pdb differ diff --git a/x64/Release/yoloSORT.exe b/yolo+ByteTrack/x64/Release/yoloSORT.exe similarity index 100% rename from x64/Release/yoloSORT.exe rename to yolo+ByteTrack/x64/Release/yoloSORT.exe diff --git a/x64/Release/yoloSORT.pdb b/yolo+ByteTrack/x64/Release/yoloSORT.pdb similarity index 100% rename from x64/Release/yoloSORT.pdb rename to yolo+ByteTrack/x64/Release/yoloSORT.pdb diff --git a/yolo+ByteTrack/x64/Release/yoloTest.exe b/yolo+ByteTrack/x64/Release/yoloTest.exe new file mode 100644 index 0000000..032df71 Binary files /dev/null and b/yolo+ByteTrack/x64/Release/yoloTest.exe differ diff --git a/yolo+ByteTrack/x64/Release/yoloTest.pdb b/yolo+ByteTrack/x64/Release/yoloTest.pdb new file mode 100644 index 0000000..2823711 Binary files /dev/null and b/yolo+ByteTrack/x64/Release/yoloTest.pdb differ diff --git a/yolo+ByteTrack/yoloTest.sln b/yolo+ByteTrack/yoloTest.sln new file mode 100644 index 0000000..f17bf59 --- /dev/null +++ b/yolo+ByteTrack/yoloTest.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34322.80 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yoloTest", "yoloTest\yoloTest.vcxproj", "{BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Debug|x64.ActiveCfg = Debug|x64 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Debug|x64.Build.0 = Debug|x64 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Debug|x86.ActiveCfg = Debug|Win32 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Debug|x86.Build.0 = Debug|Win32 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Release|x64.ActiveCfg = Release|x64 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Release|x64.Build.0 = Release|x64 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Release|x86.ActiveCfg = Release|Win32 + {BBD2F21A-3013-475E-BD5A-66EB7F9D8EC9}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1A45E097-301B-484F-BE89-BFEB6ED43DFC} + EndGlobalSection +EndGlobal diff --git a/yolo+ByteTrack/yoloTest/BYTETracker.cpp b/yolo+ByteTrack/yoloTest/BYTETracker.cpp new file mode 100644 index 0000000..7c936b8 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/BYTETracker.cpp @@ -0,0 +1,241 @@ +#include "BYTETracker.h" +#include + +BYTETracker::BYTETracker(int frame_rate, int track_buffer) +{ + track_thresh = 0.5; + high_thresh = 0.6; + match_thresh = 0.8; + + frame_id = 0; + max_time_lost = int(frame_rate / 30.0 * track_buffer); + cout << "Init ByteTrack!" << endl; +} + +BYTETracker::~BYTETracker() +{ +} + +vector BYTETracker::update(const vector& objects) +{ + + ////////////////// Step 1: Get detections ////////////////// + this->frame_id++; + vector activated_stracks; + vector refind_stracks; + vector removed_stracks; + vector lost_stracks; + vector detections; + vector detections_low; + + vector detections_cp; + vector tracked_stracks_swap; + vector resa, resb; + vector output_stracks; + + vector unconfirmed; + vector tracked_stracks; + vector strack_pool; + vector r_tracked_stracks; + + if (objects.size() > 0) + { + for (int i = 0; i < objects.size(); i++) + { + vector tlbr_; + tlbr_.resize(4); + tlbr_[0] = objects[i].rect.x; + tlbr_[1] = objects[i].rect.y; + tlbr_[2] = objects[i].rect.x + objects[i].rect.width; + tlbr_[3] = objects[i].rect.y + objects[i].rect.height; + + float score = objects[i].prob; + + STrack strack(STrack::tlbr_to_tlwh(tlbr_), score); + if (score >= track_thresh) + { + detections.push_back(strack); + } + else + { + detections_low.push_back(strack); + } + + } + } + + // Add newly detected tracklets to tracked_stracks + for (int i = 0; i < this->tracked_stracks.size(); i++) + { + if (!this->tracked_stracks[i].is_activated) + unconfirmed.push_back(&this->tracked_stracks[i]); + else + tracked_stracks.push_back(&this->tracked_stracks[i]); + } + + ////////////////// Step 2: First association, with IoU ////////////////// + strack_pool = joint_stracks(tracked_stracks, this->lost_stracks); + STrack::multi_predict(strack_pool, this->kalman_filter); + + vector > dists; + int dist_size = 0, dist_size_size = 0; + dists = iou_distance(strack_pool, detections, dist_size, dist_size_size); + + vector > matches; + vector u_track, u_detection; + linear_assignment(dists, dist_size, dist_size_size, match_thresh, matches, u_track, u_detection); + + for (int i = 0; i < matches.size(); i++) + { + STrack *track = strack_pool[matches[i][0]]; + STrack *det = &detections[matches[i][1]]; + if (track->state == TrackState::Tracked) + { + track->update(*det, this->frame_id); + activated_stracks.push_back(*track); + } + else + { + track->re_activate(*det, this->frame_id, false); + refind_stracks.push_back(*track); + } + } + + ////////////////// Step 3: Second association, using low score dets ////////////////// + for (int i = 0; i < u_detection.size(); i++) + { + detections_cp.push_back(detections[u_detection[i]]); + } + detections.clear(); + detections.assign(detections_low.begin(), detections_low.end()); + + for (int i = 0; i < u_track.size(); i++) + { + if (strack_pool[u_track[i]]->state == TrackState::Tracked) + { + r_tracked_stracks.push_back(strack_pool[u_track[i]]); + } + } + + dists.clear(); + dists = iou_distance(r_tracked_stracks, detections, dist_size, dist_size_size); + + matches.clear(); + u_track.clear(); + u_detection.clear(); + linear_assignment(dists, dist_size, dist_size_size, 0.5, matches, u_track, u_detection); + + for (int i = 0; i < matches.size(); i++) + { + STrack *track = r_tracked_stracks[matches[i][0]]; + STrack *det = &detections[matches[i][1]]; + if (track->state == TrackState::Tracked) + { + track->update(*det, this->frame_id); + activated_stracks.push_back(*track); + } + else + { + track->re_activate(*det, this->frame_id, false); + refind_stracks.push_back(*track); + } + } + + for (int i = 0; i < u_track.size(); i++) + { + STrack *track = r_tracked_stracks[u_track[i]]; + if (track->state != TrackState::Lost) + { + track->mark_lost(); + lost_stracks.push_back(*track); + } + } + + // Deal with unconfirmed tracks, usually tracks with only one beginning frame + detections.clear(); + detections.assign(detections_cp.begin(), detections_cp.end()); + + dists.clear(); + dists = iou_distance(unconfirmed, detections, dist_size, dist_size_size); + + matches.clear(); + vector u_unconfirmed; + u_detection.clear(); + linear_assignment(dists, dist_size, dist_size_size, 0.7, matches, u_unconfirmed, u_detection); + + for (int i = 0; i < matches.size(); i++) + { + unconfirmed[matches[i][0]]->update(detections[matches[i][1]], this->frame_id); + activated_stracks.push_back(*unconfirmed[matches[i][0]]); + } + + for (int i = 0; i < u_unconfirmed.size(); i++) + { + STrack *track = unconfirmed[u_unconfirmed[i]]; + track->mark_removed(); + removed_stracks.push_back(*track); + } + + ////////////////// Step 4: Init new stracks ////////////////// + for (int i = 0; i < u_detection.size(); i++) + { + STrack *track = &detections[u_detection[i]]; + if (track->score < this->high_thresh) + continue; + track->activate(this->kalman_filter, this->frame_id); + activated_stracks.push_back(*track); + } + + ////////////////// Step 5: Update state ////////////////// + for (int i = 0; i < this->lost_stracks.size(); i++) + { + if (this->frame_id - this->lost_stracks[i].end_frame() > this->max_time_lost) + { + this->lost_stracks[i].mark_removed(); + removed_stracks.push_back(this->lost_stracks[i]); + } + } + + for (int i = 0; i < this->tracked_stracks.size(); i++) + { + if (this->tracked_stracks[i].state == TrackState::Tracked) + { + tracked_stracks_swap.push_back(this->tracked_stracks[i]); + } + } + this->tracked_stracks.clear(); + this->tracked_stracks.assign(tracked_stracks_swap.begin(), tracked_stracks_swap.end()); + + this->tracked_stracks = joint_stracks(this->tracked_stracks, activated_stracks); + this->tracked_stracks = joint_stracks(this->tracked_stracks, refind_stracks); + + //std::cout << activated_stracks.size() << std::endl; + + this->lost_stracks = sub_stracks(this->lost_stracks, this->tracked_stracks); + for (int i = 0; i < lost_stracks.size(); i++) + { + this->lost_stracks.push_back(lost_stracks[i]); + } + + this->lost_stracks = sub_stracks(this->lost_stracks, this->removed_stracks); + for (int i = 0; i < removed_stracks.size(); i++) + { + this->removed_stracks.push_back(removed_stracks[i]); + } + + remove_duplicate_stracks(resa, resb, this->tracked_stracks, this->lost_stracks); + + this->tracked_stracks.clear(); + this->tracked_stracks.assign(resa.begin(), resa.end()); + this->lost_stracks.clear(); + this->lost_stracks.assign(resb.begin(), resb.end()); + + for (int i = 0; i < this->tracked_stracks.size(); i++) + { + if (this->tracked_stracks[i].is_activated) + { + output_stracks.push_back(this->tracked_stracks[i]); + } + } + return output_stracks; +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/BYTETracker.h b/yolo+ByteTrack/yoloTest/BYTETracker.h new file mode 100644 index 0000000..e3dda97 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/BYTETracker.h @@ -0,0 +1,49 @@ +#pragma once + +#include "STrack.h" + +struct Object +{ + cv::Rect_ rect; + int label; + float prob; +}; + +class BYTETracker +{ +public: + BYTETracker(int frame_rate = 30, int track_buffer = 30); + ~BYTETracker(); + + vector update(const vector& objects); + Scalar get_color(int idx); + +private: + vector joint_stracks(vector &tlista, vector &tlistb); + vector joint_stracks(vector &tlista, vector &tlistb); + + vector sub_stracks(vector &tlista, vector &tlistb); + void remove_duplicate_stracks(vector &resa, vector &resb, vector &stracksa, vector &stracksb); + + void linear_assignment(vector > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh, + vector > &matches, vector &unmatched_a, vector &unmatched_b); + vector > iou_distance(vector &atracks, vector &btracks, int &dist_size, int &dist_size_size); + vector > iou_distance(vector &atracks, vector &btracks); + vector > ious(vector > &atlbrs, vector > &btlbrs); + + double lapjv(const vector > &cost, vector &rowsol, vector &colsol, + bool extend_cost = false, float cost_limit = LONG_MAX, bool return_cost = true); + +private: + + float track_thresh; + float high_thresh; + float match_thresh; + int frame_id; + int max_time_lost; + + vector tracked_stracks; + vector lost_stracks; + vector removed_stracks; + byte_kalman::KalmanFilter kalman_filter; +}; \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/Debug/vc143.idb b/yolo+ByteTrack/yoloTest/Debug/vc143.idb new file mode 100644 index 0000000..b08a835 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/Debug/vc143.idb differ diff --git a/yolo+ByteTrack/yoloTest/Debug/vc143.pdb b/yolo+ByteTrack/yoloTest/Debug/vc143.pdb new file mode 100644 index 0000000..10430cb Binary files /dev/null and b/yolo+ByteTrack/yoloTest/Debug/vc143.pdb differ diff --git a/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/CL.command.1.tlog b/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/CL.command.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/CL.command.1.tlog @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/unsuccessfulbuild b/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/yoloTest.lastbuildstate b/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/yoloTest.lastbuildstate new file mode 100644 index 0000000..30ea54b --- /dev/null +++ b/yolo+ByteTrack/yoloTest/Debug/yoloTest.tlog/yoloTest.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.38.33130:TargetPlatformVersion=10.0.22621.0: +Debug|Win32|D:\VS\yoloTest\| diff --git a/yolo+ByteTrack/yoloTest/STrack.cpp b/yolo+ByteTrack/yoloTest/STrack.cpp new file mode 100644 index 0000000..6b02d07 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/STrack.cpp @@ -0,0 +1,194 @@ +#include "STrack.h" + +STrack::STrack(vector tlwh_, float score) +{ + _tlwh.resize(4); + _tlwh.assign(tlwh_.begin(), tlwh_.end()); + + is_activated = false; + track_id = 0; + state = TrackState::New; + + tlwh.resize(4); + tlbr.resize(4); + + static_tlwh(); + static_tlbr(); + frame_id = 0; + tracklet_len = 0; + this->score = score; + start_frame = 0; +} + +STrack::~STrack() +{ +} + +void STrack::activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id) +{ + this->kalman_filter = kalman_filter; + this->track_id = this->next_id(); + + vector _tlwh_tmp(4); + _tlwh_tmp[0] = this->_tlwh[0]; + _tlwh_tmp[1] = this->_tlwh[1]; + _tlwh_tmp[2] = this->_tlwh[2]; + _tlwh_tmp[3] = this->_tlwh[3]; + vector xyah = tlwh_to_xyah(_tlwh_tmp); + DETECTBOX xyah_box; + xyah_box[0] = xyah[0]; + xyah_box[1] = xyah[1]; + xyah_box[2] = xyah[2]; + xyah_box[3] = xyah[3]; + auto mc = this->kalman_filter.initiate(xyah_box); + this->mean = mc.first; + this->covariance = mc.second; + + static_tlwh(); + static_tlbr(); + + this->tracklet_len = 0; + this->state = TrackState::Tracked; + if (frame_id == 1) + { + this->is_activated = true; + } + //this->is_activated = true; + this->frame_id = frame_id; + this->start_frame = frame_id; +} + +void STrack::re_activate(STrack &new_track, int frame_id, bool new_id) +{ + vector xyah = tlwh_to_xyah(new_track.tlwh); + DETECTBOX xyah_box; + xyah_box[0] = xyah[0]; + xyah_box[1] = xyah[1]; + xyah_box[2] = xyah[2]; + xyah_box[3] = xyah[3]; + auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box); + this->mean = mc.first; + this->covariance = mc.second; + + static_tlwh(); + static_tlbr(); + + this->tracklet_len = 0; + this->state = TrackState::Tracked; + this->is_activated = true; + this->frame_id = frame_id; + this->score = new_track.score; + if (new_id) + this->track_id = next_id(); +} + +void STrack::update(STrack &new_track, int frame_id) +{ + this->frame_id = frame_id; + this->tracklet_len++; + + vector xyah = tlwh_to_xyah(new_track.tlwh); + DETECTBOX xyah_box; + xyah_box[0] = xyah[0]; + xyah_box[1] = xyah[1]; + xyah_box[2] = xyah[2]; + xyah_box[3] = xyah[3]; + + auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box); + this->mean = mc.first; + this->covariance = mc.second; + + static_tlwh(); + static_tlbr(); + + this->state = TrackState::Tracked; + this->is_activated = true; + + this->score = new_track.score; +} + +void STrack::static_tlwh() +{ + if (this->state == TrackState::New) + { + tlwh[0] = _tlwh[0]; + tlwh[1] = _tlwh[1]; + tlwh[2] = _tlwh[2]; + tlwh[3] = _tlwh[3]; + return; + } + + tlwh[0] = mean[0]; + tlwh[1] = mean[1]; + tlwh[2] = mean[2]; + tlwh[3] = mean[3]; + + tlwh[2] *= tlwh[3]; + tlwh[0] -= tlwh[2] / 2; + tlwh[1] -= tlwh[3] / 2; +} + +void STrack::static_tlbr() +{ + tlbr.clear(); + tlbr.assign(tlwh.begin(), tlwh.end()); + tlbr[2] += tlbr[0]; + tlbr[3] += tlbr[1]; +} + +vector STrack::tlwh_to_xyah(vector tlwh_tmp) +{ + vector tlwh_output = tlwh_tmp; + tlwh_output[0] += tlwh_output[2] / 2; + tlwh_output[1] += tlwh_output[3] / 2; + tlwh_output[2] /= tlwh_output[3]; + return tlwh_output; +} + +vector STrack::to_xyah() +{ + return tlwh_to_xyah(tlwh); +} + +vector STrack::tlbr_to_tlwh(vector &tlbr) +{ + tlbr[2] -= tlbr[0]; + tlbr[3] -= tlbr[1]; + return tlbr; +} + +void STrack::mark_lost() +{ + state = TrackState::Lost; +} + +void STrack::mark_removed() +{ + state = TrackState::Removed; +} + +int STrack::next_id() +{ + static int _count = 0; + _count++; + return _count; +} + +int STrack::end_frame() +{ + return this->frame_id; +} + +void STrack::multi_predict(vector &stracks, byte_kalman::KalmanFilter &kalman_filter) +{ + for (int i = 0; i < stracks.size(); i++) + { + if (stracks[i]->state != TrackState::Tracked) + { + stracks[i]->mean[7] = 0; + } + kalman_filter.predict(stracks[i]->mean, stracks[i]->covariance); + stracks[i]->static_tlwh(); + stracks[i]->static_tlbr(); + } +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/STrack.h b/yolo+ByteTrack/yoloTest/STrack.h new file mode 100644 index 0000000..752cbef --- /dev/null +++ b/yolo+ByteTrack/yoloTest/STrack.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "kalmanFilter.h" + +using namespace cv; +using namespace std; + +enum TrackState { New = 0, Tracked, Lost, Removed }; + +class STrack +{ +public: + STrack(vector tlwh_, float score); + ~STrack(); + + vector static tlbr_to_tlwh(vector &tlbr); + void static multi_predict(vector &stracks, byte_kalman::KalmanFilter &kalman_filter); + void static_tlwh(); + void static_tlbr(); + vector tlwh_to_xyah(vector tlwh_tmp); + vector to_xyah(); + void mark_lost(); + void mark_removed(); + int next_id(); + int end_frame(); + + void activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id); + void re_activate(STrack &new_track, int frame_id, bool new_id = false); + void update(STrack &new_track, int frame_id); + +public: + bool is_activated; + int track_id; + int state; + + vector _tlwh; + vector tlwh; + vector tlbr; + int frame_id; + int tracklet_len; + int start_frame; + + KAL_MEAN mean; + KAL_COVA covariance; + float score; + +private: + byte_kalman::KalmanFilter kalman_filter; +}; \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/bytetrack.cpp b/yolo+ByteTrack/yoloTest/bytetrack.cpp new file mode 100644 index 0000000..d6a9d1b --- /dev/null +++ b/yolo+ByteTrack/yoloTest/bytetrack.cpp @@ -0,0 +1,510 @@ + +#include +#include +#include +#include +#include +#include +#include +#include "dirent.h" +#include "NvInfer.h" +#include "cuda_runtime_api.h" +#include "logging.h" +#include "BYTETracker.h" + +#define CHECK(status) \ + do\ + {\ + auto ret = (status);\ + if (ret != 0)\ + {\ + cerr << "Cuda failure: " << ret << endl;\ + abort();\ + }\ + } while (0) + +#define DEVICE 0 // GPU id +#define NMS_THRESH 0.7 +#define BBOX_CONF_THRESH 0.1 + +using namespace nvinfer1; + +// stuff we know about the network and the input/output blobs +static const int INPUT_W = 1088; +static const int INPUT_H = 608; +const char* INPUT_BLOB_NAME = "input_0"; +const char* OUTPUT_BLOB_NAME = "output_0"; +static Logger gLogger; + +Mat static_resize(Mat& img) { + float r = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0)); + // r = std::min(r, 1.0f); + int unpad_w = r * img.cols; + int unpad_h = r * img.rows; + Mat re(unpad_h, unpad_w, CV_8UC3); + resize(img, re, re.size()); + Mat out(INPUT_H, INPUT_W, CV_8UC3, Scalar(114, 114, 114)); + re.copyTo(out(Rect(0, 0, re.cols, re.rows))); + return out; +} + +struct GridAndStride +{ + int grid0; + int grid1; + int stride; +}; + + +static void generate_grids_and_stride(const int target_w, const int target_h, vector& strides, vector& grid_strides) +{ + for (auto stride : strides) + { + int num_grid_w = target_w / stride; + int num_grid_h = target_h / stride; + for (int g1 = 0; g1 < num_grid_h; g1++) + { + for (int g0 = 0; g0 < num_grid_w; g0++) + { + GridAndStride grid = { g0, g1, stride }; + grid_strides.push_back(grid); + } + } + } +} + +static inline float intersection_area(const Object& a, const Object& b) +{ + Rect_ inter = a.rect & b.rect; + return inter.area(); +} + +static void qsort_descent_inplace(vector& faceobjects, int left, int right) +{ + int i = left; + int j = right; + float p = faceobjects[(left + right) / 2].prob; + + while (i <= j) + { + while (faceobjects[i].prob > p) + i++; + + while (faceobjects[j].prob < p) + j--; + + if (i <= j) + { + // swap + swap(faceobjects[i], faceobjects[j]); + + i++; + j--; + } + } + + #pragma omp parallel sections + { + #pragma omp section + { + if (left < j) qsort_descent_inplace(faceobjects, left, j); + } + #pragma omp section + { + if (i < right) qsort_descent_inplace(faceobjects, i, right); + } + } +} + +static void qsort_descent_inplace(vector& objects) +{ + if (objects.empty()) + return; + + qsort_descent_inplace(objects, 0, objects.size() - 1); +} + +static void nms_sorted_bboxes(const vector& faceobjects, vector& picked, float nms_threshold) +{ + picked.clear(); + + const int n = faceobjects.size(); + + vector areas(n); + for (int i = 0; i < n; i++) + { + areas[i] = faceobjects[i].rect.area(); + } + + for (int i = 0; i < n; i++) + { + const Object& a = faceobjects[i]; + + int keep = 1; + for (int j = 0; j < (int)picked.size(); j++) + { + const Object& b = faceobjects[picked[j]]; + + // intersection over union + float inter_area = intersection_area(a, b); + float union_area = areas[i] + areas[picked[j]] - inter_area; + // float IoU = inter_area / union_area + if (inter_area / union_area > nms_threshold) + keep = 0; + } + + if (keep) + picked.push_back(i); + } +} + + +static void generate_yolox_proposals(vector grid_strides, float* feat_blob, float prob_threshold, vector& objects) +{ + const int num_class = 1; + + const int num_anchors = grid_strides.size(); + + for (int anchor_idx = 0; anchor_idx < num_anchors; anchor_idx++) + { + const int grid0 = grid_strides[anchor_idx].grid0; + const int grid1 = grid_strides[anchor_idx].grid1; + const int stride = grid_strides[anchor_idx].stride; + + const int basic_pos = anchor_idx * (num_class + 5); + + // yolox/models/yolo_head.py decode logic + float x_center = (feat_blob[basic_pos+0] + grid0) * stride; + float y_center = (feat_blob[basic_pos+1] + grid1) * stride; + float w = exp(feat_blob[basic_pos+2]) * stride; + float h = exp(feat_blob[basic_pos+3]) * stride; + float x0 = x_center - w * 0.5f; + float y0 = y_center - h * 0.5f; + + float box_objectness = feat_blob[basic_pos+4]; + for (int class_idx = 0; class_idx < num_class; class_idx++) + { + float box_cls_score = feat_blob[basic_pos + 5 + class_idx]; + float box_prob = box_objectness * box_cls_score; + if (box_prob > prob_threshold) + { + Object obj; + obj.rect.x = x0; + obj.rect.y = y0; + obj.rect.width = w; + obj.rect.height = h; + obj.label = class_idx; + obj.prob = box_prob; + + objects.push_back(obj); + } + + } // class loop + + } // point anchor loop +} + +float* blobFromImage(Mat& img){ + cvtColor(img, img, COLOR_BGR2RGB); + + float* blob = new float[img.total()*3]; + int channels = 3; + int img_h = img.rows; + int img_w = img.cols; + vector mean = {0.485, 0.456, 0.406}; + vector std = {0.229, 0.224, 0.225}; + for (size_t c = 0; c < channels; c++) + { + for (size_t h = 0; h < img_h; h++) + { + for (size_t w = 0; w < img_w; w++) + { + blob[c * img_w * img_h + h * img_w + w] = + (((float)img.at(h, w)[c]) / 255.0f - mean[c]) / std[c]; + } + } + } + return blob; +} + + +static void decode_outputs(float* prob, vector& objects, float scale, const int img_w, const int img_h) { + vector proposals; + vector strides = {8, 16, 32}; + vector grid_strides; + generate_grids_and_stride(INPUT_W, INPUT_H, strides, grid_strides); + generate_yolox_proposals(grid_strides, prob, BBOX_CONF_THRESH, proposals); + //std::cout << "num of boxes before nms: " << proposals.size() << std::endl; + + qsort_descent_inplace(proposals); + + vector picked; + nms_sorted_bboxes(proposals, picked, NMS_THRESH); + + + int count = picked.size(); + + //std::cout << "num of boxes: " << count << std::endl; + + objects.resize(count); + for (int i = 0; i < count; i++) + { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x) / scale; + float y0 = (objects[i].rect.y) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height) / scale; + + // clip + // x0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f); + // y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f); + // x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f); + // y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } +} + +const float color_list[80][3] = +{ + {0.000, 0.447, 0.741}, + {0.850, 0.325, 0.098}, + {0.929, 0.694, 0.125}, + {0.494, 0.184, 0.556}, + {0.466, 0.674, 0.188}, + {0.301, 0.745, 0.933}, + {0.635, 0.078, 0.184}, + {0.300, 0.300, 0.300}, + {0.600, 0.600, 0.600}, + {1.000, 0.000, 0.000}, + {1.000, 0.500, 0.000}, + {0.749, 0.749, 0.000}, + {0.000, 1.000, 0.000}, + {0.000, 0.000, 1.000}, + {0.667, 0.000, 1.000}, + {0.333, 0.333, 0.000}, + {0.333, 0.667, 0.000}, + {0.333, 1.000, 0.000}, + {0.667, 0.333, 0.000}, + {0.667, 0.667, 0.000}, + {0.667, 1.000, 0.000}, + {1.000, 0.333, 0.000}, + {1.000, 0.667, 0.000}, + {1.000, 1.000, 0.000}, + {0.000, 0.333, 0.500}, + {0.000, 0.667, 0.500}, + {0.000, 1.000, 0.500}, + {0.333, 0.000, 0.500}, + {0.333, 0.333, 0.500}, + {0.333, 0.667, 0.500}, + {0.333, 1.000, 0.500}, + {0.667, 0.000, 0.500}, + {0.667, 0.333, 0.500}, + {0.667, 0.667, 0.500}, + {0.667, 1.000, 0.500}, + {1.000, 0.000, 0.500}, + {1.000, 0.333, 0.500}, + {1.000, 0.667, 0.500}, + {1.000, 1.000, 0.500}, + {0.000, 0.333, 1.000}, + {0.000, 0.667, 1.000}, + {0.000, 1.000, 1.000}, + {0.333, 0.000, 1.000}, + {0.333, 0.333, 1.000}, + {0.333, 0.667, 1.000}, + {0.333, 1.000, 1.000}, + {0.667, 0.000, 1.000}, + {0.667, 0.333, 1.000}, + {0.667, 0.667, 1.000}, + {0.667, 1.000, 1.000}, + {1.000, 0.000, 1.000}, + {1.000, 0.333, 1.000}, + {1.000, 0.667, 1.000}, + {0.333, 0.000, 0.000}, + {0.500, 0.000, 0.000}, + {0.667, 0.000, 0.000}, + {0.833, 0.000, 0.000}, + {1.000, 0.000, 0.000}, + {0.000, 0.167, 0.000}, + {0.000, 0.333, 0.000}, + {0.000, 0.500, 0.000}, + {0.000, 0.667, 0.000}, + {0.000, 0.833, 0.000}, + {0.000, 1.000, 0.000}, + {0.000, 0.000, 0.167}, + {0.000, 0.000, 0.333}, + {0.000, 0.000, 0.500}, + {0.000, 0.000, 0.667}, + {0.000, 0.000, 0.833}, + {0.000, 0.000, 1.000}, + {0.000, 0.000, 0.000}, + {0.143, 0.143, 0.143}, + {0.286, 0.286, 0.286}, + {0.429, 0.429, 0.429}, + {0.571, 0.571, 0.571}, + {0.714, 0.714, 0.714}, + {0.857, 0.857, 0.857}, + {0.000, 0.447, 0.741}, + {0.314, 0.717, 0.741}, + {0.50, 0.5, 0} +}; + +void doInference(IExecutionContext& context, float* input, float* output, const int output_size, Size input_shape) { + const ICudaEngine& engine = context.getEngine(); + + // Pointers to input and output device buffers to pass to engine. + // Engine requires exactly IEngine::getNbBindings() number of buffers. + assert(engine.getNbBindings() == 2); + void* buffers[2]; + + // In order to bind the buffers, we need to know the names of the input and output tensors. + // Note that indices are guaranteed to be less than IEngine::getNbBindings() + const int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME); + + assert(engine.getBindingDataType(inputIndex) == nvinfer1::DataType::kFLOAT); + const int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME); + assert(engine.getBindingDataType(outputIndex) == nvinfer1::DataType::kFLOAT); + int mBatchSize = engine.getMaxBatchSize(); + + // Create GPU buffers on device + CHECK(cudaMalloc(&buffers[inputIndex], 3 * input_shape.height * input_shape.width * sizeof(float))); + CHECK(cudaMalloc(&buffers[outputIndex], output_size*sizeof(float))); + + // Create stream + cudaStream_t stream; + CHECK(cudaStreamCreate(&stream)); + + // DMA input batch data to device, infer on the batch asynchronously, and DMA output back to host + CHECK(cudaMemcpyAsync(buffers[inputIndex], input, 3 * input_shape.height * input_shape.width * sizeof(float), cudaMemcpyHostToDevice, stream)); + context.enqueue(1, buffers, stream, nullptr); + CHECK(cudaMemcpyAsync(output, buffers[outputIndex], output_size * sizeof(float), cudaMemcpyDeviceToHost, stream)); + cudaStreamSynchronize(stream); + + // Release stream and buffers + cudaStreamDestroy(stream); + CHECK(cudaFree(buffers[inputIndex])); + CHECK(cudaFree(buffers[outputIndex])); +} +/* +int main(int argc, char** argv) { + cudaSetDevice(DEVICE); + + // create a model using the API directly and serialize it to a stream + char *trtModelStream{nullptr}; + size_t size{0}; + + if (argc == 4 && string(argv[2]) == "-i") { + const string engine_file_path {argv[1]}; + ifstream file(engine_file_path, ios::binary); + if (file.good()) { + file.seekg(0, file.end); + size = file.tellg(); + file.seekg(0, file.beg); + trtModelStream = new char[size]; + assert(trtModelStream); + file.read(trtModelStream, size); + file.close(); + } + } else { + cerr << "arguments not right!" << endl; + cerr << "run 'python3 tools/trt.py -f exps/example/mot/yolox_s_mix_det.py -c pretrained/bytetrack_s_mot17.pth.tar' to serialize model first!" << std::endl; + cerr << "Then use the following command:" << endl; + cerr << "cd demo/TensorRT/cpp/build" << endl; + cerr << "./bytetrack ../../../../YOLOX_outputs/yolox_s_mix_det/model_trt.engine -i ../../../../videos/palace.mp4 // deserialize file and run inference" << std::endl; + return -1; + } + const string input_video_path {argv[3]}; + + IRuntime* runtime = createInferRuntime(gLogger); + assert(runtime != nullptr); + ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, size); + assert(engine != nullptr); + IExecutionContext* context = engine->createExecutionContext(); + assert(context != nullptr); + delete[] trtModelStream; + auto out_dims = engine->getBindingDimensions(1); + auto output_size = 1; + for(int j=0;j(cap.get(CAP_PROP_FRAME_COUNT)); + cout << "Total frames: " << nFrame << endl; + + VideoWriter writer("demo.mp4", VideoWriter::fourcc('m', 'p', '4', 'v'), fps, Size(img_w, img_h)); + + Mat img; + BYTETracker tracker(fps, 30); + int num_frames = 0; + int total_ms = 0; + while (true) + { + if(!cap.read(img)) + break; + num_frames ++; + if (num_frames % 20 == 0) + { + cout << "Processing frame " << num_frames << " (" << num_frames * 1000000 / total_ms << " fps)" << endl; + } + if (img.empty()) + break; + Mat pr_img = static_resize(img); + + float* blob; + blob = blobFromImage(pr_img); + float scale = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0)); + + // run inference + auto start = chrono::system_clock::now(); + doInference(*context, blob, prob, output_size, pr_img.size()); + vector objects; + decode_outputs(prob, objects, scale, img_w, img_h); + vector output_stracks = tracker.update(objects); + auto end = chrono::system_clock::now(); + total_ms = total_ms + chrono::duration_cast(end - start).count(); + + for (int i = 0; i < output_stracks.size(); i++) + { + vector tlwh = output_stracks[i].tlwh; + bool vertical = tlwh[2] / tlwh[3] > 1.6; + if (tlwh[2] * tlwh[3] > 20 && !vertical) + { + Scalar s = tracker.get_color(output_stracks[i].track_id); + putText(img, format("%d", output_stracks[i].track_id), Point(tlwh[0], tlwh[1] - 5), + 0, 0.6, Scalar(0, 0, 255), 2, LINE_AA); + rectangle(img, Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), s, 2); + } + } + putText(img, format("frame: %d fps: %d num: %d", num_frames, num_frames * 1000000 / total_ms, output_stracks.size()), + Point(0, 30), 0, 0.6, Scalar(0, 0, 255), 2, LINE_AA); + writer.write(img); + + delete blob; + char c = waitKey(1); + if (c > 0) + { + break; + } + } + cap.release(); + cout << "FPS: " << num_frames * 1000000 / total_ms << endl; + // destroy the engine + context->destroy(); + engine->destroy(); + runtime->destroy(); + return 0; +} +*/ \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/dataType.h b/yolo+ByteTrack/yoloTest/dataType.h new file mode 100644 index 0000000..a7821a3 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/dataType.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include +#include +typedef Eigen::Matrix DETECTBOX; +typedef Eigen::Matrix DETECTBOXSS; +typedef Eigen::Matrix FEATURE; +typedef Eigen::Matrix FEATURESS; +//typedef std::vector FEATURESS; + +//Kalmanfilter +//typedef Eigen::Matrix KAL_FILTER; +typedef Eigen::Matrix KAL_MEAN; +typedef Eigen::Matrix KAL_COVA; +typedef Eigen::Matrix KAL_HMEAN; +typedef Eigen::Matrix KAL_HCOVA; +using KAL_DATA = std::pair; +using KAL_HDATA = std::pair; + +//main +using RESULT_DATA = std::pair; + +//tracker: +using TRACKER_DATA = std::pair; +using MATCH_DATA = std::pair; +typedef struct t { + std::vector matches; + std::vector unmatched_tracks; + std::vector unmatched_detections; +}TRACHER_MATCHD; + +//linear_assignment: +typedef Eigen::Matrix DYNAMICM; \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/dirent.h b/yolo+ByteTrack/yoloTest/dirent.h new file mode 100644 index 0000000..37da1e8 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/dirent.h @@ -0,0 +1,1184 @@ +/* + * Dirent interface for Microsoft Visual Studio + * + * Copyright (C) 1998-2019 Toni Ronkko + * This file is part of dirent. Dirent may be freely distributed + * under the MIT license. For all details and documentation, see + * https://github.com/tronkko/dirent + */ +#ifndef DIRENT_H +#define DIRENT_H + + /* Hide warnings about unreferenced local functions */ +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunused-function" +#elif defined(_MSC_VER) +# pragma warning(disable:4505) +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +/* + * Include windows.h without Windows Sockets 1.1 to prevent conflicts with + * Windows Sockets 2.0. + */ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + /* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* Indicates that d_namlen field is available in dirent structure */ +#define _DIRENT_HAVE_D_NAMLEN + +/* Entries missing from MSVC 6.0 */ +#if !defined(FILE_ATTRIBUTE_DEVICE) +# define FILE_ATTRIBUTE_DEVICE 0x40 +#endif + +/* File type and permission flags for stat(), general mask */ +#if !defined(S_IFMT) +# define S_IFMT _S_IFMT +#endif + +/* Directory bit */ +#if !defined(S_IFDIR) +# define S_IFDIR _S_IFDIR +#endif + +/* Character device bit */ +#if !defined(S_IFCHR) +# define S_IFCHR _S_IFCHR +#endif + +/* Pipe bit */ +#if !defined(S_IFFIFO) +# define S_IFFIFO _S_IFFIFO +#endif + +/* Regular file bit */ +#if !defined(S_IFREG) +# define S_IFREG _S_IFREG +#endif + +/* Read permission */ +#if !defined(S_IREAD) +# define S_IREAD _S_IREAD +#endif + +/* Write permission */ +#if !defined(S_IWRITE) +# define S_IWRITE _S_IWRITE +#endif + +/* Execute permission */ +#if !defined(S_IEXEC) +# define S_IEXEC _S_IEXEC +#endif + +/* Pipe */ +#if !defined(S_IFIFO) +# define S_IFIFO _S_IFIFO +#endif + +/* Block device */ +#if !defined(S_IFBLK) +# define S_IFBLK 0 +#endif + +/* Link */ +#if !defined(S_IFLNK) +# define S_IFLNK 0 +#endif + +/* Socket */ +#if !defined(S_IFSOCK) +# define S_IFSOCK 0 +#endif + +/* Read user permission */ +#if !defined(S_IRUSR) +# define S_IRUSR S_IREAD +#endif + +/* Write user permission */ +#if !defined(S_IWUSR) +# define S_IWUSR S_IWRITE +#endif + +/* Execute user permission */ +#if !defined(S_IXUSR) +# define S_IXUSR 0 +#endif + +/* Read group permission */ +#if !defined(S_IRGRP) +# define S_IRGRP 0 +#endif + +/* Write group permission */ +#if !defined(S_IWGRP) +# define S_IWGRP 0 +#endif + +/* Execute group permission */ +#if !defined(S_IXGRP) +# define S_IXGRP 0 +#endif + +/* Read others permission */ +#if !defined(S_IROTH) +# define S_IROTH 0 +#endif + +/* Write others permission */ +#if !defined(S_IWOTH) +# define S_IWOTH 0 +#endif + +/* Execute others permission */ +#if !defined(S_IXOTH) +# define S_IXOTH 0 +#endif + +/* Maximum length of file name */ +#if !defined(PATH_MAX) +# define PATH_MAX MAX_PATH +#endif +#if !defined(FILENAME_MAX) +# define FILENAME_MAX MAX_PATH +#endif +#if !defined(NAME_MAX) +# define NAME_MAX FILENAME_MAX +#endif + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#if !defined(S_ISFIFO) +# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#endif +#if !defined(S_ISDIR) +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#if !defined(S_ISREG) +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISLNK) +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif +#if !defined(S_ISSOCK) +# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#endif +#if !defined(S_ISCHR) +# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#endif +#if !defined(S_ISBLK) +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#endif + + /* Return the exact length of the file name without zero terminator */ +#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) + +/* Return the maximum size of a file name */ +#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1) + + +#ifdef __cplusplus +extern "C" { +#endif + + + /* Wide-character version */ + struct _wdirent { + /* Always zero */ + long d_ino; + + /* File position within stream */ + long d_off; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + wchar_t d_name[PATH_MAX + 1]; + }; + typedef struct _wdirent _wdirent; + + struct _WDIR { + /* Current directory entry */ + struct _wdirent ent; + + /* Private file data */ + WIN32_FIND_DATAW data; + + /* True if data is valid */ + int cached; + + /* Win32 search handle */ + HANDLE handle; + + /* Initial directory name */ + wchar_t* patt; + }; + typedef struct _WDIR _WDIR; + + /* Multi-byte character version */ + struct dirent { + /* Always zero */ + long d_ino; + + /* File position within stream */ + long d_off; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + char d_name[PATH_MAX + 1]; + }; + typedef struct dirent dirent; + + struct DIR { + struct dirent ent; + struct _WDIR* wdirp; + }; + typedef struct DIR DIR; + + + /* Dirent functions */ + static DIR* opendir(const char* dirname); + static _WDIR* _wopendir(const wchar_t* dirname); + + static struct dirent* readdir(DIR* dirp); + static struct _wdirent* _wreaddir(_WDIR* dirp); + + static int readdir_r( + DIR* dirp, struct dirent* entry, struct dirent** result); + static int _wreaddir_r( + _WDIR* dirp, struct _wdirent* entry, struct _wdirent** result); + + static int closedir(DIR* dirp); + static int _wclosedir(_WDIR* dirp); + + static void rewinddir(DIR* dirp); + static void _wrewinddir(_WDIR* dirp); + + static int scandir(const char* dirname, struct dirent*** namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)); + + static int alphasort(const struct dirent** a, const struct dirent** b); + + static int versionsort(const struct dirent** a, const struct dirent** b); + + + /* For compatibility with Symbian */ +#define wdirent _wdirent +#define WDIR _WDIR +#define wopendir _wopendir +#define wreaddir _wreaddir +#define wclosedir _wclosedir +#define wrewinddir _wrewinddir + + +/* Internal utility functions */ + static WIN32_FIND_DATAW* dirent_first(_WDIR* dirp); + static WIN32_FIND_DATAW* dirent_next(_WDIR* dirp); + + static int dirent_mbstowcs_s( + size_t* pReturnValue, + wchar_t* wcstr, + size_t sizeInWords, + const char* mbstr, + size_t count); + + static int dirent_wcstombs_s( + size_t* pReturnValue, + char* mbstr, + size_t sizeInBytes, + const wchar_t* wcstr, + size_t count); + + static void dirent_set_errno(int error); + + + /* + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ + static _WDIR* + _wopendir( + const wchar_t* dirname) + { + _WDIR* dirp; + DWORD n; + wchar_t* p; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno(ENOENT); + return NULL; + } + + /* Allocate new _WDIR structure */ + dirp = (_WDIR*)malloc(sizeof(struct _WDIR)); + if (!dirp) { + return NULL; + } + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* + * Compute the length of full path plus zero terminator + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + /* Desktop */ + n = GetFullPathNameW(dirname, 0, NULL, NULL); +#else + /* WinRT */ + n = wcslen(dirname); +#endif + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = (wchar_t*)malloc(sizeof(wchar_t) * n + 16); + if (dirp->patt == NULL) { + goto exit_closedir; + } + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + /* Desktop */ + n = GetFullPathNameW(dirname, n, dirp->patt, NULL); + if (n <= 0) { + goto exit_closedir; + } +#else + /* WinRT */ + wcsncpy_s(dirp->patt, n + 1, dirname, n); +#endif + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + switch (p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if (!dirent_first(dirp)) { + goto exit_closedir; + } + + /* Success */ + return dirp; + + /* Failure */ + exit_closedir: + _wclosedir(dirp); + return NULL; + } + + /* + * Read next directory entry. + * + * Returns pointer to static directory entry which may be overwritten by + * subsequent calls to _wreaddir(). + */ + static struct _wdirent* + _wreaddir( + _WDIR* dirp) + { + struct _wdirent* entry; + + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void)_wreaddir_r(dirp, &dirp->ent, &entry); + + /* Return pointer to statically allocated directory entry */ + return entry; + } + + /* + * Read next directory entry. + * + * Returns zero on success. If end of directory stream is reached, then sets + * result to NULL and returns zero. + */ + static int + _wreaddir_r( + _WDIR* dirp, + struct _wdirent* entry, + struct _wdirent** result) + { + WIN32_FIND_DATAW* datap; + + /* Read next directory entry */ + datap = dirent_next(dirp); + if (datap) { + size_t n; + DWORD attr; + + /* + * Copy file name as wide-character string. If the file name is too + * long to fit in to the destination buffer, then truncate file name + * to PATH_MAX characters and zero-terminate the buffer. + */ + n = 0; + while (n < PATH_MAX && datap->cFileName[n] != 0) { + entry->d_name[n] = datap->cFileName[n]; + n++; + } + entry->d_name[n] = 0; + + /* Length of file name excluding zero terminator */ + entry->d_namlen = n; + + /* File type */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entry->d_type = DT_CHR; + } + else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entry->d_type = DT_DIR; + } + else { + entry->d_type = DT_REG; + } + + /* Reset dummy fields */ + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof(struct _wdirent); + + /* Set result address */ + *result = entry; + + } + else { + + /* Return NULL to indicate end of directory */ + *result = NULL; + + } + + return /*OK*/0; + } + + /* + * Close directory stream opened by opendir() function. This invalidates the + * DIR structure as well as any directory entry read previously by + * _wreaddir(). + */ + static int + _wclosedir( + _WDIR* dirp) + { + int ok; + if (dirp) { + + /* Release search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + } + + /* Release search pattern */ + free(dirp->patt); + + /* Release directory structure */ + free(dirp); + ok = /*success*/0; + + } + else { + + /* Invalid directory stream */ + dirent_set_errno(EBADF); + ok = /*failure*/-1; + + } + return ok; + } + + /* + * Rewind directory stream such that _wreaddir() returns the very first + * file name again. + */ + static void + _wrewinddir( + _WDIR* dirp) + { + if (dirp) { + /* Release existing search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + } + + /* Open new search handle */ + dirent_first(dirp); + } + } + + /* Get first directory entry (internal) */ + static WIN32_FIND_DATAW* + dirent_first( + _WDIR* dirp) + { + WIN32_FIND_DATAW* datap; + DWORD error; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileExW( + dirp->patt, FindExInfoStandard, &dirp->data, + FindExSearchNameMatch, NULL, 0); + if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } + else { + + /* Failed to open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + /* Set error code */ + error = GetLastError(); + switch (error) { + case ERROR_ACCESS_DENIED: + /* No read access to directory */ + dirent_set_errno(EACCES); + break; + + case ERROR_DIRECTORY: + /* Directory name is invalid */ + dirent_set_errno(ENOTDIR); + break; + + case ERROR_PATH_NOT_FOUND: + default: + /* Cannot find the file */ + dirent_set_errno(ENOENT); + } + + } + return datap; + } + + /* + * Get next directory entry (internal). + * + * Returns + */ + static WIN32_FIND_DATAW* + dirent_next( + _WDIR* dirp) + { + WIN32_FIND_DATAW* p; + + /* Get next directory entry */ + if (dirp->cached != 0) { + + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + + } + else if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* Get the next directory entry from stream */ + if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) { + /* Got a file */ + p = &dirp->data; + } + else { + /* The very last entry has been processed or an error occurred */ + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; + } + + } + else { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; + } + + /* + * Open directory stream using plain old C-string. + */ + static DIR* + opendir( + const char* dirname) + { + struct DIR* dirp; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno(ENOENT); + return NULL; + } + + /* Allocate memory for DIR structure */ + dirp = (DIR*)malloc(sizeof(struct DIR)); + if (!dirp) { + return NULL; + } + { + int error; + wchar_t wname[PATH_MAX + 1]; + size_t n; + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s( + &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); + if (error) { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + goto exit_free; + } + + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir(wname); + if (!dirp->wdirp) { + goto exit_free; + } + + } + + /* Success */ + return dirp; + + /* Failure */ + exit_free: + free(dirp); + return NULL; + } + + /* + * Read next directory entry. + */ + static struct dirent* + readdir( + DIR* dirp) + { + struct dirent* entry; + + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void)readdir_r(dirp, &dirp->ent, &entry); + + /* Return pointer to statically allocated directory entry */ + return entry; + } + + /* + * Read next directory entry into called-allocated buffer. + * + * Returns zero on success. If the end of directory stream is reached, then + * sets result to NULL and returns zero. + */ + static int + readdir_r( + DIR* dirp, + struct dirent* entry, + struct dirent** result) + { + WIN32_FIND_DATAW* datap; + + /* Read next directory entry */ + datap = dirent_next(dirp->wdirp); + if (datap) { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if (error && datap->cAlternateFileName[0] != '\0') { + error = dirent_wcstombs_s( + &n, entry->d_name, PATH_MAX + 1, + datap->cAlternateFileName, PATH_MAX + 1); + } + + if (!error) { + DWORD attr; + + /* Length of file name excluding zero terminator */ + entry->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entry->d_type = DT_CHR; + } + else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entry->d_type = DT_DIR; + } + else { + entry->d_type = DT_REG; + } + + /* Reset dummy fields */ + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof(struct dirent); + + } + else { + + /* + * Cannot convert file name to multi-byte string so construct + * an erroneous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entry->d_name[0] = '?'; + entry->d_name[1] = '\0'; + entry->d_namlen = 1; + entry->d_type = DT_UNKNOWN; + entry->d_ino = 0; + entry->d_off = -1; + entry->d_reclen = 0; + + } + + /* Return pointer to directory entry */ + *result = entry; + + } + else { + + /* No more directory entries */ + *result = NULL; + + } + + return /*OK*/0; + } + + /* + * Close directory stream. + */ + static int + closedir( + DIR* dirp) + { + int ok; + if (dirp) { + + /* Close wide-character directory stream */ + ok = _wclosedir(dirp->wdirp); + dirp->wdirp = NULL; + + /* Release multi-byte character version */ + free(dirp); + + } + else { + + /* Invalid directory stream */ + dirent_set_errno(EBADF); + ok = /*failure*/-1; + + } + return ok; + } + + /* + * Rewind directory stream to beginning. + */ + static void + rewinddir( + DIR* dirp) + { + /* Rewind wide-character string directory stream */ + _wrewinddir(dirp->wdirp); + } + + /* + * Scan directory for entries. + */ + static int + scandir( + const char* dirname, + struct dirent*** namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)) + { + struct dirent** files = NULL; + size_t size = 0; + size_t allocated = 0; + const size_t init_size = 1; + DIR* dir = NULL; + struct dirent* entry; + struct dirent* tmp = NULL; + size_t i; + int result = 0; + + /* Open directory stream */ + dir = opendir(dirname); + if (dir) { + + /* Read directory entries to memory */ + while (1) { + + /* Enlarge pointer table to make room for another pointer */ + if (size >= allocated) { + void* p; + size_t num_entries; + + /* Compute number of entries in the enlarged pointer table */ + if (size < init_size) { + /* Allocate initial pointer table */ + num_entries = init_size; + } + else { + /* Double the size */ + num_entries = size * 2; + } + + /* Allocate first pointer table or enlarge existing table */ + p = realloc(files, sizeof(void*) * num_entries); + if (p != NULL) { + /* Got the memory */ + files = (dirent**)p; + allocated = num_entries; + } + else { + /* Out of memory */ + result = -1; + break; + } + + } + + /* Allocate room for temporary directory entry */ + if (tmp == NULL) { + tmp = (struct dirent*)malloc(sizeof(struct dirent)); + if (tmp == NULL) { + /* Cannot allocate temporary directory entry */ + result = -1; + break; + } + } + + /* Read directory entry to temporary area */ + if (readdir_r(dir, tmp, &entry) == /*OK*/0) { + + /* Did we get an entry? */ + if (entry != NULL) { + int pass; + + /* Determine whether to include the entry in result */ + if (filter) { + /* Let the filter function decide */ + pass = filter(tmp); + } + else { + /* No filter function, include everything */ + pass = 1; + } + + if (pass) { + /* Store the temporary entry to pointer table */ + files[size++] = tmp; + tmp = NULL; + + /* Keep up with the number of files */ + result++; + } + + } + else { + + /* + * End of directory stream reached => sort entries and + * exit. + */ + qsort(files, size, sizeof(void*), + (int (*) (const void*, const void*)) compare); + break; + + } + + } + else { + /* Error reading directory entry */ + result = /*Error*/ -1; + break; + } + + } + + } + else { + /* Cannot open directory */ + result = /*Error*/ -1; + } + + /* Release temporary directory entry */ + free(tmp); + + /* Release allocated memory on error */ + if (result < 0) { + for (i = 0; i < size; i++) { + free(files[i]); + } + free(files); + files = NULL; + } + + /* Close directory stream */ + if (dir) { + closedir(dir); + } + + /* Pass pointer table to caller */ + if (namelist) { + *namelist = files; + } + return result; + } + + /* Alphabetical sorting */ + static int + alphasort( + const struct dirent** a, const struct dirent** b) + { + return strcoll((*a)->d_name, (*b)->d_name); + } + + /* Sort versions */ + static int + versionsort( + const struct dirent** a, const struct dirent** b) + { + /* FIXME: implement strverscmp and use that */ + return alphasort(a, b); + } + + /* Convert multi-byte string to wide character string */ + static int + dirent_mbstowcs_s( + size_t* pReturnValue, + wchar_t* wcstr, + size_t sizeInWords, + const char* mbstr, + size_t count) + { + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to wide-character string (or count characters) */ + n = mbstowcs(wcstr, mbstr, sizeInWords); + if (!wcstr || n < count) { + + /* Zero-terminate output buffer */ + if (wcstr && sizeInWords) { + if (n >= sizeInWords) { + n = sizeInWords - 1; + } + wcstr[n] = 0; + } + + /* Length of resulting multi-byte string WITH zero terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } + else { + + /* Could not convert string */ + error = 1; + + } + +#endif + return error; + } + + /* Convert wide-character string to multi-byte string */ + static int + dirent_wcstombs_s( + size_t* pReturnValue, + char* mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t* wcstr, + size_t count) + { + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to multi-byte string (or count the number of bytes needed) */ + n = wcstombs(mbstr, wcstr, sizeInBytes); + if (!mbstr || n < count) { + + /* Zero-terminate output buffer */ + if (mbstr && sizeInBytes) { + if (n >= sizeInBytes) { + n = sizeInBytes - 1; + } + mbstr[n] = '\0'; + } + + /* Length of resulting multi-bytes string WITH zero-terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } + else { + + /* Cannot convert string */ + error = 1; + + } + +#endif + return error; + } + + /* Set errno variable */ + static void + dirent_set_errno( + int error) + { +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 and later */ + _set_errno(error); + +#else + + /* Non-Microsoft compiler or older Microsoft compiler */ + errno = error; + +#endif + } + + +#ifdef __cplusplus +} +#endif +#endif /*DIRENT_H*/ + + + diff --git a/yolo+ByteTrack/yoloTest/kalmanFilter.cpp b/yolo+ByteTrack/yoloTest/kalmanFilter.cpp new file mode 100644 index 0000000..168432a --- /dev/null +++ b/yolo+ByteTrack/yoloTest/kalmanFilter.cpp @@ -0,0 +1,152 @@ +#include "kalmanFilter.h" +#include + +namespace byte_kalman +{ + const double KalmanFilter::chi2inv95[10] = { + 0, + 3.8415, + 5.9915, + 7.8147, + 9.4877, + 11.070, + 12.592, + 14.067, + 15.507, + 16.919 + }; + KalmanFilter::KalmanFilter() + { + int ndim = 4; + double dt = 1.; + + _motion_mat = Eigen::MatrixXf::Identity(8, 8); + for (int i = 0; i < ndim; i++) { + _motion_mat(i, ndim + i) = dt; + } + _update_mat = Eigen::MatrixXf::Identity(4, 8); + + this->_std_weight_position = 1. / 20; + this->_std_weight_velocity = 1. / 160; + } + + KAL_DATA KalmanFilter::initiate(const DETECTBOX &measurement) + { + DETECTBOX mean_pos = measurement; + DETECTBOX mean_vel; + for (int i = 0; i < 4; i++) mean_vel(i) = 0; + + KAL_MEAN mean; + for (int i = 0; i < 8; i++) { + if (i < 4) mean(i) = mean_pos(i); + else mean(i) = mean_vel(i - 4); + } + + KAL_MEAN std; + std(0) = 2 * _std_weight_position * measurement[3]; + std(1) = 2 * _std_weight_position * measurement[3]; + std(2) = 1e-2; + std(3) = 2 * _std_weight_position * measurement[3]; + std(4) = 10 * _std_weight_velocity * measurement[3]; + std(5) = 10 * _std_weight_velocity * measurement[3]; + std(6) = 1e-5; + std(7) = 10 * _std_weight_velocity * measurement[3]; + + KAL_MEAN tmp = std.array().square(); + KAL_COVA var = tmp.asDiagonal(); + return std::make_pair(mean, var); + } + + void KalmanFilter::predict(KAL_MEAN &mean, KAL_COVA &covariance) + { + //revise the data; + DETECTBOX std_pos; + std_pos << _std_weight_position * mean(3), + _std_weight_position * mean(3), + 1e-2, + _std_weight_position * mean(3); + DETECTBOX std_vel; + std_vel << _std_weight_velocity * mean(3), + _std_weight_velocity * mean(3), + 1e-5, + _std_weight_velocity * mean(3); + KAL_MEAN tmp; + tmp.block<1, 4>(0, 0) = std_pos; + tmp.block<1, 4>(0, 4) = std_vel; + tmp = tmp.array().square(); + KAL_COVA motion_cov = tmp.asDiagonal(); + KAL_MEAN mean1 = this->_motion_mat * mean.transpose(); + KAL_COVA covariance1 = this->_motion_mat * covariance *(_motion_mat.transpose()); + covariance1 += motion_cov; + + mean = mean1; + covariance = covariance1; + } + + KAL_HDATA KalmanFilter::project(const KAL_MEAN &mean, const KAL_COVA &covariance) + { + DETECTBOX std; + std << _std_weight_position * mean(3), _std_weight_position * mean(3), + 1e-1, _std_weight_position * mean(3); + KAL_HMEAN mean1 = _update_mat * mean.transpose(); + KAL_HCOVA covariance1 = _update_mat * covariance * (_update_mat.transpose()); + Eigen::Matrix diag = std.asDiagonal(); + diag = diag.array().square().matrix(); + covariance1 += diag; + // covariance1.diagonal() << diag; + return std::make_pair(mean1, covariance1); + } + + KAL_DATA + KalmanFilter::update( + const KAL_MEAN &mean, + const KAL_COVA &covariance, + const DETECTBOX &measurement) + { + KAL_HDATA pa = project(mean, covariance); + KAL_HMEAN projected_mean = pa.first; + KAL_HCOVA projected_cov = pa.second; + + //chol_factor, lower = + //scipy.linalg.cho_factor(projected_cov, lower=True, check_finite=False) + //kalmain_gain = + //scipy.linalg.cho_solve((cho_factor, lower), + //np.dot(covariance, self._upadte_mat.T).T, + //check_finite=False).T + Eigen::Matrix B = (covariance * (_update_mat.transpose())).transpose(); + Eigen::Matrix kalman_gain = (projected_cov.llt().solve(B)).transpose(); // eg.8x4 + Eigen::Matrix innovation = measurement - projected_mean; //eg.1x4 + auto tmp = innovation * (kalman_gain.transpose()); + KAL_MEAN new_mean = (mean.array() + tmp.array()).matrix(); + KAL_COVA new_covariance = covariance - kalman_gain * projected_cov*(kalman_gain.transpose()); + return std::make_pair(new_mean, new_covariance); + } + + Eigen::Matrix + KalmanFilter::gating_distance( + const KAL_MEAN &mean, + const KAL_COVA &covariance, + const std::vector &measurements, + bool only_position) + { + KAL_HDATA pa = this->project(mean, covariance); + if (only_position) { + printf("not implement!"); + exit(0); + } + KAL_HMEAN mean1 = pa.first; + KAL_HCOVA covariance1 = pa.second; + + // Eigen::Matrix d(size, 4); + DETECTBOXSS d(measurements.size(), 4); + int pos = 0; + for (DETECTBOX box : measurements) { + d.row(pos++) = box - mean1; + } + Eigen::Matrix factor = covariance1.llt().matrixL(); + Eigen::Matrix z = factor.triangularView().solve(d).transpose(); + auto zz = ((z.array())*(z.array())).matrix(); + auto square_maha = zz.colwise().sum(); + return square_maha; + } +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/kalmanFilter.h b/yolo+ByteTrack/yoloTest/kalmanFilter.h new file mode 100644 index 0000000..6596b54 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/kalmanFilter.h @@ -0,0 +1,31 @@ +#pragma once + +#include "dataType.h" + +namespace byte_kalman +{ + class KalmanFilter + { + public: + static const double chi2inv95[10]; + KalmanFilter(); + KAL_DATA initiate(const DETECTBOX& measurement); + void predict(KAL_MEAN& mean, KAL_COVA& covariance); + KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance); + KAL_DATA update(const KAL_MEAN& mean, + const KAL_COVA& covariance, + const DETECTBOX& measurement); + + Eigen::Matrix gating_distance( + const KAL_MEAN& mean, + const KAL_COVA& covariance, + const std::vector& measurements, + bool only_position = false); + + private: + Eigen::Matrix _motion_mat; + Eigen::Matrix _update_mat; + float _std_weight_position; + float _std_weight_velocity; + }; +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/lapjv.cpp b/yolo+ByteTrack/yoloTest/lapjv.cpp new file mode 100644 index 0000000..169efd5 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/lapjv.cpp @@ -0,0 +1,343 @@ +#include +#include +#include + +#include "lapjv.h" + +/** Column-reduction and reduction transfer for a dense cost matrix. + */ +int_t _ccrrt_dense(const uint_t n, cost_t *cost[], + int_t *free_rows, int_t *x, int_t *y, cost_t *v) +{ + int_t n_free_rows; + boolean *unique; + + for (uint_t i = 0; i < n; i++) { + x[i] = -1; + v[i] = LARGE; + y[i] = 0; + } + for (uint_t i = 0; i < n; i++) { + for (uint_t j = 0; j < n; j++) { + const cost_t c = cost[i][j]; + if (c < v[j]) { + v[j] = c; + y[j] = i; + } + PRINTF("i=%d, j=%d, c[i,j]=%f, v[j]=%f y[j]=%d\n", i, j, c, v[j], y[j]); + } + } + PRINT_COST_ARRAY(v, n); + PRINT_INDEX_ARRAY(y, n); + NEW(unique, boolean, n); + memset(unique, TRUE, n); + { + int_t j = n; + do { + j--; + const int_t i = y[j]; + if (x[i] < 0) { + x[i] = j; + } + else { + unique[i] = FALSE; + y[j] = -1; + } + } while (j > 0); + } + n_free_rows = 0; + for (uint_t i = 0; i < n; i++) { + if (x[i] < 0) { + free_rows[n_free_rows++] = i; + } + else if (unique[i]) { + const int_t j = x[i]; + cost_t min = LARGE; + for (uint_t j2 = 0; j2 < n; j2++) { + if (j2 == (uint_t)j) { + continue; + } + const cost_t c = cost[i][j2] - v[j2]; + if (c < min) { + min = c; + } + } + PRINTF("v[%d] = %f - %f\n", j, v[j], min); + v[j] -= min; + } + } + FREE(unique); + return n_free_rows; +} + + +/** Augmenting row reduction for a dense cost matrix. + */ +int_t _carr_dense( + const uint_t n, cost_t *cost[], + const uint_t n_free_rows, + int_t *free_rows, int_t *x, int_t *y, cost_t *v) +{ + uint_t current = 0; + int_t new_free_rows = 0; + uint_t rr_cnt = 0; + PRINT_INDEX_ARRAY(x, n); + PRINT_INDEX_ARRAY(y, n); + PRINT_COST_ARRAY(v, n); + PRINT_INDEX_ARRAY(free_rows, n_free_rows); + while (current < n_free_rows) { + int_t i0; + int_t j1, j2; + cost_t v1, v2, v1_new; + boolean v1_lowers; + + rr_cnt++; + PRINTF("current = %d rr_cnt = %d\n", current, rr_cnt); + const int_t free_i = free_rows[current++]; + j1 = 0; + v1 = cost[free_i][0] - v[0]; + j2 = -1; + v2 = LARGE; + for (uint_t j = 1; j < n; j++) { + PRINTF("%d = %f %d = %f\n", j1, v1, j2, v2); + const cost_t c = cost[free_i][j] - v[j]; + if (c < v2) { + if (c >= v1) { + v2 = c; + j2 = j; + } + else { + v2 = v1; + v1 = c; + j2 = j1; + j1 = j; + } + } + } + i0 = y[j1]; + v1_new = v[j1] - (v2 - v1); + v1_lowers = v1_new < v[j1]; + PRINTF("%d %d 1=%d,%f 2=%d,%f v1'=%f(%d,%g) \n", free_i, i0, j1, v1, j2, v2, v1_new, v1_lowers, v[j1] - v1_new); + if (rr_cnt < current * n) { + if (v1_lowers) { + v[j1] = v1_new; + } + else if (i0 >= 0 && j2 >= 0) { + j1 = j2; + i0 = y[j2]; + } + if (i0 >= 0) { + if (v1_lowers) { + free_rows[--current] = i0; + } + else { + free_rows[new_free_rows++] = i0; + } + } + } + else { + PRINTF("rr_cnt=%d >= %d (current=%d * n=%d)\n", rr_cnt, current * n, current, n); + if (i0 >= 0) { + free_rows[new_free_rows++] = i0; + } + } + x[free_i] = j1; + y[j1] = free_i; + } + return new_free_rows; +} + + +/** Find columns with minimum d[j] and put them on the SCAN list. + */ +uint_t _find_dense(const uint_t n, uint_t lo, cost_t *d, int_t *cols, int_t *y) +{ + uint_t hi = lo + 1; + cost_t mind = d[cols[lo]]; + for (uint_t k = hi; k < n; k++) { + int_t j = cols[k]; + if (d[j] <= mind) { + if (d[j] < mind) { + hi = lo; + mind = d[j]; + } + cols[k] = cols[hi]; + cols[hi++] = j; + } + } + return hi; +} + + +// Scan all columns in TODO starting from arbitrary column in SCAN +// and try to decrease d of the TODO columns using the SCAN column. +int_t _scan_dense(const uint_t n, cost_t *cost[], + uint_t *plo, uint_t*phi, + cost_t *d, int_t *cols, int_t *pred, + int_t *y, cost_t *v) +{ + uint_t lo = *plo; + uint_t hi = *phi; + cost_t h, cred_ij; + + while (lo != hi) { + int_t j = cols[lo++]; + const int_t i = y[j]; + const cost_t mind = d[j]; + h = cost[i][j] - v[j] - mind; + PRINTF("i=%d j=%d h=%f\n", i, j, h); + // For all columns in TODO + for (uint_t k = hi; k < n; k++) { + j = cols[k]; + cred_ij = cost[i][j] - v[j] - h; + if (cred_ij < d[j]) { + d[j] = cred_ij; + pred[j] = i; + if (cred_ij == mind) { + if (y[j] < 0) { + return j; + } + cols[k] = cols[hi]; + cols[hi++] = j; + } + } + } + } + *plo = lo; + *phi = hi; + return -1; +} + + +/** Single iteration of modified Dijkstra shortest path algorithm as explained in the JV paper. + * + * This is a dense matrix version. + * + * \return The closest free column index. + */ +int_t find_path_dense( + const uint_t n, cost_t *cost[], + const int_t start_i, + int_t *y, cost_t *v, + int_t *pred) +{ + uint_t lo = 0, hi = 0; + int_t final_j = -1; + uint_t n_ready = 0; + int_t *cols; + cost_t *d; + + NEW(cols, int_t, n); + NEW(d, cost_t, n); + + for (uint_t i = 0; i < n; i++) { + cols[i] = i; + pred[i] = start_i; + d[i] = cost[start_i][i] - v[i]; + } + PRINT_COST_ARRAY(d, n); + while (final_j == -1) { + // No columns left on the SCAN list. + if (lo == hi) { + PRINTF("%d..%d -> find\n", lo, hi); + n_ready = lo; + hi = _find_dense(n, lo, d, cols, y); + PRINTF("check %d..%d\n", lo, hi); + PRINT_INDEX_ARRAY(cols, n); + for (uint_t k = lo; k < hi; k++) { + const int_t j = cols[k]; + if (y[j] < 0) { + final_j = j; + } + } + } + if (final_j == -1) { + PRINTF("%d..%d -> scan\n", lo, hi); + final_j = _scan_dense( + n, cost, &lo, &hi, d, cols, pred, y, v); + PRINT_COST_ARRAY(d, n); + PRINT_INDEX_ARRAY(cols, n); + PRINT_INDEX_ARRAY(pred, n); + } + } + + PRINTF("found final_j=%d\n", final_j); + PRINT_INDEX_ARRAY(cols, n); + { + const cost_t mind = d[cols[lo]]; + for (uint_t k = 0; k < n_ready; k++) { + const int_t j = cols[k]; + v[j] += d[j] - mind; + } + } + + FREE(cols); + FREE(d); + + return final_j; +} + + +/** Augment for a dense cost matrix. + */ +int_t _ca_dense( + const uint_t n, cost_t *cost[], + const uint_t n_free_rows, + int_t *free_rows, int_t *x, int_t *y, cost_t *v) +{ + int_t *pred; + + NEW(pred, int_t, n); + + for (int_t *pfree_i = free_rows; pfree_i < free_rows + n_free_rows; pfree_i++) { + int_t i = -1, j; + uint_t k = 0; + + PRINTF("looking at free_i=%d\n", *pfree_i); + j = find_path_dense(n, cost, *pfree_i, y, v, pred); + ASSERT(j >= 0); + ASSERT(j < n); + while (i != *pfree_i) { + PRINTF("augment %d\n", j); + PRINT_INDEX_ARRAY(pred, n); + i = pred[j]; + PRINTF("y[%d]=%d -> %d\n", j, y[j], i); + y[j] = i; + PRINT_INDEX_ARRAY(x, n); + SWAP_INDICES(j, x[i]); + k++; + if (k >= n) { + ASSERT(FALSE); + } + } + } + FREE(pred); + return 0; +} + + +/** Solve dense sparse LAP. + */ +int lapjv_internal( + const uint_t n, cost_t *cost[], + int_t *x, int_t *y) +{ + int ret; + int_t *free_rows; + cost_t *v; + + NEW(free_rows, int_t, n); + NEW(v, cost_t, n); + ret = _ccrrt_dense(n, cost, free_rows, x, y, v); + int i = 0; + while (ret > 0 && i < 2) { + ret = _carr_dense(n, cost, ret, free_rows, x, y, v); + i++; + } + if (ret > 0) { + ret = _ca_dense(n, cost, ret, free_rows, x, y, v); + } + FREE(v); + FREE(free_rows); + return ret; +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/lapjv.h b/yolo+ByteTrack/yoloTest/lapjv.h new file mode 100644 index 0000000..0e34385 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/lapjv.h @@ -0,0 +1,63 @@ +#ifndef LAPJV_H +#define LAPJV_H + +#define LARGE 1000000 + +#if !defined TRUE +#define TRUE 1 +#endif +#if !defined FALSE +#define FALSE 0 +#endif + +#define NEW(x, t, n) if ((x = (t *)malloc(sizeof(t) * (n))) == 0) { return -1; } +#define FREE(x) if (x != 0) { free(x); x = 0; } +#define SWAP_INDICES(a, b) { int_t _temp_index = a; a = b; b = _temp_index; } + +#if 0 +#include +#define ASSERT(cond) assert(cond) +#define PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) +#define PRINT_COST_ARRAY(a, n) \ + while (1) { \ + printf(#a" = ["); \ + if ((n) > 0) { \ + printf("%f", (a)[0]); \ + for (uint_t j = 1; j < n; j++) { \ + printf(", %f", (a)[j]); \ + } \ + } \ + printf("]\n"); \ + break; \ + } +#define PRINT_INDEX_ARRAY(a, n) \ + while (1) { \ + printf(#a" = ["); \ + if ((n) > 0) { \ + printf("%d", (a)[0]); \ + for (uint_t j = 1; j < n; j++) { \ + printf(", %d", (a)[j]); \ + } \ + } \ + printf("]\n"); \ + break; \ + } +#else +#define ASSERT(cond) +#define PRINTF(fmt, ...) +#define PRINT_COST_ARRAY(a, n) +#define PRINT_INDEX_ARRAY(a, n) +#endif + + +typedef signed int int_t; +typedef unsigned int uint_t; +typedef double cost_t; +typedef char boolean; +typedef enum fp_t { FP_1 = 1, FP_2 = 2, FP_DYNAMIC = 3 } fp_t; + +extern int_t lapjv_internal( + const uint_t n, cost_t *cost[], + int_t *x, int_t *y); + +#endif // LAPJV_H \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/logging.h b/yolo+ByteTrack/yoloTest/logging.h new file mode 100644 index 0000000..813828e --- /dev/null +++ b/yolo+ByteTrack/yoloTest/logging.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma warning( disable : 4996 ) +#ifndef TENSORRT_LOGGING_H +#define TENSORRT_LOGGING_H + +#include "NvInferRuntimeCommon.h" +#include +#include +#include +#include +#include +#include +#include + +using Severity = nvinfer1::ILogger::Severity; + +class LogStreamConsumerBuffer : public std::stringbuf +{ +public: + LogStreamConsumerBuffer(std::ostream& stream, const std::string& prefix, bool shouldLog) + : mOutput(stream) + , mPrefix(prefix) + , mShouldLog(shouldLog) + { + } + + LogStreamConsumerBuffer(LogStreamConsumerBuffer&& other) + : mOutput(other.mOutput) + { + } + + ~LogStreamConsumerBuffer() + { + // std::streambuf::pbase() gives a pointer to the beginning of the buffered part of the output sequence + // std::streambuf::pptr() gives a pointer to the current position of the output sequence + // if the pointer to the beginning is not equal to the pointer to the current position, + // call putOutput() to log the output to the stream + if (pbase() != pptr()) + { + putOutput(); + } + } + + // synchronizes the stream buffer and returns 0 on success + // synchronizing the stream buffer consists of inserting the buffer contents into the stream, + // resetting the buffer and flushing the stream + virtual int sync() + { + putOutput(); + return 0; + } + + void putOutput() + { + if (mShouldLog) + { + // prepend timestamp + std::time_t timestamp = std::time(nullptr); + tm* tm_local = std::localtime(×tamp); + std::cout << "["; + std::cout << std::setw(2) << std::setfill('0') << 1 + tm_local->tm_mon << "/"; + std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_mday << "/"; + std::cout << std::setw(4) << std::setfill('0') << 1900 + tm_local->tm_year << "-"; + std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_hour << ":"; + std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_min << ":"; + std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_sec << "] "; + // std::stringbuf::str() gets the string contents of the buffer + // insert the buffer contents pre-appended by the appropriate prefix into the stream + mOutput << mPrefix << str(); + // set the buffer to empty + str(""); + // flush the stream + mOutput.flush(); + } + } + + void setShouldLog(bool shouldLog) + { + mShouldLog = shouldLog; + } + +private: + std::ostream& mOutput; + std::string mPrefix; + bool mShouldLog; +}; + +//! +//! \class LogStreamConsumerBase +//! \brief Convenience object used to initialize LogStreamConsumerBuffer before std::ostream in LogStreamConsumer +//! +class LogStreamConsumerBase +{ +public: + LogStreamConsumerBase(std::ostream& stream, const std::string& prefix, bool shouldLog) + : mBuffer(stream, prefix, shouldLog) + { + } + +protected: + LogStreamConsumerBuffer mBuffer; +}; + +//! +//! \class LogStreamConsumer +//! \brief Convenience object used to facilitate use of C++ stream syntax when logging messages. +//! Order of base classes is LogStreamConsumerBase and then std::ostream. +//! This is because the LogStreamConsumerBase class is used to initialize the LogStreamConsumerBuffer member field +//! in LogStreamConsumer and then the address of the buffer is passed to std::ostream. +//! This is necessary to prevent the address of an uninitialized buffer from being passed to std::ostream. +//! Please do not change the order of the parent classes. +//! +class LogStreamConsumer : protected LogStreamConsumerBase, public std::ostream +{ +public: + //! \brief Creates a LogStreamConsumer which logs messages with level severity. + //! Reportable severity determines if the messages are severe enough to be logged. + LogStreamConsumer(Severity reportableSeverity, Severity severity) + : LogStreamConsumerBase(severityOstream(severity), severityPrefix(severity), severity <= reportableSeverity) + , std::ostream(&mBuffer) // links the stream buffer with the stream + , mShouldLog(severity <= reportableSeverity) + , mSeverity(severity) + { + } + + LogStreamConsumer(LogStreamConsumer&& other) + : LogStreamConsumerBase(severityOstream(other.mSeverity), severityPrefix(other.mSeverity), other.mShouldLog) + , std::ostream(&mBuffer) // links the stream buffer with the stream + , mShouldLog(other.mShouldLog) + , mSeverity(other.mSeverity) + { + } + + void setReportableSeverity(Severity reportableSeverity) + { + mShouldLog = mSeverity <= reportableSeverity; + mBuffer.setShouldLog(mShouldLog); + } + +private: + static std::ostream& severityOstream(Severity severity) + { + return severity >= Severity::kINFO ? std::cout : std::cerr; + } + + static std::string severityPrefix(Severity severity) + { + switch (severity) + { + case Severity::kINTERNAL_ERROR: return "[F] "; + case Severity::kERROR: return "[E] "; + case Severity::kWARNING: return "[W] "; + case Severity::kINFO: return "[I] "; + case Severity::kVERBOSE: return "[V] "; + default: assert(0); return ""; + } + } + + bool mShouldLog; + Severity mSeverity; +}; + +//! \class Logger +//! +//! \brief Class which manages logging of TensorRT tools and samples +//! +//! \details This class provides a common interface for TensorRT tools and samples to log information to the console, +//! and supports logging two types of messages: +//! +//! - Debugging messages with an associated severity (info, warning, error, or internal error/fatal) +//! - Test pass/fail messages +//! +//! The advantage of having all samples use this class for logging as opposed to emitting directly to stdout/stderr is +//! that the logic for controlling the verbosity and formatting of sample output is centralized in one location. +//! +//! In the future, this class could be extended to support dumping test results to a file in some standard format +//! (for example, JUnit XML), and providing additional metadata (e.g. timing the duration of a test run). +//! +//! TODO: For backwards compatibility with existing samples, this class inherits directly from the nvinfer1::ILogger +//! interface, which is problematic since there isn't a clean separation between messages coming from the TensorRT +//! library and messages coming from the sample. +//! +//! In the future (once all samples are updated to use Logger::getTRTLogger() to access the ILogger) we can refactor the +//! class to eliminate the inheritance and instead make the nvinfer1::ILogger implementation a member of the Logger +//! object. + +class Logger : public nvinfer1::ILogger +{ +public: + Logger(Severity severity = Severity::kWARNING) + : mReportableSeverity(severity) + { + } + + //! + //! \enum TestResult + //! \brief Represents the state of a given test + //! + enum class TestResult + { + kRUNNING, //!< The test is running + kPASSED, //!< The test passed + kFAILED, //!< The test failed + kWAIVED //!< The test was waived + }; + + //! + //! \brief Forward-compatible method for retrieving the nvinfer::ILogger associated with this Logger + //! \return The nvinfer1::ILogger associated with this Logger + //! + //! TODO Once all samples are updated to use this method to register the logger with TensorRT, + //! we can eliminate the inheritance of Logger from ILogger + //! + nvinfer1::ILogger& getTRTLogger() + { + return *this; + } + + //! + //! \brief Implementation of the nvinfer1::ILogger::log() virtual method + //! + //! Note samples should not be calling this function directly; it will eventually go away once we eliminate the + //! inheritance from nvinfer1::ILogger + //! + void log(Severity severity, const char* msg) noexcept override + { + LogStreamConsumer(mReportableSeverity, severity) << "[TRT] " << std::string(msg) << std::endl; + } + + //! + //! \brief Method for controlling the verbosity of logging output + //! + //! \param severity The logger will only emit messages that have severity of this level or higher. + //! + void setReportableSeverity(Severity severity) + { + mReportableSeverity = severity; + } + + //! + //! \brief Opaque handle that holds logging information for a particular test + //! + //! This object is an opaque handle to information used by the Logger to print test results. + //! The sample must call Logger::defineTest() in order to obtain a TestAtom that can be used + //! with Logger::reportTest{Start,End}(). + //! + class TestAtom + { + public: + TestAtom(TestAtom&&) = default; + + private: + friend class Logger; + + TestAtom(bool started, const std::string& name, const std::string& cmdline) + : mStarted(started) + , mName(name) + , mCmdline(cmdline) + { + } + + bool mStarted; + std::string mName; + std::string mCmdline; + }; + + //! + //! \brief Define a test for logging + //! + //! \param[in] name The name of the test. This should be a string starting with + //! "TensorRT" and containing dot-separated strings containing + //! the characters [A-Za-z0-9_]. + //! For example, "TensorRT.sample_googlenet" + //! \param[in] cmdline The command line used to reproduce the test + // + //! \return a TestAtom that can be used in Logger::reportTest{Start,End}(). + //! + static TestAtom defineTest(const std::string& name, const std::string& cmdline) + { + return TestAtom(false, name, cmdline); + } + + //! + //! \brief A convenience overloaded version of defineTest() that accepts an array of command-line arguments + //! as input + //! + //! \param[in] name The name of the test + //! \param[in] argc The number of command-line arguments + //! \param[in] argv The array of command-line arguments (given as C strings) + //! + //! \return a TestAtom that can be used in Logger::reportTest{Start,End}(). + static TestAtom defineTest(const std::string& name, int argc, char const* const* argv) + { + auto cmdline = genCmdlineString(argc, argv); + return defineTest(name, cmdline); + } + + //! + //! \brief Report that a test has started. + //! + //! \pre reportTestStart() has not been called yet for the given testAtom + //! + //! \param[in] testAtom The handle to the test that has started + //! + static void reportTestStart(TestAtom& testAtom) + { + reportTestResult(testAtom, TestResult::kRUNNING); + assert(!testAtom.mStarted); + testAtom.mStarted = true; + } + + //! + //! \brief Report that a test has ended. + //! + //! \pre reportTestStart() has been called for the given testAtom + //! + //! \param[in] testAtom The handle to the test that has ended + //! \param[in] result The result of the test. Should be one of TestResult::kPASSED, + //! TestResult::kFAILED, TestResult::kWAIVED + //! + static void reportTestEnd(const TestAtom& testAtom, TestResult result) + { + assert(result != TestResult::kRUNNING); + assert(testAtom.mStarted); + reportTestResult(testAtom, result); + } + + static int reportPass(const TestAtom& testAtom) + { + reportTestEnd(testAtom, TestResult::kPASSED); + return EXIT_SUCCESS; + } + + static int reportFail(const TestAtom& testAtom) + { + reportTestEnd(testAtom, TestResult::kFAILED); + return EXIT_FAILURE; + } + + static int reportWaive(const TestAtom& testAtom) + { + reportTestEnd(testAtom, TestResult::kWAIVED); + return EXIT_SUCCESS; + } + + static int reportTest(const TestAtom& testAtom, bool pass) + { + return pass ? reportPass(testAtom) : reportFail(testAtom); + } + + Severity getReportableSeverity() const + { + return mReportableSeverity; + } + +private: + //! + //! \brief returns an appropriate string for prefixing a log message with the given severity + //! + static const char* severityPrefix(Severity severity) + { + switch (severity) + { + case Severity::kINTERNAL_ERROR: return "[F] "; + case Severity::kERROR: return "[E] "; + case Severity::kWARNING: return "[W] "; + case Severity::kINFO: return "[I] "; + case Severity::kVERBOSE: return "[V] "; + default: assert(0); return ""; + } + } + + //! + //! \brief returns an appropriate string for prefixing a test result message with the given result + //! + static const char* testResultString(TestResult result) + { + switch (result) + { + case TestResult::kRUNNING: return "RUNNING"; + case TestResult::kPASSED: return "PASSED"; + case TestResult::kFAILED: return "FAILED"; + case TestResult::kWAIVED: return "WAIVED"; + default: assert(0); return ""; + } + } + + //! + //! \brief returns an appropriate output stream (cout or cerr) to use with the given severity + //! + static std::ostream& severityOstream(Severity severity) + { + return severity >= Severity::kINFO ? std::cout : std::cerr; + } + + //! + //! \brief method that implements logging test results + //! + static void reportTestResult(const TestAtom& testAtom, TestResult result) + { + severityOstream(Severity::kINFO) << "&&&& " << testResultString(result) << " " << testAtom.mName << " # " + << testAtom.mCmdline << std::endl; + } + + //! + //! \brief generate a command line string from the given (argc, argv) values + //! + static std::string genCmdlineString(int argc, char const* const* argv) + { + std::stringstream ss; + for (int i = 0; i < argc; i++) + { + if (i > 0) + ss << " "; + ss << argv[i]; + } + return ss.str(); + } + + Severity mReportableSeverity; +}; + +namespace +{ + +//! +//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kVERBOSE +//! +//! Example usage: +//! +//! LOG_VERBOSE(logger) << "hello world" << std::endl; +//! +inline LogStreamConsumer LOG_VERBOSE(const Logger& logger) +{ + return LogStreamConsumer(logger.getReportableSeverity(), Severity::kVERBOSE); +} + +//! +//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINFO +//! +//! Example usage: +//! +//! LOG_INFO(logger) << "hello world" << std::endl; +//! +inline LogStreamConsumer LOG_INFO(const Logger& logger) +{ + return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINFO); +} + +//! +//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kWARNING +//! +//! Example usage: +//! +//! LOG_WARN(logger) << "hello world" << std::endl; +//! +inline LogStreamConsumer LOG_WARN(const Logger& logger) +{ + return LogStreamConsumer(logger.getReportableSeverity(), Severity::kWARNING); +} + +//! +//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kERROR +//! +//! Example usage: +//! +//! LOG_ERROR(logger) << "hello world" << std::endl; +//! +inline LogStreamConsumer LOG_ERROR(const Logger& logger) +{ + return LogStreamConsumer(logger.getReportableSeverity(), Severity::kERROR); +} + +//! +//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINTERNAL_ERROR +// ("fatal" severity) +//! +//! Example usage: +//! +//! LOG_FATAL(logger) << "hello world" << std::endl; +//! +inline LogStreamConsumer LOG_FATAL(const Logger& logger) +{ + return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINTERNAL_ERROR); +} + +} // anonymous namespace + +#endif // TENSORRT_LOGGING_H diff --git a/yolo+ByteTrack/yoloTest/main.cpp b/yolo+ByteTrack/yoloTest/main.cpp new file mode 100644 index 0000000..6613449 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/main.cpp @@ -0,0 +1,241 @@ +#include "yolo.h" +#include "kalmanFilter.h" +#include +#include +#include +#include +#include "BYTETracker.h" +using namespace std; +using namespace cv; +using namespace cv::dnn; + +int main() +{ + string img_path = "D:/VS/yoloTest/images/detect.mp4"; + string model_path = "D:/VS/yoloTest/models/yolov5s.onnx"; + + // Yolov5ģͺ͸ + Yolov5 yolo; + Net net; + BYTETracker tracker(30, 30); // Sort + + // ȡYoloģ + if (!yolo.readModel(net, model_path, true)) { + cout << "޷Yoloģ" << endl; + return -1; + } + + // ɫÿӦһɫ + vector colors; + srand(42); // ̶ӣȷÿɫһ + for (int i = 0; i < 80; i++) { // 80 + int b = rand() % 256; + int g = rand() % 256; + int r = rand() % 256; + colors.push_back(Scalar(b, g, r)); + } + + // ȡƵ + VideoCapture cap(img_path); + if (!cap.isOpened()) { + cout << "޷Ƶļ" << endl; + return -1; + } + + VideoWriter writer; + writer = VideoWriter("D:/VS/yoloTest/images/test.mp4", CAP_OPENCV_MJPEG, 30, Size(1920, 1080), true); + + clock_t start, end; //ʱ + start = clock(); + int num = 0; + + Mat frame; + int frame_counter = 0; + int detect_interval = 3; // ÿ֡µһYOLOм + vector detection_rects; + vector objects; + + while (cap.read(frame)) { + if (frame.empty()) { + cout << "Ƶѽ" << endl; + break; + } + + vector result; + + // ÿ detect_interval ֡һ YOLO + if (frame_counter % detect_interval == 0) { + detection_rects.clear(); // ֮ǰļ + objects.clear(); + + // Ŀ + if (yolo.Detect(frame, net, result)) { + for (int i = 0; i < result.size(); i++) { + int x = result[i].box.x; + int y = result[i].box.y; + int w = result[i].box.width; + int h = result[i].box.height; + Rect rect(x, y, w, h); + Object object; + object.label = result[i].id; + object.prob = result[i].confidence; + object.rect = rect; + objects.push_back(object); + } + } + + // ݸ SORT гʼ + vector object_trackers = tracker.update(objects); + // Ƹٽ + vector> trackers; + for (int i = 0; i < object_trackers.size(); i++) { + trackers.push_back(object_trackers[i].tlwh); + } + + + for (int i = 0; i < trackers.size(); i++) { + Rect rect(trackers[i][0], trackers[i][1], trackers[i][2], trackers[i][3]); + + // ȡŶ + // ǼŶûб仯 + int class_id = 0; // ID Ϊ 0ʾ + float confidence = 0.8f; // ŶΪ 0.8ʾ + + // ʹɫлȡɫ + Scalar color = colors[class_id % colors.size()]; // ʹɫеɫ + + // ǩݣ + Ŷ + string label = "box"; + + // ƾοǩ + rectangle(frame, rect, color, 2); // ƾο + putText(frame, label, Point(rect.x, rect.y), FONT_HERSHEY_SIMPLEX, 1, color, 2); // ʾƺŶ + } + } + else { + // Ǽ֡ʹ SORT ĿԤ͸ + vector object_trackers = tracker.update(objects); + // Ƹٽ + vector> trackers; + for (int i = 0; i < object_trackers.size(); i++) { + trackers.push_back(object_trackers[i].tlwh); + } + + // Ƹٽ + for (int i = 0; i < trackers.size(); i++) { + Rect rect(trackers[i][0], trackers[i][1], trackers[i][2], trackers[i][3]); + + // ȡŶ + // ǼŶûб仯 + int class_id = 0; // ID Ϊ 0ʾ + float confidence = 0.8f; // ŶΪ 0.8ʾ + + // ʹɫлȡɫ + Scalar color = colors[class_id % colors.size()]; // ʹɫеɫ + + // ǩݣ + Ŷ + string label = "box"; + + // ƾοǩ + rectangle(frame, rect, color, 2); // ƾο + putText(frame, label, Point(rect.x, rect.y), FONT_HERSHEY_SIMPLEX, 1, color, 2); // ʾƺŶ + } + } + + // ʾ֡ + imshow("img", frame); + writer << frame; + + if (waitKey(10) == 27) { + break; // ˳ѭ + } + + frame_counter++; + num++; + } + + end = clock(); + cout << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; // ʱ䣨λs + cout << "frame num: " << num << endl; + cout << "Speed = " << double(end - start) * 1000 / CLOCKS_PER_SEC / num << "ms" << endl; // ʱ䣨λms + + cap.release(); + destroyAllWindows(); + writer.release(); + + return 0; +} + +/* +#include "yolo.h" +#include +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace dnn; + +int main() +{ + string img_path = "D:/VS/yoloTest/images/2.mp4"; + string model = "D:/VS/yoloTest/models/yolov5s.onnx"; + + Yolov5 test; + Net net; + if (test.readModel(net, model, false)) { + cout << "read net ok!" << endl; + } + else { + return -1; + } + + //ɫ + vector color; + srand(time(0)); + for (int i = 0; i < 80; i++) { + int b = rand() % 256; + int g = rand() % 256; + int r = rand() % 256; + color.push_back(Scalar(b, g, r)); + } + vector result; + + VideoCapture cap(img_path); //ȡͼ/Ƶ + + VideoWriter writer; + writer = VideoWriter("D:/VS/yoloTest/images/test.mp4", CAP_OPENCV_MJPEG, 20, Size(2560, 1440), true); //ΪƵ + + clock_t start, end; //ʱ + start = clock(); + int num = 0; + + Mat frame; + while (cap.read(frame)) { + + vector result; + if (test.Detect(frame, net, result)) { + test.drawPred(frame, result, color); + } + + imshow("img", frame); + writer << frame; + if (waitKey(10) == 27) { + break; // ˳ѭ + } + num++; + } + end = clock(); + cout << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; //ʱ䣨λ + cout << "frame num: " << num << endl; + cout << "Speed = " << double(end - start)*1000 / CLOCKS_PER_SEC/num << "ms" << endl; //ʱ䣨λm + + cap.release(); + destroyAllWindows(); + + system("pause"); + return 0; +} + +*/ \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/utils.cpp b/yolo+ByteTrack/yoloTest/utils.cpp new file mode 100644 index 0000000..4aa0305 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/utils.cpp @@ -0,0 +1,429 @@ +#include "BYTETracker.h" +#include "lapjv.h" + +vector BYTETracker::joint_stracks(vector &tlista, vector &tlistb) +{ + map exists; + vector res; + for (int i = 0; i < tlista.size(); i++) + { + exists.insert(pair(tlista[i]->track_id, 1)); + res.push_back(tlista[i]); + } + for (int i = 0; i < tlistb.size(); i++) + { + int tid = tlistb[i].track_id; + if (!exists[tid] || exists.count(tid) == 0) + { + exists[tid] = 1; + res.push_back(&tlistb[i]); + } + } + return res; +} + +vector BYTETracker::joint_stracks(vector &tlista, vector &tlistb) +{ + map exists; + vector res; + for (int i = 0; i < tlista.size(); i++) + { + exists.insert(pair(tlista[i].track_id, 1)); + res.push_back(tlista[i]); + } + for (int i = 0; i < tlistb.size(); i++) + { + int tid = tlistb[i].track_id; + if (!exists[tid] || exists.count(tid) == 0) + { + exists[tid] = 1; + res.push_back(tlistb[i]); + } + } + return res; +} + +vector BYTETracker::sub_stracks(vector &tlista, vector &tlistb) +{ + map stracks; + for (int i = 0; i < tlista.size(); i++) + { + stracks.insert(pair(tlista[i].track_id, tlista[i])); + } + for (int i = 0; i < tlistb.size(); i++) + { + int tid = tlistb[i].track_id; + if (stracks.count(tid) != 0) + { + stracks.erase(tid); + } + } + + vector res; + std::map::iterator it; + for (it = stracks.begin(); it != stracks.end(); ++it) + { + res.push_back(it->second); + } + + return res; +} + +void BYTETracker::remove_duplicate_stracks(vector &resa, vector &resb, vector &stracksa, vector &stracksb) +{ + vector > pdist = iou_distance(stracksa, stracksb); + vector > pairs; + for (int i = 0; i < pdist.size(); i++) + { + for (int j = 0; j < pdist[i].size(); j++) + { + if (pdist[i][j] < 0.15) + { + pairs.push_back(pair(i, j)); + } + } + } + + vector dupa, dupb; + for (int i = 0; i < pairs.size(); i++) + { + int timep = stracksa[pairs[i].first].frame_id - stracksa[pairs[i].first].start_frame; + int timeq = stracksb[pairs[i].second].frame_id - stracksb[pairs[i].second].start_frame; + if (timep > timeq) + dupb.push_back(pairs[i].second); + else + dupa.push_back(pairs[i].first); + } + + for (int i = 0; i < stracksa.size(); i++) + { + vector::iterator iter = find(dupa.begin(), dupa.end(), i); + if (iter == dupa.end()) + { + resa.push_back(stracksa[i]); + } + } + + for (int i = 0; i < stracksb.size(); i++) + { + vector::iterator iter = find(dupb.begin(), dupb.end(), i); + if (iter == dupb.end()) + { + resb.push_back(stracksb[i]); + } + } +} + +void BYTETracker::linear_assignment(vector > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh, + vector > &matches, vector &unmatched_a, vector &unmatched_b) +{ + if (cost_matrix.size() == 0) + { + for (int i = 0; i < cost_matrix_size; i++) + { + unmatched_a.push_back(i); + } + for (int i = 0; i < cost_matrix_size_size; i++) + { + unmatched_b.push_back(i); + } + return; + } + + vector rowsol; vector colsol; + float c = lapjv(cost_matrix, rowsol, colsol, true, thresh); + for (int i = 0; i < rowsol.size(); i++) + { + if (rowsol[i] >= 0) + { + vector match; + match.push_back(i); + match.push_back(rowsol[i]); + matches.push_back(match); + } + else + { + unmatched_a.push_back(i); + } + } + + for (int i = 0; i < colsol.size(); i++) + { + if (colsol[i] < 0) + { + unmatched_b.push_back(i); + } + } +} + +vector > BYTETracker::ious(vector > &atlbrs, vector > &btlbrs) +{ + vector > ious; + if (atlbrs.size()*btlbrs.size() == 0) + return ious; + + ious.resize(atlbrs.size()); + for (int i = 0; i < ious.size(); i++) + { + ious[i].resize(btlbrs.size()); + } + + //bbox_ious + for (int k = 0; k < btlbrs.size(); k++) + { + vector ious_tmp; + float box_area = (btlbrs[k][2] - btlbrs[k][0] + 1)*(btlbrs[k][3] - btlbrs[k][1] + 1); + for (int n = 0; n < atlbrs.size(); n++) + { + float iw = min(atlbrs[n][2], btlbrs[k][2]) - max(atlbrs[n][0], btlbrs[k][0]) + 1; + if (iw > 0) + { + float ih = min(atlbrs[n][3], btlbrs[k][3]) - max(atlbrs[n][1], btlbrs[k][1]) + 1; + if(ih > 0) + { + float ua = (atlbrs[n][2] - atlbrs[n][0] + 1)*(atlbrs[n][3] - atlbrs[n][1] + 1) + box_area - iw * ih; + ious[n][k] = iw * ih / ua; + } + else + { + ious[n][k] = 0.0; + } + } + else + { + ious[n][k] = 0.0; + } + } + } + + return ious; +} + +vector > BYTETracker::iou_distance(vector &atracks, vector &btracks, int &dist_size, int &dist_size_size) +{ + vector > cost_matrix; + if (atracks.size() * btracks.size() == 0) + { + dist_size = atracks.size(); + dist_size_size = btracks.size(); + return cost_matrix; + } + vector > atlbrs, btlbrs; + for (int i = 0; i < atracks.size(); i++) + { + atlbrs.push_back(atracks[i]->tlbr); + } + for (int i = 0; i < btracks.size(); i++) + { + btlbrs.push_back(btracks[i].tlbr); + } + + dist_size = atracks.size(); + dist_size_size = btracks.size(); + + vector > _ious = ious(atlbrs, btlbrs); + + for (int i = 0; i < _ious.size();i++) + { + vector _iou; + for (int j = 0; j < _ious[i].size(); j++) + { + _iou.push_back(1 - _ious[i][j]); + } + cost_matrix.push_back(_iou); + } + + return cost_matrix; +} + +vector > BYTETracker::iou_distance(vector &atracks, vector &btracks) +{ + vector > atlbrs, btlbrs; + for (int i = 0; i < atracks.size(); i++) + { + atlbrs.push_back(atracks[i].tlbr); + } + for (int i = 0; i < btracks.size(); i++) + { + btlbrs.push_back(btracks[i].tlbr); + } + + vector > _ious = ious(atlbrs, btlbrs); + vector > cost_matrix; + for (int i = 0; i < _ious.size(); i++) + { + vector _iou; + for (int j = 0; j < _ious[i].size(); j++) + { + _iou.push_back(1 - _ious[i][j]); + } + cost_matrix.push_back(_iou); + } + + return cost_matrix; +} + +double BYTETracker::lapjv(const vector > &cost, vector &rowsol, vector &colsol, + bool extend_cost, float cost_limit, bool return_cost) +{ + vector > cost_c; + cost_c.assign(cost.begin(), cost.end()); + + vector > cost_c_extended; + + int n_rows = cost.size(); + int n_cols = cost[0].size(); + rowsol.resize(n_rows); + colsol.resize(n_cols); + + int n = 0; + if (n_rows == n_cols) + { + n = n_rows; + } + else + { + if (!extend_cost) + { + cout << "set extend_cost=True" << endl; + system("pause"); + exit(0); + } + } + + if (extend_cost || cost_limit < LONG_MAX) + { + n = n_rows + n_cols; + cost_c_extended.resize(n); + for (int i = 0; i < cost_c_extended.size(); i++) + cost_c_extended[i].resize(n); + + if (cost_limit < LONG_MAX) + { + for (int i = 0; i < cost_c_extended.size(); i++) + { + for (int j = 0; j < cost_c_extended[i].size(); j++) + { + cost_c_extended[i][j] = cost_limit / 2.0; + } + } + } + else + { + float cost_max = -1; + for (int i = 0; i < cost_c.size(); i++) + { + for (int j = 0; j < cost_c[i].size(); j++) + { + if (cost_c[i][j] > cost_max) + cost_max = cost_c[i][j]; + } + } + for (int i = 0; i < cost_c_extended.size(); i++) + { + for (int j = 0; j < cost_c_extended[i].size(); j++) + { + cost_c_extended[i][j] = cost_max + 1; + } + } + } + + for (int i = n_rows; i < cost_c_extended.size(); i++) + { + for (int j = n_cols; j < cost_c_extended[i].size(); j++) + { + cost_c_extended[i][j] = 0; + } + } + for (int i = 0; i < n_rows; i++) + { + for (int j = 0; j < n_cols; j++) + { + cost_c_extended[i][j] = cost_c[i][j]; + } + } + + cost_c.clear(); + cost_c.assign(cost_c_extended.begin(), cost_c_extended.end()); + } + + double **cost_ptr; + cost_ptr = new double *[sizeof(double *) * n]; + for (int i = 0; i < n; i++) + cost_ptr[i] = new double[sizeof(double) * n]; + + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + { + cost_ptr[i][j] = cost_c[i][j]; + } + } + + int* x_c = new int[sizeof(int) * n]; + int *y_c = new int[sizeof(int) * n]; + + int ret = lapjv_internal(n, cost_ptr, x_c, y_c); + if (ret != 0) + { + cout << "Calculate Wrong!" << endl; + system("pause"); + exit(0); + } + + double opt = 0.0; + + if (n != n_rows) + { + for (int i = 0; i < n; i++) + { + if (x_c[i] >= n_cols) + x_c[i] = -1; + if (y_c[i] >= n_rows) + y_c[i] = -1; + } + for (int i = 0; i < n_rows; i++) + { + rowsol[i] = x_c[i]; + } + for (int i = 0; i < n_cols; i++) + { + colsol[i] = y_c[i]; + } + + if (return_cost) + { + for (int i = 0; i < rowsol.size(); i++) + { + if (rowsol[i] != -1) + { + //cout << i << "\t" << rowsol[i] << "\t" << cost_ptr[i][rowsol[i]] << endl; + opt += cost_ptr[i][rowsol[i]]; + } + } + } + } + else if (return_cost) + { + for (int i = 0; i < rowsol.size(); i++) + { + opt += cost_ptr[i][rowsol[i]]; + } + } + + for (int i = 0; i < n; i++) + { + delete[]cost_ptr[i]; + } + delete[]cost_ptr; + delete[]x_c; + delete[]y_c; + + return opt; +} + +Scalar BYTETracker::get_color(int idx) +{ + idx += 3; + return Scalar(37 * idx % 255, 17 * idx % 255, 29 * idx % 255); +} \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/main.obj b/yolo+ByteTrack/yoloTest/x64/Debug/main.obj new file mode 100644 index 0000000..80754f4 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/main.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/vc143.idb b/yolo+ByteTrack/yoloTest/x64/Debug/vc143.idb new file mode 100644 index 0000000..440e745 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/vc143.idb differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/vc143.pdb b/yolo+ByteTrack/yoloTest/x64/Debug/vc143.pdb new file mode 100644 index 0000000..2c64f10 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/vc143.pdb differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yolo.obj b/yolo+ByteTrack/yoloTest/x64/Debug/yolo.obj new file mode 100644 index 0000000..7af00d5 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yolo.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.exe.recipe b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.exe.recipe new file mode 100644 index 0000000..b8d7a61 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.exe.recipe @@ -0,0 +1,11 @@ + + + + + D:\VS\yoloTest\x64\Debug\yoloTest.exe + + + + + + \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.ilk b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.ilk new file mode 100644 index 0000000..6a4b9f1 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.ilk differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.log b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.log new file mode 100644 index 0000000..15fb7a6 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.log @@ -0,0 +1,5 @@ + yoloTest.cpp +D:\VS\yoloTest\yoloTest\yolo.h(43,24): warning C4305: “初始化”: 从“double”到“float”截断 + (编译源文件“yoloTest.cpp”) + + yoloTest.vcxproj -> D:\VS\yoloTest\x64\Debug\yoloTest.exe diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.obj b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.obj new file mode 100644 index 0000000..6439c56 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.command.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.command.1.tlog new file mode 100644 index 0000000..d83bacc Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.command.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.read.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.read.1.tlog new file mode 100644 index 0000000..da1c733 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.read.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.write.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.write.1.tlog new file mode 100644 index 0000000..b7a9ab9 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/CL.write.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/Cl.items.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/Cl.items.tlog new file mode 100644 index 0000000..c917a3c --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/Cl.items.tlog @@ -0,0 +1,2 @@ +D:\VS\yoloTest\yoloTest\yoloTest.cpp;D:\VS\yoloTest\yoloTest\x64\Debug\yoloTest.obj +D:\VS\yoloTest\yoloTest\yolo.cpp;D:\VS\yoloTest\yoloTest\x64\Debug\yolo.obj diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.command.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.command.1.tlog new file mode 100644 index 0000000..cf7e593 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.command.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.read.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.read.1.tlog new file mode 100644 index 0000000..e7cc26f Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.read.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.write.1.tlog b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.write.1.tlog new file mode 100644 index 0000000..50b7ad6 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/link.write.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/yoloTest.lastbuildstate b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/yoloTest.lastbuildstate new file mode 100644 index 0000000..6b0f3cd --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Debug/yoloTest.tlog/yoloTest.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.38.33130:TargetPlatformVersion=10.0.22621.0: +Debug|x64|D:\VS\yoloTest\| diff --git a/yolo+ByteTrack/yoloTest/x64/Release/BYTETracker.obj b/yolo+ByteTrack/yoloTest/x64/Release/BYTETracker.obj new file mode 100644 index 0000000..b42abe7 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/BYTETracker.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/STrack.obj b/yolo+ByteTrack/yoloTest/x64/Release/STrack.obj new file mode 100644 index 0000000..db21fd1 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/STrack.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/bytetrack.obj b/yolo+ByteTrack/yoloTest/x64/Release/bytetrack.obj new file mode 100644 index 0000000..71c2034 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/bytetrack.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/dirent.obj b/yolo+ByteTrack/yoloTest/x64/Release/dirent.obj new file mode 100644 index 0000000..07af44f Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/dirent.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/kalmanFilter.obj b/yolo+ByteTrack/yoloTest/x64/Release/kalmanFilter.obj new file mode 100644 index 0000000..60410e5 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/kalmanFilter.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/lapjv.obj b/yolo+ByteTrack/yoloTest/x64/Release/lapjv.obj new file mode 100644 index 0000000..edb0c09 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/lapjv.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/main.obj b/yolo+ByteTrack/yoloTest/x64/Release/main.obj new file mode 100644 index 0000000..b55b644 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/main.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/utils.obj b/yolo+ByteTrack/yoloTest/x64/Release/utils.obj new file mode 100644 index 0000000..d9334f5 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/utils.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/vc143.pdb b/yolo+ByteTrack/yoloTest/x64/Release/vc143.pdb new file mode 100644 index 0000000..73bf10c Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/vc143.pdb differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yolo.obj b/yolo+ByteTrack/yoloTest/x64/Release/yolo.obj new file mode 100644 index 0000000..a2090c9 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yolo.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.exe.recipe b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.exe.recipe new file mode 100644 index 0000000..3ebac7b --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.exe.recipe @@ -0,0 +1,11 @@ + + + + + D:\VS\yoloTest\x64\Release\yoloTest.exe + + + + + + \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.iobj b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.iobj new file mode 100644 index 0000000..60ca206 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.iobj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.ipdb b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.ipdb new file mode 100644 index 0000000..b58c97d Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.ipdb differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.log b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.log new file mode 100644 index 0000000..5728592 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.log @@ -0,0 +1,91 @@ + main.cpp +D:\VS\yoloTest\yoloTest\yolo.h(43,24): warning C4305: “初始化”: 从“double”到“float”截断 + (编译源文件“main.cpp”) + +D:\VS\eigen3\Eigen\src\Core\arch\Default\Half.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 + (编译源文件“main.cpp”) + +D:\VS\eigen3\Eigen\src\Core\arch\Default\BFloat16.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 + (编译源文件“main.cpp”) + +D:\VS\eigen3\Eigen\src\Core\arch\Default\GenericPacketMathFunctions.h(676,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 + (编译源文件“main.cpp”) + +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(97,88): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(97,72): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(97,56): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(97,40): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(126,88): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(126,72): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(126,56): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: “参数”: 从“_Ty”转换到“_Tp”,可能丢失数据 +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: with +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: _Ty=float +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: ] +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: and +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: [ +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: _Tp=int +D:\VS\yoloTest\yoloTest\main.cpp(126,40): warning C4244: ] + 正在生成代码 + 1 of 7465 functions (<0.1%) were compiled, the rest were copied from previous compilation. + 0 functions were new in current compilation + 425 functions had inline decision re-evaluated but remain unchanged + 已完成代码的生成 + yoloTest.vcxproj -> D:\VS\yoloTest\x64\Release\yoloTest.exe diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.obj b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.obj new file mode 100644 index 0000000..be00551 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.obj differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.command.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.command.1.tlog new file mode 100644 index 0000000..8dbff7a Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.command.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.read.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.read.1.tlog new file mode 100644 index 0000000..0ca87aa Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.read.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.write.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.write.1.tlog new file mode 100644 index 0000000..44169fa Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/CL.write.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/Cl.items.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/Cl.items.tlog new file mode 100644 index 0000000..8b6dd1d --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/Cl.items.tlog @@ -0,0 +1,8 @@ +D:\VS\yoloTest\yoloTest\bytetrack.cpp;D:\VS\yoloTest\yoloTest\x64\Release\bytetrack.obj +D:\VS\yoloTest\yoloTest\BYTETracker.cpp;D:\VS\yoloTest\yoloTest\x64\Release\BYTETracker.obj +D:\VS\yoloTest\yoloTest\kalmanFilter.cpp;D:\VS\yoloTest\yoloTest\x64\Release\kalmanFilter.obj +D:\VS\yoloTest\yoloTest\lapjv.cpp;D:\VS\yoloTest\yoloTest\x64\Release\lapjv.obj +D:\VS\yoloTest\yoloTest\main.cpp;D:\VS\yoloTest\yoloTest\x64\Release\main.obj +D:\VS\yoloTest\yoloTest\STrack.cpp;D:\VS\yoloTest\yoloTest\x64\Release\STrack.obj +D:\VS\yoloTest\yoloTest\utils.cpp;D:\VS\yoloTest\yoloTest\x64\Release\utils.obj +D:\VS\yoloTest\yoloTest\yolo.cpp;D:\VS\yoloTest\yoloTest\x64\Release\yolo.obj diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.command.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.command.1.tlog new file mode 100644 index 0000000..d03f79f Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.command.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.read.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.read.1.tlog new file mode 100644 index 0000000..2c3870e Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.read.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.write.1.tlog b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.write.1.tlog new file mode 100644 index 0000000..2610191 Binary files /dev/null and b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/link.write.1.tlog differ diff --git a/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/yoloTest.lastbuildstate b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/yoloTest.lastbuildstate new file mode 100644 index 0000000..a9f1030 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/x64/Release/yoloTest.tlog/yoloTest.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.38.33130:TargetPlatformVersion=10.0.22621.0: +Release|x64|D:\VS\yoloTest\| diff --git a/yolo+ByteTrack/yoloTest/yolo.cpp b/yolo+ByteTrack/yoloTest/yolo.cpp new file mode 100644 index 0000000..5e15303 --- /dev/null +++ b/yolo+ByteTrack/yoloTest/yolo.cpp @@ -0,0 +1,183 @@ +#include"yolo.h" +using namespace std; +using namespace cv; +using namespace cv::dnn; + +void Yolov5::LetterBox(const cv::Mat& image, cv::Mat& outImage, cv::Vec4d& params, const cv::Size& newShape, + bool autoShape, bool scaleFill, bool scaleUp, int stride, const cv::Scalar& color) +{ + if (false) { + int maxLen = MAX(image.rows, image.cols); + outImage = Mat::zeros(Size(maxLen, maxLen), CV_8UC3); + image.copyTo(outImage(Rect(0, 0, image.cols, image.rows))); + params[0] = 1; + params[1] = 1; + params[3] = 0; + params[2] = 0; + } + + cv::Size shape = image.size(); + float r = std::min((float)newShape.height / (float)shape.height, + (float)newShape.width / (float)shape.width); + if (!scaleUp) + r = std::min(r, 1.0f); + + float ratio[2]{ r, r }; + int new_un_pad[2] = { (int)std::round((float)shape.width * r),(int)std::round((float)shape.height * r) }; + + auto dw = (float)(newShape.width - new_un_pad[0]); + auto dh = (float)(newShape.height - new_un_pad[1]); + + if (autoShape) + { + dw = (float)((int)dw % stride); + dh = (float)((int)dh % stride); + } + else if (scaleFill) + { + dw = 0.0f; + dh = 0.0f; + new_un_pad[0] = newShape.width; + new_un_pad[1] = newShape.height; + ratio[0] = (float)newShape.width / (float)shape.width; + ratio[1] = (float)newShape.height / (float)shape.height; + } + + dw /= 2.0f; + dh /= 2.0f; + + if (shape.width != new_un_pad[0] && shape.height != new_un_pad[1]) + { + cv::resize(image, outImage, cv::Size(new_un_pad[0], new_un_pad[1])); + } + else { + outImage = image.clone(); + } + + int top = int(std::round(dh - 0.1f)); + int bottom = int(std::round(dh + 0.1f)); + int left = int(std::round(dw - 0.1f)); + int right = int(std::round(dw + 0.1f)); + params[0] = ratio[0]; + params[1] = ratio[1]; + params[2] = left; + params[3] = top; + cv::copyMakeBorder(outImage, outImage, top, bottom, left, right, cv::BORDER_CONSTANT, color); +} + + + +bool Yolov5::readModel(Net& net, string& netPath, bool isCuda = false) { + try { + + net = readNet(netPath); +#if CV_VERSION_MAJOR==4 &&CV_VERSION_MINOR==7&&CV_VERSION_REVISION==0 + net.enableWinograd(false); //bug of opencv4.7.x in AVX only platform ,https://github.com/opencv/opencv/pull/23112 and https://github.com/opencv/opencv/issues/23080 + //net.enableWinograd(true); //If your CPU supports AVX2, you can set it true to speed up +#endif + } + catch (const std::exception&) { + return false; + } + //cuda + if (isCuda) { + net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA); + net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA); + } + //cpu + else { + net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT); + net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU); + } + return true; +} +bool Yolov5::Detect(Mat& SrcImg, Net& net, vector& output) { + Mat blob; + int col = SrcImg.cols; + int row = SrcImg.rows; + int maxLen = MAX(col, row); + Mat netInputImg = SrcImg.clone(); + Vec4d params; + LetterBox(SrcImg, netInputImg, params, cv::Size(_netWidth, _netHeight)); + + blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(_netWidth, _netHeight), cv::Scalar(0, 0, 0), true, false); + //ûµǽƫܴ󣬿Գ + //blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(_netWidth, _netHeight), cv::Scalar(104, 117, 123), true, false); + //blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(_netWidth, _netHeight), cv::Scalar(114, 114,114), true, false); + net.setInput(blob); + std::vector netOutputImg; + vector outputLayerName{"345","403", "461","output" }; + net.forward(netOutputImg, outputLayerName[3]); //ȡoutput + //net.forward(netOutputImg, net.getUnconnectedOutLayersNames()); + std::vector classIds;//id + std::vector confidences;//ÿidӦŶ + std::vector boxes;//ÿidο + int net_width = _className.size() + 5; //+5 + int net_out_width = netOutputImg[0].size[2]; + assert(net_out_width == net_width, "Error Wrong number of _className"); //ģĿ + float* pdata = (float*)netOutputImg[0].data; + int net_height = netOutputImg[0].size[1]; + for (int r = 0; r < net_height; ++r) { + float box_score = pdata[4]; ;//ȡÿһеboxкijĸ + if (box_score >= _classThreshold) { + cv::Mat scores(1, _className.size(), CV_32FC1, pdata + 5); + Point classIdPoint; + double max_class_socre; + minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint); + max_class_socre = max_class_socre * box_score; + if (max_class_socre >= _classThreshold) { + //rect [x,y,w,h] + float x = (pdata[0] - params[2]) / params[0]; + float y = (pdata[1] - params[3]) / params[1]; + float w = pdata[2] / params[0]; + float h = pdata[3] / params[1]; + int left = MAX(round(x - 0.5 * w + 0.5), 0); + int top = MAX(round(y - 0.5 * h + 0.5), 0); + classIds.push_back(classIdPoint.x); + confidences.push_back(max_class_socre); + boxes.push_back(Rect(left, top, int(w + 0.5), int(h + 0.5))); + } + } + pdata += net_width;//һ + + } + + //ִзнϵŶȵصNMS + vector nms_result; + NMSBoxes(boxes, confidences, _classThreshold, _nmsThreshold, nms_result); + for (int i = 0; i < nms_result.size(); i++) { + int idx = nms_result[i]; + Output result; + result.id = classIds[idx]; + result.confidence = confidences[idx]; + result.box = boxes[idx]; + output.push_back(result); + } + if (output.size()) + return true; + else + return false; +} + +void Yolov5::drawPred(Mat& img, vector result, vector color) { + for (int i = 0; i < result.size(); i++) { + int left, top; + left = result[i].box.x; + top = result[i].box.y; + int color_num = i; + rectangle(img, result[i].box, color[result[i].id], 2, 8); + + string label = _className[result[i].id] + ":" + to_string(result[i].confidence); + + int baseLine; + Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + top = max(top, labelSize.height); + //rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED); + putText(img, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 1, color[result[i].id], 2); + } + //imshow("1", img); + //imwrite("out.bmp", img); + //waitKey(); + //destroyAllWindows(); + +} diff --git a/yoloSORT/yolo.h b/yolo+ByteTrack/yoloTest/yolo.h similarity index 100% rename from yoloSORT/yolo.h rename to yolo+ByteTrack/yoloTest/yolo.h diff --git a/yolo+ByteTrack/yoloTest/yoloTest.vcxproj b/yolo+ByteTrack/yoloTest/yoloTest.vcxproj new file mode 100644 index 0000000..87a378f --- /dev/null +++ b/yolo+ByteTrack/yoloTest/yoloTest.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {bbd2f21a-3013-475e-bd5a-66eb7f9d8ec9} + yoloTest + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + D:\VS\OpenCV\opencv\build\include;$(IncludePath) + D:\VS\OpenCV\opencv\build\x64\vc16\lib;$(LibraryPath) + + + D:\VS\OpenCV\opencv\build\include;D:\VS\eigen3;$(IncludePath) + D:\VS\OpenCV\opencv\build\x64\vc16\lib;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + opencv_world480.lib;opencv_world480d.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\include;D:\VS\TensorRT\TensorRT-8.5.1.7\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + opencv_world480.lib;opencv_world480d.lib;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\lib\x64\*.lib;D:\VS\TensorRT\TensorRT-8.5.1.7\lib\*.lib;%(AdditionalDependencies) + C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\lib\x64;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\lib;D:\VS\TensorRT\TensorRT-8.5.1.7\lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yolo+ByteTrack/yoloTest/yoloTest.vcxproj.filters b/yolo+ByteTrack/yoloTest/yoloTest.vcxproj.filters new file mode 100644 index 0000000..911541d --- /dev/null +++ b/yolo+ByteTrack/yoloTest/yoloTest.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/yoloSORT/yoloSORT.vcxproj.user b/yolo+ByteTrack/yoloTest/yoloTest.vcxproj.user similarity index 100% rename from yoloSORT/yoloSORT.vcxproj.user rename to yolo+ByteTrack/yoloTest/yoloTest.vcxproj.user diff --git a/yolo+SORT/README.md b/yolo+SORT/README.md new file mode 100644 index 0000000..0982a6c --- /dev/null +++ b/yolo+SORT/README.md @@ -0,0 +1,25 @@ +## Yolov5s+SORT(卡尔曼+匈牙利) + +利用目标跟踪对检测框进行预测的技术,对目标检测任务进行加速,在yolov5检测的帧之间穿插使用卡尔曼滤波进行目标检测框的预测,减少对模型的调用,实现目标检测帧率提升的目的。 + +#### 代码运行环境: + +| 开发环境 | Visual Studio 2022 | +| -------- | -------------------- | +| OpenCV | opencv-4.8.0-windows | +| 调用模型 | YOLOv5s 6.0 | + + + +#### 主要代码设置: + +main.py中 + +![img1](./images/img1.png) + +使用到的模型以及检测视频的路径。 + +![img2](./images/img2.png) + +模型的调用频率设置,设置为3表示帧率为3的倍数时进行模型的目标检测,其他时候使用预测的目标框。 + diff --git a/images/img1.png b/yolo+SORT/images/img1.png similarity index 100% rename from images/img1.png rename to yolo+SORT/images/img1.png diff --git a/images/img2.png b/yolo+SORT/images/img2.png similarity index 100% rename from images/img2.png rename to yolo+SORT/images/img2.png diff --git a/yolo+SORT/x64/Release/yoloSORT.exe b/yolo+SORT/x64/Release/yoloSORT.exe new file mode 100644 index 0000000..8418e9f Binary files /dev/null and b/yolo+SORT/x64/Release/yoloSORT.exe differ diff --git a/yolo+SORT/x64/Release/yoloSORT.pdb b/yolo+SORT/x64/Release/yoloSORT.pdb new file mode 100644 index 0000000..260f845 Binary files /dev/null and b/yolo+SORT/x64/Release/yoloSORT.pdb differ diff --git a/yoloSORT.sln b/yolo+SORT/yoloSORT.sln similarity index 100% rename from yoloSORT.sln rename to yolo+SORT/yoloSORT.sln diff --git a/yoloSORT/hungarian.cpp b/yolo+SORT/yoloSORT/hungarian.cpp similarity index 100% rename from yoloSORT/hungarian.cpp rename to yolo+SORT/yoloSORT/hungarian.cpp diff --git a/yoloSORT/hungarian.h b/yolo+SORT/yoloSORT/hungarian.h similarity index 100% rename from yoloSORT/hungarian.h rename to yolo+SORT/yoloSORT/hungarian.h diff --git a/yoloSORT/kalmanboxtracker.cpp b/yolo+SORT/yoloSORT/kalmanboxtracker.cpp similarity index 100% rename from yoloSORT/kalmanboxtracker.cpp rename to yolo+SORT/yoloSORT/kalmanboxtracker.cpp diff --git a/yoloSORT/kalmanboxtracker.h b/yolo+SORT/yoloSORT/kalmanboxtracker.h similarity index 100% rename from yoloSORT/kalmanboxtracker.h rename to yolo+SORT/yoloSORT/kalmanboxtracker.h diff --git a/yoloSORT/main.cpp b/yolo+SORT/yoloSORT/main.cpp similarity index 100% rename from yoloSORT/main.cpp rename to yolo+SORT/yoloSORT/main.cpp diff --git a/yoloSORT/sort.cpp b/yolo+SORT/yoloSORT/sort.cpp similarity index 100% rename from yoloSORT/sort.cpp rename to yolo+SORT/yoloSORT/sort.cpp diff --git a/yoloSORT/sort.h b/yolo+SORT/yoloSORT/sort.h similarity index 100% rename from yoloSORT/sort.h rename to yolo+SORT/yoloSORT/sort.h diff --git a/yoloSORT/utils.cpp b/yolo+SORT/yoloSORT/utils.cpp similarity index 100% rename from yoloSORT/utils.cpp rename to yolo+SORT/yoloSORT/utils.cpp diff --git a/yoloSORT/utils.h b/yolo+SORT/yoloSORT/utils.h similarity index 100% rename from yoloSORT/utils.h rename to yolo+SORT/yoloSORT/utils.h diff --git a/yoloSORT/x64/Release/hungarian.obj b/yolo+SORT/yoloSORT/x64/Release/hungarian.obj similarity index 100% rename from yoloSORT/x64/Release/hungarian.obj rename to yolo+SORT/yoloSORT/x64/Release/hungarian.obj diff --git a/yoloSORT/x64/Release/kalmanboxtracker.obj b/yolo+SORT/yoloSORT/x64/Release/kalmanboxtracker.obj similarity index 100% rename from yoloSORT/x64/Release/kalmanboxtracker.obj rename to yolo+SORT/yoloSORT/x64/Release/kalmanboxtracker.obj diff --git a/yoloSORT/x64/Release/main.obj b/yolo+SORT/yoloSORT/x64/Release/main.obj similarity index 100% rename from yoloSORT/x64/Release/main.obj rename to yolo+SORT/yoloSORT/x64/Release/main.obj diff --git a/yoloSORT/x64/Release/maintest.obj b/yolo+SORT/yoloSORT/x64/Release/maintest.obj similarity index 100% rename from yoloSORT/x64/Release/maintest.obj rename to yolo+SORT/yoloSORT/x64/Release/maintest.obj diff --git a/yoloSORT/x64/Release/sort.obj b/yolo+SORT/yoloSORT/x64/Release/sort.obj similarity index 100% rename from yoloSORT/x64/Release/sort.obj rename to yolo+SORT/yoloSORT/x64/Release/sort.obj diff --git a/yoloSORT/x64/Release/utils.obj b/yolo+SORT/yoloSORT/x64/Release/utils.obj similarity index 100% rename from yoloSORT/x64/Release/utils.obj rename to yolo+SORT/yoloSORT/x64/Release/utils.obj diff --git a/yoloSORT/x64/Release/vc143.pdb b/yolo+SORT/yoloSORT/x64/Release/vc143.pdb similarity index 100% rename from yoloSORT/x64/Release/vc143.pdb rename to yolo+SORT/yoloSORT/x64/Release/vc143.pdb diff --git a/yoloSORT/x64/Release/yolo.obj b/yolo+SORT/yoloSORT/x64/Release/yolo.obj similarity index 100% rename from yoloSORT/x64/Release/yolo.obj rename to yolo+SORT/yoloSORT/x64/Release/yolo.obj diff --git a/yoloSORT/x64/Release/yoloSORT.exe.recipe b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.exe.recipe similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.exe.recipe rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.exe.recipe diff --git a/yoloSORT/x64/Release/yoloSORT.iobj b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.iobj similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.iobj rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.iobj diff --git a/yoloSORT/x64/Release/yoloSORT.ipdb b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.ipdb similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.ipdb rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.ipdb diff --git a/yoloSORT/x64/Release/yoloSORT.log b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.log similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.log rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.log diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/CL.command.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.command.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/CL.command.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.command.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/CL.read.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.read.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/CL.read.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.read.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/CL.write.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.write.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/CL.write.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/CL.write.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/Cl.items.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/Cl.items.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/Cl.items.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/Cl.items.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/link.command.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.command.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/link.command.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.command.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/link.read.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.read.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/link.read.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.read.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/link.write.1.tlog b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.write.1.tlog similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/link.write.1.tlog rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/link.write.1.tlog diff --git a/yoloSORT/x64/Release/yoloSORT.tlog/yoloSORT.lastbuildstate b/yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/yoloSORT.lastbuildstate similarity index 100% rename from yoloSORT/x64/Release/yoloSORT.tlog/yoloSORT.lastbuildstate rename to yolo+SORT/yoloSORT/x64/Release/yoloSORT.tlog/yoloSORT.lastbuildstate diff --git a/yoloSORT/yolo.cpp b/yolo+SORT/yoloSORT/yolo.cpp similarity index 100% rename from yoloSORT/yolo.cpp rename to yolo+SORT/yoloSORT/yolo.cpp diff --git a/yolo+SORT/yoloSORT/yolo.h b/yolo+SORT/yoloSORT/yolo.h new file mode 100644 index 0000000..93d1ecd --- /dev/null +++ b/yolo+SORT/yoloSORT/yolo.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include + +#define YOLO_P6 false //ǷʹP6ģ + +struct Output { + int id; //id + float confidence; //Ŷ + cv::Rect box; //ο +}; + +class Yolov5 { +public: + Yolov5() { + } + ~Yolov5() {} + bool readModel(cv::dnn::Net& net, std::string& netPath, bool isCuda); + bool Detect(cv::Mat& SrcImg, cv::dnn::Net& net, std::vector& output); + void drawPred(cv::Mat& img, std::vector result, std::vector color); + +private: + + void LetterBox(const cv::Mat& image, cv::Mat& outImage, + cv::Vec4d& params, //[ratio_x,ratio_y,dw,dh] + const cv::Size& newShape = cv::Size(640, 640), + bool autoShape = false, + bool scaleFill = false, + bool scaleUp = true, + int stride = 32, + const cv::Scalar& color = cv::Scalar(114, 114, 114)); + +#if(defined YOLO_P6 && YOLO_P6==true) + const int _netWidth = 640; //ONNXͼƬ + const int _netHeight = 640; //ONNXͼƬ߶ +#else + + const int _netWidth = 640; //ONNXͼƬ + const int _netHeight = 640; //ONNXͼƬ߶ +#endif // YOLO_P6 + + float _classThreshold = 0.25; + float _nmsThreshold = 0.45; +public: + std::vector _className = { "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", + "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", + "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", + "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", + "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", + "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", + "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", + "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", + "hair drier", "toothbrush" }; +}; diff --git a/yoloSORT/yoloSORT.vcxproj b/yolo+SORT/yoloSORT/yoloSORT.vcxproj similarity index 100% rename from yoloSORT/yoloSORT.vcxproj rename to yolo+SORT/yoloSORT/yoloSORT.vcxproj diff --git a/yoloSORT/yoloSORT.vcxproj.filters b/yolo+SORT/yoloSORT/yoloSORT.vcxproj.filters similarity index 100% rename from yoloSORT/yoloSORT.vcxproj.filters rename to yolo+SORT/yoloSORT/yoloSORT.vcxproj.filters diff --git a/yolo+SORT/yoloSORT/yoloSORT.vcxproj.user b/yolo+SORT/yoloSORT/yoloSORT.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/yolo+SORT/yoloSORT/yoloSORT.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file