Spaces:
Runtime error
Runtime error
| import os | |
| import torch | |
| import numpy as np | |
| import cv2 | |
| import requests | |
| import gradio as gr | |
| from segment_anything import sam_model_registry, SamPredictor | |
| import supervision as sv | |
| # ------------------------------ | |
| # 1. Setup & Model Loading | |
| # ------------------------------ | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| print(f"Device used: {device}") | |
| model_type = "vit_b" | |
| checkpoint_path = "sam_vit_b_01ec64.pth" | |
| # Download model if needed | |
| if not os.path.exists(checkpoint_path): | |
| print("Downloading SAM checkpoint...") | |
| url = "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth" | |
| r = requests.get(url, stream=True) | |
| with open(checkpoint_path, "wb") as f: | |
| for chunk in r.iter_content(1024 * 1024): | |
| if chunk: | |
| f.write(chunk) | |
| sam = sam_model_registry[model_type](checkpoint=checkpoint_path) | |
| sam.to(device) | |
| # Note: We kept the model in float32. | |
| # Using sam.half() often causes runtime type mismatch errors with SamPredictor | |
| # unless the input image is explicitly cast to half-precision manually. | |
| predictor = SamPredictor(sam) | |
| # ------------------------------ | |
| # 2. The API Function | |
| # ------------------------------ | |
| def run_sam_api(image_url, box_coords): | |
| """ | |
| Args: | |
| image_url (str): HTTP link to the image. | |
| box_coords (list): A list of 4 integers [x1, y1, x2, y2]. | |
| """ | |
| print(f"Received URL: {image_url}") | |
| print(f"Received Box: {box_coords}") | |
| # 1. Download the Image | |
| try: | |
| # Use a user-agent to avoid 403 Forbidden errors on some sites | |
| headers = {'User-Agent': 'Mozilla/5.0'} | |
| resp = requests.get(image_url, stream=True, headers=headers).raw | |
| image_array = np.asarray(bytearray(resp.read()), dtype="uint8") | |
| image = cv2.imdecode(image_array, cv2.IMREAD_COLOR) | |
| if image is None: | |
| raise ValueError("Could not decode image.") | |
| image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # Convert to RGB | |
| except Exception as e: | |
| print(f"Error downloading image: {e}") | |
| raise gr.Error(f"Failed to load image: {e}") | |
| # 2. Set Image for SAM | |
| predictor.set_image(image) | |
| # 3. Prepare Box | |
| # Ensure it's a numpy array: [x_min, y_min, x_max, y_max] | |
| input_box = np.array(box_coords) | |
| # 4. Predict | |
| # SAM expects box shape (1, 4) | |
| masks, scores, logits = predictor.predict( | |
| point_coords=None, | |
| point_labels=None, | |
| box=input_box[None, :], | |
| multimask_output=False | |
| ) | |
| # 5. Annotate / Visualize | |
| # Convert SAM masks to Supervision Detections | |
| # masks shape is (1, H, W), we need to ensure it fits supervision expectations | |
| detections = sv.Detections( | |
| xyxy=sv.mask_to_xyxy(masks=masks), | |
| mask=masks | |
| ) | |
| # Create annotators | |
| mask_annotator = sv.MaskAnnotator(color=sv.Color.RED) | |
| box_annotator = sv.BoxAnnotator(color=sv.Color.RED) | |
| # Apply annotations | |
| annotated_image = mask_annotator.annotate(scene=image.copy(), detections=detections) | |
| annotated_image = box_annotator.annotate(scene=annotated_image, detections=detections) | |
| return annotated_image | |
| demo = gr.Interface( | |
| fn=run_sam_api, | |
| inputs=[ | |
| gr.Textbox(label="Image URL", placeholder="http://..."), | |
| gr.JSON(label="Box Coords [x1, y1, x2, y2]", value=[100, 100, 200, 200]) | |
| ], | |
| outputs=gr.Image(type="numpy", label="Segmented Output"), | |
| title="SAM API via Gradio", | |
| description="Send an image URL and bounding box coordinates to segment objects.", | |
| api_name="predict_api" | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue().launch(share=True) |