经过5天的学习,我做了一个界面。
我称它为 yolox-qt 1.0
下面看下界面
来测一下功能
训练完成自动删除路径
功能基本成功
在测试中发现了一个问题将是在显示图片的时候
我写死了,你们可以自己改进一下。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '1.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Copyright (c) Megvii, Inc. and its affiliates.
# coding=utf-8
import pyautogui
import os
import time
import pyperclip
import os
from yolox.exp import get_exp
import cv2
import torch
from yolox.data.data_augment import ValTransform
from yolox.utils import fuse_model, get_model_info, postprocess, vis
IMAGE_EXT = [".jpg", ".jpeg", ".webp", ".bmp", ".png"]
from PySide2.QtWidgets import QMessageBox
from PyQt5 import QtCore, QtWidgets ,QtGui
import sys
from 学生系统 import demo
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(716, 598)
self.plainTextEdit = QtWidgets.QPlainTextEdit(Form)
self.plainTextEdit.setGeometry(QtCore.QRect(180, 110, 381, 31))
self.plainTextEdit.setObjectName("plainTextEdit")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(10, 110, 181, 20))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(160, 0, 251, 61))
self.label_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setGeometry(QtCore.QRect(50, 310, 471, 231))
self.label_3.setObjectName("label_3")
self.widget = QtWidgets.QWidget(Form)
self.widget.setGeometry(QtCore.QRect(40, 170, 341, 43))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.radioButton = QtWidgets.QRadioButton(self.widget)
self.radioButton.setMinimumSize(QtCore.QSize(91, 41))
self.radioButton.setObjectName("radioButton")
self.buttonGroup = QtWidgets.QButtonGroup(Form)
self.buttonGroup.setObjectName("buttonGroup")
self.buttonGroup.addButton(self.radioButton)
self.horizontalLayout.addWidget(self.radioButton)
self.radioButton_2 = QtWidgets.QRadioButton(self.widget)
self.radioButton_2.setObjectName("radioButton_2")
self.buttonGroup.addButton(self.radioButton_2)
self.horizontalLayout.addWidget(self.radioButton_2)
self.widget1 = QtWidgets.QWidget(Form)
self.widget1.setGeometry(QtCore.QRect(40, 220, 401, 71))
self.widget1.setObjectName("widget1")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget1)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.pushButton = QtWidgets.QPushButton(self.widget1)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_2.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.widget1)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout_2.addWidget(self.pushButton_2)
self.pushButton_3 = QtWidgets.QPushButton(self.widget1)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout_2.addWidget(self.pushButton_3)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "请输入 图片 的 路径"))
self.label_2.setText(_translate("Form", " yolox 可视化 界面 "))
self.label_3.setText(_translate("Form", " 显示界面中"))
self.radioButton.setText(_translate("Form", "yolox_s"))
self.radioButton_2.setText(_translate("Form", "yolox_m"))
self.buttonGroup.buttonClicked.connect(self.qz)
self.pushButton.setText(_translate("Form", "测试"))
self.pushButton.clicked.connect(self.ceshi)
self.pushButton_2.setText(_translate("Form", "显示"))
self.pushButton_2.clicked.connect(self.xianshi)
self.pushButton_3.setText(_translate("Form", "关闭软件"))
self.pushButton_3.clicked.connect(self.guanbi)
def ceshi(self):
global a,c
self.pushButton.setEnabled(False)
print("测试中")
app_dir = "C:\Windows\system32\cmd.exe"
b=self.plainTextEdit.toPlainText()
# C:/Users/pc/Desktop/new/qt/yolox/dog.jpg
# 执行命令列表
if a==1:
cmds = ["python demo.py image -n yolox-s -c C:/Users/pc/Desktop/new/qt/yolox/w/yolox_s.pth --path "+b+" --conf 0.25 --nms 0.45 --tsize 320 --save_result --device gpu "
]
elif a==2:
cmds = [
"python demo.py image -n yolox-m -c C:/Users/pc/Desktop/new/qt/yolox/w/yolox_m.pth --path "+b+" --conf 0.25 --nms 0.45 --tsize 640 --save_result --device gpu"]
# 打开windows应用
time.sleep(5)
os.startfile(app_dir)
# 自动跑输入命令
pyautogui.typewrite(["enter"], '0.25')
# 暂停5秒,定位应用界面
# time.sleep(3)
# 获取应用坐标,通过鼠标位置获取python demo.py image -n yolox-m -c C:/Users/pc/Desktop/new/qt/yolox/w/yolox_m.pth --path C:/Users/pc/Desktop/new/qt/yolox/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device gpu
# 获取鼠标位置
x, y = pyautogui.position()
# 输入命令
for i in cmds:
"""
解决CMD中中文不可用情况,使用右键复制
"""
# 放置到剪贴板
pyperclip.copy(i)
# 右键粘贴命令
pyautogui.click(x=x, y=y, button='right')
time.sleep(0.5)
# pyautogui.typewrite([x for x in i], '0.25')
pyautogui.typewrite(["enter"], '0.25')
os.system("taskkill /f /im cmd.exe")
self.plainTextEdit.clear()
c=1
self.pushButton.setEnabled(True)
print("训练完成")
return c
def xianshi(self):
global a, c
print("显示")
if c==1:
if a==1:
print("显示s")
jpg = QtGui.QPixmap("C:\\Users\\31319\\Desktop\\qt\\yolox\\YOLOX_outputs\\yolox_s\\vis_res\\2022\\dog.jpg").scaled(310, 200)
self.label_3.setPixmap(jpg)
elif a==2:
print("显示m")
jpg = QtGui.QPixmap(
"C:\\Users\\31319\\Desktop\\qt\\yolox\\YOLOX_outputs\\yolox_m\\vis_res\\2022\\dog.jpg").scaled(310,
200)
self.label_3.setPixmap(jpg)
else:
QtWidgets.QMessageBox.critical(widget, "错误", "你还没有测试")
def guanbi(self):
print("软件已关闭")
exit(0)
def qz(self):
global a
self.neir = self.buttonGroup.checkedButton().text()
print("你选择的模型是")
print(self.neir)
if self.neir == 'yolox_s':
a=1
elif self.neir == 'yolox_m':
a = 2
return a
if __name__ == "__main__":
c=0
a=3
app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(widget)
widget.show()
sys.exit(app.exec_())
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Copyright (c) Megvii, Inc. and its affiliates.
import argparse
import os
import time
from loguru import logger
import cv2
import torch
from yolox.data.data_augment import ValTransform
from yolox.data.datasets import COCO_CLASSES
from yolox.exp import get_exp
from yolox.utils import fuse_model, get_model_info, postprocess, vis
IMAGE_EXT = [".jpg", ".jpeg", ".webp", ".bmp", ".png"]
def make_parser():
parser = argparse.ArgumentParser("YOLOX Demo!")
parser.add_argument(
"demo", default="image", help="demo type, eg. image, video and webcam"
)
parser.add_argument("-expn", "--experiment-name", type=str, default=None)
parser.add_argument("-n", "--name", type=str, default=None, help="model name")
parser.add_argument(
"--path", default="./assets/dog.jpg",help="path to images or video"
)
parser.add_argument("--camid", type=int, default=0, help="webcam demo camera id")
parser.add_argument(
"--save_result",
action="store_true",
help="whether to save the inference result of image/video",
)
# exp file
parser.add_argument(
"-f",
"--exp_file",
default=None,
type=str,
help="pls input your experiment description file",
)
parser.add_argument("-c", "--ckpt", default=None, type=str, help="ckpt for eval")
parser.add_argument(
"--device",
default="cpu",
type=str,
help="device to run our model, can either be cpu or gpu",
)
parser.add_argument("--conf", default=0.3, type=float, help="test conf")
parser.add_argument("--nms", default=0.3, type=float, help="test nms threshold")
parser.add_argument("--tsize", default=None, type=int, help="test img size")
parser.add_argument(
"--fp16",
dest="fp16",
default=False,
action="store_true",
help="Adopting mix precision evaluating.",
)
parser.add_argument(
"--legacy",
dest="legacy",
default=False,
action="store_true",
help="To be compatible with older versions",
)
parser.add_argument(
"--fuse",
dest="fuse",
default=False,
action="store_true",
help="Fuse conv and bn for testing.",
)
parser.add_argument(
"--trt",
dest="trt",
default=False,
action="store_true",
help="Using TensorRT model for testing.",
)
return parser
def get_image_list(path):
image_names = []
for maindir, subdir, file_name_list in os.walk(path):
for filename in file_name_list:
apath = os.path.join(maindir, filename)
ext = os.path.splitext(apath)[1]
if ext in IMAGE_EXT:
image_names.append(apath)
return image_names
class Predictor(object):
def __init__(
self,
model,
exp,
cls_names=COCO_CLASSES,
trt_file=None,
decoder=None,
device="cpu",
fp16=False,
legacy=False,
):
self.model = model
self.cls_names = cls_names
self.decoder = decoder
self.num_classes = exp.num_classes
self.confthre = exp.test_conf
self.nmsthre = exp.nmsthre
self.test_size = exp.test_size
self.device = device
self.fp16 = fp16
self.preproc = ValTransform(legacy=legacy)
if trt_file is not None:
from torch2trt import TRTModule
model_trt = TRTModule()
model_trt.load_state_dict(torch.load(trt_file))
x = torch.ones(1, 3, exp.test_size[0], exp.test_size[1]).cuda()
self.model(x)
self.model = model_trt
def inference(self, img):
img_info = {"id": 0}
if isinstance(img, str):
img_info["file_name"] = os.path.basename(img)
img = cv2.imread(img)
else:
img_info["file_name"] = None
height, width = img.shape[:2]
img_info["height"] = height
img_info["width"] = width
img_info["raw_img"] = img
ratio = min(self.test_size[0] / img.shape[0], self.test_size[1] / img.shape[1])
img_info["ratio"] = ratio
img, _ = self.preproc(img, None, self.test_size)
img = torch.from_numpy(img).unsqueeze(0)
img = img.float()
if self.device == "gpu":
img = img.cuda()
if self.fp16:
img = img.half() # to FP16
with torch.no_grad():
t0 = time.time()
outputs = self.model(img)
if self.decoder is not None:
outputs = self.decoder(outputs, dtype=outputs.type())
outputs = postprocess(
outputs, self.num_classes, self.confthre,
self.nmsthre, class_agnostic=True
)
logger.info("Infer time: {:.4f}s".format(time.time() - t0))
return outputs, img_info
def visual(self, output, img_info, cls_conf=0.35):
ratio = img_info["ratio"]
img = img_info["raw_img"]
if output is None:
return img
output = output.cpu()
bboxes = output[:, 0:4]
# preprocessing: resize
bboxes /= ratio
cls = output[:, 6]
scores = output[:, 4] * output[:, 5]
vis_res = vis(img, bboxes, scores, cls, cls_conf, self.cls_names)
return vis_res
def image_demo(predictor, vis_folder, path, current_time, save_result):
if os.path.isdir(path):
files = get_image_list(path)
else:
files = [path]
files.sort()
for image_name in files:
outputs, img_info = predictor.inference(image_name)
result_image = predictor.visual(outputs[0], img_info, predictor.confthre)
if save_result:
save_folder = os.path.join(
vis_folder, time.strftime("%Y", current_time)
)
os.makedirs(save_folder, exist_ok=True)
save_file_name = os.path.join(save_folder, os.path.basename(image_name))
logger.info("Saving detection result in {}".format(save_file_name))
cv2.imwrite(save_file_name, result_image)
ch = cv2.waitKey(0)
if ch == 27 or ch == ord("q") or ch == ord("Q"):
break
def imageflow_demo(predictor, vis_folder, current_time, args):
cap = cv2.VideoCapture(args.path if args.demo == "video" else args.camid)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
fps = cap.get(cv2.CAP_PROP_FPS)
save_folder = os.path.join(
vis_folder, time.strftime("%Y_%m_%d", current_time)
)
os.makedirs(save_folder, exist_ok=True)
if args.demo == "video":
save_path = os.path.join(save_folder, args.path.split("/")[-1])
else:
save_path = os.path.join(save_folder, "camera.mp4")
logger.info(f"video save_path is {save_path}")
vid_writer = cv2.VideoWriter(
save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (int(width), int(height))
)
while True:
ret_val, frame = cap.read()
if ret_val:
outputs, img_info = predictor.inference(frame)
result_frame = predictor.visual(outputs[0], img_info, predictor.confthre)
if args.save_result:
vid_writer.write(result_frame)
ch = cv2.waitKey(1)
if ch == 27 or ch == ord("q") or ch == ord("Q"):
break
else:
break
def main(exp, args):
if not args.experiment_name:
args.experiment_name = exp.exp_name
file_name = os.path.join(exp.output_dir, args.experiment_name)
os.makedirs(file_name, exist_ok=True)
vis_folder = None
if args.save_result:
vis_folder = os.path.join(file_name, "vis_res")
os.makedirs(vis_folder, exist_ok=True)
if args.trt:
args.device = "gpu"
logger.info("Args: {}".format(args))
if args.conf is not None:
exp.test_conf = args.conf
if args.nms is not None:
exp.nmsthre = args.nms
if args.tsize is not None:
exp.test_size = (args.tsize, args.tsize)
model = exp.get_model()
logger.info("Model Summary: {}".format(get_model_info(model, exp.test_size)))
if args.device == "gpu":
model.cuda()
if args.fp16:
model.half() # to FP16
model.eval()
if not args.trt:
if args.ckpt is None:
ckpt_file = os.path.join(file_name, "best_ckpt.pth")
else:
ckpt_file = args.ckpt
logger.info("loading checkpoint")
ckpt = torch.load(ckpt_file, map_location="cpu")
# load the model state dict
model.load_state_dict(ckpt["model"])
logger.info("loaded checkpoint done.")
if args.fuse:
logger.info("\tFusing model...")
model = fuse_model(model)
if args.trt:
assert not args.fuse, "TensorRT model is not support model fusing!"
trt_file = os.path.join(file_name, "model_trt.pth")
assert os.path.exists(
trt_file
), "TensorRT model is not found!\n Run python3 tools/trt.py first!"
model.head.decode_in_inference = False
decoder = model.head.decode_outputs
logger.info("Using TensorRT to inference")
else:
trt_file = None
decoder = None
predictor = Predictor(
model, exp, COCO_CLASSES, trt_file, decoder,
args.device, args.fp16, args.legacy,
)
current_time = time.localtime()
if args.demo == "image":
image_demo(predictor, vis_folder, args.path, current_time, args.save_result)
elif args.demo == "video" or args.demo == "webcam":
imageflow_demo(predictor, vis_folder, current_time, args)
if __name__ == '__main__':
args = make_parser().parse_args()
exp = get_exp(args.exp_file, args.name)
main(exp, args)
链接:https://pan.baidu.com/s/1Z08uL6-sRe-VX-1GywCT8w
提取码:gope
环境