51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
"""
|
|
Example client: how your annotation tool calls the SAM 3 server.
|
|
|
|
Run the server first:
|
|
python sam3_server.py --host 0.0.0.0 --port 8000
|
|
|
|
Then, from your annotation tool, POST an image + bbox and render the mask.
|
|
"""
|
|
|
|
import base64
|
|
import io
|
|
import requests
|
|
from PIL import Image
|
|
|
|
SERVER = "http://localhost:8000"
|
|
|
|
|
|
def segment_with_bbox(image_path: str, bbox_xyxy: list[float]):
|
|
with open(image_path, "rb") as f:
|
|
img_b64 = base64.b64encode(f.read()).decode("ascii")
|
|
|
|
r = requests.post(
|
|
f"{SERVER}/segment/box",
|
|
json={
|
|
"image": img_b64,
|
|
"bbox": bbox_xyxy, # [x1, y1, x2, y2] in pixels
|
|
"multimask_output": False,
|
|
"return_polygon": True, # get contour for polygon-based annotation
|
|
"return_rle": True, # get COCO RLE for COCO-format export
|
|
},
|
|
timeout=60,
|
|
)
|
|
r.raise_for_status()
|
|
data = r.json()
|
|
|
|
# Decode mask (single-channel PNG, 0 or 255)
|
|
mask_png = base64.b64decode(data["mask"])
|
|
mask = Image.open(io.BytesIO(mask_png))
|
|
mask.save("mask_out.png")
|
|
|
|
print(f"score: {data['score']:.3f}")
|
|
print(f"bbox: {data['bbox_out']}")
|
|
print(f"polygon: {len(data['polygon']) if data['polygon'] else 0} points")
|
|
print(f"rle: size={data['rle']['size']} (counts length={len(str(data['rle']['counts']))})")
|
|
return data
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Example: segment the object inside this bbox
|
|
segment_with_bbox("example.jpg", [120, 80, 540, 420])
|