Skip to content

add Random Frame Extractor #464

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ More information on contributing and the general code of conduct for discussion
| Word to PDF | [Word to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/main/Word%20to%20PDF%20converter) | A Python script to convert an MS Word file to a PDF file. |
| Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/main/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! |
| Youtube Playlist Info Scraper | [Youtube Playlist Info Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/main/Youtube%20Playlist%20Info%20Scraper) | This python module retrieve information about a YouTube playlist in json format using playlist link. |
| Random Frame extractor | [Random Frame extractor ](https://github.com/DhanushNehru/Python-Scripts/tree/main/Random%Frame%20Extractor) | This python based command prompt will help you generate n number of frame from a video as an input. |
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple issues: 'extractor' should be capitalized as 'Extractor' for consistency, there's an extra space before the closing bracket in the link text, the URL has '%Frame%20Extractor' which should be '%20Frame%20Extractor', and the description has grammatical errors - should be 'This Python-based command-line tool will help you generate n number of frames from a video input.'

Suggested change
| Random Frame extractor | [Random Frame extractor ](https://github.com/DhanushNehru/Python-Scripts/tree/main/Random%Frame%20Extractor) | This python based command prompt will help you generate n number of frame from a video as an input. |
| Random Frame Extractor | [Random Frame Extractor](https://github.com/DhanushNehru/Python-Scripts/tree/main/Random%20Frame%20Extractor) | This Python-based command-line tool will help you generate n number of frames from a video input. |

Copilot uses AI. Check for mistakes.


## Gitpod

Expand Down
Empty file.
57 changes: 57 additions & 0 deletions Random Frame Extractor/RandomFrameExtractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import cv2
import os
import random
import uuid
import argparse

def extract_random_frames(video_path, num_frames=15, output_folder="./datasets/images"):
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function should validate that num_frames is a positive integer to prevent unexpected behavior with zero or negative values.

Suggested change
def extract_random_frames(video_path, num_frames=15, output_folder="./datasets/images"):
def extract_random_frames(video_path, num_frames=15, output_folder="./datasets/images"):
if not isinstance(num_frames, int) or num_frames <= 0:
raise ValueError("num_frames must be a positive integer.")

Copilot uses AI. Check for mistakes.

# Create output directory if it doesn't exist
os.makedirs(output_folder, exist_ok=True)

# Load video
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print("Error: Could not open video.")
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message should be more descriptive and include the video path to help users identify which file failed to open.

Suggested change
print("Error: Could not open video.")
print(f"Error: Could not open video at path: {video_path}")

Copilot uses AI. Check for mistakes.

return

total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
if total_frames < num_frames:
print(f"Video has only {total_frames} frames. Reducing number of outputs.")
num_frames = total_frames

# Generate a short UUID for file prefix
video_id = str(uuid.uuid4().hex)[:8]

# Select random frame indices
selected_frames = sorted(random.sample(range(total_frames), num_frames))
print(f"Extracting frames at indices: {selected_frames}")

frame_idx = 0
save_idx = 1

while cap.isOpened():
ret, frame = cap.read()
if not ret:
break

if frame_idx in selected_frames:
filename = os.path.join(output_folder, f"{video_id}_{save_idx}.png")
cv2.imwrite(filename, frame)
print(f"Saved: {filename}")
save_idx += 1

frame_idx += 1
if save_idx > num_frames:
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition should be save_idx > len(selected_frames) or removed entirely. The current logic could cause early termination when save_idx exceeds num_frames, but save_idx starts at 1 while num_frames represents the count.

Suggested change
if save_idx > num_frames:
if save_idx > len(selected_frames):

Copilot uses AI. Check for mistakes.

break

cap.release()
print("Done.")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Extract random frames from a video.")
parser.add_argument("video_path", help="Path to the input video file")
parser.add_argument("num_frames", type=int, help="Number of random frames to extract")
parser.add_argument("--output", default="./datasets/images", help="Output folder for images (default: ./datasets/images)")

args = parser.parse_args()
extract_random_frames(args.video_path, args.num_frames, args.output)