package main import ( "fmt" "image" "image/color" "gocv.io/x/gocv" ) // ScreenLayout holds the SpO2 and HR display areas // Used by processor.go for OCR extraction type ScreenLayout struct { SpO2Area image.Rectangle HRArea image.Rectangle } // saveLayoutVisualization draws the detected layout on an image for debugging func saveLayoutVisualization(img gocv.Mat, layout *ScreenLayout, filename string) { visualization := gocv.NewMat() defer visualization.Close() // Convert to color if grayscale if img.Channels() == 1 { gocv.CvtColor(img, &visualization, gocv.ColorGrayToBGR) } else { img.CopyTo(&visualization) } // Draw SpO2 box in red red := color.RGBA{255, 0, 0, 255} gocv.Rectangle(&visualization, layout.SpO2Area, red, 3) gocv.PutText(&visualization, "SpO2", image.Pt(layout.SpO2Area.Min.X, layout.SpO2Area.Min.Y-10), gocv.FontHersheyDuplex, 1.2, red, 2) // Draw HR box in cyan cyan := color.RGBA{0, 255, 255, 255} gocv.Rectangle(&visualization, layout.HRArea, cyan, 3) gocv.PutText(&visualization, "HR", image.Pt(layout.HRArea.Min.X, layout.HRArea.Min.Y-10), gocv.FontHersheyDuplex, 1.2, cyan, 2) // Add dimensions spo2Text := fmt.Sprintf("%dx%d", layout.SpO2Area.Dx(), layout.SpO2Area.Dy()) gocv.PutText(&visualization, spo2Text, image.Pt(layout.SpO2Area.Min.X, layout.SpO2Area.Max.Y+20), gocv.FontHersheyPlain, 1.0, red, 1) hrText := fmt.Sprintf("%dx%d", layout.HRArea.Dx(), layout.HRArea.Dy()) gocv.PutText(&visualization, hrText, image.Pt(layout.HRArea.Min.X, layout.HRArea.Max.Y+20), gocv.FontHersheyPlain, 1.0, cyan, 1) gocv.IMWrite(filename, visualization) }