前一阵在看yolo v3 keras版本的代码,看完后自己重新训练了一个自己的数据集,但在测试时总觉得不太方便,于是尝试着在代码基础上增加一个可视化界面,可以进行图片的测试和视频的测试,由于是python新手,界面不求美观,但求基础功能能用,下面是最终的界面图:
界面左上部分显示检测的结果图片,右上半部分是选择图片和视频的按钮,其中点击视频检测时,选择mp4文件后,会弹出另一个视频实时检测的界面。
图片检测时,下面每一行显示一个检测结果,单击对应的结果后,图片上会只显示此结果的对应框,如下图:
目前这个代码基本功能可用,因此分享出来,修改的地方主要是修改了yolo_video.py和yolo.py模块。
感兴趣的童鞋可以在下面链接中下载源码(不包括.h5模型库):
https://github.com/markwentian/AI.git
yolo_video.py模块主要是添加界面功能,修改后代码为:
import sys
import argparse
from yolo import YOLO, detect_video
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from PIL import Image,ImageFont,ImageDraw,ImageTk
import numpy as np
from timeit import default_timer as timer
import time
def detect_img(yolo):
while True:
img = input('Input image filename:')
try:
image = Image.open('./'+img)
except:
print('Open Error! Try again!')
break
else:
r_image = yolo.detect_image(image)
r_image.show()
yolo.close_session()
FLAGS = None
class App:
def __init__(self,master,yolo):
self.master=master
self.initWidgets()
self.yolo=yolo
def initWidgets(self):
topF=Frame(self.master)
topF.pack(side=TOP,fill=BOTH)
self.cv=Canvas(topF,background='white',width=450,height=450)
self.cv.pack(side=LEFT,fill=BOTH,expand=YES)
ttk.Button(topF,text='打开图片文件',command=self.open_file).pack(side=RIGHT,fill=Y,expand=YES,anchor=CENTER)
ttk.Button(topF,text='打开MP4视频文件',command=self.open_video).pack(side=RIGHT,fill=Y,expand=YES,anchor=CENTER)
self.yolo_result=StringVar()
topF3=Frame(self.master)
topF3.pack(side=BOTTOM,fill=BOTH)
ttk.Label(topF3,text='检测结果',padding=20).pack(side=TOP,fill=X,expand=YES)
self.lb=Listbox(topF3,listvariable=self.yolo_result,selectmode='single')
self.lb.pack(side=BOTTOM,fill=X,expand=YES)
self.lb.bind("<ButtonRelease-1>",self.click)
self.yolo_result_store=[]
self.class_names=[]
self.colors=[]
def click(self,event):
index_temp=self.lb.curselection()
index_temp2=index_temp[0]
yolo_result_click=self.yolo_result_store[index_temp2]
wdawdaw=self.yolo_result_store
predicted_class_click=yolo_result_click[0]
score_click=yolo_result_click[1]
box_click=yolo_result_click[2]
thickness_click=yolo_result_click[3]
c_click=yolo_result_click[4]
image_click=self.image.crop()
predicted_class=predicted_class_click
box=box_click
score=score_click
label='{} {:.2f}'.format(predicted_class,score)
draw=ImageDraw.Draw(image_click)
label_size=draw.textsize(label,self.font)
top, left, bottom, right = box
top = max(0, np.floor(top + 0.5).astype('int32'))
left = max(0, np.floor(left + 0.5).astype('int32'))
bottom = min(self.image.size[1], np.floor(bottom + 0.5).astype('int32'))
right = min(self.image.size[0], np.floor(right + 0.5).astype('int32'))
if top - label_size[1] >= 0:
text_origin = np.array([left, top - label_size[1]])
else:
text_origin = np.array([left, top + 1])
# My kingdom for a good redistributable image drawing library.
for i in range(thickness_click):
draw.rectangle(
[left + i, top + i, right - i, bottom - i],
outline=self.colors[c_click])
draw.rectangle(
[tuple(text_origin), tuple(text_origin + label_size)],
fill=self.colors[c_click])
draw.text(text_origin, label, fill=(0, 0, 0), font=self.font)
del draw
image_click=image_click.resize((416,416))
size0=image_click.size[0]
size1=image_click.size[1]
self.cv.