1 Star 0 Fork 0

蛋蛋编程/基于yolov3和Tkinter的组合开发检测界面(文字按钮界面)

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
detect_gui.py 48.95 KB
一键复制 编辑 原始数据 按行查看 历史
蛋蛋编程 提交于 2022-08-24 23:28 . v1.0
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
import os
import shutil
import time
import cv2
import pyperclip
import threading
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk
import numpy as np
import tkinter.filedialog as tkf
from tkinterdnd2 import *
from tkinter import ttk
import tkinter.font as tkFont
import tkinter.messagebox as tkm
from subprocess import Popen, PIPE, STDOUT, TimeoutExpired
from threading import Thread, Event
from queue import Queue, Empty
from tkinter import Text, END
mask_icon = './load_file/img/mask_icon.ico'
mask_title = './load_file/img/mask_title.png'
bg_path = './load_file/bg/'
init_bg = './load_file/bg/bg_05.jpg'
run_resut_path = './run.log'
images_temp_path = './temp_images/'
weight_file = './weights/yolov3-tiny.pt'
camera_source = './photo_detection/source/'
camera_result = './photo_detection/result/'
weight_format = ['pt', 'pth']
image_format = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo']
video_format = ['mov', 'avi', 'mp4', 'mpg', 'mpeg', 'm4v', 'wmv', 'mkv']
class MyThread(threading.Thread):
def __init__(self, func, *args):
super().__init__()
self.func = func
self.args = args
self.setDaemon(True)
self.start()
def run(self):
self.func(*self.args)
class ProcessOutputReader(Thread):
def __init__(self, queue, cmd, params=(),
group=None, name=None, daemon=True):
super().__init__(group=group, name=name, daemon=daemon)
self._stop_request = Event()
self.queue = queue
self.process = Popen((cmd,) + tuple(params),
stdout=PIPE,
stderr=STDOUT,
universal_newlines=True)
def run(self):
for line in self.process.stdout:
if self._stop_request.is_set():
self.process.terminate()
break
self.queue.put(line)
self.write_log(line)
try:
self.process.wait(timeout=3)
except TimeoutExpired:
self.process.kill()
def stop(self):
self._stop_request.set()
while True:
try:
self.queue.get(block=False)
except Empty:
break
self.queue.task_done()
def write_log(self, line):
if not os.path.exists(run_resut_path):
f = open(run_resut_path, 'a+')
f.write(line)
f.close()
else:
f = open(run_resut_path, 'a+')
f.write(line)
f.close()
class MyConsole(Text):
def __init__(self, parent, queue, update_interval=50, process_lines=500):
super().__init__(parent)
self.queue = queue
self.update_interval = update_interval
self.process_lines = process_lines
self.after(self.update_interval, self.fetch_lines)
def fetch_lines(self):
something_inserted = False
for _ in range(self.process_lines):
try:
line = self.queue.get(block=False)
except Empty:
break
self.insert(END, line)
self.queue.task_done()
something_inserted = True
if something_inserted:
self.see(END)
self.after(self.update_interval, self.fetch_lines)
top = TkinterDnD.Tk()
top.title('口罩佩戴检测')
top.geometry('1660x900+90+60')
top.resizable(0, 0)
top.config(bg='#F0F0F0')
font_Title = ("华光粗圆_CNKI", 20)
font_Radio = ("微软雅黑", 12, "bold")
font_Scale = ("微软雅黑", 9, "bold")
font_Button = ("微软雅黑", 10, "bold")
font_Label = ("微软雅黑", 10, "bold")
image_width = 640
image_height = 480
image_title_width = 108
image_title_height = 108
top.iconbitmap(mask_icon)
canvas = Canvas(top,
bg='white',
width=image_width,
height=image_height)
canvas.place(x=200, y=120)
Label(top,
text='程\n\n\n出',
font=font_Radio,
width=2,
height=4).place(x=1600, y=305, anchor='nw')
canvas_mask_right = Canvas(top,
width=image_title_width,
height=image_title_height)
canvas_mask_right.place(x=1155, y=8)
def imgConvert(img,
resize_flag=False,
image_width=image_width,
image_height=image_height):
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.uint8)
img = Image.fromarray(img)
if resize_flag:
img = img.resize((image_width, image_height),
Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
return img
xVariable = tk.StringVar()
env_com = ttk.Combobox(top, textvariable=xVariable, width=8)
env_com.place(x=860, y=575)
def init_env_com():
bg_list = os.listdir(bg_path)
env_com["value"] = tuple(bg_list)
index = bg_list.index(init_bg[-9:])
env_com.current(index)
def xFunc(event):
global bg
bg_full_path = bg_path + env_com.get()
bg_ = cv2.imread(bg_full_path)
bg = imgConvert(bg_, True)
canvas.create_image(0, 0,
anchor='nw',
image=bg,
tag='bg_img')
top.update()
top.after(1)
env_com.bind("<<ComboboxSelected>>", xFunc)
init_env_com()
def on_close():
close = tkm.askokcancel("关闭", "是否关闭程序")
if close:
if os.path.exists('./photo_detection'):
shutil.rmtree('./photo_detection')
if os.path.exists(run_resut_path):
os.remove(run_resut_path)
top.destroy()
top.protocol("WM_DELETE_WINDOW", on_close)
def close_radio(flag):
if flag:
cam_01_Ra.config(state='disable')
cam_02_Ra.config(state='disable')
cam_03_Ra.config(state='disable')
GPU_Ra.config(state='disable')
CPU_Ra.config(state='disable')
conf_thres_label_scale.config(state='disable')
iou_thres_label_scale.config(state='disable')
thres_Btn.config(state='disable')
reset_canvas_Btn.config(state='disable')
reset_Btn_state_Btn.config(state='disable')
clear_cache_Btn.config(state='disable')
open_dir_Btn.config(state='disable')
conf_thres_Btn.config(state='disable')
iou_thres_Btn.config(state='disable')
play_cound_cbtn.config(state='disable')
env_com.config(state='disable')
open_camera_Btn.config(state='disable')
select_dir_Btn.config(state='disable')
detect_dir_Btn.config(state='disable')
select_file_Btn.config(state='disable')
detect_file_Btn.config(state='disable')
weight_Btn.config(state='disable')
link_Btn.config(state='disable')
delete_text_Btn.config(state='disable')
open_train_dir_Btn.config(state='disable')
copy_run_result_Btn.config(state='disable')
test_result_Btn.config(state='disable')
all_result_dir_Btn.config(state='disable')
open_code_dir_Btn.config(state='disable')
open_dataset_dir_Btn.config(state='disable')
iou_thres_Entry.config(state='disable')
conf_thres_Entry.config(state='disable')
else:
cam_01_Ra.config(state='normal')
cam_02_Ra.config(state='normal')
cam_03_Ra.config(state='normal')
GPU_Ra.config(state='normal')
CPU_Ra.config(state='normal')
conf_thres_label_scale.config(state='normal')
iou_thres_label_scale.config(state='normal')
thres_Btn.config(state='normal')
reset_canvas_Btn.config(state='normal')
reset_Btn_state_Btn.config(state='normal')
clear_cache_Btn.config(state='normal')
open_dir_Btn.config(state='normal')
conf_thres_Btn.config(state='normal')
iou_thres_Btn.config(state='normal')
play_cound_cbtn.config(state='normal')
env_com.config(state='normal')
open_camera_Btn.config(state='normal')
select_dir_Btn.config(state='normal')
detect_dir_Btn.config(state='normal')
select_file_Btn.config(state='normal')
detect_file_Btn.config(state='normal')
weight_Btn.config(state='normal')
link_Btn.config(state='normal')
delete_text_Btn.config(state='normal')
open_train_dir_Btn.config(state='normal')
copy_run_result_Btn.config(state='normal')
test_result_Btn.config(state='normal')
all_result_dir_Btn.config(state='normal')
open_code_dir_Btn.config(state='normal')
open_dataset_dir_Btn.config(state='normal')
iou_thres_Entry.config(state='normal')
conf_thres_Entry.config(state='normal')
bg = cv2.imread(init_bg)
bg = imgConvert(bg, True)
canvas.create_image(0, 0,
anchor='nw',
image=bg,
tag='bg_img')
img_title = cv2.imread(mask_title)
img_title = imgConvert(img_title,
True,
image_title_width,
image_title_height)
canvas_mask_right.create_image(0, 0,
anchor='nw',
image=img_title)
play_flag = False
def print_selection():
global play_flag
if play_var.get() == 1:
play_flag = True
else:
play_flag = False
play_var = tk.IntVar()
play_cound_cbtn = tk.Checkbutton(top, text='播放声音', variable=play_var, onvalue=1, offvalue=0,
command=print_selection)
play_cound_cbtn.place(x=72, y=80)
play_var.set(0)
conf_thres_input_value = tk.DoubleVar()
conf_thres_Entry = tk.Entry(top,
textvariable=conf_thres_input_value,
width=4)
conf_thres_Entry.place(x=315, y=815)
conf_thres_input_value.set(0.45)
conf_thres_label = tk.Label(top,
width=8,
text='Conf-thres',
font=font_Scale)
conf_thres_label.place(x=208, y=815)
def print_conf_thres_selection(value):
global conf_thres
conf_thres = value
conf_thres_input_value.set(value)
conf_thres_label_scale = tk.Scale(top,
from_=0,
to=1,
orient=tk.HORIZONTAL,
length=250,
showvalue=0,
tickinterval=0.2,
resolution=0.01,
command=print_conf_thres_selection)
conf_thres_label_scale.place(x=207, y=840)
conf_thres_label_scale.set(0.25)
def update_conf_scale():
conf_thres_label_scale.set(conf_thres_Entry.get())
conf_thres_Btn = tk.Button(top,
text="更新",
command=update_conf_scale,
relief=RIDGE,
font=("黑体", 9))
conf_thres_Btn.place(x=415, y=814)
iou_thres_input_value = tk.DoubleVar()
iou_thres_Entry = tk.Entry(top,
textvariable=iou_thres_input_value,
width=4)
iou_thres_Entry.place(x=582, y=815)
iou_thres_input_value.set(0.45)
iou_thres_label = tk.Label(top,
width=7,
text='Iou-thres',
font=font_Scale)
iou_thres_label.place(x=475, y=815)
def print_iou_thres_selection(value):
global iou_thres
iou_thres = value
iou_thres_input_value.set(value)
iou_thres_label_scale = tk.Scale(top,
from_=0,
to=1,
orient=tk.HORIZONTAL,
length=250,
showvalue=0,
tickinterval=0.2,
resolution=0.01,
command=print_iou_thres_selection)
iou_thres_label_scale.place(x=475, y=840)
iou_thres_label_scale.set(0.45)
def update_iou_scale():
iou_thres_label_scale.set(iou_thres_Entry.get())
iou_thres_Btn = tk.Button(top,
text="更新",
command=update_iou_scale,
relief=RIDGE,
font=("黑体", 9))
iou_thres_Btn.place(x=683, y=814)
def thres_reset():
conf_thres_label_scale.set(0.25)
iou_thres_label_scale.set(0.45)
thres_Btn = tk.Button(top,
text=" 阈 值 重 置 ",
command=thres_reset,
relief=RIDGE,
height=2,
font=font_Button)
thres_Btn.place(x=730, y=813)
weight_path = tk.StringVar()
def dragWeight(event):
global weight_file
_weight_format = ""
for weight_format_ele in weight_format:
_weight_format += '*.' + weight_format_ele + ' '
_weight_format = _weight_format[:-1]
pathList = event.data.split(' ')
if len(pathList) > 1:
tkm.showinfo(title='提示',
message='权重只能选择一个,请重新选择!')
else:
path = event.data
if path.split('.')[-1] in weight_format:
if path != '':
path_ = path.replace('/', '\\')
message_Isdetect = "选择的权重文件:" + path
if tkm.askokcancel(title='开始检测',
message=message_Isdetect):
weight_path.set("当前权重 " + path)
weight_file = path_
tkm.showinfo(title="提示",
message="权重更新成功!")
else:
tkm.showinfo(title="提示",
message="未选择权重文件执行默认权重!")
else:
tkm.showinfo(title="提示",
message="未选择权重文件执行默认权重!")
else:
tkm.showinfo(title="提示",
message="权重文件格式须为pt或pth!")
def selectWeight():
global weight_file
_weight_format = ""
for weight_format_ele in weight_format:
_weight_format += '*.' + weight_format_ele + ' '
_weight_format = _weight_format[:-1]
path = tkf.askopenfilename(filetypes=
[("weight file", _weight_format)])
if path != '':
path_ = path.replace('/', '\\')
message_Isdetect = "选择的权重文件:" + path
if tkm.askokcancel(title='开始检测',
message=message_Isdetect):
weight_path.set("当前权重 " + path)
weight_file = path_
tkm.showinfo(title="提示",
message="权重更新成功!")
else:
tkm.showinfo(title="提示",
message="未选择权重文件执行默认权重!")
else:
tkm.showinfo(title="提示",
message="未选择权重文件执行默认权重!")
weight_Entry = tk.Entry(top,
textvariable=weight_path,
width=57)
weight_Entry.place(x=210, y=720)
weight_Entry.drop_target_register(DND_FILES)
weight_Entry.dnd_bind('<<Drop>>', dragWeight)
weight_path.set("当前权重 ( "+ weight_file +" [可拖拽文件到此处] )")
weight_Btn = tk.Button(top,
text=" 选 择 权 重 ",
command=selectWeight,
relief=RIDGE,
font=font_Button)
weight_Btn.place(x=730, y=710)
var = tk.IntVar()
device_Label = tk.Label(top,
width=13,
height=1,
text='empty',
font=font_Button)
device_Label.place(x=860, y=115)
device_parameter = {'GPU': '0', 'CPU': 'cpu'}
device_dict = {0: "GPU", 1: "CPU"}
var.set(0)
device_Label.config(text='计算设备 [ ' + device_dict[var.get()] + ' ]')
device_parameter_elem = device_parameter[device_dict[var.get()]]
def device_trigger():
global device_parameter_elem
device_Label.config(text='计算设备 [ ' + device_dict[var.get()] + ' ]')
device_parameter_elem = device_parameter[device_dict[var.get()]]
GPU_Ra = tk.Radiobutton(top,
text='GPU',
variable=var,
value=0,
command=device_trigger,
font=font_Button)
GPU_Ra.place(x=1010, y=113)
CPU_Ra = tk.Radiobutton(top,
text='CPU',
variable=var,
value=1,
command=device_trigger,
font=font_Button)
CPU_Ra.place(x=1100, y=113)
var_camdev = tk.IntVar()
l2 = tk.Label(top,
width=9,
height=1,
text='empty',
font=font_Button)
l2.place(x=1260, y=115)
camera_parameter = {'#1': 0, '#2': 1, '#3': 2}
camera_dict = {0: "#1", 1: "#2", 2: "#3"}
var_camdev.set(0)
l2.config(text='摄像头 [ ' + camera_dict[var_camdev.get()] + ' ]')
camera_parameter_elem = camera_parameter[camera_dict[var_camdev.get()]]
def camera_trigger():
global camera_parameter_elem
l2.config(text='摄像头 [ ' + camera_dict[var_camdev.get()] + ' ]')
camera_parameter_elem = camera_parameter[camera_dict[var_camdev.get()]]
cam_01_Ra = tk.Radiobutton(top,
text='#1',
variable=var_camdev,
value=0,
command=camera_trigger,
font=font_Radio)
cam_01_Ra.place(x=1370, y=113)
cam_02_Ra = tk.Radiobutton(top,
text='#2',
variable=var_camdev,
value=1,
command=camera_trigger,
font=font_Radio)
cam_02_Ra.place(x=1445, y=113)
cam_03_Ra = tk.Radiobutton(top,
text='#3',
variable=var_camdev,
value=2,
command=camera_trigger,
font=font_Radio)
cam_03_Ra.place(x=1520, y=113)
def get_params(useCamera=True) ->list :
params = ['-u', 'detect.py']
if device_parameter_elem == '0':
params.append('-d')
params.append(device_parameter_elem)
elif device_parameter_elem == 'cpu':
params.append('-d')
params.append(device_parameter_elem)
if play_flag == True:
params.append('-ps')
params.append('open')
else:
params.append('-ps')
params.append('close')
params.append('-w')
params.append(weight_file)
params.append('--conf-thres')
params.append(conf_thres)
params.append('--iou-thres')
params.append(iou_thres)
if useCamera:
params.append('-s')
params.append('0')
return params
def open_camera():
global cap, frame_
open_camera_Btn.config(state='disable')
close_camrea_Btn.config(state='normal')
photo_detection_Btn.config(state='normal')
close_radio(True)
try:
cap = cv2.VideoCapture(camera_parameter_elem)
except Exception:
tkm.showinfo(title="提示",
message="该相机设备不存在, 自动跳转存在设备!")
while True:
ref, frame = cap.read()
frame_ = cv2.flip(frame, 1)
tkimg = imgConvert(frame)
canvas.create_image(0, 0,
anchor='nw',
image=tkimg)
temp = tkimg
top.update()
top.after(1)
open_camera_Btn = tk.Button(top,
text='打开摄像头',
command=lambda: MyThread(open_camera),
relief=RIDGE,
width=9,
height=2,
font=font_Button,
)
open_camera_Btn.place(x=60, y=120)
def close_camrea():
try:
open_camera_Btn.config(state='normal')
close_camrea_Btn.config(state='disable')
photo_detection_Btn.config(state='disable')
cap.release()
close_radio(False)
canvas.create_image(0, 0,
anchor='nw',
image=bg)
tkm.showinfo(title="提示",
message="摄像头已关闭!")
except NameError:
pass
finally:
open_camera_Btn.config(state='normal')
close_camrea_Btn.config(state='disable')
photo_detection_Btn.config(state='disable')
close_radio(False)
close_camrea_Btn = tk.Button(top,
text='关闭摄像头',
command=lambda: MyThread(close_camrea),
relief=RIDGE, state='disable',
width=9,
height=2,
font=font_Button)
close_camrea_Btn.place(x=60, y=280)
def photo_detection():
open_camera_Btn.config(state='normal')
close_camrea_Btn.config(state='disable')
photo_detection_Btn.config(state='disable')
if not os.path.exists(camera_source):
os.makedirs(camera_source)
infile_path = camera_source + 'detect.jpg'
photo_detection_Btn.config(state='disable')
global frame_
cv2.imwrite(infile_path, frame_)
tkm.showinfo(title="提示",
message="照片已保存至" + infile_path)
canvas.delete('bg_img')
cap.release()
close_radio(False)
detect_camera = cv2.imread(infile_path)
detect_camera = imgConvert(detect_camera, True)
params = get_params(useCamera=False)
params.append('-s')
params.append(infile_path)
params.append('--project')
params.append('photo_detection')
params.append('--name')
params.append('result')
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
global num_runs
num_runs = -1
canvas.delete('bg_img')
tkm.showinfo(title="提示",
message="照片已在检测中,注意查看右侧输出及左侧结果!")
canvas.create_image(0, 0,
anchor='nw',
image=detect_camera,
tag='s_img')
temp = detect_camera
top.update()
top.after(1)
if time.sleep(6) == None:
outfile_path = camera_result + 'detect.jpg'
result_camera = cv2.imread(outfile_path)
result_camera = imgConvert(result_camera, True)
canvas.delete('s_img')
canvas.create_image(0, 0,
anchor='nw',
image=result_camera,
tag='r_img')
temp = result_camera
top.update()
top.after(1)
if time.sleep(10) == None:
canvas.delete('r_img')
canvas.create_image(0, 0,
anchor='nw',
image=bg)
temp = bg
photo_detection_Btn = tk.Button(top,
text='拍照检测',
command=lambda: MyThread(photo_detection),
relief=RIDGE, state='disable',
width=9,
height=2,
font=font_Button)
photo_detection_Btn.place(x=60, y=200)
num_runs = 0
def start_detect():
try:
if os.path.exists('./temp_images'):
shutil.rmtree('./temp_images')
if not os.path.exists('./temp_images/'):
os.mkdir('./temp_images/')
except FileNotFoundError:
pass
global reader
global num_runs
try:
start_detect_Btn.config(state='disable')
stop_detect_Btn.config(state='normal')
params = get_params(useCamera=False)
params.append('-s')
params.append(str(camera_parameter_elem))
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
close_radio(True)
num_runs = 1
max = -1
while True:
max_ = max
if os.listdir(images_temp_path):
files = os.listdir(images_temp_path)
for file in files:
file_num = int(file.split('.')[0])
if file_num > max:
max = int(file_num)
if max_ > 0 and max_ < max:
filename = images_temp_path + str(max_).zfill(8) + '.jpg'
dynamic_images = cv2.imread(filename)
dynamic_images = imgConvert(dynamic_images)
canvas.create_image(0, 0, anchor='nw', image=dynamic_images)
temp = dynamic_images
top.update()
top.after(1)
except EOFError:
tkm.showerror(title="错误",
message="权重文件加载失败,请重新选择!")
except FileNotFoundError:
pass;
start_detect_Btn = tk.Button(top,
text='开始检测',
command=lambda: MyThread(start_detect),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
start_detect_Btn.place(x=60, y=360)
def stop_detect():
try:
start_detect_Btn.config(state='normal')
stop_detect_Btn.config(state='disable')
reader.stop()
reader.join(timeout=5)
canvas.create_image(0, 0, anchor='nw', image=bg)
close_radio(False)
tkm.showinfo(title="提示",
message="已停止检测!")
if os.listdir(images_temp_path):
file_list = os.listdir(images_temp_path)
for file in file_list:
image_temp_path = images_temp_path + file
os.remove(image_temp_path)
if reader.is_alive():
raise RuntimeError("process output reader failed to stop")
except RuntimeError:
tkm.showinfo(title="提示",
message="检测已运行,请勿重复点击!")
except (UnicodeDecodeError, NameError):
pass
finally:
start_detect_Btn.config(state='normal')
stop_detect_Btn.config(state='disable')
close_radio(False)
stop_detect_Btn = tk.Button(top,
text='停止检测',
command=lambda: MyThread(stop_detect),
relief=RIDGE,
state='disable',
width=9,
height=2,
font=font_Button)
stop_detect_Btn.place(x=60, y=440)
def current_result():
result_dir_name = './runs/detect/'
current_path = os.getcwd()
result_dir_name = current_path + result_dir_name
try:
if os.listdir(result_dir_name):
files = os.listdir(result_dir_name)
index = [1]
for dir_file in files:
dir_file = dir_file[3:]
if dir_file != '':
dir_file = int(dir_file)
index.append(dir_file)
sort_index = sorted(index)
max_index = sort_index[-1]
if max_index and max_index != 1:
if num_runs == 0:
tkm.showinfo(title="提示",
message="未运行程序,无检测结果!")
elif num_runs == -1:
current_path = os.getcwd()
camera_result_path = current_path + '/photo_detection/result/'
os.startfile(camera_result_path)
else:
for num in range(num_runs):
path = result_dir_name + 'exp' + str(max_index)
os.startfile(path)
del sort_index[-1]
max_index = sort_index[-1]
elif max_index == 1:
path = result_dir_name + 'exp'
os.startfile(path)
time.sleep(0.25)
except UnboundLocalError:
tkm.showinfo(title="提示",
message="检测结果为空!")
open_dir_Btn = tk.Button(top,
text="检测结果",
command=lambda: MyThread(current_result),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
open_dir_Btn.place(x=60, y=520)
def clear_cache():
if tkm.askokcancel(title='清空缓存',
message="是否清空程序缓存\n"
"(包括运行日志和图片缓存,当运行结果复制不正确需要此功能)"):
file_list = os.listdir(images_temp_path)
for file in file_list:
image_temp_path = images_temp_path + file
os.remove(image_temp_path)
if os.path.exists('run.log'):
os.remove("run.log")
if os.path.exists('./photo_detection/'):
shutil.rmtree('./photo_detection/')
if not os.listdir(images_temp_path) and not os.path.exists("run.log") \
and not os.path.exists('./photo_detection/'):
tkm.showinfo(title="提示",
message="缓存已清空!")
clear_cache_Btn = tk.Button(top,
text="清空缓存",
command=lambda: MyThread(clear_cache),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
clear_cache_Btn.place(x=60, y=600)
def reset_canvas():
if tkm.askokcancel(title='重置画布',
message="是否将画布重置到初始状态(当画布显示不正确需要此功能)"):
canvas.delete('All')
canvas.create_image(0, 0,
anchor='nw',
image=bg,
tag='bg_img')
tkm.showinfo(title="提示",
message="画布已重置!")
reset_canvas_Btn = tk.Button(top,
text="重置画布",
command=lambda: MyThread(reset_canvas),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
reset_canvas_Btn.place(x=60, y=680)
def reset_Btn_state():
if tkm.askokcancel(title='重置按钮状态',
message="是否重置按钮到初始状态(非必要请勿点击)"):
close_radio(False)
open_camera_Btn.config(state='normal')
photo_detection_Btn.config(state='disable')
close_camrea_Btn.config(state='disable')
start_detect_Btn.config(state='normal')
stop_detect_Btn.config(state='disable')
tkm.showinfo(title="提示",
message="按钮状态已重置!")
reset_Btn_state_Btn = tk.Button(top,
text="重置按钮状态",
command=lambda: MyThread(reset_Btn_state),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
reset_Btn_state_Btn.place(x=60, y=760)
line_queue = Queue(maxsize=2000)
console = MyConsole(top, line_queue)
console.place(x=860, y=150)
dir_path = tk.StringVar()
def dragDir(event):
global selecct_dir_path
selecct_dir_path = event.data
mulFile_flag = False
sinFile_flag = False
flag = False
count_image = 0
count_video = 0
global num_runs
if len(event.data.split(' ')) > 1:
mulFile_flag = True
if event.data.split(' ')[0].find('.') != -1:
sinFile_flag = True
if mulFile_flag == False and sinFile_flag == False:
dir_path.set(event.data)
try:
if os.listdir(selecct_dir_path):
files = os.listdir(selecct_dir_path)
for file in files:
fulldirct = os.path.join(selecct_dir_path, file)
if os.path.isfile(fulldirct):
suffix = file.split('.')[1]
if suffix in image_format:
count_image += 1
elif suffix in video_format:
count_video += 1
else:
flag = True
count = count_video + count_image
if count == 0:
num_runs = 0
tkm.showinfo(title='提示',
message='该文件夹内无图像或视频文件,请重新选择!')
elif flag == True:
num_runs = 0
tkm.showinfo(title='提示',
message='该文件夹有不支持的文件格式')
else:
dir_path.set(selecct_dir_path)
global message_Isdetectdir
message_Isdetectdir = "共检测到" + str(count_image) + \
"张图片和" + str(count_video) + "个视频文件,确认开始检测?"
tkm.showinfo(title="提示",
message=message_Isdetectdir[:-8])
except FileNotFoundError:
num_runs = 0
dir_path.set("文件夹检测( 将要检测的图片或视频放到检测的文件夹下 )")
tkm.showinfo(title="提示",
message="未选择文件!")
elif mulFile_flag == True:
tkm.showinfo(title="提示",
message="多文件检查请拖入下行!")
elif sinFile_flag == True:
tkm.showinfo(title="提示",
message="单文件检查请拖入下行!")
def selectDir():
global selecct_dir_path
selecct_dir_path = tkf.askdirectory()
flag = False
count_image = 0
count_video = 0
global num_runs
try:
if os.listdir(selecct_dir_path):
files = os.listdir(selecct_dir_path)
for file in files:
fulldirct = os.path.join(selecct_dir_path, file)
if os.path.isfile(fulldirct):
suffix = file.split('.')[1]
if suffix in image_format:
count_image += 1
elif suffix in video_format:
count_video += 1
else:
flag = True
count = count_video + count_image
if count == 0:
num_runs = 0
tkm.showinfo(title='提示',
message='该文件夹内无图像或视频文件,请重新选择!')
elif flag == True:
num_runs = 0
tkm.showinfo(title='提示',
message='该文件夹有不支持的文件格式')
else:
dir_path.set(selecct_dir_path)
global message_Isdetectdir
message_Isdetectdir = "共检测到" + str(count_image) + \
"张图片和" + str(count_video) + "个视频文件,确认开始检测?"
tkm.showinfo(title="提示",
message=message_Isdetectdir[:-8])
except FileNotFoundError:
num_runs = 0
dir_path.set("文件夹检测( 将要检测的图片或视频放到检测的文件夹下 )")
tkm.showinfo(title="提示",
message="未选择文件!")
def detectDir():
global num_runs
try:
if tkm.askokcancel(title='开始检测',
message=message_Isdetectdir):
num_runs = 1
tkm.showinfo(title="提示",
message="检测中,关闭该窗口查看右侧文本输出窗口查看程序输出结果!")
params = get_params(useCamera=False)
params.append('-s')
params.append(selecct_dir_path)
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
except NameError:
tkm.showinfo(title="提示",
message="请先选择文件夹!")
dir_Entry = tk.Entry(top,
textvariable=dir_path,
width=57)
dir_Entry.place(x=210, y=620)
dir_path.set("文件夹检测( 选择包含图片和视频的文件夹[可拖拽文件夹到此处] )")
dir_Entry.drop_target_register(DND_FILES)
dir_Entry.dnd_bind('<<Drop>>', dragDir)
select_dir_Btn = tk.Button(top,
text="选择",
command=selectDir,
relief=RIDGE,
font=font_Button)
select_dir_Btn.place(x=730, y=610)
detect_dir_Btn = tk.Button(top,
text="检测",
command=detectDir,
relief=RIDGE,
font=font_Button)
detect_dir_Btn.place(x=790, y=610)
file_path = tk.StringVar()
def dragFile(event):
global selecct_file_path
selecct_file_path = tuple(event.data.split(' '))
path_list = event.data.split(' ')
img_vid_format = image_format + video_format
exist_flag = False
for file in path_list:
if file.split('.')[-1] not in img_vid_format:
exist_flag = True
dir_flag = False
if event.data.find('.') == -1:
dir_flag = True
if exist_flag == False and dir_flag == False:
file_path.set(event.data)
global num_runs
count_image = 0
count_video = 0
for file in selecct_file_path:
file_format = file.split('.')[1]
if file_format in image_format:
count_image += 1
elif file_format in video_format:
count_video += 1
count = count_image + count_video
if count != 0:
file_path.set(selecct_file_path)
global path_
path_ = ''
for index in range(len(selecct_file_path)):
path_ += selecct_file_path[index] + ' '
path_ = path_[:-1].replace('/', '\\')
path_ = path_.split(' ')
global message_IsdetectFile
message_IsdetectFile = "共检测到" + str(count_image) + \
"张图片和" + str(count_video) + \
"个视频文件,确认开始检测?"
tkm.showinfo(title="提示",
message=message_IsdetectFile[:-8])
elif dir_flag == True:
tkm.showinfo(title="提示",
message='文件夹请拖入上行!')
elif exist_flag == True:
tkm.showinfo(title="提示",
message='文件格式非图片或视频,请重新选择!')
def selectFile():
global num_runs
_image_format = ""
_video_format = ""
for image_format_ele in image_format:
_image_format += '*.' + image_format_ele + ' '
_image_format = _image_format[:-1]
for video_format_ele in video_format:
_video_format += '*.' + video_format_ele + ' '
_video_format = _video_format[:-1]
path = tkf.askopenfilenames(
filetypes=[("image file", _image_format),
("video file", _video_format)])
count_image = 0
count_video = 0
for file in path:
file_format = file.split('.')[1]
if file_format in image_format:
count_image += 1
elif file_format in video_format:
count_video += 1
count = count_image + count_video
if count != 0:
file_path.set(path)
global path_
path_ = ''
for index in range(len(path)):
path_ += path[index] + ' '
path_ = path_[:-1].replace('/', '\\')
path_ = path_.split(' ')
global message_IsdetectFile
message_IsdetectFile = "共检测到" + str(count_image) + \
"张图片和" + str(count_video) + \
"个视频文件,确认开始检测?"
tkm.showinfo(title="提示",
message=message_IsdetectFile[:-8])
def detectFile():
global num_runs
try:
if tkm.askokcancel(title='开始检测',
message=message_IsdetectFile):
params = get_params(useCamera=False)
params.append('-s')
for path_ele in path_:
params.append(path_ele)
num_runs = len(path_)
tkm.showinfo(title="提示",
message="检测中,关闭该窗口查看右侧文本输出窗口查看程序输出结果!")
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
else:
num_runs = 0
tkm.showinfo(title="提示",
message="用户取消检测!")
except NameError:
tkm.showinfo(title="提示",
message="请先选择文件!")
file_Entry = tk.Entry(top,
textvariable=file_path,
width=57)
file_Entry.place(x=210, y=670)
file_Entry.drop_target_register(DND_FILES)
file_Entry.dnd_bind('<<Drop>>', dragFile)
file_path.set("文件检测( 选择图片和视频[可多选、可拖拽文件到此处] )")
select_file_Btn = tk.Button(top,
text="选择",
command=selectFile,
relief=RIDGE,
font=font_Button)
select_file_Btn.place(x=730, y=660)
detect_file_Btn = tk.Button(top,
text="检测",
command=detectFile,
relief=RIDGE,
font=font_Button)
detect_file_Btn.place(x=790, y=660)
link_path = tk.StringVar()
def selectPath():
global num_runs
global reader
message_Islink_path = "确认开始检测链接:" + link_path.get()
if tkm.askokcancel(title='开始检测',
message=message_Islink_path):
print(link_path.get())
if link_path.get().startswith("https://") or \
link_path.get().startswith("http://"):
num_runs = 1
params = get_params(useCamera=False)
params.append('-s')
params.append(link_path.get())
try:
close_radio(True)
start_detect_Btn.config(state='disable')
stop_detect_Btn.config(state='normal')
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
close_radio(False)
except AssertionError:
num_runs = 0
tkm.showinfo(title='提示',
message="该链接不是视频链接,请重新输入!")
close_radio(True)
start_detect_Btn.config(state='disable')
stop_detect_Btn.config(state='normal')
else:
num_runs = 0
tkm.showinfo(title='提示',
message="链接格式不正确,请重新输入!")
else:
num_runs = 0
tkm.showinfo(title="提示",
message="用户取消检测!")
link_Entry = tk.Entry(top,
textvariable=link_path,
width=57)
link_Entry.place(x=210, y=770)
link_path.set("链接检测( 放入单个视频网页链接 )")
link_Btn = tk.Button(top,
text=" 链 接 检 测 ",
command=selectPath,
relief=RIDGE,
font=font_Button)
link_Btn.place(x=730, y=760)
def delete_text():
console.delete('1.0', END)
tkm.showinfo(title='提示',
message="清空成功!")
delete_text_Btn = tk.Button(top,
text='清空文本',
command=delete_text,
relief=RIDGE,
width=9,
height=2,
font=font_Button)
delete_text_Btn.place(x=1050, y=580)
def copy_run_result():
if not os.path.exists(run_resut_path):
tkm.showinfo(title='提示',
message="当前还未产生结果,请运行程序后再复制!")
return
else:
f = open(run_resut_path, 'r')
result_lines = f.readlines()
if result_lines == []:
if tkm.askokcancel(title='复制结果',
message="当前运行结果为空,是否继续复制!"):
pyperclip.copy('说了空的你还不信!v( ̄_ ̄|||)')
spam = pyperclip.paste()
tkm.showinfo(title='提示',
message="复制成功!")
else:
tkm.showinfo(title='提示',
message="用户取消!")
else:
temp_run_result = ''
for result_line in result_lines:
temp_run_result += result_line
pyperclip.copy(temp_run_result)
spam = pyperclip.paste()
tkm.showinfo(title='提示',
message="复制成功!")
copy_run_result_Btn = tk.Button(top,
text='复制结果',
command=copy_run_result,
relief=RIDGE,
width=9,
height=2,
font=font_Button)
copy_run_result_Btn.place(x=1300, y=580)
def train_dir():
current_path = os.getcwd()
absolute_path = current_path + '/runs/train/'
try:
os.startfile(absolute_path)
except FileNotFoundError:
tkm.showinfo(title='提示',
message="当前目录为空!")
open_train_dir_Btn = tk.Button(top,
text='训练结果',
command=train_dir,
relief=RIDGE,
width=9,
height=2,
font=font_Button)
open_train_dir_Btn.place(x=900, y=670)
def test_result():
current_path = os.getcwd()
absolute_path = current_path + '/runs/test/'
try:
os.startfile(absolute_path)
except FileNotFoundError:
tkm.showinfo(title='提示',
message="当前目录为空!")
test_result_Btn = tk.Button(top,
text='测试结果',
command=test_result,
relief=RIDGE,
width=9,
height=2,
font=font_Button)
test_result_Btn.place(x=1177, y=670)
def detect_result():
current_path = os.getcwd()
absolute_path = current_path + '/runs/detect/'
try:
os.startfile(absolute_path)
except FileNotFoundError:
tkm.showinfo(title='提示',
message="当前目录为空!")
all_result_dir_Btn = tk.Button(top,
text='检测结果',
command=lambda: MyThread(detect_result),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
all_result_dir_Btn.place(x=1450, y=670)
def open_code_dir():
current_path = os.getcwd()
os.startfile(current_path)
open_code_dir_Btn = tk.Button(top,
text='代码',
command=lambda: MyThread(open_code_dir),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
open_code_dir_Btn.place(x=1050, y=760)
def open_dataset_dir():
current_path = os.getcwd()
dataset_image_path = '/data/images/'
dataset_label_path = '/data/Annotations/'
dataset_image_path = current_path + dataset_image_path
dataset_label_path = current_path + dataset_label_path
try:
os.startfile(dataset_image_path)
time.sleep(0.25)
os.startfile(dataset_label_path)
except FileNotFoundError:
tkm.showinfo(title='提示',
message="文件夹为空!")
open_dataset_dir_Btn = tk.Button(top,
text='数据集',
command=lambda: MyThread(open_dataset_dir),
relief=RIDGE,
width=9,
height=2,
font=font_Button)
open_dataset_dir_Btn.place(x=1300, y=760)
def local_detect():
global num_runs
global reader
num_runs = 1
params = get_params(useCamera=True)
params.append('-dr')
params.append('open')
try:
close_radio(True)
start_detect_Btn.config(state='disable')
stop_detect_Btn.config(state='normal')
reader = ProcessOutputReader(line_queue, 'python', params=params)
reader.start()
close_radio(False)
except AssertionError:
pass
close_radio(True)
start_detect_Btn.config(state='disable')
stop_detect_Btn.config(state='normal')
local_detect_Btn = tk.Button(top,
text='基于yolov3-tiny的口罩佩戴检测程序',
command=lambda: MyThread(local_detect),
relief=RIDGE,
width=32,
height=1,
bd=0,
font=font_Title,
)
local_detect_Btn.place(x=570, y=35, anchor='nw')
cv2.destroyAllWindows()
top.mainloop()
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/luokai-dandan/yolov3-tk-text.git
git@gitee.com:luokai-dandan/yolov3-tk-text.git
luokai-dandan
yolov3-tk-text
基于yolov3和Tkinter的组合开发检测界面(文字按钮界面)
master

搜索帮助