fix: scale YOLO coordinates from 640x640 to original image size, add debug output
Build and Deploy / build (push) Successful in 2m42s
Build and Deploy / deploy (push) Successful in 9s

This commit is contained in:
2026-07-17 13:14:41 +00:00
parent b0555e2281
commit 5cb160432a
+19 -3
View File
@@ -869,6 +869,10 @@ func (h *Handler) detectYOLO(modelName, imageBase64 string) (*DetectionResult, e
return nil, err return nil, err
} }
// 获取原图尺寸
origW := img.Bounds().Dx()
origH := img.Bounds().Dy()
// 预处理:Resize 到 640x640,归一化 // 预处理:Resize 到 640x640,归一化
input, err := preprocessYOLO(img) input, err := preprocessYOLO(img)
if err != nil { if err != nil {
@@ -882,8 +886,8 @@ func (h *Handler) detectYOLO(modelName, imageBase64 string) (*DetectionResult, e
} }
// YOLO11 输出: [1, 5, 8400] 或 [1, 84, 8400] // YOLO11 输出: [1, 5, 8400] 或 [1, 84, 8400]
// 需要转置 + NMS 后处理 // 需要转置 + NMS 后处理,坐标从 640x640 缩放到原图尺寸
detections := postprocessYOLO(output, 640, 640, 0.25, 0.45) detections := postprocessYOLO(output, origW, origH, 0.25, 0.45)
result := &DetectionResult{ result := &DetectionResult{
Detections: make([]Detection, len(detections)), Detections: make([]Detection, len(detections)),
@@ -896,6 +900,8 @@ func (h *Handler) detectYOLO(modelName, imageBase64 string) (*DetectionResult, e
} }
} }
fmt.Printf("DEBUG YOLO '%s': detected %d objects, origSize=%dx%d\n", modelName, len(detections), origW, origH)
return result, nil return result, nil
} }
@@ -928,7 +934,7 @@ func preprocessYOLO(img image.Image) ([]float32, error) {
} }
// postprocessYOLO YOLO11 后处理 // postprocessYOLO YOLO11 后处理
func postprocessYOLO(output []float32, imgW, imgH int, confThresh, nmsThresh float64) []YOLODetection { func postprocessYOLO(output []float32, origW, origH int, confThresh, nmsThresh float64) []YOLODetection {
// YOLO11 输出格式: [1, 5, 8400] 或 [1, 84, 8400] // YOLO11 输出格式: [1, 5, 8400] 或 [1, 84, 8400]
// 5 = x, y, w, h, conf (单类) // 5 = x, y, w, h, conf (单类)
// 84 = x, y, w, h, conf*80 (80类) // 84 = x, y, w, h, conf*80 (80类)
@@ -955,6 +961,10 @@ func postprocessYOLO(output []float32, imgW, imgH int, confThresh, nmsThresh flo
// 类别名称(根据模型调整) // 类别名称(根据模型调整)
classNames := []string{"icon"} // Detection_Icon 只有一个类 classNames := []string{"icon"} // Detection_Icon 只有一个类
// 坐标缩放比例:从 640x640 到原图
scaleX := float64(origW) / 640.0
scaleY := float64(origH) / 640.0
detections := []YOLODetection{} detections := []YOLODetection{}
// 遍历所有检测框 // 遍历所有检测框
@@ -988,6 +998,12 @@ func postprocessYOLO(output []float32, imgW, imgH int, confThresh, nmsThresh flo
w := float64(output[wIdx]) w := float64(output[wIdx])
h := float64(output[hIdx]) h := float64(output[hIdx])
// 缩放坐标到原图尺寸
cx *= scaleX
cy *= scaleY
w *= scaleX
h *= scaleY
// 转换为 x1, y1, x2, y2 // 转换为 x1, y1, x2, y2
x1 := cx - w/2 x1 := cx - w/2
y1 := cy - h/2 y1 := cy - h/2