I have a Tkinter app for detecting the objects by importing images or videos from my system(using my custom model which predict fine when used via cmd predict function).
It works well, without any errors but it doesn’t display the image which gets imported neither it showcases detections after clicking on Detect button. Basically the output is “blank”.
My model image resolution is 640×640 and my system image size is 3840×2160
import tkinter as tk
from tkinter import filedialog
import cv2
import numpy as np
import onnxruntime
from PIL import Image, ImageTk
class ObjectDetector:
def __init__(self, model_path):
self.session = onnxruntime.InferenceSession(model_path)
self.input_name = self.session.get_inputs()[0].name
self.output_name = self.session.get_outputs()[0].name
self.input_shape = self.session.get_inputs()[0].shape[2:] # Get input shape from model
def detect_objects(self, image):
input_image = cv2.resize(image, (self.input_shape[1], self.input_shape[0])) # Resize image
input_image = np.transpose(input_image, (2, 0, 1)) # Change to NCHW format
input_image = np.expand_dims(input_image, axis=0).astype(np.float32)
input_image /= 255.0 # Normalize image
outputs = self.session.run([self.output_name], {self.input_name: input_image})
return outputs[0]
class App:
def __init__(self, root):
self.root = root
self.root.title("Object Detection App")
self.detector = None
self.image_path = None
self.create_widgets()
def create_widgets(self):
self.select_button = tk.Button(self.root, text="Select Image or Video", command=self.select_file)
self.select_button.pack()
self.detect_button = tk.Button(self.root, text="Detect Objects", command=self.detect_objects, state=tk.DISABLED)
self.detect_button.pack()
# Use a smaller canvas size
self.canvas = tk.Canvas(self.root, bg="white", width=800, height=600)
self.canvas.pack()
def select_file(self):
self.image_path = filedialog.askopenfilename()
if self.image_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
self.detect_button.config(state="normal")
self.display_image()
else:
self.detect_button.config(state="disabled")
def display_image(self):
if self.image_path:
image = cv2.imread(self.image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (800, 600)) # Resize image to fit canvas
img_tk = self.convert_image_to_tkinter(image)
self.canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)
def detect_objects(self):
if self.image_path:
if self.image_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
image = cv2.imread(self.image_path)
detector = ObjectDetector("C:/Software/anaconda22/envs/yolov8_custom/yolov8m_custom.onnx")
results = detector.detect_objects(image)
self.draw_bounding_boxes(image, results)
img_tk = self.convert_image_to_tkinter(image)
self.canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)
else:
print("Unsupported file format. Please select an image file.")
def draw_bounding_boxes(self, image, results):
for result in results:
for detection in result:
score = detection[-1]
if score > 0.2: # Filter out detections with low confidence
if len(detection) >= 7: # Check if the detection array has enough elements
x_min, y_min, x_max, y_max = detection[-4:]
# Scale bounding box coordinates to fit canvas size
x_min *= (800 / image.shape[1])
y_min *= (600 / image.shape[0])
x_max *= (800 / image.shape[1])
y_max *= (600 / image.shape[0])
cv2.rectangle(image, (int(x_min), int(y_min)), (int(x_max), int(y_max)), (0, 255, 0), 2)
def convert_image_to_tkinter(self, image):
img = Image.fromarray(image)
img_tk = ImageTk.PhotoImage(image=img)
return img_tk
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
I have tried including labels also for the draw_bounding_boxes func but even that didn’t work.