| 57 | } |
| 58 | |
| 59 | func (s *SAM3) Detect(opts *pb.DetectOptions) (pb.DetectResponse, error) { |
| 60 | // Decode base64 image and write to temp file |
| 61 | imgData, err := base64.StdEncoding.DecodeString(opts.Src) |
| 62 | if err != nil { |
| 63 | return pb.DetectResponse{}, fmt.Errorf("failed to decode image: %w", err) |
| 64 | } |
| 65 | |
| 66 | tmpFile, err := os.CreateTemp("", "sam3-*.png") |
| 67 | if err != nil { |
| 68 | return pb.DetectResponse{}, fmt.Errorf("failed to create temp file: %w", err) |
| 69 | } |
| 70 | defer os.Remove(tmpFile.Name()) |
| 71 | |
| 72 | if _, err := tmpFile.Write(imgData); err != nil { |
| 73 | tmpFile.Close() |
| 74 | return pb.DetectResponse{}, fmt.Errorf("failed to write temp file: %w", err) |
| 75 | } |
| 76 | tmpFile.Close() |
| 77 | |
| 78 | // Encode image |
| 79 | ret := CppEncodeImage(tmpFile.Name()) |
| 80 | if ret != 0 { |
| 81 | return pb.DetectResponse{}, fmt.Errorf("failed to encode image (error %d)", ret) |
| 82 | } |
| 83 | |
| 84 | threshold := opts.Threshold |
| 85 | if threshold <= 0 { |
| 86 | threshold = 0.5 |
| 87 | } |
| 88 | |
| 89 | // Determine segmentation mode |
| 90 | var nDetections int |
| 91 | if opts.Prompt != "" { |
| 92 | // Text-prompted segmentation (PCS mode, SAM 3 only) |
| 93 | nDetections = CppSegmentPCS(opts.Prompt, threshold) |
| 94 | } else { |
| 95 | // Point/box-prompted segmentation (PVS mode) |
| 96 | var pointsPtr uintptr |
| 97 | var boxesPtr uintptr |
| 98 | nPointTriples := len(opts.Points) / 3 |
| 99 | nBoxQuads := len(opts.Boxes) / 4 |
| 100 | |
| 101 | if nPointTriples > 0 { |
| 102 | pointsPtr = uintptr(unsafe.Pointer(&opts.Points[0])) |
| 103 | } |
| 104 | if nBoxQuads > 0 { |
| 105 | boxesPtr = uintptr(unsafe.Pointer(&opts.Boxes[0])) |
| 106 | } |
| 107 | |
| 108 | nDetections = CppSegmentPVS(pointsPtr, nPointTriples, boxesPtr, nBoxQuads, threshold) |
| 109 | } |
| 110 | |
| 111 | if nDetections < 0 { |
| 112 | return pb.DetectResponse{}, fmt.Errorf("segmentation failed") |
| 113 | } |
| 114 | |
| 115 | defer CppFreeResults() |
| 116 | |