Skip to content

Commit 6ca6a58

Browse files
committed
Add yolov26
1 parent 6b5ab80 commit 6ca6a58

11 files changed

Lines changed: 710 additions & 10 deletions

data/settings_yolov26m.ini

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
[detection]
2+
3+
#-----------------------------
4+
# opencv_dnn = 6
5+
# tensorrt = 5
6+
detector_backend = 5
7+
8+
#-----------------------------
9+
# Target and backend for opencv_dnn detector
10+
# DNN_TARGET_CPU
11+
# DNN_TARGET_OPENCL
12+
# DNN_TARGET_OPENCL_FP16
13+
# DNN_TARGET_MYRIAD
14+
# DNN_TARGET_CUDA
15+
# DNN_TARGET_CUDA_FP16
16+
ocv_dnn_target = DNN_TARGET_CPU
17+
18+
# DNN_BACKEND_DEFAULT
19+
# DNN_BACKEND_HALIDE
20+
# DNN_BACKEND_INFERENCE_ENGINE
21+
# DNN_BACKEND_OPENCV
22+
# DNN_BACKEND_VKCOM
23+
# DNN_BACKEND_CUDA
24+
# DNN_BACKEND_INFERENCE_ENGINE_NGRAPH
25+
# DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019
26+
ocv_dnn_backend = DNN_BACKEND_INFERENCE_ENGINE
27+
28+
#-----------------------------
29+
nn_weights = C:/work/home/mtracker/Multitarget-tracker/data/coco/yolo26m.onnx
30+
nn_config = C:/work/home/mtracker/Multitarget-tracker/data/coco/yolo26m.onnx
31+
class_names = C:/work/home/mtracker/Multitarget-tracker/data/coco/coco.names
32+
33+
#-----------------------------
34+
confidence_threshold = 0.5
35+
36+
max_crop_ratio = 0
37+
max_batch = 1
38+
gpu_id = 0
39+
40+
#-----------------------------
41+
# YOLOV3
42+
# YOLOV4
43+
# YOLOV5
44+
net_type = YOLOV26
45+
46+
#-----------------------------
47+
# INT8
48+
# FP16
49+
# FP32
50+
inference_precision = FP16
51+
52+
53+
[tracking]
54+
55+
#-----------------------------
56+
# DistCenters = 0 // Euclidean distance between centers, pixels
57+
# DistRects = 1 // Euclidean distance between bounding rectangles, pixels
58+
# DistJaccard = 2 // Intersection over Union, IoU, [0, 1]
59+
# DistHist = 3 // Bhatacharia distance between histograms, [0, 1]
60+
61+
distance_type = 0
62+
63+
#-----------------------------
64+
# KalmanLinear = 0
65+
# KalmanUnscented = 1
66+
67+
kalman_type = 0
68+
69+
#-----------------------------
70+
# FilterCenter = 0
71+
# FilterRect = 1
72+
# FilterRRect = 2
73+
74+
filter_goal = 0
75+
76+
#-----------------------------
77+
# TrackNone = 0
78+
# TrackKCF = 1
79+
# TrackMIL = 2
80+
# TrackMedianFlow = 3
81+
# TrackGOTURN = 4
82+
# TrackMOSSE = 5
83+
# TrackCSRT = 6
84+
# TrackDAT = 7
85+
# TrackSTAPLE = 8
86+
# TrackLDES = 9
87+
# TrackDaSiamRPN = 10
88+
# Used if filter_goal == FilterRect
89+
90+
lost_track_type = 0
91+
92+
#-----------------------------
93+
# MatchHungrian = 0
94+
# MatchBipart = 1
95+
96+
match_type = 0
97+
98+
#-----------------------------
99+
# Use constant acceleration motion model:
100+
# 0 - unused (stable)
101+
# 1 - use acceleration in Kalman filter (experimental)
102+
use_aceleration = 0
103+
104+
#-----------------------------
105+
# Delta time for Kalman filter
106+
delta_time = 0.4
107+
108+
#-----------------------------
109+
# Accel noise magnitude for Kalman filter
110+
accel_noise = 0.2
111+
112+
#-----------------------------
113+
# Distance threshold between region and object on two frames
114+
dist_thresh = 0.8
115+
116+
#-----------------------------
117+
# If this value > 0 than will be used circle with this radius
118+
# If this value <= 0 than will be used ellipse with size (3*vx, 3*vy), vx and vy - horizontal and vertical speed in pixelsa
119+
min_area_radius_pix = -1
120+
121+
#-----------------------------
122+
# Minimal area radius in ration for object size. Used if min_area_radius_pix < 0
123+
min_area_radius_k = 0.8
124+
125+
#-----------------------------
126+
# If the object do not assignment more than this seconds then it will be removed
127+
max_lost_time = 2
128+
129+
#-----------------------------
130+
# The maximum trajectory length
131+
max_trace_len = 2
132+
133+
#-----------------------------
134+
# Detection abandoned objects
135+
detect_abandoned = 0
136+
# After this time (in seconds) the object is considered abandoned
137+
min_static_time = 5
138+
# After this time (in seconds) the abandoned object will be removed
139+
max_static_time = 25
140+
# Speed in pixels. If speed of object is more that this value than object is non static
141+
max_speed_for_static = 10

example/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int main(int argc, char** argv)
1515
const char* keys =
1616
{
1717
"{ @1 |../data/atrium.avi | movie file | }"
18-
"{ e example |1 | number of example 0 - MouseTracking, 1 - MotionDetector, 3 - YOLO TensorRT Detector, 4 - Cars counting | }"
18+
"{ e example |1 | number of example 0 - MouseTracking, 1 - MotionDetector, 2 - opencv_dnn detector, 3 - YOLO TensorRT Detector, 4 - Cars counting | }"
1919
"{ sf start_frame |0 | Start a video from this position | }"
2020
"{ ef end_frame |0 | Play a video to this position (if 0 then played to the end of file) | }"
2121
"{ ed end_delay |0 | Delay in milliseconds after video ending | }"

src/Detector/OCVDNNDetector.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ bool OCVDNNDetector::Init(const config_t& config)
173173
dictNetType["DFINE"] = ModelType::DFINE;
174174
dictNetType["YOLOV13"] = ModelType::YOLOV13;
175175
dictNetType["DFINE_IS"] = ModelType::DFINE_IS;
176+
dictNetType["YOLOV26"] = ModelType::YOLOV26;
177+
dictNetType["YOLOV26_OBB"] = ModelType::YOLOV26_OBB;
178+
dictNetType["YOLOV26Mask"] = ModelType::YOLOV26Mask;
176179

177180
auto netType = dictNetType.find(net_type->second);
178181
if (netType != dictNetType.end())
@@ -400,16 +403,21 @@ void OCVDNNDetector::DetectInCrop(const cv::UMat& colorFrame, const cv::Rect& cr
400403
case ModelType::YOLOV12:
401404
ParseYOLOv11(crop, detections, tmpRegions);
402405
break;
406+
case ModelType::YOLOV26:
407+
ParseYOLOv26(crop, detections, tmpRegions);
408+
break;
403409

404410
case ModelType::YOLOV5_OBB:
405411
case ModelType::YOLOV8_OBB:
406412
case ModelType::YOLOV11_OBB:
413+
case ModelType::YOLOV26_OBB:
407414
ParseYOLOv5_8_11_obb(crop, detections, tmpRegions);
408415
break;
409416

410417
case ModelType::YOLOV5Mask:
411418
case ModelType::YOLOV8Mask:
412419
case ModelType::YOLOV11Mask:
420+
case ModelType::YOLOV26Mask:
413421
ParseYOLOv5_8_11_seg(crop, detections, tmpRegions);
414422
break;
415423

@@ -1071,3 +1079,50 @@ void OCVDNNDetector::ParseDFINE_IS(const cv::Rect& crop, std::vector<cv::Mat>& d
10711079
assert(0);
10721080
}
10731081

1082+
///
1083+
/// \brief OCVDNNDetector::ParseYOLOv26
1084+
/// \param crop
1085+
/// \param detections
1086+
/// \param tmpRegions
1087+
///
1088+
void OCVDNNDetector::ParseYOLOv26(const cv::Rect& crop, std::vector<cv::Mat>& detections, regions_t& tmpRegions)
1089+
{
1090+
int rows = detections[0].size[1];
1091+
1092+
//0: name: images, size: 1x3x640x640
1093+
//1: name: output0, size: 1x300x6
1094+
1095+
float* dets = (float*)detections[0].data;
1096+
1097+
float x_factor = crop.width / static_cast<float>(m_inWidth);
1098+
float y_factor = crop.height / static_cast<float>(m_inHeight);
1099+
1100+
//std::cout << "detections: " << rows << std::endl;
1101+
1102+
for (int i = 0; i < rows; ++i)
1103+
{
1104+
auto ind = 6 * i;
1105+
1106+
float maxClassScore = dets[ind + 4];
1107+
size_t classId = static_cast<size_t>(dets[ind + 5]);
1108+
1109+
if (maxClassScore > m_confidenceThreshold)
1110+
{
1111+
float x = dets[ind + 0];
1112+
float y = dets[ind + 1];
1113+
float w = dets[ind + 2] - x;
1114+
float h = dets[ind + 3] - y;
1115+
1116+
int left = cvRound(x * x_factor);
1117+
int top = cvRound(y * y_factor);
1118+
1119+
int width = cvRound(w * x_factor);
1120+
int height = cvRound(h * y_factor);
1121+
1122+
//std::cout << "ind: " << ind << ", score = " << maxClassScore << ", class = " << classId << ", rect = " << cv::Rect(left, top, width, height) << std::endl;
1123+
1124+
if (m_classesWhiteList.empty() || m_classesWhiteList.find(T2T(classId)) != std::end(m_classesWhiteList))
1125+
tmpRegions.emplace_back(cv::Rect(left + crop.x, top + crop.y, width, height), T2T(classId), static_cast<float>(maxClassScore));
1126+
}
1127+
}
1128+
}

src/Detector/OCVDNNDetector.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ class OCVDNNDetector final : public BaseDetector
5353
RFDETR_IS,
5454
DFINE,
5555
YOLOV13,
56-
DFINE_IS
56+
DFINE_IS,
57+
YOLOV26,
58+
YOLOV26_OBB,
59+
YOLOV26Mask
5760
};
5861

5962
cv::dnn::Net m_net;
@@ -91,6 +94,7 @@ class OCVDNNDetector final : public BaseDetector
9194
void ParseRFDETR_IS(const cv::Rect& crop, std::vector<cv::Mat>& detections, regions_t& tmpRegions);
9295
void ParseDFINE(const cv::Rect& crop, std::vector<cv::Mat>& detections, regions_t& tmpRegions);
9396
void ParseDFINE_IS(const cv::Rect& crop, std::vector<cv::Mat>& detections, regions_t& tmpRegions);
97+
void ParseYOLOv26(const cv::Rect& crop, std::vector<cv::Mat>& detections, regions_t& tmpRegions);
9498
};
9599

96100
#endif

src/Detector/ONNXTensorRTDetector.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ bool ONNXTensorRTDetector::Init(const config_t& config)
102102
dictNetType["DFINE"] = tensor_rt::DFINE;
103103
dictNetType["YOLOV13"] = tensor_rt::YOLOV13;
104104
dictNetType["DFINE_IS"] = tensor_rt::DFINE_IS;
105+
dictNetType["YOLOV26"] = tensor_rt::YOLOV26;
106+
dictNetType["YOLOV26_OBB"] = tensor_rt::YOLOV26_OBB;
107+
dictNetType["YOLOV26Mask"] = tensor_rt::YOLOV26Mask;
105108

106109
auto netType = dictNetType.find(net_type->second);
107110
if (netType != dictNetType.end())
@@ -304,7 +307,8 @@ void ONNXTensorRTDetector::CalcMotionMap(cv::Mat& frame)
304307
{
305308
if (m_localConfig.m_netType == tensor_rt::YOLOV7Mask
306309
|| m_localConfig.m_netType == tensor_rt::YOLOV8Mask
307-
|| m_localConfig.m_netType == tensor_rt::YOLOV11Mask)
310+
|| m_localConfig.m_netType == tensor_rt::YOLOV11Mask
311+
|| m_localConfig.m_netType == tensor_rt::YOLOV26Mask)
308312
{
309313
static std::vector<cv::Scalar> color;
310314
if (color.empty())

src/Detector/tensorrt_onnx/DFINE_is.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ class DFINE_is_onnx : public YoloONNX
3131
//2: name: boxes, size: 1x300x4
3232
//3: name: mask_probs, size: 1x300x160x160
3333

34-
35-
//0: name: input, size: 1x3x432x432
36-
//1: name: dets, size: 1x200x4
37-
//2: name: labels, size: 1x200x91
38-
//3: name: 4245, size: 1x200x108x108
39-
4034
const float fw = static_cast<float>(frameSize.width) / static_cast<float>(m_resizedROI.width);
4135
const float fh = static_cast<float>(frameSize.height) / static_cast<float>(m_resizedROI.height);
4236

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#pragma once
2+
3+
#include "YoloONNX.hpp"
4+
5+
///
6+
/// \brief The YOLOv26_bb_onnx class
7+
///
8+
class YOLOv26_bb_onnx : public YoloONNX
9+
{
10+
public:
11+
YOLOv26_bb_onnx(std::vector<std::string>& inputTensorNames, std::vector<std::string>& outputTensorNames)
12+
{
13+
inputTensorNames.push_back("images");
14+
outputTensorNames.push_back("output0");
15+
}
16+
17+
protected:
18+
///
19+
/// \brief GetResult
20+
/// \param output
21+
/// \return
22+
///
23+
std::vector<tensor_rt::Result> GetResult(size_t imgIdx, int /*keep_topk*/, const std::vector<float*>& outputs, cv::Size frameSize)
24+
{
25+
std::vector<tensor_rt::Result> resBoxes;
26+
27+
//0: name: images, size: 1x3x640x640
28+
//1: name: output0, size: 1x300x6
29+
30+
const float fw = static_cast<float>(frameSize.width) / static_cast<float>(m_resizedROI.width);
31+
const float fh = static_cast<float>(frameSize.height) / static_cast<float>(m_resizedROI.height);
32+
33+
auto output = outputs[0];
34+
35+
size_t lenInd = 1;
36+
size_t len = static_cast<size_t>(m_outpuDims[0].d[lenInd]);
37+
auto volume = len * m_outpuDims[0].d[2];
38+
output += volume * imgIdx;
39+
//std::cout << "len = " << len << ", confThreshold = " << m_params.m_confThreshold << ", volume = " << volume << std::endl;
40+
41+
for (size_t i = 0; i < len; ++i)
42+
{
43+
auto ind = i * m_outpuDims[0].d[2];
44+
45+
float classConf = output[ind + 4];
46+
int64_t classId = output[ind + 5];
47+
48+
if (classConf >= m_params.m_confThreshold)
49+
{
50+
float x = fw * (output[ind + 0] - m_resizedROI.x);
51+
float y = fh * (output[ind + 1] - m_resizedROI.y);
52+
float width = fw * (output[ind + 2] - output[ind + 0]);
53+
float height = fh * (output[ind + 3] - output[ind + 1]);
54+
55+
//std::cout << "ind = " << ind << ", output[0] = " << output[ind + 0] << ", output[1] = " << output[ind + 1] << ", output[2] = " << output[ind + 2] << ", output[3] = " << output[ind + 3] << std::endl;
56+
//std::cout << "ind = " << ind << ", classConf = " << classConf << ", classId = " << classId << ", x = " << x << ", y = " << y << ", width = " << width << ", height = " << height << std::endl;
57+
58+
resBoxes.emplace_back(classId, classConf, cv::Rect(cvRound(x), cvRound(y), cvRound(width), cvRound(height)));
59+
}
60+
}
61+
62+
return resBoxes;
63+
}
64+
};

0 commit comments

Comments
 (0)