Hello hoodies I have trained a model for yolov8.
I want to use this in python exe.
Here is my code below:
try:
import time
import cv2
import mss
import numpy as np
from ultralytics import YOLO
import math
import os
import sys
def screen_capture():
with mss.mss() as sct:
monitor = sct.monitors[2]
sct_img = sct.grab(monitor)
frame = np.array(sct_img)
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
return frame
def detect_realtime(model):
while True:
frame = screen_capture()
results = model(frame,device="cpu")
highest_conf = 0
best_box = None
for r in results:
boxes = r.boxes
for box in boxes:
conf = box.conf[0]
if conf > highest_conf:
highest_conf = conf
best_box = box
if best_box:
x1, y1, x2, y2 = best_box.xyxy[0]
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
cls_id = int(best_box.cls[0])
conf = math.ceil(highest_conf * 100) / 100
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, f'{model.names[cls_id]} {conf:.2f}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
print([(x1+x2)//2, (y1+y2)//2])
resized_frame = cv2.resize(frame, (1366, 768))
cv2.imshow('YOLO Realtime Detection', resized_frame)
cv2.moveWindow('YOLO Realtime Detection', 2000, 100)
if cv2.waitKey(500) == ord('q'):
break
cv2.destroyAllWindows()
if __name__ == '__main__':
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
print(base_path)
anvil_model= os.path.join(base_path,'best.pt')
model = YOLO(anvil_model)
detect_realtime(model)
except Exception as e:
time.sleep(5555)
After, i make an exe with this command:
pyinstaller --onefile --add-data "best.pt;." main.py
Console wrote this error: [Errno 2] No such file or directory: 'C:\Users\User\AppData\Local\Temp\_MEI119602\ultralytics\cfg\default.yaml'
I have searched the YOLOv8 issues, I fount two issues below but there is not solution.
https://github.com/ultralytics/ultralytics/issues/7143
https://github.com/ultralytics/ultralytics/issues/1158
--onedir is not solution for me. I need one exe this can workable other pc's.
What sould I need do?
When packaging Python applications into a standalone executable (e.g., using PyInstaller), it's important to correctly determine the base path where the application's resources are located. This is crucial for accessing files bundled with the executable. There are different approaches to find this path, and understanding their differences can help in selecting the right method for your application.
First Approach Using _MEIPASS and file:
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
In this approach, getattr(sys, '_MEIPASS', ...) tries to get the attribute _MEIPASS from the sys module. _MEIPASS is a special attribute set by PyInstaller at runtime when the application is frozen (i.e., compiled as an executable). It points to a temporary folder where PyInstaller unpacks your bundled resources.
If _MEIPASS is not present (which is the case when running the script in an IDE or normally via Python interpreter), os.path.dirname(os.path.abspath(file)) is used. This gives the directory where the Python script is located.
if getattr(sys, 'frozen', False):
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
This approach uses an explicit check for the 'frozen' state of the application. getattr(sys, 'frozen', False) checks if the attribute frozen exists in the sys module and returns its value, or False if it doesn't exist. When a Python application is compiled into an executable, PyInstaller sets sys.frozen to True.
Based on this check, if the application is frozen, it uses sys._MEIPASS as the application path, otherwise, it falls back to the script's directory.