RCaz commited on
Commit
d347385
·
1 Parent(s): 1a1daaa

added extract keyframes

Browse files
Files changed (2) hide show
  1. app.py +31 -21
  2. utils.py +62 -1
app.py CHANGED
@@ -1,32 +1,42 @@
1
  import gradio as gr
2
  from textblob import TextBlob
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- def sentiment_analysis(text: str) -> dict:
5
- """
6
- Analyze the sentiment of the given text.
7
-
8
- Args:
9
- text (str): The text to analyze
10
-
11
- Returns:
12
- dict: A dictionary containing polarity, subjectivity, and assessment
13
- """
14
- blob = TextBlob(text)
15
- sentiment = blob.sentiment
16
-
17
- return {
18
- "polarity": round(sentiment.polarity, 2), # -1 (negative) to 1 (positive)
19
- "subjectivity": round(sentiment.subjectivity, 2), # 0 (objective) to 1 (subjective)
20
- "assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
21
- }
22
 
23
  # Create the Gradio interface
24
  demo = gr.Interface(
25
- fn=sentiment_analysis,
26
- inputs=gr.Textbox(placeholder="Enter text to analyze..."),
 
 
 
 
27
  outputs=gr.JSON(),
28
  title="Text Sentiment Analysis",
29
- description="Analyze the sentiment of text using TextBlob"
30
  )
31
 
32
  # Launch the interface and MCP server
 
1
  import gradio as gr
2
  from textblob import TextBlob
3
+ import utils
4
+ import tempfile
5
+
6
+
7
+ def answer_video_question(query : str, url : str, file : bytes) -> dict:
8
+ # Either `file` or `url` must be provided
9
+ if file is not None:
10
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_vid:
11
+ temp_vid.write(file.read())
12
+ temp_video_path = temp_vid.name
13
+
14
+ # Output frame folder
15
+ frame_output_path = './cache/uploaded_video/frames'
16
+ extract_keyframes(temp_video_path)
17
+
18
+ return {"out_vid_frame_from_file":frame_output_path}
19
+
20
+ elif url:
21
+ files_path = download_video(url)
22
+ extract_keyframes(files_path['video_path'])
23
+ return {"out_vid_path_from_url":}
24
+
25
+ else:
26
+ return {"error": "Please provide a movie file or URL."}
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  # Create the Gradio interface
30
  demo = gr.Interface(
31
+ fn=answer_video_question,
32
+ inputs=[
33
+ gr.Textbox(placeholder="Enter Query about the movie", label="Query"),
34
+ gr.Textbox(placeholder="Paste the URL of the movie", label="Movie URL (optional)"),
35
+ gr.File(label="Upload Movie File (optional)")
36
+ ],
37
  outputs=gr.JSON(),
38
  title="Text Sentiment Analysis",
39
+ description="Ask a question about a movie. You can provide a movie via a URL or by uploading a file. The movie will be cached and deleted when the Space goes to sleep."
40
  )
41
 
42
  # Launch the interface and MCP server
utils.py CHANGED
@@ -63,4 +63,65 @@ def download_video(url):
63
  return {
64
  "video_path": video_filename,
65
  "audio_path": audio_filename,
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  return {
64
  "video_path": video_filename,
65
  "audio_path": audio_filename,
66
+ }
67
+
68
+
69
+
70
+ import cv2
71
+ import os
72
+ from skimage.metrics import structural_similarity as ssim
73
+
74
+
75
+ def is_significantly_different(img1, img2, threshold=0.4):
76
+ """Check if two images are significantly different using SSIM.
77
+ Args:
78
+ img1 (numpy.ndarray): First image.
79
+ img2 (numpy.ndarray): Second image.
80
+ threshold (float): SSIM threshold to determine significant difference.
81
+ Returns:
82
+ bool: True if images are significantly different, False otherwise.
83
+ """
84
+ grayA = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
85
+ grayB = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
86
+ score, _ = ssim(grayA, grayB, full=True)
87
+ return score < threshold # Lower score means more different
88
+
89
+
90
+
91
+ def extract_keyframes(video_path, diff_threshold=0.4):
92
+ """Extract key frames from a video based on significant differences.
93
+ Args:
94
+ video_path (str): Path to the input video file.
95
+ output_path (str): Directory to save the extracted key frames.
96
+ diff_threshold (float): SSIM threshold to determine significant difference.
97
+ """
98
+ cap = cv2.VideoCapture(video_path)
99
+ frame_id = 0
100
+ saved_id = 0
101
+ success, prev_frame = cap.read()
102
+
103
+ if not success:
104
+ print("Failed to read video.")
105
+ return
106
+
107
+ output_path='./cache/video/frames'
108
+ if not os.path.exists(output_path):
109
+ os.mkdir(output_path)
110
+
111
+ while True:
112
+ success, frame = cap.read()
113
+ if not success:
114
+ break
115
+ frame_id += 1
116
+
117
+ if is_significantly_different(prev_frame, frame, threshold=diff_threshold):
118
+ filename = os.path.join("./cache/video/frames/",f"keyframe_{saved_id:04d}.jpg")
119
+ cv2.imwrite(filename, frame)
120
+ prev_frame = frame
121
+ saved_id += 1
122
+
123
+ cap.release()
124
+ print(f"Extracted {saved_id} key frames.")
125
+
126
+ # Example usage
127
+ extract_keyframes(video_path)