Views
No views yet
mask-generation pipeline:1>>> from transformers import pipeline
2
3>>> generator = pipeline("mask-generation", model="yonigozlan/EdgeTAM-hf", 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, EdgeTamModel
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 = EdgeTamModel.from_pretrained("yonigozlan/EdgeTAM-hf").to(device)
9>>> processor = Sam2Processor.from_pretrained("yonigozlan/EdgeTAM-hf")
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, EdgeTamModel
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 = EdgeTamModel.from_pretrained("yonigozlan/EdgeTAM-hf").to(device)
9>>> processor = Sam2Processor.from_pretrained("yonigozlan/EdgeTAM-hf")
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 EdgeTamVideoModel, Sam2VideoProcessor
2>>> import torch
3
4>>> device = "cuda" if torch.cuda.is_available() else "cpu"
5>>> model = EdgeTamVideoModel.from_pretrained("yonigozlan/EdgeTAM-hf").to(device, dtype=torch.bfloat16)
6>>> processor = Sam2VideoProcessor.from_pretrained("yonigozlan/EdgeTAM-hf")
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 edgetam_video_output in model.propagate_in_video_iterator(inference_session):
51... video_res_masks = processor.post_process_masks(
52... [edgetam_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
53... )[0]
54... video_segments[edgetam_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 edgetam_video_output in model.propagate_in_video_iterator(inference_session):
27... video_res_masks = processor.post_process_masks(
28... [edgetam_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
29... )[0]
30... video_segments[edgetam_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 edgetam_video_output in model.propagate_in_video_iterator(inference_session):
18... video_res_masks = processor.post_process_masks(
19... [edgetam_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
20... )[0]
21... video_segments[edgetam_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... edgetam_video_output = model(inference_session=inference_session, frame=inputs.pixel_values[0])
24...
25... video_res_masks = processor.post_process_masks(
26... [edgetam_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 edgetam_video_output in model.propagate_in_video_iterator(inference_session):
40... video_res_masks = processor.post_process_masks(
41... [edgetam_video_output.pred_masks], original_sizes=[[inference_session.video_height, inference_session.video_width]], binarize=False
42... )[0]
43... video_segments[edgetam_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{zhou2025edgetam,
title={EdgeTAM: On-Device Track Anything Model},
author={Zhou, Chong and Zhu, Chenchen and Xiong, Yunyang and Suri, Saksham and Xiao, Fanyi and Wu, Lemeng and Krishnamoorthi, Raghuraman and Dai, Bo and Loy, Chen Change and Chandra, Vikas and Soran, Bilge},
journal={arXiv preprint arXiv:2501.07256},
year={2025}
}