Upload 12 files
Browse files- .gitattributes +1 -0
- app.py +64 -0
- images/posing-sample-image1.jpg +0 -0
- images/posing-sample-image2.png +3 -0
- images/posing-sample-image3.jpg +0 -0
- images/posing-sample-image4.jpg +0 -0
- images/posing-sample-image5.jpg +0 -0
- requirements.txt +6 -0
- src/__init__.py +0 -0
- src/app/__init__.py +0 -0
- src/app/predict_pose.py +62 -0
- src/exception.py +50 -0
- src/logger.py +21 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
images/posing-sample-image2.png filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Importing the requirements
|
2 |
+
import warnings
|
3 |
+
warnings.filterwarnings("ignore")
|
4 |
+
|
5 |
+
import gradio as gr
|
6 |
+
from src.app.predict_pose import predict_pose
|
7 |
+
|
8 |
+
|
9 |
+
# Image and input parameters
|
10 |
+
image = gr.Image(type="pil", label="Image")
|
11 |
+
confidence_threshold = gr.Slider(
|
12 |
+
minimum=0, maximum=1, step=0.01, value=0.25, label="Confidence threshold"
|
13 |
+
)
|
14 |
+
iou_threshold = gr.Slider(
|
15 |
+
minimum=0, maximum=1, step=0.01, value=0.45, label="IoU threshold"
|
16 |
+
)
|
17 |
+
max_detections = gr.Slider(
|
18 |
+
minimum=1, maximum=300, step=1, value=300, label="Max detections"
|
19 |
+
)
|
20 |
+
model_name = gr.Radio(
|
21 |
+
choices=[
|
22 |
+
"yolo11n-pose.pt",
|
23 |
+
"yolo11s-pose.pt",
|
24 |
+
"yolo11m-pose.pt",
|
25 |
+
"yolo11l-pose.pt",
|
26 |
+
"yolo11x-pose.pt",
|
27 |
+
],
|
28 |
+
label="Model name",
|
29 |
+
value="yolo11n-pose.pt",
|
30 |
+
)
|
31 |
+
|
32 |
+
# Output image
|
33 |
+
pose_image = gr.Image(type="pil", label="Output Image")
|
34 |
+
|
35 |
+
# Examples for the interface
|
36 |
+
examples = [
|
37 |
+
["images/posing-sample-image3.jpg", 0.25, 0.45, 300, "yolo11n-pose.pt"],
|
38 |
+
["images/posing-sample-image4.jpg", 0.25, 0.45, 300, "yolo11s-pose.pt"],
|
39 |
+
["images/posing-sample-image5.jpg", 0.25, 0.45, 300, "yolo11m-pose.pt"],
|
40 |
+
["images/posing-sample-image1.jpg", 0.25, 0.45, 300, "yolo11l-pose.pt"],
|
41 |
+
["images/posing-sample-image2.png", 0.25, 0.45, 300, "yolo11x-pose.pt"],
|
42 |
+
]
|
43 |
+
|
44 |
+
# Title, description, and article for the interface
|
45 |
+
title = "YOLO11 Pose Estimation"
|
46 |
+
description = "Gradio Demo for the YOLO11 Pose Estimation model. This model can detect and predict the poses of people in images. To use it, upload your image, select associated parameters, or use the default values, click 'Submit', or click one of the examples to load them. You can read more at the links below."
|
47 |
+
article = "<p style='text-align: center'><a href='https://github.com/ultralytics/ultralytics' target='_blank'>Ultralytics GitHub</a> | <a href='https://docs.ultralytics.com/models/yolo11/' target='_blank'>Model Page</a></p>"
|
48 |
+
|
49 |
+
|
50 |
+
# Launch the interface
|
51 |
+
interface = gr.Interface(
|
52 |
+
fn=predict_pose,
|
53 |
+
inputs=[image, confidence_threshold, iou_threshold, max_detections, model_name],
|
54 |
+
outputs=pose_image,
|
55 |
+
examples=examples,
|
56 |
+
cache_examples=True,
|
57 |
+
cache_mode="lazy",
|
58 |
+
title=title,
|
59 |
+
description=description,
|
60 |
+
article=article,
|
61 |
+
theme="Nymbo/Nymbo_Theme",
|
62 |
+
flagging_mode="never",
|
63 |
+
)
|
64 |
+
interface.launch(debug=False)
|
images/posing-sample-image1.jpg
ADDED
images/posing-sample-image2.png
ADDED
Git LFS Details
|
images/posing-sample-image3.jpg
ADDED
images/posing-sample-image4.jpg
ADDED
images/posing-sample-image5.jpg
ADDED
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Pillow
|
2 |
+
torch==2.4.0
|
3 |
+
torchvision>=0.9.0
|
4 |
+
ultralytics>=8.3.0
|
5 |
+
spaces
|
6 |
+
gradio
|
src/__init__.py
ADDED
File without changes
|
src/app/__init__.py
ADDED
File without changes
|
src/app/predict_pose.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sys
|
2 |
+
import PIL.Image as Image
|
3 |
+
from ultralytics import YOLO
|
4 |
+
import gradio as gr
|
5 |
+
import spaces
|
6 |
+
|
7 |
+
# Local imports
|
8 |
+
from src.logger import logging
|
9 |
+
from src.exception import CustomExceptionHandling
|
10 |
+
|
11 |
+
|
12 |
+
@spaces.GPU
|
13 |
+
def predict_pose(
|
14 |
+
img: str, conf_threshold: float, iou_threshold: float, model_name: str
|
15 |
+
) -> Image.Image:
|
16 |
+
"""
|
17 |
+
Predicts objects in an image using a YOLOv8 model with adjustable confidence and IOU thresholds.
|
18 |
+
|
19 |
+
Args:
|
20 |
+
- img (str or numpy.ndarray): The input image or path to the image file.
|
21 |
+
- conf_threshold (float): The confidence threshold for object detection.
|
22 |
+
- iou_threshold (float): The Intersection Over Union (IOU) threshold for non-max suppression.
|
23 |
+
- model_name (str): The name or path of the YOLOv8 model to be used for prediction.
|
24 |
+
|
25 |
+
Returns:
|
26 |
+
PIL.Image.Image: The image with predicted objects plotted on it.
|
27 |
+
"""
|
28 |
+
try:
|
29 |
+
# Check if image is None
|
30 |
+
if img is None:
|
31 |
+
gr.Warning("Please provide an image.")
|
32 |
+
|
33 |
+
# Load the YOLO model
|
34 |
+
model = YOLO(model_name)
|
35 |
+
|
36 |
+
# Predict objects in the image
|
37 |
+
results = model.predict(
|
38 |
+
source=img,
|
39 |
+
conf=conf_threshold,
|
40 |
+
iou=iou_threshold,
|
41 |
+
show_labels=True,
|
42 |
+
show_conf=True,
|
43 |
+
imgsz=640,
|
44 |
+
half=True,
|
45 |
+
device="cuda:0",
|
46 |
+
)
|
47 |
+
|
48 |
+
# Plot the predicted objects on the image
|
49 |
+
for r in results:
|
50 |
+
im_array = r.plot()
|
51 |
+
im = Image.fromarray(im_array[..., ::-1])
|
52 |
+
|
53 |
+
# Log the successful prediction
|
54 |
+
logging.info("Pose estimated successfully.")
|
55 |
+
|
56 |
+
# Return the image
|
57 |
+
return im
|
58 |
+
|
59 |
+
# Handle exceptions that may occur during the process
|
60 |
+
except Exception as e:
|
61 |
+
# Custom exception handling
|
62 |
+
raise CustomExceptionHandling(e, sys) from e
|
src/exception.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
This module defines a custom exception handling class and a function to get error message with details of the error.
|
3 |
+
"""
|
4 |
+
|
5 |
+
# Standard Library
|
6 |
+
import sys
|
7 |
+
|
8 |
+
# Local imports
|
9 |
+
from src.logger import logging
|
10 |
+
|
11 |
+
|
12 |
+
# Function Definition to get error message with details of the error (file name and line number) when an error occurs in the program
|
13 |
+
def get_error_message(error, error_detail: sys):
|
14 |
+
"""
|
15 |
+
Get error message with details of the error.
|
16 |
+
|
17 |
+
Args:
|
18 |
+
- error (Exception): The error that occurred.
|
19 |
+
- error_detail (sys): The details of the error.
|
20 |
+
|
21 |
+
Returns:
|
22 |
+
str: A string containing the error message along with the file name and line number where the error occurred.
|
23 |
+
"""
|
24 |
+
_, _, exc_tb = error_detail.exc_info()
|
25 |
+
|
26 |
+
# Get error details
|
27 |
+
file_name = exc_tb.tb_frame.f_code.co_filename
|
28 |
+
return "Error occured in python script name [{0}] line number [{1}] error message[{2}]".format(
|
29 |
+
file_name, exc_tb.tb_lineno, str(error)
|
30 |
+
)
|
31 |
+
|
32 |
+
|
33 |
+
# Custom Exception Handling Class Definition
|
34 |
+
class CustomExceptionHandling(Exception):
|
35 |
+
"""
|
36 |
+
Custom Exception Handling:
|
37 |
+
This class defines a custom exception that can be raised when an error occurs in the program.
|
38 |
+
It takes an error message and an error detail as input and returns a formatted error message when the exception is raised.
|
39 |
+
"""
|
40 |
+
|
41 |
+
# Constructor
|
42 |
+
def __init__(self, error_message, error_detail: sys):
|
43 |
+
"""Initialize the exception"""
|
44 |
+
super().__init__(error_message)
|
45 |
+
|
46 |
+
self.error_message = get_error_message(error_message, error_detail=error_detail)
|
47 |
+
|
48 |
+
def __str__(self):
|
49 |
+
"""String representation of the exception"""
|
50 |
+
return self.error_message
|
src/logger.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Importing the required modules
|
2 |
+
import os
|
3 |
+
import logging
|
4 |
+
from datetime import datetime
|
5 |
+
|
6 |
+
# Creating a log file with the current date and time as the name of the file
|
7 |
+
LOG_FILE = f"{datetime.now().strftime('%m_%d_%Y_%H_%M_%S')}.log"
|
8 |
+
|
9 |
+
# Creating a logs folder if it does not exist
|
10 |
+
logs_path = os.path.join(os.getcwd(), "logs", LOG_FILE)
|
11 |
+
os.makedirs(logs_path, exist_ok=True)
|
12 |
+
|
13 |
+
# Setting the log file path and the log level
|
14 |
+
LOG_FILE_PATH = os.path.join(logs_path, LOG_FILE)
|
15 |
+
|
16 |
+
# Configuring the logger
|
17 |
+
logging.basicConfig(
|
18 |
+
filename=LOG_FILE_PATH,
|
19 |
+
format="[ %(asctime)s ] %(lineno)d %(name)s - %(levelname)s - %(message)s",
|
20 |
+
level=logging.INFO,
|
21 |
+
)
|