Scope tkinter and streamlit in Solutions tests (#14426)

Signed-off-by: Glenn Jocher <glenn.jocher@ultralytics.com>
Co-authored-by: UltralyticsAssistant <web@ultralytics.com>
This commit is contained in:
Glenn Jocher 2024-07-15 02:16:23 +02:00 committed by GitHub
parent c67a3039c1
commit e094f9c371
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 19 deletions

View file

@ -512,14 +512,14 @@ def handle_yolo_settings(args: List[str]) -> None:
def handle_explorer(): def handle_explorer():
"""Open the Ultralytics Explorer GUI for dataset exploration and analysis.""" """Open the Ultralytics Explorer GUI for dataset exploration and analysis."""
checks.check_requirements("streamlit") checks.check_requirements("streamlit>=1.29.0")
LOGGER.info("💡 Loading Explorer dashboard...") LOGGER.info("💡 Loading Explorer dashboard...")
subprocess.run(["streamlit", "run", ROOT / "data/explorer/gui/dash.py", "--server.maxMessageSize", "2048"]) subprocess.run(["streamlit", "run", ROOT / "data/explorer/gui/dash.py", "--server.maxMessageSize", "2048"])
def handle_streamlit_inference(): def handle_streamlit_inference():
"""Open the Ultralytics Live Inference streamlit app for real time object detection.""" """Open the Ultralytics Live Inference streamlit app for real time object detection."""
checks.check_requirements(["streamlit", "opencv-python", "torch"]) checks.check_requirements("streamlit>=1.29.0")
LOGGER.info("💡 Loading Ultralytics Live Inference app...") LOGGER.info("💡 Loading Ultralytics Live Inference app...")
subprocess.run(["streamlit", "run", ROOT / "solutions/streamlit_inference.py", "--server.headless", "true"]) subprocess.run(["streamlit", "run", ROOT / "solutions/streamlit_inference.py", "--server.headless", "true"])

View file

@ -1,11 +1,9 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license # Ultralytics YOLO 🚀, AGPL-3.0 license
import json import json
from tkinter import filedialog, messagebox
import cv2 import cv2
import numpy as np import numpy as np
from PIL import Image, ImageTk
from ultralytics.utils.checks import check_imshow, check_requirements from ultralytics.utils.checks import check_imshow, check_requirements
from ultralytics.utils.plotting import Annotator from ultralytics.utils.plotting import Annotator
@ -16,7 +14,7 @@ class ParkingPtsSelection:
"""Initializes the UI for selecting parking zone points in a tkinter window.""" """Initializes the UI for selecting parking zone points in a tkinter window."""
check_requirements("tkinter") check_requirements("tkinter")
import tkinter as tk import tkinter as tk # scope for multi-environment compatibility
self.tk = tk self.tk = tk
self.master = tk.Tk() self.master = tk.Tk()
@ -55,6 +53,10 @@ class ParkingPtsSelection:
def upload_image(self): def upload_image(self):
"""Upload an image and resize it to fit canvas.""" """Upload an image and resize it to fit canvas."""
from tkinter import filedialog
from PIL import Image, ImageTk # scope because ImageTk requires tkinter package
self.image_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")]) self.image_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
if not self.image_path: if not self.image_path:
return return
@ -115,6 +117,8 @@ class ParkingPtsSelection:
def remove_last_bounding_box(self): def remove_last_bounding_box(self):
"""Remove the last drawn bounding box from canvas.""" """Remove the last drawn bounding box from canvas."""
from tkinter import messagebox # scope for multi-environment compatibility
if self.bounding_boxes: if self.bounding_boxes:
self.bounding_boxes.pop() # Remove the last bounding box self.bounding_boxes.pop() # Remove the last bounding box
self.canvas.delete("all") # Clear the canvas self.canvas.delete("all") # Clear the canvas
@ -130,6 +134,8 @@ class ParkingPtsSelection:
def save_to_json(self): def save_to_json(self):
"""Saves rescaled bounding boxes to 'bounding_boxes.json' based on image-to-canvas size ratio.""" """Saves rescaled bounding boxes to 'bounding_boxes.json' based on image-to-canvas size ratio."""
from tkinter import messagebox # scope for multi-environment compatibility
canvas_width, canvas_height = self.canvas.winfo_width(), self.canvas.winfo_height() canvas_width, canvas_height = self.canvas.winfo_width(), self.canvas.winfo_height()
width_scaling_factor = self.img_width / canvas_width width_scaling_factor = self.img_width / canvas_width
height_scaling_factor = self.img_height / canvas_height height_scaling_factor = self.img_height / canvas_height
@ -141,8 +147,8 @@ class ParkingPtsSelection:
rescaled_y = int(y * height_scaling_factor) rescaled_y = int(y * height_scaling_factor)
rescaled_box.append((rescaled_x, rescaled_y)) rescaled_box.append((rescaled_x, rescaled_y))
bounding_boxes_data.append({"points": rescaled_box}) bounding_boxes_data.append({"points": rescaled_box})
with open("bounding_boxes.json", "w") as json_file: with open("bounding_boxes.json", "w") as f:
json.dump(bounding_boxes_data, json_file, indent=4) json.dump(bounding_boxes_data, f, indent=4)
messagebox.showinfo("Success", "Bounding boxes saved to bounding_boxes.json") messagebox.showinfo("Success", "Bounding boxes saved to bounding_boxes.json")
@ -187,11 +193,10 @@ class ParkingManagement:
self.env_check = check_imshow(warn=True) self.env_check = check_imshow(warn=True)
def load_model(self): def load_model(self):
"""Load the Ultralytics YOLOv8 model for inference and analytics.""" """Load the Ultralytics YOLO model for inference and analytics."""
from ultralytics import YOLO from ultralytics import YOLO
self.model = YOLO(self.model_path) return YOLO(self.model_path)
return self.model
@staticmethod @staticmethod
def parking_regions_extraction(json_file): def parking_regions_extraction(json_file):
@ -201,8 +206,8 @@ class ParkingManagement:
Args: Args:
json_file (str): file that have all parking slot points json_file (str): file that have all parking slot points
""" """
with open(json_file, "r") as json_file: with open(json_file, "r") as f:
return json.load(json_file) return json.load(f)
def process_data(self, json_data, im0, boxes, clss): def process_data(self, json_data, im0, boxes, clss):
""" """
@ -219,12 +224,9 @@ class ParkingManagement:
empty_slots (int): total slots that are available in parking lot empty_slots (int): total slots that are available in parking lot
""" """
annotator = Annotator(im0) annotator = Annotator(im0)
total_slots, filled_slots = len(json_data), 0 empty_slots, filled_slots = len(json_data), 0
empty_slots = total_slots
for region in json_data: for region in json_data:
points = region["points"] points_array = np.array(region["points"], dtype=np.int32).reshape((-1, 1, 2))
points_array = np.array(points, dtype=np.int32).reshape((-1, 1, 2))
region_occupied = False region_occupied = False
for box, cls in zip(boxes, clss): for box, cls in zip(boxes, clss):

View file

@ -6,13 +6,13 @@ import time
import cv2 import cv2
import torch import torch
from ultralytics.utils.checks import check_requirements
from ultralytics.utils.downloads import GITHUB_ASSETS_STEMS from ultralytics.utils.downloads import GITHUB_ASSETS_STEMS
def inference(): def inference():
"""Runs real-time object detection on video input using Ultralytics YOLOv8 in a Streamlit application.""" """Runs real-time object detection on video input using Ultralytics YOLOv8 in a Streamlit application."""
check_requirements("streamlit>=1.29.0") # scope imports for faster ultralytics package load speeds
# Scope imports for faster ultralytics package load speeds
import streamlit as st import streamlit as st
from ultralytics import YOLO from ultralytics import YOLO