StarLord69 commited on
Commit
fd3abd4
·
verified ·
1 Parent(s): 515f13d

Upload 2 files

Browse files
Files changed (2) hide show
  1. app-3.py +306 -0
  2. requirements-3.txt +8 -0
app-3.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import torch
4
+ import tempfile
5
+ import requests
6
+ import base64
7
+ import mimetypes
8
+ import urllib.parse
9
+ import instaloader
10
+ from ultralytics import YOLO
11
+ import gradio as gr
12
+ import numpy as np
13
+ from PIL import Image
14
+ from pytube import YouTube
15
+ from io import BytesIO
16
+ from typing import Optional, Tuple, Union
17
+
18
+ def load_yolov8_model(model_name: str = 'yolov8s.pt') -> Optional[YOLO]:
19
+ """
20
+ Load a YOLOv8 model.
21
+
22
+ Args:
23
+ model_name (str): Name of the model to load.
24
+
25
+ Returns:
26
+ Optional[YOLO]: Loaded YOLO model or None if loading fails.
27
+ """
28
+ try:
29
+ return YOLO(model_name)
30
+ except Exception as e:
31
+ print(f"Error loading model: {e}")
32
+ return None
33
+
34
+ def detect_objects(image: np.ndarray, model: YOLO) -> Optional[np.ndarray]:
35
+ """
36
+ Perform object detection on an image.
37
+
38
+ Args:
39
+ image (np.ndarray): Input image.
40
+ model (YOLO): Loaded YOLO model.
41
+
42
+ Returns:
43
+ Optional[np.ndarray]: Processed image with bounding boxes or None if detection fails.
44
+ """
45
+ try:
46
+ results = model(image)
47
+
48
+ for result in results[0].boxes:
49
+ x1, y1, x2, y2 = map(int, result.xyxy[0])
50
+ label = model.names[int(result.cls)]
51
+ confidence = result.conf.item()
52
+
53
+ cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
54
+ label_text = f'{label} {confidence:.2f}'
55
+ cv2.putText(image, label_text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
56
+
57
+ return image
58
+ except Exception as e:
59
+ print(f"Error during object detection: {e}")
60
+ return None
61
+
62
+ def process_image_with_yolov8(model_name: str, image: Optional[Image.Image] = None, url: Optional[str] = None) -> Optional[np.ndarray]:
63
+ """
64
+ Process an image with YOLOv8 model.
65
+
66
+ Args:
67
+ model_name (str): Name of the YOLO model to use.
68
+ image (Optional[Image.Image]): Input image.
69
+ url (Optional[str]): URL of the image to process.
70
+
71
+ Returns:
72
+ Optional[np.ndarray]: Processed image or None if processing fails.
73
+ """
74
+ model = load_yolov8_model(model_name)
75
+ if model is None:
76
+ return None
77
+
78
+ try:
79
+ if url:
80
+ response = requests.get(url)
81
+ response.raise_for_status()
82
+ image = Image.open(BytesIO(response.content))
83
+
84
+ if image is None:
85
+ raise ValueError("No image provided")
86
+
87
+ return detect_objects(np.array(image), model)
88
+ except Exception as e:
89
+ print(f"Error processing image: {e}")
90
+ return None
91
+
92
+ def download_image(url: str, save_path: str) -> None:
93
+ """
94
+ Download an image from a URL and save it to a specified path.
95
+
96
+ Args:
97
+ url (str): URL of the image to download.
98
+ save_path (str): Path to save the downloaded image.
99
+ """
100
+ try:
101
+ response = requests.get(url)
102
+ response.raise_for_status()
103
+ image = Image.open(BytesIO(response.content))
104
+ image.save(save_path)
105
+ print(f"Image saved to {save_path}")
106
+ except requests.exceptions.RequestException as e:
107
+ print(f"Failed to retrieve image. Error: {e}")
108
+
109
+ def download_base64_image(base64_data: str, save_path: str) -> None:
110
+ """
111
+ Decode a base64 image and save it to a specified path.
112
+
113
+ Args:
114
+ base64_data (str): Base64 encoded image data.
115
+ save_path (str): Path to save the decoded image.
116
+ """
117
+ try:
118
+ header, encoded = base64_data.split(',', 1)
119
+ data = base64.b64decode(encoded)
120
+ image = Image.open(BytesIO(data))
121
+ image.save(save_path)
122
+ print(f"Image saved to {save_path}")
123
+ except Exception as e:
124
+ print(f"Failed to decode base64 image. Error: {e}")
125
+
126
+ def download_video(url: str, save_path: str) -> None:
127
+ """
128
+ Download a video from a URL and save it to a specified path.
129
+
130
+ Args:
131
+ url (str): URL of the video to download.
132
+ save_path (str): Path to save the downloaded video.
133
+ """
134
+ try:
135
+ yt = YouTube(url)
136
+ stream = yt.streams.get_highest_resolution()
137
+ stream.download(output_path=save_path)
138
+ print(f"Video saved to {os.path.join(save_path, stream.default_filename)}")
139
+ except Exception as e:
140
+ print(f"Failed to retrieve video. Error: {e}")
141
+
142
+ def download_instagram_post(url: str, save_path: str) -> None:
143
+ """
144
+ Download an Instagram post (image or video) and save it to a specified path.
145
+
146
+ Args:
147
+ url (str): URL of the Instagram post.
148
+ save_path (str): Path to save the downloaded content.
149
+ """
150
+ loader = instaloader.Instaloader()
151
+ post = instaloader.Post.from_shortcode(loader.context, url.split("/")[-2])
152
+ if post.is_video:
153
+ loader.download_post(post, target=save_path)
154
+ print(f"Video saved to {save_path}")
155
+ else:
156
+ for file in post.get_sidecar_nodes():
157
+ file_url = file.display_url
158
+ download_image(file_url, os.path.join(save_path, f'insta_image_{file.shortcode}.jpg'))
159
+ print(f"Images saved to {save_path}")
160
+
161
+ def download_youtube_video(youtube_url: str) -> Optional[str]:
162
+ """
163
+ Download a YouTube video and return the path to the downloaded file.
164
+
165
+ Args:
166
+ youtube_url (str): URL of the YouTube video.
167
+
168
+ Returns:
169
+ Optional[str]: Path to the downloaded video file or None if download fails.
170
+ """
171
+ try:
172
+ yt = YouTube(youtube_url)
173
+ stream = yt.streams.filter(file_extension='mp4', res="720p").first()
174
+ if not stream:
175
+ stream = yt.streams.filter(file_extension='mp4').first()
176
+ output_path = os.path.join(tempfile.gettempdir(), "downloaded_video.mp4")
177
+ stream.download(output_path=os.path.dirname(output_path), filename=os.path.basename(output_path))
178
+ return output_path
179
+ except Exception as e:
180
+ print(f"Failed to retrieve video from YouTube. Error: {e}")
181
+ return None
182
+
183
+ def process_video(input_video_path: str, output_video_path: str, model: YOLO) -> Optional[str]:
184
+ """
185
+ Process a video file with object detection and save the result.
186
+
187
+ Args:
188
+ input_video_path (str): Path to the input video file.
189
+ output_video_path (str): Path to save the processed video.
190
+ model (YOLO): Loaded YOLO model.
191
+
192
+ Returns:
193
+ Optional[str]: Path to the processed video or None if processing fails.
194
+ """
195
+ cap = cv2.VideoCapture(input_video_path)
196
+ if not cap.isOpened():
197
+ print(f"Error: Cannot open video file {input_video_path}")
198
+ return None
199
+
200
+ frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
201
+ frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
202
+ fps = cap.get(cv2.CAP_PROP_FPS)
203
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
204
+
205
+ out = cv2.VideoWriter(output_video_path, fourcc, fps, (frame_width, frame_height))
206
+
207
+ while True:
208
+ ret, frame = cap.read()
209
+ if not ret:
210
+ break
211
+
212
+ processed_frame = detect_objects(frame, model)
213
+ out.write(processed_frame)
214
+
215
+ cap.release()
216
+ out.release()
217
+
218
+ return output_video_path
219
+
220
+ def handle_input_selection(model_name: str, choice: str, image: Optional[Image.Image], url: Optional[str]) -> Tuple[Optional[np.ndarray], Optional[str]]:
221
+ """
222
+ Handle input selection and process the image accordingly.
223
+
224
+ Args:
225
+ model_name (str): Name of the YOLO model to use.
226
+ choice (str): Input method choice ('Upload' or 'URL').
227
+ image (Optional[Image.Image]): Uploaded image.
228
+ url (Optional[str]): Image URL.
229
+
230
+ Returns:
231
+ Tuple[Optional[np.ndarray], Optional[str]]: Processed image and error message (if any).
232
+ """
233
+ if choice == "Upload" and image is not None:
234
+ return process_image_with_yolov8(model_name, image=image), None
235
+ elif choice == "URL" and url:
236
+ return process_image_with_yolov8(model_name, url=url), None
237
+ else:
238
+ return None, "Invalid input. Please provide an image or URL."
239
+
240
+ def process_input(model_name: str, local_video: Optional[str] = None, video_url: Optional[str] = None) -> Union[str, Optional[str]]:
241
+ """
242
+ Process input video with YOLOv8 model.
243
+
244
+ Args:
245
+ model_name (str): Name of the YOLO model to use.
246
+ local_video (Optional[str]): Path to local video file.
247
+ video_url (Optional[str]): YouTube video URL.
248
+
249
+ Returns:
250
+ Union[str, Optional[str]]: Path to processed video or error message.
251
+ """
252
+ model = load_yolov8_model(model_name)
253
+ if model is None:
254
+ return "Failed to load YOLO model."
255
+
256
+ output_path = os.path.join(tempfile.gettempdir(), "processed_video.mp4")
257
+
258
+ if local_video:
259
+ input_path = local_video
260
+ elif video_url:
261
+ input_path = download_youtube_video(video_url)
262
+ else:
263
+ return "Please provide a video file or YouTube URL."
264
+
265
+ if input_path is None:
266
+ return "Error downloading or accessing video."
267
+
268
+ result = process_video(input_path, output_path, model)
269
+ return result if result else "Error processing video."
270
+
271
+ # Create Gradio Interface
272
+ with gr.Blocks() as demo:
273
+ gr.Markdown("## Multimedia Object Detection Using YOLO")
274
+
275
+ model_choice = gr.Radio(["yolov8s.pt", "yolov8m.pt"], label="Select Model")
276
+
277
+ with gr.Tabs() as tabs:
278
+ with gr.TabItem("Image Detection"):
279
+ input_choice = gr.Radio(["Upload", "URL"], label="Select Input Method")
280
+ with gr.Row():
281
+ with gr.Column(visible=False) as upload_section:
282
+ input_image = gr.Image(type="pil", label="Upload Image")
283
+ with gr.Column(visible=False) as url_section:
284
+ input_url = gr.Textbox(label="Image URL", placeholder="Enter URL of the image")
285
+
286
+ def toggle_inputs(choice):
287
+ return (
288
+ gr.update(visible=choice == "Upload"),
289
+ gr.update(visible=choice == "URL")
290
+ )
291
+
292
+ input_choice.change(toggle_inputs, input_choice, [upload_section, url_section])
293
+ output_image = gr.Image(type="numpy", label="Processed Image")
294
+ process_button_image = gr.Button("Process Image")
295
+ process_button_image.click(handle_input_selection, [model_choice, input_choice, input_image, input_url], [output_image, gr.State()])
296
+
297
+ with gr.TabItem("Video Detection"):
298
+ local_video = gr.Video(label="Upload Local Video")
299
+ video_url = gr.Textbox(label="YouTube Video URL")
300
+ output_video = gr.Video(label="Processed Video")
301
+ process_button_video = gr.Button("Process Video")
302
+ process_button_video.click(process_input, [model_choice, local_video, video_url], output_video)
303
+
304
+ gr.Markdown("Upload an image, provide an image URL, or provide a YouTube video URL to perform object detection using YOLOv8 model.")
305
+
306
+ demo.launch()
requirements-3.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ opencv-python
3
+ numpy<2
4
+ pillow
5
+ pytube
6
+ requests
7
+ ultralytics
8
+ instaloader