mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #29515 from Prasadayus:yolov3_replace
Replace Qualcomm yolov3.onnx with darknet-converted yolov3 for better results
This commit is contained in:
@@ -218,7 +218,7 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||||
cv::resize(sample, sample, Size(640, 640));
|
cv::resize(sample, sample, Size(416, 416));
|
||||||
Mat inp = blobFromImage(sample, 1.0 / 255.0, Size(), Scalar(), true);
|
Mat inp = blobFromImage(sample, 1.0 / 255.0, Size(), Scalar(), true);
|
||||||
processNet("dnn/yolov3.onnx", "", inp);
|
processNet("dnn/yolov3.onnx", "", inp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,46 +117,12 @@ public:
|
|||||||
std::vector<Mat> outs;
|
std::vector<Mat> outs;
|
||||||
net.forward(outs, net.getUnconnectedOutLayersNames());
|
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||||
|
|
||||||
// Detect output format: pytorch-YOLOv4 exports "boxes" [batch, N, 1, 4] + "confs" [batch, N, classes]
|
|
||||||
bool isBoxConfsFormat = (outs.size() == 2 && outs[0].dims == 4 && outs[0].size[outs[0].dims - 1] == 4);
|
|
||||||
// Detect 3-output format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
|
|
||||||
bool isBoxScoresIdxFormat = (outs.size() == 3 && outs[0].dims == 3 && outs[0].size[2] == 4);
|
|
||||||
|
|
||||||
for (int b = 0; b < batch_size; ++b)
|
for (int b = 0; b < batch_size; ++b)
|
||||||
{
|
{
|
||||||
std::vector<int> classIds;
|
std::vector<int> classIds;
|
||||||
std::vector<float> confidences;
|
std::vector<float> confidences;
|
||||||
std::vector<Rect2d> boxes;
|
std::vector<Rect2d> boxes;
|
||||||
if (isBoxScoresIdxFormat)
|
|
||||||
{
|
{
|
||||||
// yolov3-style format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
|
|
||||||
// boxes are [x1, y1, x2, y2] in pixel coords (relative to model input size)
|
|
||||||
int N = outs[0].size[1];
|
|
||||||
float* boxesPtr = outs[0].ptr<float>(b);
|
|
||||||
float* scoresPtr = outs[1].ptr<float>(b);
|
|
||||||
float* classIdxPtr = outs[2].ptr<float>(b);
|
|
||||||
|
|
||||||
float modelW = (float)inp.size[3];
|
|
||||||
float modelH = (float)inp.size[2];
|
|
||||||
|
|
||||||
for (int j = 0; j < N; ++j)
|
|
||||||
{
|
|
||||||
float score = scoresPtr[j];
|
|
||||||
if (score > confThreshold)
|
|
||||||
{
|
|
||||||
float x1 = boxesPtr[j * 4 + 0] / modelW;
|
|
||||||
float y1 = boxesPtr[j * 4 + 1] / modelH;
|
|
||||||
float x2 = boxesPtr[j * 4 + 2] / modelW;
|
|
||||||
float y2 = boxesPtr[j * 4 + 3] / modelH;
|
|
||||||
boxes.push_back(Rect2d(x1, y1, x2 - x1, y2 - y1));
|
|
||||||
confidences.push_back(score);
|
|
||||||
classIds.push_back((int)classIdxPtr[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isBoxConfsFormat)
|
|
||||||
{
|
|
||||||
// boxes [batch, N, 1, 4] (x1,y1,x2,y2), confs [batch, N, num_classes]
|
|
||||||
Mat boxesMat = outs[0];
|
Mat boxesMat = outs[0];
|
||||||
Mat confsMat = outs[1];
|
Mat confsMat = outs[1];
|
||||||
if (batch_size > 1)
|
if (batch_size > 1)
|
||||||
@@ -195,40 +161,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (int)outs.size(); ++i)
|
|
||||||
{
|
|
||||||
Mat out;
|
|
||||||
if (batch_size > 1){
|
|
||||||
Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
|
||||||
out = outs[i](ranges).reshape(1, outs[i].size[1]);
|
|
||||||
}else{
|
|
||||||
out = outs[i];
|
|
||||||
}
|
|
||||||
for (int j = 0; j < out.rows; ++j)
|
|
||||||
{
|
|
||||||
float objConf = out.at<float>(j, 4);
|
|
||||||
Mat scores = out.row(j).colRange(5, out.cols);
|
|
||||||
double maxClsScore;
|
|
||||||
Point maxLoc;
|
|
||||||
minMaxLoc(scores, 0, &maxClsScore, 0, &maxLoc);
|
|
||||||
double confidence = objConf * maxClsScore;
|
|
||||||
|
|
||||||
if (confidence > confThreshold) {
|
|
||||||
float* detection = out.ptr<float>(j);
|
|
||||||
double centerX = detection[0];
|
|
||||||
double centerY = detection[1];
|
|
||||||
double width = detection[2];
|
|
||||||
double height = detection[3];
|
|
||||||
boxes.push_back(Rect2d(centerX - 0.5 * width, centerY - 0.5 * height,
|
|
||||||
width, height));
|
|
||||||
confidences.push_back(confidence);
|
|
||||||
classIds.push_back(maxLoc.x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we need NMS of boxes
|
// here we need NMS of boxes
|
||||||
std::vector<int> indices;
|
std::vector<int> indices;
|
||||||
@@ -384,11 +316,17 @@ TEST_P(Test_YOLO_nets, YOLOv3)
|
|||||||
|
|
||||||
// batchId, classId, confidence, left, top, right, bottom
|
// batchId, classId, confidence, left, top, right, bottom
|
||||||
const int N0 = 3;
|
const int N0 = 3;
|
||||||
const int N1 = 0;
|
const int N1 = 5;
|
||||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||||
0, 7, 0.606292f, 0.612037f, 0.149921f, 0.910763f, 0.300503f,
|
0, 16, 0.998835f, 0.160018f, 0.389962f, 0.417889f, 0.943715f,
|
||||||
0, 16, 0.55195f, 0.17069f, 0.356024f, 0.471459f, 0.877178f,
|
0, 1, 0.987915f, 0.150904f, 0.221934f, 0.742265f, 0.746256f,
|
||||||
0, 1, 0.433444f, 0.199235f, 0.301175f, 0.753253f, 0.744156f,
|
0, 7, 0.952998f, 0.614625f, 0.150259f, 0.901366f, 0.289251f,
|
||||||
|
|
||||||
|
1, 2, 0.997410f, 0.647584f, 0.459938f, 0.821038f, 0.663948f,
|
||||||
|
1, 2, 0.989632f, 0.450719f, 0.463353f, 0.496306f, 0.522258f,
|
||||||
|
1, 0, 0.980047f, 0.195857f, 0.378452f, 0.258626f, 0.629259f,
|
||||||
|
1, 9, 0.785156f, 0.665503f, 0.373544f, 0.688893f, 0.439243f,
|
||||||
|
1, 9, 0.733130f, 0.376029f, 0.315696f, 0.401777f, 0.395165f,
|
||||||
};
|
};
|
||||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||||
|
|
||||||
@@ -407,7 +345,12 @@ TEST_P(Test_YOLO_nets, YOLOv3)
|
|||||||
|
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("batch size 1");
|
SCOPED_TRACE("batch size 1");
|
||||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
|
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.5, 0.4, false, 0, Size(416, 416));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("batch size 2");
|
||||||
|
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.5, 0.4, false, 0, Size(416, 416));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -332,26 +332,19 @@ TEST_P(Test_Model, YOLOv3)
|
|||||||
|
|
||||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||||
|
|
||||||
// The in-graph YOLO decode (Split) is not evaluable by the OpenVINO backend.
|
|
||||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||||
|
|
||||||
std::string model_file = _tf("yolov3.onnx", false);
|
checkBackend();
|
||||||
std::string img_path = _tf("dog416.png"); // Matches standard YOLO inference classes
|
|
||||||
|
|
||||||
// Extracted from original flat ref_ array: batchId, classId, confidence, left, top, right, bottom
|
std::vector<int> refClassIds = {16, 1, 7};
|
||||||
std::vector<int> refClassIds = {7, 16, 1};
|
std::vector<float> refConfidences = {0.998835f, 0.987915f, 0.952998f};
|
||||||
std::vector<float> refConfidences = {0.606292f, 0.55195f, 0.433444f};
|
|
||||||
|
|
||||||
// Rect2d requires (x, y, width, height) format
|
|
||||||
std::vector<Rect2d> refBoxes = {
|
std::vector<Rect2d> refBoxes = {
|
||||||
Rect2d(0.612037f, 0.149921f, 0.910763f - 0.612037f, 0.300503f - 0.149921f), // Class 7
|
Rect2d(0.160018f, 0.389962f, 0.257871f, 0.553753f),
|
||||||
Rect2d(0.170690f, 0.356024f, 0.471459f - 0.170690f, 0.877178f - 0.356024f), // Class 16
|
Rect2d(0.150904f, 0.221934f, 0.591361f, 0.524322f),
|
||||||
Rect2d(0.199235f, 0.301175f, 0.753253f - 0.199235f, 0.744156f - 0.301175f) // Class 1
|
Rect2d(0.614625f, 0.150259f, 0.286741f, 0.138992f),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setting precision tolerances
|
|
||||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
|
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
|
||||||
{
|
{
|
||||||
@@ -364,16 +357,49 @@ TEST_P(Test_Model, YOLOv3)
|
|||||||
iouDiff = 0.03;
|
iouDiff = 0.03;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model parameters
|
const float confThreshold = 0.5f, nmsThreshold = 0.4f;
|
||||||
double confThreshold = 0.24;
|
const Size inputSize(416, 416);
|
||||||
double nmsThreshold = 0.4;
|
|
||||||
Size size{640, 640};
|
|
||||||
double scale = 1.0 / 255.0; // Standard image scaling for YOLO models
|
|
||||||
Scalar mean = Scalar();
|
|
||||||
bool swapRB = true; // YOLO expects RGB
|
|
||||||
|
|
||||||
testDetectModel(model_file, "", img_path, refClassIds, refConfidences, refBoxes,
|
Mat img = imread(_tf("dog416.png"));
|
||||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean, scale, swapRB);
|
cv::resize(img, img, inputSize);
|
||||||
|
Mat blob = blobFromImage(img, 1.0 / 255.0, inputSize, Scalar(), true, false);
|
||||||
|
|
||||||
|
Net net = readNet(_tf("yolov3.onnx", false));
|
||||||
|
net.setPreferableBackend(backend);
|
||||||
|
net.setPreferableTarget(target);
|
||||||
|
net.setInput(blob);
|
||||||
|
std::vector<Mat> outs;
|
||||||
|
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||||
|
|
||||||
|
int numBoxes = (int)(outs[0].total() / 4);
|
||||||
|
Mat boxesMat = outs[0].reshape(1, numBoxes);
|
||||||
|
Mat confsMat = outs[1].reshape(1, numBoxes);
|
||||||
|
|
||||||
|
std::vector<Rect2d> boxes;
|
||||||
|
std::vector<float> confidences;
|
||||||
|
std::vector<int> classIds;
|
||||||
|
for (int j = 0; j < numBoxes; ++j)
|
||||||
|
{
|
||||||
|
Mat scores = confsMat.row(j);
|
||||||
|
double confidence; Point maxLoc;
|
||||||
|
minMaxLoc(scores, 0, &confidence, 0, &maxLoc);
|
||||||
|
if (confidence >= confThreshold)
|
||||||
|
{
|
||||||
|
float* b = boxesMat.ptr<float>(j);
|
||||||
|
boxes.emplace_back(b[0], b[1], b[2] - b[0], b[3] - b[1]);
|
||||||
|
confidences.push_back((float)confidence);
|
||||||
|
classIds.push_back(maxLoc.x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> keep;
|
||||||
|
NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, keep);
|
||||||
|
|
||||||
|
std::vector<Rect2d> nmsBoxes; std::vector<float> nmsConfs; std::vector<int> nmsCls;
|
||||||
|
for (int k : keep) { nmsBoxes.push_back(boxes[k]); nmsConfs.push_back(confidences[k]); nmsCls.push_back(classIds[k]); }
|
||||||
|
|
||||||
|
normAssertDetections(refClassIds, refConfidences, refBoxes,
|
||||||
|
nmsCls, nmsConfs, nmsBoxes, "", confThreshold, scoreDiff, iouDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(Test_Model, Keypoints_pose)
|
TEST_P(Test_Model, Keypoints_pose)
|
||||||
|
|||||||
@@ -123,13 +123,13 @@ yolov4-tiny:
|
|||||||
|
|
||||||
yolov3:
|
yolov3:
|
||||||
load_info:
|
load_info:
|
||||||
url: "https://huggingface.co/qualcomm/Yolo-v3/resolve/226ada6de9dcb32eebad7f74bf526714e2af6136/Yolo-v3.onnx"
|
url: "https://huggingface.co/opencv/opencv_contribution/resolve/main/yolov3/yolov3.onnx"
|
||||||
sha1: "c37641ddf05cfe133efd4b66832f269d95f523cf"
|
sha1: "2b433d879f318efa55de62a630556162665c6d8e"
|
||||||
model: "yolov3.onnx"
|
model: "yolov3.onnx"
|
||||||
mean: [0, 0, 0]
|
mean: [0, 0, 0]
|
||||||
scale: 0.00392
|
scale: 0.00392
|
||||||
width: 640
|
width: 416
|
||||||
height: 640
|
height: 416
|
||||||
rgb: true
|
rgb: true
|
||||||
labels: "object_detection_classes_yolo.txt"
|
labels: "object_detection_classes_yolo.txt"
|
||||||
postprocessing: "yolov4"
|
postprocessing: "yolov4"
|
||||||
|
|||||||
@@ -551,31 +551,6 @@ void postprocess(Mat& frame, const vector<Mat>& outs, Net& net, vector<int>& cla
|
|||||||
}
|
}
|
||||||
else if (postprocessing == "yolov4")
|
else if (postprocessing == "yolov4")
|
||||||
{
|
{
|
||||||
// boxes[b,N,1,4]+confs[b,N,classes] (normalized) or boxes[b,N,4]+scores[b,N]+classIdx[b,N] (model-px)
|
|
||||||
bool isBoxConfsFormat = (outs.size() == 2 && outs[0].dims == 4 && outs[0].size[outs[0].dims - 1] == 4);
|
|
||||||
bool isBoxScoresIdxFormat = (outs.size() == 3 && outs[0].dims == 3 && outs[0].size[2] == 4);
|
|
||||||
if (isBoxScoresIdxFormat)
|
|
||||||
{
|
|
||||||
int N = outs[0].size[1];
|
|
||||||
const float* boxesPtr = outs[0].ptr<float>(0);
|
|
||||||
const float* scoresPtr = outs[1].ptr<float>(0);
|
|
||||||
const float* classIdxPtr = outs[2].ptr<float>(0);
|
|
||||||
for (int j = 0; j < N; ++j)
|
|
||||||
{
|
|
||||||
float score = scoresPtr[j];
|
|
||||||
if (score > confThreshold)
|
|
||||||
{
|
|
||||||
float x1 = boxesPtr[j * 4 + 0];
|
|
||||||
float y1 = boxesPtr[j * 4 + 1];
|
|
||||||
float x2 = boxesPtr[j * 4 + 2];
|
|
||||||
float y2 = boxesPtr[j * 4 + 3];
|
|
||||||
boxes.push_back(Rect((int)x1, (int)y1, (int)(x2 - x1), (int)(y2 - y1)));
|
|
||||||
confidences.push_back(score);
|
|
||||||
classIds.push_back((int)classIdxPtr[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isBoxConfsFormat)
|
|
||||||
{
|
{
|
||||||
Mat boxesMat = outs[0];
|
Mat boxesMat = outs[0];
|
||||||
Mat confsMat = outs[1];
|
Mat confsMat = outs[1];
|
||||||
@@ -597,11 +572,6 @@ void postprocess(Mat& frame, const vector<Mat>& outs, Net& net, vector<int>& cla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << "Unsupported YOLO ONNX output format" << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
Image2BlobParams paramNet;
|
Image2BlobParams paramNet;
|
||||||
paramNet.scalefactor = Scalar::all(scale);
|
paramNet.scalefactor = Scalar::all(scale);
|
||||||
paramNet.size = Size(inpWidth, inpHeight);
|
paramNet.size = Size(inpWidth, inpHeight);
|
||||||
|
|||||||
@@ -159,43 +159,20 @@ def postprocess(frame, outs):
|
|||||||
boxes.append([left, top, width, height])
|
boxes.append([left, top, width, height])
|
||||||
|
|
||||||
elif args.postprocessing == 'yolov4':
|
elif args.postprocessing == 'yolov4':
|
||||||
# boxes[b,N,1,4]+confs[b,N,classes] (normalized) or boxes[b,N,4]+scores[b,N]+classIdx[b,N] (model-px)
|
boxesArr = outs[0].reshape(-1, 4)
|
||||||
if len(outs) == 3 and outs[0].ndim == 3 and outs[0].shape[2] == 4:
|
confsArr = outs[1].reshape(boxesArr.shape[0], -1)
|
||||||
boxesArr = outs[0][0]
|
for j in range(boxesArr.shape[0]):
|
||||||
scoresArr = outs[1][0]
|
classId = np.argmax(confsArr[j])
|
||||||
classIdxArr = outs[2][0]
|
confidence = float(confsArr[j][classId])
|
||||||
for j in range(boxesArr.shape[0]):
|
if confidence > confThreshold:
|
||||||
score = float(scoresArr[j])
|
box = boxesArr[j]
|
||||||
if score > confThreshold:
|
left = int(box[0] * frameWidth)
|
||||||
x1 = boxesArr[j][0] / args.width
|
top = int(box[1] * frameHeight)
|
||||||
y1 = boxesArr[j][1] / args.height
|
width = int((box[2] - box[0]) * frameWidth)
|
||||||
x2 = boxesArr[j][2] / args.width
|
height = int((box[3] - box[1]) * frameHeight)
|
||||||
y2 = boxesArr[j][3] / args.height
|
classIds.append(classId)
|
||||||
left = int(x1 * frameWidth)
|
confidences.append(confidence)
|
||||||
top = int(y1 * frameHeight)
|
boxes.append([left, top, width, height])
|
||||||
width = int((x2 - x1) * frameWidth)
|
|
||||||
height = int((y2 - y1) * frameHeight)
|
|
||||||
classIds.append(int(classIdxArr[j]))
|
|
||||||
confidences.append(score)
|
|
||||||
boxes.append([left, top, width, height])
|
|
||||||
elif len(outs) == 2 and outs[0].ndim == 4 and outs[0].shape[-1] == 4:
|
|
||||||
boxesArr = outs[0].reshape(-1, 4)
|
|
||||||
confsArr = outs[1].reshape(boxesArr.shape[0], -1)
|
|
||||||
for j in range(boxesArr.shape[0]):
|
|
||||||
classId = np.argmax(confsArr[j])
|
|
||||||
confidence = float(confsArr[j][classId])
|
|
||||||
if confidence > confThreshold:
|
|
||||||
box = boxesArr[j]
|
|
||||||
left = int(box[0] * frameWidth)
|
|
||||||
top = int(box[1] * frameHeight)
|
|
||||||
width = int((box[2] - box[0]) * frameWidth)
|
|
||||||
height = int((box[3] - box[1]) * frameHeight)
|
|
||||||
classIds.append(classId)
|
|
||||||
confidences.append(confidence)
|
|
||||||
boxes.append([left, top, width, height])
|
|
||||||
else:
|
|
||||||
print('Unsupported YOLO ONNX output format')
|
|
||||||
exit()
|
|
||||||
|
|
||||||
elif args.postprocessing == 'yolov8' or args.postprocessing == 'yolov5':
|
elif args.postprocessing == 'yolov8' or args.postprocessing == 'yolov5':
|
||||||
# Network produces output blob with a shape NxC where N is a number of
|
# Network produces output blob with a shape NxC where N is a number of
|
||||||
@@ -236,7 +213,7 @@ def postprocess(frame, outs):
|
|||||||
|
|
||||||
# NMS is used inside Region layer only on DNN_BACKEND_OPENCV for another backends we need NMS in sample
|
# NMS is used inside Region layer only on DNN_BACKEND_OPENCV for another backends we need NMS in sample
|
||||||
# or NMS is required if number of outputs > 1
|
# or NMS is required if number of outputs > 1
|
||||||
if len(outNames) > 1 or (args.postprocessing == 'yolov8' or args.postprocessing == 'yolov5') and args.backend != cv.dnn.DNN_BACKEND_OPENCV:
|
if len(outNames) > 1 or args.postprocessing == 'yolov4' or (args.postprocessing == 'yolov8' or args.postprocessing == 'yolov5') and args.backend != cv.dnn.DNN_BACKEND_OPENCV:
|
||||||
indices = []
|
indices = []
|
||||||
classIds = np.array(classIds)
|
classIds = np.array(classIds)
|
||||||
boxes = np.array(boxes)
|
boxes = np.array(boxes)
|
||||||
|
|||||||
Reference in New Issue
Block a user