From 5cb160432a1f8f09440fea8162f27013b3aa6af8 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 17 Jul 2026 13:14:41 +0000 Subject: [PATCH] fix: scale YOLO coordinates from 640x640 to original image size, add debug output --- internal/captcha/handler.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/internal/captcha/handler.go b/internal/captcha/handler.go index 6e45917..f679e3a 100644 --- a/internal/captcha/handler.go +++ b/internal/captcha/handler.go @@ -869,6 +869,10 @@ func (h *Handler) detectYOLO(modelName, imageBase64 string) (*DetectionResult, e return nil, err } + // 获取原图尺寸 + origW := img.Bounds().Dx() + origH := img.Bounds().Dy() + // 预处理:Resize 到 640x640,归一化 input, err := preprocessYOLO(img) if err != nil { @@ -882,8 +886,8 @@ func (h *Handler) detectYOLO(modelName, imageBase64 string) (*DetectionResult, e } // YOLO11 输出: [1, 5, 8400] 或 [1, 84, 8400] - // 需要转置 + NMS 后处理 - detections := postprocessYOLO(output, 640, 640, 0.25, 0.45) + // 需要转置 + NMS 后处理,坐标从 640x640 缩放到原图尺寸 + detections := postprocessYOLO(output, origW, origH, 0.25, 0.45) result := &DetectionResult{ 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 } @@ -928,7 +934,7 @@ func preprocessYOLO(img image.Image) ([]float32, error) { } // 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] // 5 = x, y, w, h, conf (单类) // 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 只有一个类 + // 坐标缩放比例:从 640x640 到原图 + scaleX := float64(origW) / 640.0 + scaleY := float64(origH) / 640.0 + detections := []YOLODetection{} // 遍历所有检测框 @@ -988,6 +998,12 @@ func postprocessYOLO(output []float32, imgW, imgH int, confThresh, nmsThresh flo w := float64(output[wIdx]) h := float64(output[hIdx]) + // 缩放坐标到原图尺寸 + cx *= scaleX + cy *= scaleY + w *= scaleX + h *= scaleY + // 转换为 x1, y1, x2, y2 x1 := cx - w/2 y1 := cy - h/2