Views
No views yet
1import torch
2from sam2.sam2_image_predictor import SAM2ImagePredictor
3
4predictor = SAM2ImagePredictor.from_pretrained("facebook/sam2.1-hiera-large")
5
6with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16):
7 predictor.set_image(<your_image>)
8 masks, _, _ = predictor.predict(<input_prompts>)1import torch
2from sam2.sam2_video_predictor import SAM2VideoPredictor
3
4predictor = SAM2VideoPredictor.from_pretrained("facebook/sam2.1-hiera-large")
5
6with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16):
7 state = predictor.init_state(<your_video>)
8
9 # add new prompts and instantly get the output on the same frame
10 frame_idx, object_ids, masks = predictor.add_new_points_or_box(state, <your_prompts>):
11
12 # propagate the prompts to get masklets throughout the video
13 for frame_idx, object_ids, masks in predictor.propagate_in_video(state):
14 ...mask-generation pipeline:1>>> from transformers import pipeline
2
3>>> generator = pipeline("mask-generation", model="facebook/sam2.1-hiera-large", device=0)
4>>> image_url = "https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/truck.jpg"
5>>> outputs = generator(image_url, points_per_batch=64)
6
7>>> len(outputs["masks"]) # Number of masks generated
8391>>> from transformers import Sam2Processor, Sam2Model
2>>> import torch
3>>> from PIL import Image
4>>> import requests
5
6>>> device = "cuda" if torch.cuda.is_available() else "cpu"
7
8>>> model = Sam2Model.from_pretrained("facebook/sam2.1-hiera-large").to(device)
9>>> processor = Sam2Processor.from_pretrained("facebook/sam2.1-hiera-large")
10
11>>> image_url = "https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/truck.jpg"
12>>> raw_image = Image.open(requests.get(image_url, stream=True).raw).convert("RGB")
13
14>>> input_points = [[[[500, 375]]]] # Single point click, 4 dimensions (image_dim, object_dim, point_per_object_dim, coordinates)
15>>> input_labels = [[[1]]] # 1 for positive click, 0 for negative click, 3 dimensions (image_dim, object_dim, point_label)
16
17>>> inputs = processor(images=raw_image, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
18
19>>> with torch.no_grad():
20... outputs = model(**inputs)
21
22>>> masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])[0]
23
24>>> # The model outputs multiple mask predictions ranked by quality score
25>>> print(f"Generated {masks.shape[1]} masks with shape {masks.shape}")
26Generated 3 masks with shape torch.Size(1, 3, 1500, 2250)1>>> # Add both positive and negative points to refine the mask
2>>> input_points = [[[[500, 375], [1125, 625]]]] # Multiple points for refinement
3>>> input_labels = [[[1, 1]]] # Both positive clicks
4
5>>> inputs = processor(images=raw_image, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
6
7>>> with torch.no_grad():
8... outputs = model(**inputs)
9
10>>> masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])[0]1>>> # Define bounding box as [x_min, y_min, x_max, y_max]
2>>> input_boxes = [[[75, 275, 1725, 850]]]
3
4>>> inputs = processor(images=raw_image, input_boxes=input_boxes, return_tensors="pt").to(device)
5
6>>> with torch.no_grad():
7... outputs = model(**inputs)
8
9>>> masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])[0]1>>> # Define points for two different objects
2>>> input_points = [[[[500, 375]], [[650, 750]]]] # Points for two objects in same image
3>>> input_labels = [[[1], [1]]] # Positive clicks for both objects
4
5>>> inputs = processor(images=raw_image, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
6
7>>> with torch.no_grad():
8... outputs = model(**inputs, multimask_output=False)
9
10>>> # Each object gets its own mask
11>>> masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])[0]
12>>> print(f"Generated masks for {masks.shape[0]} objects")
13Generated masks for 2 objects1>>> from transformers import Sam2Processor, Sam2Model
2>>> import torch
3>>> from PIL import Image
4>>> import requests
5
6>>> device = "cuda" if torch.cuda.is_available() else "cpu"
7
8>>> model = Sam2Model.from_pretrained("facebook/sam2.1-hiera-large").to(device)
9>>> processor = Sam2Processor.from_pretrained("facebook/sam2.1-hiera-large")
10
11>>> # Load multiple images
12>>> image_urls = [
13... "https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/truck.jpg",
14... "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/model_doc/dog-sam.png"
15... ]
16>>> raw_images = [Image.open(requests.get(url, stream=True).raw).convert("RGB") for url in image_urls]
17
18>>> # Single point per image
19>>> input_points = [[[[500, 375]]], [[[770, 200]]]] # One point for each image
20>>> input_labels = [[[1]], [[1]]] # Positive clicks for both images
21
22>>> inputs = processor(images=raw_images, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
23
24>>> with torch.no_grad():
25... outputs = model(**inputs, multimask_output=False)
26
27>>> # Post-process masks for each image
28>>> all_masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])
29>>> print(f"Processed {len(all_masks)} images, each with {all_masks[0].shape[0]} objects")
30Processed 2 images, each with 1 objects1>>> # Multiple objects per image - different numbers of objects per image
2>>> input_points = [
3... [[[500, 375]], [[650, 750]]], # Truck image: 2 objects
4... [[[770, 200]]] # Dog image: 1 object
5... ]
6>>> input_labels = [
7... [[1], [1]], # Truck image: positive clicks for both objects
8... [[1]] # Dog image: positive click for the object
9... ]
10
11>>> inputs = processor(images=raw_images, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
12
13>>> with torch.no_grad():
14... outputs = model(**inputs, multimask_output=False)
15
16>>> all_masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])1>>> # Add groceries image for more complex example
2>>> groceries_url = "https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/groceries.jpg"
3>>> groceries_image = Image.open(requests.get(groceries_url, stream=True).raw).convert("RGB")
4>>> raw_images = [raw_images[0], groceries_image] # Use truck and groceries images
5
6>>> # Complex batching: multiple images, multiple objects, multiple points per object
7>>> input_points = [
8... [[[500, 375]], [[650, 750]]], # Truck image: 2 objects with 1 point each
9... [[[400, 300]], [[630, 300], [550, 300]]] # Groceries image: obj1 has 1 point, obj2 has 2 points
10... ]
11>>> input_labels = [
12... [[1], [1]], # Truck image: positive clicks
13... [[1], [1, 1]] # Groceries image: positive clicks for refinement
14... ]
15
16>>> inputs = processor(images=raw_images, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
17
18>>> with torch.no_grad():
19... outputs = model(**inputs, multimask_output=False)
20
21>>> all_masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])1>>> # Multiple bounding boxes per image (using truck and groceries images)
2>>> input_boxes = [
3... [[75, 275, 1725, 850], [425, 600, 700, 875], [1375, 550, 1650, 800], [1240, 675, 1400, 750]], # Truck image: 4 boxes
4... [[450, 170, 520, 350], [350, 190, 450, 350], [500, 170, 580, 350], [580, 170, 640, 350]] # Groceries image: 4 boxes
5... ]
6
7>>> # Update images for this example
8>>> raw_images = [raw_images[0], groceries_image] # truck and groceries
9
10>>> inputs = processor(images=raw_images, input_boxes=input_boxes, return_tensors="pt").to(device)
11
12>>> with torch.no_grad():
13... outputs = model(**inputs, multimask_output=False)
14
15>>> all_masks = processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"])
16>>> print(f"Processed {len(input_boxes)} images with {len(input_boxes[0])} and {len(input_boxes[1])} boxes respectively")
17Processed 2 images with 4 and 4 boxes respectively1>>> # Get initial segmentation
2>>> input_points = [[[[500, 375]]]]
3>>> input_labels = [[[1]]]
4>>> inputs = processor(images=raw_image, input_points=input_points, input_labels=input_labels, return_tensors="pt").to(device)
5
6>>> with torch.no_grad():
7... outputs = model(**inputs)
8
9>>> # Use the best mask as input for refinement
10>>> mask_input = outputs.pred_masks[:, :, torch.argmax(outputs.iou_scores.squeeze())]
11
12>>> # Add additional points with the mask input
13>>> new_input_points = [[[[500, 375], [450, 300]]]]
14>>> new_input_labels = [[[1, 1]]]
15>>> inputs = processor(
16... input_points=new_input_points,
17... input_labels=new_input_labels,
18... original_sizes=inputs["original_sizes"],
19... return_tensors="pt",
20... ).to(device)
21
22>>> with torch.no_grad():
23... refined_outputs = model(
24... **inputs,
25... input_masks=mask_input,
26... image_embeddings=outputs.image_embeddings,
27... multimask_output=False,
28... )1>>> from transformers import Sam2VideoModel, Sam2VideoProcessor
2>>> import torch
3
4>>> device = "cuda" if torch.cuda.is_available() else "cpu"
5>>> model = Sam2VideoModel.from_pretrained("facebook/sam2.1-hiera-large").to(device, dtype=torch.bfloat16)
6>>> processor = Sam2VideoProcessor.from_pretrained("facebook/sam2.1-hiera-large")
7
8>>> # Load video frames (example assumes you have a list of PIL Images)
9>>> # video_frames = [Image.open(f"frame_{i:05d}.jpg") for i in range(num_frames)]
10
11>>> # For this example, we'll use the video loading utility
12>>> from transformers.video_utils import load_video
13>>> video_url = "https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/bedroom.mp4"
14>>> video_frames, _ = load_video(video_url)
15
16>>> # Initialize video inference session
17>>> inference_session = processor.init_video_session(
18... video=video_frames,
19... inference_device=device,
20... torch_dtype=torch.bfloat16,
21... )
22
23>>> # Add click on first frame to select object
24>>> ann_frame_idx = 0
25>>> ann_obj_id = 1
26>>> points = [[[[210, 350]]]]
27>>> labels = [[[1]]]
28
29>>> processor.add_inputs_to_inference_session(
30... inference_session=inference_session,
31... frame_idx=ann_frame_idx,
32... obj_ids=ann_obj_id,
33... input_points=points,
34... input_labels=labels,
35... )
36
37>>> # Segment the object on the first frame
38>>> outputs = model(
39... inference_session=inference_session,
40... frame_idx=ann_frame_idx,
41... )
42>>> video_res_masks = processor.post_process_masks(
43... [outputs.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
44... )[0]
45>>> print(f"Segmentation shape: {video_res_masks.shape}")
46Segmentation shape: torch.Size([1, 1, 480, 854])
47
48>>> # Propagate through the entire video
49>>> video_segments = {}
50>>> for sam2_video_output in model.propagate_in_video_iterator(inference_session):
51... video_res_masks = processor.post_process_masks(
52... [sam2_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
53... )[0]
54... video_segments[sam2_video_output.frame_idx] = video_res_masks
55
56>>> print(f"Tracked object through {len(video_segments)} frames")
57Tracked object through 180 frames1>>> # Reset for new tracking session
2>>> inference_session.reset_inference_session()
3
4>>> # Add multiple objects on the first frame
5>>> ann_frame_idx = 0
6>>> obj_ids = [2, 3]
7>>> input_points = [[[[200, 300]], [[400, 150]]]] # Points for two objects (batched)
8>>> input_labels = [[[1], [1]]]
9
10>>> processor.add_inputs_to_inference_session(
11... inference_session=inference_session,
12... frame_idx=ann_frame_idx,
13... obj_ids=obj_ids,
14... input_points=input_points,
15... input_labels=input_labels,
16... )
17
18>>> # Get masks for both objects on first frame
19>>> outputs = model(
20... inference_session=inference_session,
21... frame_idx=ann_frame_idx,
22... )
23
24>>> # Propagate both objects through video
25>>> video_segments = {}
26>>> for sam2_video_output in model.propagate_in_video_iterator(inference_session):
27... video_res_masks = processor.post_process_masks(
28... [sam2_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
29... )[0]
30... video_segments[sam2_video_output.frame_idx] = {
31... obj_id: video_res_masks[i]
32... for i, obj_id in enumerate(inference_session.obj_ids)
33... }
34
35>>> print(f"Tracked {len(inference_session.obj_ids)} objects through {len(video_segments)} frames")
36Tracked 2 objects through 180 frames1>>> # Add refinement click on a later frame
2>>> refine_frame_idx = 50
3>>> ann_obj_id = 2 # Refining first object
4>>> points = [[[[220, 280]]]] # Additional point
5>>> labels = [[[1]]] # Positive click
6
7>>> processor.add_inputs_to_inference_session(
8... inference_session=inference_session,
9... frame_idx=refine_frame_idx,
10... obj_ids=ann_obj_id,
11... input_points=points,
12... input_labels=labels,
13... )
14
15>>> # Re-propagate with the additional information
16>>> video_segments = {}
17>>> for sam2_video_output in model.propagate_in_video_iterator(inference_session):
18... video_res_masks = processor.post_process_masks(
19... [sam2_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
20... )[0]
21... video_segments[sam2_video_output.frame_idx] = video_res_masks1>>> # Initialize session for streaming
2>>> inference_session = processor.init_video_session(
3... inference_device=device,
4... torch_dtype=torch.bfloat16,
5... )
6
7>>> # Process frames one by one
8>>> for frame_idx, frame in enumerate(video_frames[:10]): # Process first 10 frames
9... inputs = processor(images=frame, device=device, return_tensors="pt")
10...
11... if frame_idx == 0:
12... # Add point input on first frame
13... processor.add_inputs_to_inference_session(
14... inference_session=inference_session,
15... frame_idx=0,
16... obj_ids=1,
17... input_points=[[[[210, 350], [250, 220]]]],
18... input_labels=[[[1, 1]]],
19... original_size=inputs.original_sizes[0], # need to be provided when using streaming video inference
20... )
21...
22... # Process current frame
23... sam2_video_output = model(inference_session=inference_session, frame=inputs.pixel_values[0])
24...
25... video_res_masks = processor.post_process_masks(
26... [sam2_video_output.pred_masks], original_sizes=inputs.original_sizes, binarize=False
27... )[0]
28... print(f"Frame {frame_idx}: mask shape {video_res_masks.shape}")1>>> # Initialize video session
2>>> inference_session = processor.init_video_session(
3... video=video_frames,
4... inference_device=device,
5... torch_dtype=torch.bfloat16,
6... )
7
8>>> # Add multiple objects on the first frame using batch processing
9>>> ann_frame_idx = 0
10>>> obj_ids = [2, 3] # Track two different objects
11>>> input_points = [
12... [[[200, 300], [230, 250], [275, 175]], [[400, 150]]]
13... ] # Object 2: 3 points (2 positive, 1 negative); Object 3: 1 point
14>>> input_labels = [
15... [[1, 1, 0], [1]]
16... ] # Object 2: positive, positive, negative; Object 3: positive
17
18>>> processor.add_inputs_to_inference_session(
19... inference_session=inference_session,
20... frame_idx=ann_frame_idx,
21... obj_ids=obj_ids,
22... input_points=input_points,
23... input_labels=input_labels,
24... )
25
26>>> # Get masks for all objects on the first frame
27>>> outputs = model(
28... inference_session=inference_session,
29... frame_idx=ann_frame_idx,
30... )
31>>> video_res_masks = processor.post_process_masks(
32... [outputs.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
33... )[0]
34>>> print(f"Generated masks for {video_res_masks.shape[0]} objects")
35Generated masks for 2 objects
36
37>>> # Propagate all objects through the video
38>>> video_segments = {}
39>>> for sam2_video_output in model.propagate_in_video_iterator(inference_session):
40... video_res_masks = processor.post_process_masks(
41... [sam2_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
42... )[0]
43... video_segments[sam2_video_output.frame_idx] = {
44... obj_id: video_res_masks[i]
45... for i, obj_id in enumerate(inference_session.obj_ids)
46... }
47
48>>> print(f"Tracked {len(inference_session.obj_ids)} objects through {len(video_segments)} frames")
49Tracked 2 objects through 180 frames@article{ravi2024sam2,
title={SAM 2: Segment Anything in Images and Videos},
author={Ravi, Nikhila and Gabeur, Valentin and Hu, Yuan-Ting and Hu, Ronghang and Ryali, Chaitanya and Ma, Tengyu and Khedr, Haitham and R{\"a}dle, Roman and Rolland, Chloe and Gustafson, Laura and Mintun, Eric and Pan, Junting and Alwala, Kalyan Vasudev and Carion, Nicolas and Wu, Chao-Yuan and Girshick, Ross and Doll{\'a}r, Piotr and Feichtenhofer, Christoph},
journal={arXiv preprint arXiv:2408.00714},
url={https://arxiv.org/abs/2408.00714},
year={2024}
}