diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index 34886eb140e..b69280278b4 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -512,14 +512,14 @@ def handle_yolo_settings(args: List[str]) -> None: def handle_explorer(): """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...") subprocess.run(["streamlit", "run", ROOT / "data/explorer/gui/dash.py", "--server.maxMessageSize", "2048"]) def handle_streamlit_inference(): """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...") subprocess.run(["streamlit", "run", ROOT / "solutions/streamlit_inference.py", "--server.headless", "true"]) diff --git a/ultralytics/solutions/parking_management.py b/ultralytics/solutions/parking_management.py index 19564cf9145..c19f994d79a 100644 --- a/ultralytics/solutions/parking_management.py +++ b/ultralytics/solutions/parking_management.py @@ -1,11 +1,9 @@ # Ultralytics YOLO 🚀, AGPL-3.0 license import json -from tkinter import filedialog, messagebox import cv2 import numpy as np -from PIL import Image, ImageTk from ultralytics.utils.checks import check_imshow, check_requirements from ultralytics.utils.plotting import Annotator @@ -16,7 +14,7 @@ def __init__(self): """Initializes the UI for selecting parking zone points in a tkinter window.""" check_requirements("tkinter") - import tkinter as tk + import tkinter as tk # scope for multi-environment compatibility self.tk = tk self.master = tk.Tk() @@ -55,6 +53,10 @@ def __init__(self): def upload_image(self): """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")]) if not self.image_path: return @@ -115,6 +117,8 @@ def draw_bounding_box(self, box): def remove_last_bounding_box(self): """Remove the last drawn bounding box from canvas.""" + from tkinter import messagebox # scope for multi-environment compatibility + if self.bounding_boxes: self.bounding_boxes.pop() # Remove the last bounding box self.canvas.delete("all") # Clear the canvas @@ -130,6 +134,8 @@ def remove_last_bounding_box(self): def save_to_json(self): """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() width_scaling_factor = self.img_width / canvas_width height_scaling_factor = self.img_height / canvas_height @@ -141,8 +147,8 @@ def save_to_json(self): rescaled_y = int(y * height_scaling_factor) rescaled_box.append((rescaled_x, rescaled_y)) bounding_boxes_data.append({"points": rescaled_box}) - with open("bounding_boxes.json", "w") as json_file: - json.dump(bounding_boxes_data, json_file, indent=4) + with open("bounding_boxes.json", "w") as f: + json.dump(bounding_boxes_data, f, indent=4) messagebox.showinfo("Success", "Bounding boxes saved to bounding_boxes.json") @@ -187,11 +193,10 @@ def __init__( self.env_check = check_imshow(warn=True) 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 - self.model = YOLO(self.model_path) - return self.model + return YOLO(self.model_path) @staticmethod def parking_regions_extraction(json_file): @@ -201,8 +206,8 @@ def parking_regions_extraction(json_file): Args: json_file (str): file that have all parking slot points """ - with open(json_file, "r") as json_file: - return json.load(json_file) + with open(json_file, "r") as f: + return json.load(f) def process_data(self, json_data, im0, boxes, clss): """ @@ -219,12 +224,9 @@ def process_data(self, json_data, im0, boxes, clss): empty_slots (int): total slots that are available in parking lot """ annotator = Annotator(im0) - total_slots, filled_slots = len(json_data), 0 - empty_slots = total_slots - + empty_slots, filled_slots = len(json_data), 0 for region in json_data: - points = region["points"] - points_array = np.array(points, dtype=np.int32).reshape((-1, 1, 2)) + points_array = np.array(region["points"], dtype=np.int32).reshape((-1, 1, 2)) region_occupied = False for box, cls in zip(boxes, clss): diff --git a/ultralytics/solutions/streamlit_inference.py b/ultralytics/solutions/streamlit_inference.py index 7f89963ace9..9335690f104 100644 --- a/ultralytics/solutions/streamlit_inference.py +++ b/ultralytics/solutions/streamlit_inference.py @@ -6,13 +6,13 @@ import cv2 import torch +from ultralytics.utils.checks import check_requirements from ultralytics.utils.downloads import GITHUB_ASSETS_STEMS def inference(): """Runs real-time object detection on video input using Ultralytics YOLOv8 in a Streamlit application.""" - - # Scope imports for faster ultralytics package load speeds + check_requirements("streamlit>=1.29.0") # scope imports for faster ultralytics package load speeds import streamlit as st from ultralytics import YOLO