fix: handle YOLO11 output format [1,5,8400] with transpose for OpenCV DNN
This commit is contained in:
+43
-12
@@ -165,24 +165,55 @@ int cv_yolo_detect(const char* name, const unsigned char* img_data, int width, i
|
||||
float scaleY = (float)frame.rows / inpHeight;
|
||||
|
||||
for (size_t i = 0; i < outs.size(); ++i) {
|
||||
float* data = (float*)outs[i].data;
|
||||
for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols) {
|
||||
Mat scores = outs[i].row(j).colRange(5, outs[i].cols);
|
||||
Point classIdPoint;
|
||||
double confidence;
|
||||
minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
|
||||
// YOLO11 输出格式: [1, 5+num_classes, 8400] (通道在前)
|
||||
// 需要转置为 [8400, 5+num_classes]
|
||||
Mat out = outs[i];
|
||||
int num_detections = out.size[2]; // 8400
|
||||
int num_features = out.size[1]; // 5 + num_classes
|
||||
|
||||
// 转置输出
|
||||
Mat out_transposed;
|
||||
if (out.size[1] < out.size[2]) {
|
||||
// [1, features, detections] -> [detections, features]
|
||||
Mat out_2d(out.size[1], out.size[2], CV_32F, out.data);
|
||||
transpose(out_2d, out_transposed);
|
||||
} else {
|
||||
out_transposed = out;
|
||||
}
|
||||
|
||||
for (int j = 0; j < num_detections; ++j) {
|
||||
float* data = out_transposed.ptr<float>(j);
|
||||
|
||||
float obj_conf = data[4];
|
||||
if (obj_conf < detector->confThreshold) continue;
|
||||
|
||||
// 找最大类别分数
|
||||
int classId = 0;
|
||||
float maxScore = 0;
|
||||
for (int k = 5; k < num_features; ++k) {
|
||||
if (data[k] > maxScore) {
|
||||
maxScore = data[k];
|
||||
classId = k - 5;
|
||||
}
|
||||
}
|
||||
float confidence = obj_conf * maxScore;
|
||||
|
||||
if (confidence > detector->confThreshold) {
|
||||
int centerX = (int)(data[0] * scaleX);
|
||||
int centerY = (int)(data[1] * scaleY);
|
||||
int width = (int)(data[2] * scaleX);
|
||||
int height = (int)(data[3] * scaleY);
|
||||
float cx = data[0];
|
||||
float cy = data[1];
|
||||
float w = data[2];
|
||||
float h = data[3];
|
||||
|
||||
int centerX = (int)(cx * scaleX);
|
||||
int centerY = (int)(cy * scaleY);
|
||||
int width = (int)(w * scaleX);
|
||||
int height = (int)(h * scaleY);
|
||||
|
||||
int left = centerX - width / 2;
|
||||
int top = centerY - height / 2;
|
||||
|
||||
classIds.push_back(classIdPoint.x);
|
||||
confidences.push_back((float)confidence);
|
||||
classIds.push_back(classId);
|
||||
confidences.push_back(confidence);
|
||||
boxes.push_back(Rect(left, top, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user