File size: 1,528 Bytes
aa975a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import cv2, numpy as np
from typing import List, Tuple, Dict

def read_video_meta(video_path: str):
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        raise RuntimeError(f'无法打开视频: {video_path}')
    fps = cap.get(cv2.CAP_PROP_FPS) or 30.0
    total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT) or 0)
    w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) or 0)
    h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) or 0)
    cap.release()
    return {'fps': fps, 'total': total, 'w': w, 'h': h}

def sample_indices_uniform(total: int, n: int) -> List[int]:
    if n<=1 or total<=1:
        return [0]
    idxs = np.linspace(0, total-1, n, dtype=int).tolist()
    return sorted(set(int(i) for i in idxs))

def sample_indices_fps(total: int, native_fps: float, target_fps: float) -> List[int]:
    if target_fps <= 0:
        target_fps = 1.0
    step = max(int(round(native_fps / target_fps)), 1)
    idxs = list(range(0, total, step))
    return idxs

def grab_frames(video_path: str, indices: List[int]) -> Tuple[List[np.ndarray], Dict[int,int]]:
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        raise RuntimeError(f'无法打开视频: {video_path}')
    frames = []
    mapping = {}  # t -> global index
    for i, gi in enumerate(indices):
        cap.set(cv2.CAP_PROP_POS_FRAMES, gi)
        ok, frame = cap.read()
        if not ok:
            break
        frames.append(frame[:, :, ::-1])  # BGR->RGB for model
        mapping[i] = gi
    cap.release()
    return frames, mapping