YoloV8 可视化界面 GUI
- 本项目旨在基于 YoloV8 目标检测算法开发一个直观的可视化界面,使用户能够轻松上传图像或视频,并对其进行目标检测。
- 通过图形用户界面,用户可以方便地调整检测参数、查看检测结果,并将结果保存或导出。同时,该界面还将提供实时目标检测功能,让用户能够在视频流中实时观察目标的检测情况。
- 这个项目将结合 YoloV8 强大的检测能力和直观的用户交互,为用户提供一种全新的目标检测体验。
如何运行
- python>=3.8
- pip install ultralytics==8.0.48
- pip install pyside6==6.4.2
- python main.py
运行上述指令,则可以看到介入下界面!
!!必须安装相应版本的库
!!否则,将出现以下错误:not enough values to unpack (expected 5, got 4)
注意事项
ultralytics 遵循 GPL-3.0 协议,如需商业使用,需获得其许可。
建议
资源文件为 resources.qrc,如果您修改了默认图标,需要使用 pyside6-rcc resoures.qrc >
ui/resources_rc.py 命令来重新生成 .py 文件。
- 如果您希望使用自己的模型,您需要使用 ultralytics 先训练 yolov8/5 模型,然后将训练好的 .pt 文件放入
models 文件夹中。
- 软件中仍然存在一些 bug,我会在有时间的情况下持续优化并增加一些更有趣的功能。
- 如果您勾选保存结果,结果将保存在 ./run 路径下。
- UI 设计文件为 home.ui,如果您对其进行修改,需要使用 pyside6-uic home.ui > ui/home.py
命令来重新生成 .py 文件。
- 资源文件为 resources.qrc,如果您修改了默认图标,需要使用 pyside6-rcc resoures.qrc >
ui/resources_rc.py 命令来重新生成 .py 文件。
更改自己想要的界面,你可以按照以下步骤进行操作:
- 修改 UI 设计文件: 打开 UI 设计文件(如 .ui 文件),使用 PySide6 的 pyside6-uic 工具将其转换为
Python 代码。然后在生成的 Python 代码中进行修改,包括布局、组件样式、交互逻辑等。
- 修改资源文件: 如果界面中使用了自定义图标、图片等资源,你需要编辑资源文件(如 .qrc 文件),将新的资源添加进去,并使用
pyside6-rcc 工具将其编译成 Python 代码。
- 重新编译界面: 保存所有修改后的文件,并重新编译生成的 Python 代码。确保所有文件路径和引用都正确。
- 运行程序: 运行程序,查看界面效果,并进行调试和优化。
主要代码
class YoloPredictor(BasePredictor, QObject): yolo2main_pre_img = Signal(np.ndarray) # raw image signal yolo2main_res_img = Signal(np.ndarray) # test result signal yolo2main_status_msg = Signal(str) # Detecting/pausing/stopping/testing complete/error reporting signal yolo2main_fps = Signal(str) # fps yolo2main_labels = Signal(dict) # Detected target results (number of each category) yolo2main_progress = Signal(int) # Completeness yolo2main_class_num = Signal(int) # Number of categories detected yolo2main_target_num = Signal(int) # Targets detected def __init__(self, cfg=DEFAULT_CFG, overrides=None): super(YoloPredictor, self).__init__() QObject.__init__(self) self.args = get_cfg(cfg, overrides) project = self.args.project or Path(SETTINGS['runs_dir']) / self.args.task name = f'{self.args.mode}' self.save_dir = increment_path(Path(project) / name, exist_ok=self.args.exist_ok) self.done_warmup = False if self.args.show: self.args.show = check_imshow(warn=True) # GUI args self.used_model_name = None # The detection model name to use self.new_model_name = None # Models that change in real time self.source = '' # input source self.stop_dtc = False # Termination detection self.continue_dtc = True # pause self.save_res = False # Save test results self.save_txt = False # save label(txt) file self.iou_thres = 0.45 # iou self.conf_thres = 0.25 # conf self.speed_thres = 10 # delay, ms self.labels_dict = {} # return a dictionary of results self.progress_value = 0 # progress bar # Usable if setup is done self.model = None self.data = self.args.data # data_dict self.imgsz = None self.device = None self.dataset = None self.vid_path, self.vid_writer = None, None self.annotator = None self.data_path = None self.source_type = None self.batch = None self.callbacks = defaultdict(list, callbacks.default_callbacks) # add callbacks callbacks.add_integration_callbacks(self) # main for detect @smart_inference_mode() def run(self): try: if self.args.verbose: LOGGER.info('') # set model self.yolo2main_status_msg.emit('Loding Model...') if not self.model: self.setup_model(self.new_model_name) self.used_model_name = self.new_model_name # set source self.setup_source(self.source if self.source is not None else self.args.source) # Check save path/label if self.save_res or self.save_txt: (self.save_dir / 'labels' if self.save_txt else self.save_dir).mkdir(parents=True, exist_ok=True) # warmup model if not self.done_warmup: self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else self.dataset.bs, 3, *self.imgsz)) self.done_warmup = True self.seen, self.windows, self.dt, self.batch = 0, [], (ops.Profile(), ops.Profile(), ops.Profile()), None # start detection # for batch in self.dataset: count = 0 # run location frame start_time = time.time() # used to calculate the frame rate batch = iter(self.dataset) while True: # Termination detection if self.stop_dtc: if isinstance(self.vid_writer[-1], cv2.VideoWriter): self.vid_writer[-1].release() # release final video writer self.yolo2main_status_msg.emit('Detection terminated!') break # Change the model midway if self.used_model_name != self.new_model_name: # self.yolo2main_status_msg.emit('Change Model...') self.setup_model(self.new_model_name) self.used_model_name = self.new_model_name # pause switch if self.continue_dtc: # time.sleep(0.001) self.yolo2main_status_msg.emit('Detecting...') batch = next(self.dataset) # next data self.batch = batch path, im, im0s, vid_cap, s = batch visualize = increment_path(self.save_dir / Path(path).stem, mkdir=True) if self.args.visualize else False # Calculation completion and frame rate (to be optimized) count += 1 # frame count +1 if vid_cap: all_count = vid_cap.get(cv2.CAP_PROP_FRAME_COUNT) # total frames else: all_count = 1 self.progress_value = int(count/all_count*1000) # progress bar(0~1000) if count % 5 == 0 and count >= 5: # Calculate the frame rate every 5 frames