Spaces:
Sleeping
Sleeping
File size: 7,093 Bytes
2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 2e176bb 219d623 |
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
import streamlit as st
import cv2
import numpy as np
from sklearn.cluster import KMeans
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.preprocessing import image
import tempfile
import os
# Function to extract VGG16 features from a frame
def extract_vgg_features(frame):
frame = cv2.resize(frame, (224, 224)) # Resize frame to 224x224 (required by VGG16)
img_array = image.img_to_array(frame) # Convert frame to a NumPy array
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
img_array = preprocess_input(img_array) # Preprocess input for VGG16
features = VGG16(weights="imagenet", include_top=False, pooling="avg").predict(img_array) # Extract features
return features.flatten() # Flatten features to 1D array
# Function to compute histogram difference
def histogram_difference(frame1, frame2):
hist1 = cv2.calcHist([frame1], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256]) # Compute histogram for frame1
hist2 = cv2.calcHist([frame2], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256]) # Compute histogram for frame2
hist1 = cv2.normalize(hist1, hist1).flatten() # Normalize and flatten histogram
hist2 = cv2.normalize(hist2, hist2).flatten() # Normalize and flatten histogram
return cv2.compareHist(hist1, hist2, cv2.HISTCMP_BHATTACHARYYA) # Compare histograms
# Function to detect scene changes using histogram comparison
def detect_scene_changes(video_path, threshold=0.2):
cap = cv2.VideoCapture(video_path) # Open the video file
prev_frame = None
scene_change_frames = []
while True:
ret, frame = cap.read() # Read the next frame
if not ret:
break
if prev_frame is not None:
diff = histogram_difference(prev_frame, frame) # Compute histogram difference
if diff > threshold: # If difference exceeds threshold, consider it a scene change
scene_change_frames.append(frame)
prev_frame = frame # Update previous frame
cap.release() # Release the video capture object
return scene_change_frames[:5] # Limit to 5 frames
# Function to select frames based on motion
def motion_based_selection(video_path, num_frames=5):
cap = cv2.VideoCapture(video_path) # Open the video file
prev_frame = None
motion_scores = []
while True:
ret, frame = cap.read() # Read the next frame
if not ret:
break
if prev_frame is not None:
diff = cv2.absdiff(prev_frame, frame) # Compute absolute difference between frames
motion_score = np.mean(diff) # Compute mean difference as motion score
motion_scores.append((frame, motion_score)) # Save frame and motion score
prev_frame = frame # Update previous frame
cap.release() # Release the video capture object
# Sort frames by motion score and select top frames
motion_scores.sort(key=lambda x: x[1], reverse=True)
selected_frames = [x[0] for x in motion_scores[:num_frames]]
return selected_frames
# Function to cluster frames using VGG16 features
def cluster_frames(video_path, num_clusters=5):
cap = cv2.VideoCapture(video_path) # Open the video file
frames = []
features = []
while True:
ret, frame = cap.read() # Read the next frame
if not ret:
break
frames.append(frame) # Save the frame
feature = extract_vgg_features(frame) # Extract features using VGG16
features.append(feature) # Save the features
cap.release() # Release the video capture object
# Perform K-Means clustering
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
clusters = kmeans.fit_predict(features) # Cluster the frames
# Select one frame from each cluster
selected_frames = []
for cluster_id in range(num_clusters):
cluster_indices = np.where(clusters == cluster_id)[0] # Find frames in the cluster
centroid_index = cluster_indices[0] # Select the first frame in the cluster
selected_frames.append(frames[centroid_index]) # Save the frame
return selected_frames
# Function to convert video to 15 FPS
def convert_to_15fps(video_path, output_path):
cap = cv2.VideoCapture(video_path) # Open the video file
fps = int(cap.get(cv2.CAP_PROP_FPS)) # Get the original FPS
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # Get the frame width
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Get the frame height
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*"mp4v") # Use MP4 codec
out = cv2.VideoWriter(output_path, fourcc, 15, (width, height)) # Set output FPS to 15
while True:
ret, frame = cap.read() # Read the next frame
if not ret:
break
# Write the frame to the output video
out.write(frame)
# Skip frames to achieve 15 FPS
for _ in range(int(fps / 15) - 1):
cap.read()
cap.release() # Release the video capture object
out.release() # Release the video writer object
# Streamlit app
def main():
st.title("Video Frame Selection App")
st.write("Upload a 60-second video to extract the best 5 frames using three methods.")
# Upload video
uploaded_file = st.file_uploader("Upload a 60-second video", type=["mp4", "avi", "mov"])
if uploaded_file is not None:
# Save the uploaded video to a temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
temp_file.write(uploaded_file.getbuffer())
temp_video_path = temp_file.name
# Convert the video to 15 FPS
output_video_path = "temp_15fps_video.mp4"
convert_to_15fps(temp_video_path, output_video_path)
# Motion-based selection
st.header("Motion-Based Frames")
motion_frames = motion_based_selection(output_video_path, num_frames=5)
for i, frame in enumerate(motion_frames):
st.image(frame, caption=f"Motion Frame {i + 1}", use_column_width=True)
# Scene change detection
st.header("Scene Change-Based Frames")
scene_change_frames = detect_scene_changes(output_video_path, threshold=0.2)
for i, frame in enumerate(scene_change_frames):
st.image(frame, caption=f"Scene Change Frame {i + 1}", use_column_width=True)
# Clustering-based selection
st.header("Clustering-Based Frames")
clustered_frames = cluster_frames(output_video_path, num_clusters=5)
for i, frame in enumerate(clustered_frames):
st.image(frame, caption=f"Clustered Frame {i + 1}", use_column_width=True)
# Clean up temporary files
os.unlink(temp_video_path)
os.unlink(output_video_path)
# Run the app
if __name__ == "__main__":
main()
|