Views
No views yet
| Model Detail | Description |
|---|---|
| Model Authors | Yimeng Zhang, Xin Chen, Jinghan Jia, Sijia Liu, Ke Ding |
| Date | 2023 |
| Version | Base |
| Type | Text-Visual Prompting for Temporal Video Grounding |
| Paper or Other Resources | Paper: Text-Visual Prompting for Efficient 2D Temporal Video Grounding Dataset: Charades |
| License | Other |
| Questions or Comments | Community Tab and Intel DevHub Discord |
| Intended Use | Description |
|---|---|
| Primary intended uses | The TVP model is designed for temporal video grounding (TVG), specifically to predict the start and end times of moments described by a text sentence within a long, untrimmed video. |
| Primary intended users | Researchers and developers working in the field of computer vision, particularly those focused on video understanding and cross-modal (text and video) tasks. |
| Out-of-scope uses | The model is not intended for real-time video processing or applications requiring 3D visual features extraction due to its design for efficiency with 2D features. |
1import av
2import cv2
3import numpy as np
4import torch
5from huggingface_hub import hf_hub_download
6from transformers import AutoProcessor, TvpForVideoGrounding
7
8
9def pyav_decode(container, sampling_rate, num_frames, clip_idx, num_clips, target_fps):
10 '''
11 Convert the video from its original fps to the target_fps and decode the video with PyAV decoder.
12 Returns:
13 frames (tensor): decoded frames from the video. Return None if the no
14 video stream was found.
15 fps (float): the number of frames per second of the video.
16 '''
17 fps = float(container.streams.video[0].average_rate)
18 clip_size = sampling_rate * num_frames / target_fps * fps
19 delta = max(container.streams.video[0].frames - clip_size, 0)
20 start_idx = delta * clip_idx / num_clips
21 end_idx = start_idx + clip_size - 1
22 timebase = container.streams.video[0].duration / container.streams.video[0].frames
23 video_start_pts = int(start_idx * timebase)
24 video_end_pts = int(end_idx * timebase)
25 stream_name = {"video": 0}
26 seek_offset = max(video_start_pts - 1024, 0)
27 container.seek(seek_offset, any_frame=False, backward=True, stream=container.streams.video[0])
28 frames = {}
29 for frame in container.decode(**stream_name):
30 if frame.pts < video_start_pts:
31 continue
32 if frame.pts <= video_end_pts:
33 frames[frame.pts] = frame
34 else:
35 frames[frame.pts] = frame
36 break
37 frames = [frames[pts] for pts in sorted(frames)]
38 return frames, fps
39
40
41def decode(container, sampling_rate, num_frames, clip_idx, num_clips, target_fps):
42 '''
43 Decode the video and perform temporal sampling.
44 Args:
45 container (container): pyav container.
46 sampling_rate (int): frame sampling rate (interval between two sampled frames).
47 num_frames (int): number of frames to sample.
48 clip_idx (int): if clip_idx is -1, perform random temporal sampling.
49 If clip_idx is larger than -1, uniformly split the video to num_clips
50 clips, and select the clip_idx-th video clip.
51 num_clips (int): overall number of clips to uniformly sample from the given video.
52 target_fps (int): the input video may have different fps, convert it to
53 the target video fps before frame sampling.
54 Returns:
55 frames (tensor): decoded frames from the video.
56 '''
57 assert clip_idx >= -2, "Not a valied clip_idx {}".format(clip_idx)
58 frames, fps = pyav_decode(container, sampling_rate, num_frames, clip_idx, num_clips, target_fps)
59 clip_size = sampling_rate * num_frames / target_fps * fps
60 index = torch.linspace(0, clip_size - 1, num_frames)
61 index = torch.clamp(index, 0, len(frames) - 1).long().tolist()
62 frames = [frames[idx] for idx in index]
63 frames = [frame.to_rgb().to_ndarray() for frame in frames]
64 frames = torch.from_numpy(np.stack(frames))
65 return frames
66
67def get_resize_size(image, max_size):
68 '''
69 Args:
70 image: np.ndarray
71 max_size: The max size of height and width
72 Returns:
73 (height, width)
74 Note the height/width order difference >>> pil_img = Image.open("raw_img_tensor.jpg") >>> pil_img.size (640,
75 480) # (width, height) >>> np_img = np.array(pil_img) >>> np_img.shape (480, 640, 3) # (height, width, 3)
76 '''
77 height, width = image.shape[-2:]
78 if height >= width:
79 ratio = width * 1.0 / height
80 new_height = max_size
81 new_width = new_height * ratio
82 else:
83 ratio = height * 1.0 / width
84 new_width = max_size
85 new_height = new_width * ratio
86 size = {"height": int(new_height), "width": int(new_width)}
87 return size
88
89file = hf_hub_download(repo_id="Intel/tvp_demo", filename="AK2KG.mp4", repo_type="dataset")
90model = TvpForVideoGrounding.from_pretrained("Intel/tvp-base")
91
92decoder_kwargs = dict(
93 container=av.open(file, metadata_errors="ignore"),
94 sampling_rate=1,
95 num_frames=model.config.num_frames,
96 clip_idx=0,
97 num_clips=1,
98 target_fps=3,
99)
100raw_sampled_frms = decode(**decoder_kwargs).permute(0, 3, 1, 2)
101
102text = "a person is sitting on a bed."
103processor = AutoProcessor.from_pretrained("Intel/tvp-base")
104size = get_resize_size(raw_sampled_frms, model.config.max_img_size)
105model_inputs = processor(
106 text=[text], videos=list(raw_sampled_frms.numpy()), return_tensors="pt", max_text_length=100, size=size
107)
108
109model_inputs["pixel_values"] = model_inputs["pixel_values"].to(model.dtype)
110model_inputs["labels"] = torch.tensor([18.1, 0.0, 6.8])
111output = model(**model_inputs)
112print(f"The model's output is {output}")
113
114def get_video_duration(filename):
115 cap = cv2.VideoCapture(filename)
116 if cap.isOpened():
117 rate = cap.get(5)
118 frame_num = cap.get(7)
119 duration = frame_num/rate
120 return duration
121 return -1
122
123duration = get_video_duration(file)
124timestamp = output['logits'].tolist()
125start, end = round(timestamp[0][0]*duration, 1), round(timestamp[0][1]*duration, 1)
126print(f"The time slot of the video corresponding to the text \"{text}\" is from {start}s to {end}s")1@inproceedings{zhang2023text,
2 title={Text-visual prompting for efficient 2d temporal video grounding},
3 author={Zhang, Yimeng and Chen, Xin and Jia, Jinghan and Liu, Sijia and Ding, Ke},
4 booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
5 pages={14794--14804},
6 year={2023}
7}