-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Video Features, for example How2Sign #1359
Comments
Hi @kerolos, thanks for opening this discussion! I can help you get your video recipe set up.
There is one AV recipe currently for GRID AV corpus: https://github.com/lhotse-speech/lhotse/blob/master/lhotse/recipes/grid.py
Once you create a recording, you can load the video, process it with some module, and save + attach as a custom field to the cut. For example: video_recording = Recording.from_file("/path/to/-fZc293MpJk_0-1-rgb_front.mp4") # lhotse will auto-construct video recording manifest
video_cut = video_recording.to_cut()
video_frames = video_cut.load_video() # video frames is a uint8 np.array with shape (T, C, H, W) [or some other permutation, I don't remember off the top of my head]
video_features = compute_some_features(video_frames) # video_features is np.array with arbitrary shape
# Option 1 -> save to some storage directly
# temporal_dim indicates which dimension in video_features shape corresponds to time; set accordingly.
with NumpyHdf5Writer("video_features.h5") as writer:
video_cut.video_features = writer.store_array(video_cut.id, video_features, frame_shift=video_recording.video.fps, temporal_dim=0)
# Option 2 -> holds data in memory, write to some storage later (useful if you're going to use Lhotse Shar format):
video_cut = video_cut.attach_tensor("video_features", video_features, frame_shift=video_recording.video.fps, temporal_dim=0) If you save the final
I would use one of numpy format writers in lhotse (e.g. That said, video features would likely require better compression for very large datasets, which is something we can explore later.
You can access the fps via Final comment, |
In the beginning, I tried to use to load the video mp4 format (this mp4 does not have an audio form sign language dataset) : recording = Recording.from_file("test_rgb_front_clips/raw_videos/_fZbAxSSbX4_0-5-rgb_front.mp4") I got this error :
|
I would like to use the "Lhotse SHAR format" to save SHAR files from manifests jsonl. I have two options:
from lhotse import RecordingSet, SupervisionSet, CutSet
from lhotse.shar import SharWriter
output_dir = "./data-shar"
recordings_manifest = src_dir / 'recordings.jsonl'
supervisions_manifest = src_dir / 'supervisions.jsonl'
recordings = RecordingSet.from_jsonl(recordings_manifest)
supervisions = SupervisionSet.from_jsonl(supervisions_manifest)
cuts = CutSet.from_manifests(recordings, supervisions).trim_to_supervisions()
try:
shards = cuts.to_shar(output_dir, fields={"recording": "mp4"}, shard_size=15)
except AssertionError as e:
print(f"Error: {e}") Error:
from lhotse import load_manifest_lazy, Recording
from lhotse.shar import ArrayTarWriter
import cv2
import logging
from tqdm import tqdm
import mediapipe as mp
output_dir = "./data-shar"
recordings_manifest_path = src_dir / 'recordings.jsonl'
supervisions_manifest_path = src_dir / 'supervisions.jsonl'
recordings_manifest = load_manifest_lazy(recordings_manifest_path)
supervisions_manifest = load_manifest_lazy(supervisions_manifest_path)
tar_path = output_dir / "video_features.%06d.tar"
with ArrayTarWriter(tar_path, shard_size=15) as writer, tqdm(total=len(recordings_manifest)) as pbar, mp.solutions.holistic.Holistic(
static_image_mode=False, model_complexity=0, min_detection_confidence=0.5, min_tracking_confidence=0.5) as holistic:
for recording in recordings_manifest:
try:
video_recording = Recording.from_dict(recording.to_dict())
video_cut = video_recording.to_cut()
video_frames = video_cut.load_video()
video_path = video_recording.sources[0].source # Get the video path from sources
logging.info(f"Loading video frames from {video_path}")
# Get FPS using OpenCV
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
cap.release()
video_features = extract_features_from_video(video_path, holistic)
if video_features is None:
logging.error(f"Failed to load video frames for recording ID: {video_recording.id}, video path: {video_path}")
continue
# Attach features to video_cut
video_cut = video_cut.attach_tensor("video_features", video_features, frame_shift=float(1.0 / fps), temporal_dim=0)
# Store the features using ArrayTarWriter
writer.write(video_cut.id, video_features, video_cut.video_features)
except Exception as e:
logging.error(f"Error processing recording ID {recording.id}: {e}")
pbar.update(1) I can save features video_features.000000.tar (inside this folder for each video has two files -fZc293MpJk_0-1-rgb_front.json , and -fZc293MpJk_0-1-rgb_front.npy) Hint: i have not compressed with "lilcom" in ArrayTarWriter and also not saved
I also want to be able to use the from_shar function and later training DataLoader with Lhotse Shar: cuts_nodata = CutSet.from_shar(fields={"cuts": shards["cuts"]})
or
cuts = CutSet.from_shar(
fields={
"cuts": shards["cuts"],
"recording": shards["recording"],
}, In this tutorial (examples: 04-lhotse-shar.ipynb) Implementation note: the use of IterableDataset: How the code be modified in the way to read the existed features from shads "feature_shards" in this DynamicBucketingSampler not extracting a new one from shards recording in (Implementation note: the use of IterableDataset session ) ? Thanks in advance @pzelasko |
Video loading features depend on you having a recent version of pytorch, torchaudio, and compatible ffmpeg version to load videos. Based on the call stack I think maybe you don't have this backend available. Try updating your torch/torchaudio and setting the env var
Try using |
As for your other question:
Yeah we'll need to add mp4 support for AudioTarWriter. I don't have the bandwidth for this right now but I can give help you get started. First we'll need to add
You have two options. There is a high-level utility
I think what you want is, after executing the suggestions before, this: cuts = CutSet.from_shar(
fields={
"cuts": shards["cuts"],
"video_features": shards["video_features"],
},
) |
Extend Lhotse to support video features for tasks such as sign language recognition (e.g., How2Sign) and human activity recognition. This enhancement will be useful for the Icefall platform.
Details
With the recent support for video in PR #1151, I am interested in developing a new recipe to handle video data and extract features using tools like MediaPipe.
Objectives
Recipe Addition:
lhotse/recipes
directory.Feature Extraction:
Implementation Steps
Create Manifest Files:
Recordings manifest (
recordings.jsonl
):Supervisions manifest (
supervisions.jsonl
):Feature Extraction Script:
compute_features_sign_language.py
:Questions
and load them later for training ?
4- i have also Frames per second, it is not always fixed it in between 24 fps to 50 fps , how can i deal with that ?
I would appreciate any guidance or support on implementing this feature and utilizing it within the Icefall platform @pzelasko .
Thank you!
The text was updated successfully, but these errors were encountered: