Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,29 +3,28 @@ import gradio as gr
|
|
| 3 |
import os
|
| 4 |
import tempfile
|
| 5 |
import cv2
|
|
|
|
| 6 |
from ultralytics import YOLO
|
| 7 |
|
| 8 |
-
#
|
| 9 |
sys.argv = [arg for arg in sys.argv if arg != "--import"]
|
| 10 |
|
| 11 |
-
# Load the YOLO11-pose model (
|
| 12 |
model = YOLO("yolo11n-pose.pt")
|
| 13 |
|
| 14 |
-
def process_input(uploaded_file, youtube_link):
|
| 15 |
"""
|
| 16 |
-
Process an uploaded file
|
| 17 |
-
Returns a tuple: (annotated_file_path, status_message).
|
| 18 |
-
|
| 19 |
"""
|
| 20 |
-
error_message = ""
|
| 21 |
input_path = None
|
| 22 |
|
| 23 |
-
#
|
| 24 |
if youtube_link and youtube_link.strip():
|
| 25 |
try:
|
| 26 |
from pytube import YouTube
|
| 27 |
yt = YouTube(youtube_link)
|
| 28 |
-
# Get the highest resolution progressive mp4 stream
|
| 29 |
stream = yt.streams.filter(file_extension='mp4', progressive=True)\
|
| 30 |
.order_by("resolution").desc().first()
|
| 31 |
if stream is None:
|
|
@@ -33,54 +32,70 @@ def process_input(uploaded_file, youtube_link):
|
|
| 33 |
input_path = stream.download()
|
| 34 |
except Exception as e:
|
| 35 |
return None, f"Error downloading video: {e}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
elif uploaded_file is not None:
|
| 37 |
input_path = uploaded_file.name
|
| 38 |
else:
|
| 39 |
-
return None, "Please provide
|
| 40 |
|
| 41 |
-
# Run pose detection (with save=True so
|
| 42 |
try:
|
| 43 |
results = model.predict(source=input_path, save=True)
|
| 44 |
except Exception as e:
|
| 45 |
return None, f"Error running prediction: {e}"
|
| 46 |
|
| 47 |
-
# Try to get the annotated output file:
|
| 48 |
output_path = None
|
| 49 |
try:
|
| 50 |
-
#
|
| 51 |
if hasattr(results[0], "save_path"):
|
| 52 |
output_path = results[0].save_path
|
| 53 |
else:
|
| 54 |
-
#
|
| 55 |
-
annotated = results[0].plot() # returns a numpy array
|
| 56 |
-
# Save the annotated image to a temporary file.
|
| 57 |
output_path = os.path.join(tempfile.gettempdir(), "annotated.jpg")
|
| 58 |
cv2.imwrite(output_path, annotated)
|
| 59 |
except Exception as e:
|
| 60 |
return None, f"Error processing the file: {e}"
|
| 61 |
|
| 62 |
-
#
|
| 63 |
-
if youtube_link and input_path and os.path.exists(input_path):
|
| 64 |
os.remove(input_path)
|
| 65 |
-
|
| 66 |
return output_path, "Success!"
|
| 67 |
|
| 68 |
-
# Define the Gradio interface
|
| 69 |
with gr.Blocks() as demo:
|
|
|
|
| 70 |
gr.Markdown("# Pose Detection with YOLO11-pose")
|
| 71 |
-
gr.
|
| 72 |
-
|
|
|
|
| 73 |
with gr.Row():
|
| 74 |
file_input = gr.File(label="Upload Image/Video")
|
| 75 |
-
|
| 76 |
-
|
|
|
|
|
|
|
| 77 |
output_file = gr.File(label="Download Annotated Output")
|
| 78 |
output_text = gr.Textbox(label="Status", interactive=False)
|
| 79 |
run_button = gr.Button("Run Pose Detection")
|
| 80 |
-
|
| 81 |
-
run_button.click(process_input, inputs=[file_input, youtube_input],
|
| 82 |
outputs=[output_file, output_text])
|
| 83 |
|
| 84 |
-
# Only launch the
|
| 85 |
if __name__ == "__main__":
|
| 86 |
demo.launch()
|
|
|
|
| 3 |
import os
|
| 4 |
import tempfile
|
| 5 |
import cv2
|
| 6 |
+
import requests
|
| 7 |
from ultralytics import YOLO
|
| 8 |
|
| 9 |
+
# Remove extra CLI arguments (like "--import") from Spaces.
|
| 10 |
sys.argv = [arg for arg in sys.argv if arg != "--import"]
|
| 11 |
|
| 12 |
+
# Load the YOLO11-pose model (will auto-download if needed)
|
| 13 |
model = YOLO("yolo11n-pose.pt")
|
| 14 |
|
| 15 |
+
def process_input(uploaded_file, youtube_link, image_url):
|
| 16 |
"""
|
| 17 |
+
Process an uploaded file, a YouTube link, or an image URL for pose detection.
|
| 18 |
+
Returns a tuple: (annotated_file_path, status_message).
|
| 19 |
+
Priority is given to the YouTube link first, then image URL, then the uploaded file.
|
| 20 |
"""
|
|
|
|
| 21 |
input_path = None
|
| 22 |
|
| 23 |
+
# Priority 1: YouTube link
|
| 24 |
if youtube_link and youtube_link.strip():
|
| 25 |
try:
|
| 26 |
from pytube import YouTube
|
| 27 |
yt = YouTube(youtube_link)
|
|
|
|
| 28 |
stream = yt.streams.filter(file_extension='mp4', progressive=True)\
|
| 29 |
.order_by("resolution").desc().first()
|
| 30 |
if stream is None:
|
|
|
|
| 32 |
input_path = stream.download()
|
| 33 |
except Exception as e:
|
| 34 |
return None, f"Error downloading video: {e}"
|
| 35 |
+
# Priority 2: Image URL
|
| 36 |
+
elif image_url and image_url.strip():
|
| 37 |
+
try:
|
| 38 |
+
response = requests.get(image_url, stream=True)
|
| 39 |
+
if response.status_code != 200:
|
| 40 |
+
return None, f"Error downloading image: HTTP {response.status_code}"
|
| 41 |
+
# Save the downloaded image to a temporary file.
|
| 42 |
+
temp_image_path = os.path.join(tempfile.gettempdir(), "downloaded_image.jpg")
|
| 43 |
+
with open(temp_image_path, "wb") as f:
|
| 44 |
+
f.write(response.content)
|
| 45 |
+
input_path = temp_image_path
|
| 46 |
+
except Exception as e:
|
| 47 |
+
return None, f"Error downloading image: {e}"
|
| 48 |
+
# Priority 3: Uploaded file
|
| 49 |
elif uploaded_file is not None:
|
| 50 |
input_path = uploaded_file.name
|
| 51 |
else:
|
| 52 |
+
return None, "Please provide a YouTube link, image URL, or upload a file."
|
| 53 |
|
| 54 |
+
# Run pose detection (with save=True so annotated results are written to disk)
|
| 55 |
try:
|
| 56 |
results = model.predict(source=input_path, save=True)
|
| 57 |
except Exception as e:
|
| 58 |
return None, f"Error running prediction: {e}"
|
| 59 |
|
|
|
|
| 60 |
output_path = None
|
| 61 |
try:
|
| 62 |
+
# If the results object has a save_path attribute, use it.
|
| 63 |
if hasattr(results[0], "save_path"):
|
| 64 |
output_path = results[0].save_path
|
| 65 |
else:
|
| 66 |
+
# Otherwise, generate an annotated image using plot() and save it manually.
|
| 67 |
+
annotated = results[0].plot() # returns a numpy array
|
|
|
|
| 68 |
output_path = os.path.join(tempfile.gettempdir(), "annotated.jpg")
|
| 69 |
cv2.imwrite(output_path, annotated)
|
| 70 |
except Exception as e:
|
| 71 |
return None, f"Error processing the file: {e}"
|
| 72 |
|
| 73 |
+
# If the input came from YouTube or image URL, remove the temporary file.
|
| 74 |
+
if (youtube_link or (image_url and image_url.strip())) and input_path and os.path.exists(input_path):
|
| 75 |
os.remove(input_path)
|
| 76 |
+
|
| 77 |
return output_path, "Success!"
|
| 78 |
|
| 79 |
+
# Define the Gradio interface.
|
| 80 |
with gr.Blocks() as demo:
|
| 81 |
+
# Display the default image (crowdresult.jpg) at the top.
|
| 82 |
gr.Markdown("# Pose Detection with YOLO11-pose")
|
| 83 |
+
gr.Image(value="crowdresult.jpg", label="Crowd Result", interactive=False)
|
| 84 |
+
gr.Markdown("Upload an image/video, provide an image URL, or supply a YouTube link to detect human poses.")
|
| 85 |
+
|
| 86 |
with gr.Row():
|
| 87 |
file_input = gr.File(label="Upload Image/Video")
|
| 88 |
+
with gr.Row():
|
| 89 |
+
youtube_input = gr.Textbox(label="YouTube Link", placeholder="https://...")
|
| 90 |
+
image_url_input = gr.Textbox(label="Image URL", placeholder="https://...")
|
| 91 |
+
|
| 92 |
output_file = gr.File(label="Download Annotated Output")
|
| 93 |
output_text = gr.Textbox(label="Status", interactive=False)
|
| 94 |
run_button = gr.Button("Run Pose Detection")
|
| 95 |
+
|
| 96 |
+
run_button.click(process_input, inputs=[file_input, youtube_input, image_url_input],
|
| 97 |
outputs=[output_file, output_text])
|
| 98 |
|
| 99 |
+
# Only launch the interface if executed directly.
|
| 100 |
if __name__ == "__main__":
|
| 101 |
demo.launch()
|