Spaces:
Running
Running
import streamlit as st | |
from ultralytics import YOLO | |
from huggingface_hub import hf_hub_download | |
import cv2 | |
import numpy as np | |
def get_model(): | |
repo_id = "danbiagini/hockey_breeds_v2" | |
return hf_hub_download(repo_id=repo_id, filename="hockey_breeds-v2-101623.pt") | |
def run_inference(img, model, thresh=0.5): | |
model = YOLO(model_f) | |
st.session_state.results = model(img) | |
return draw_hockey_boxes(img, st.session_state.results, thresh) | |
def draw_hockey_boxes(frame, results, thresh=0.5): | |
colors = {0: (0, 255, 0), 1: (255, 0, 0), 2: (0, 0, 255), 3: (128, 0, 0), 4: (0, 128, 0), 5: (0, 0, 128), 6: (0, 64, 0), 7: (64, 0, 0), 8: (0, 0, 64)} | |
font_scale = frame.shape[0] / 500 | |
objects = [] | |
for name in results: | |
for box in name.boxes.data.tolist(): | |
x1, y1, x2, y2, score, class_id = box | |
objects.append((name.names[int(class_id)], score)) | |
if score > thresh: | |
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), colors[(class_id % 9)], 3) | |
cv2.putText(frame, f'{name.names[int(class_id)].upper()}: {score:.2f}', (int(x1), int(y1 - 10)), | |
cv2.FONT_HERSHEY_SIMPLEX, font_scale, colors[(class_id % 9)], 3, cv2.LINE_AA) | |
else: | |
print(f'Found an object under confidence threshold {thresh} type: {name.names[class_id]}, score:{score}, x1, y2:{x1}, {y2}') | |
return objects | |
if 'results' not in st.session_state: | |
st.session_state.results = [] | |
st.set_page_config(page_title='Hockey Breeds v2 - Objects', layout="wide", | |
page_icon=":frame_with_picture:") | |
st.title('Hockey Breeds v2 - Objects') | |
intro = '''The first version of Hockey Breeds was fun and educational, but not useful for analyzing hockey videos. The second version is to a proof of concept | |
with the ability to recognize individual "objects" within an image, which paves the way to ultimately tracking those objects through game play.''' | |
st.markdown(intro) | |
st.subheader('Object Detection') | |
desc = '''Hockey Breed detector v2 uses a state of the art (circa 2023) computer vision approach. | |
I used the same training images as the first version of the Hockey Breeds model, but change the ML algorithm to use YOLO object detection (YOLO v8). | |
The output will be a set of hockey objects (defined by "bounding boxes") with labels for any hockey image uploaded. | |
**Object List**: | |
1. net | |
1. stick | |
1. puck | |
1. skater | |
1. goalie | |
1. referee | |
''' | |
st.markdown(desc) | |
st.subheader("Sample") | |
st.image('src/images/samples/v2/v2-sample1-090124.png', caption='Sample image with hockey objects detected') | |
st.subheader("Validation Results") | |
st.markdown('''Validation of the model\'s performance was done using 15 images not included in the training set. The model had many issues; it did poorly with detecting *pucks* and *sticks* vs backgrounds and even goalies and skaters. It did very well on detecting referees.''') | |
st.image("src/images/artifacts/confusion_matrix_v2.png", caption="Confusion Matrix for Hockey Breeds v2", ) | |
st.subheader("Try It Out") | |
img = st.file_uploader("Upload an image for object detection", type=["jpg", "jpeg", "png"]) | |
if img is not None: | |
thresh =st.slider('Set the object confidence threshold', min_value=0.0, max_value=1.0, value=0.5, step=0.01) | |
with st.status("Detecting hockey objects..."): | |
st.write("Loading model...") | |
model_f = get_model() | |
st.write("Processing image...") | |
frame = cv2.imdecode(np.frombuffer(img.read(), np.uint8), 1) | |
st.write("Running inference on image...") | |
objects = run_inference(frame, model_f, thresh) | |
st.dataframe(objects, column_config={ | |
"0": "Object", | |
"1": "Confidence" | |
}) | |
# check if the results list is empty | |
if len(st.session_state.results) == 0: | |
st.image(img, caption='Uploaded Image') | |
else: | |
st.image(frame, caption='Uploaded Image') | |
else: | |
st.session_state.results = [] | |