先上效果圖:
用的python tkinter,識別的模型使用yolov3.
我另一篇博客寫了如何使用yolov3去detect object,這篇博客作爲其桌面化的延伸。
yolov3使用:https://blog.csdn.net/Yonggie/article/details/104964674
因爲邏輯很簡單,所以直接上代碼:
import cv2
import numpy as np
import tkinter as tk
import tkinter.filedialog
from PIL import Image,ImageTk
class Engine:
def __init__(self):
self.img=None
self.model=None
self.colors=None
self.output_layers=None
self.classes=None
self.path=None
def LoadModel(self):
# load yolo
base = r"G:/Code/YOLO recognition/"
self.model = cv2.dnn.readNet(base + "yolov3.weights", base + "yolov3.cfg")
# load label
with open(base + "coco.names") as f:
self.classes = [line.strip() for line in f]
layer_names = self.model.getLayerNames()
self.output_layers = [layer_names[i[0] - 1] for i in self.model.getUnconnectedOutLayers()]
def GetPath(self,path):
self.path=path
def GetImg(self):
if self.path is None:
path_label.config(text='您還沒有選擇圖片!')
return
try:
self.img = cv2.imread(self.path)
except:
path_label.config(text='不能打開所選圖片!')
return
self.img = cv2.resize(self.img, None, fx=0.4, fy=0.4)
cv2.imshow("original", self.img)
def Modify(self):
if self.img is None:
return
self.colors=np.random.uniform(0, 255, size=(len(self.classes), 3))
img_height, img_width, channel = self.img.shape
blob = cv2.dnn.blobFromImage(self.img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
self.model.setInput(blob)
outs = self.model.forward(self.output_layers)
confidences = []
boxes = []
pred_indeces = []
# show info on pic
for out in outs:
for detection in out:
# why after 5
scores = detection[5:]
pred_index = np.argmax(scores)
confidence = scores[pred_index]
if confidence > 0.5:
center_x = int(detection[0] * img_width)
center_y = int(detection[1] * img_height)
rec_width = int(detection[2] * img_width)
rec_height = int(detection[3] * img_height)
left_top_x = int(center_x - rec_width / 2)
left_top_y = int(center_y - rec_height / 2)
boxes.append([left_top_x, left_top_y, rec_width, rec_height])
pred_indeces.append(pred_index)
confidences.append(float(confidence))
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
font = cv2.FONT_HERSHEY_PLAIN
for i in range(len(boxes)):
if i in indexes:
left_top_x, left_top_y, rec_width, rec_height = boxes[i]
label = self.classes[pred_indeces[i]]
color = self.colors[i]
cv2.rectangle(self.img, (left_top_x, left_top_y), (left_top_x + rec_width, left_top_y + rec_height), color, 2)
cv2.putText(self.img, label, (left_top_x, left_top_y + 30), font, 1, color, 2)
def ShowRes(self):
if self.img is None:
return
cv2.imshow("detected",self.img)
def Detect():
#get picture
engine.GetImg()
engine.Modify()
engine.ShowRes()
def SelectPic():
filename = tk.filedialog.askopenfilename()
if filename != '':
path_label.config(text = "您選擇的文件是:"+filename)
engine.GetPath(filename)
else:
path_label.config(text = "您沒有選擇任何文件")
def center_window(w,h):
ws = window.winfo_screenwidth()
hs = window.winfo_screenheight()
# 計算 x, y 位置
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
window.geometry('%dx%d+%d+%d' % (w, h, x, y))
if __name__ == '__main__':
window=tk.Tk()
window.title("object detection")
center_window(500,250)
window.iconbitmap('detect.ico')
# cv2.moveWindow("winname", x, y)
engine=Engine()
engine.LoadModel()
path_label=tk.Label(window,text='select a picture:')
path_label.pack()
select_button=tk.Button(window, text='select', command=SelectPic)
select_button.pack()
empty_label1 = tk.Label(window, text='')
empty_label1.pack()
button=tk.Button(window,
text='detect object',
width=13,height=1,
command=Detect)
button.pack()
empty_label2 = tk.Label(window, text='')
empty_label2.pack()
img=Image.open('background.png')
img = img.resize((100, 100), Image.ANTIALIAS)
img=ImageTk.PhotoImage(img)
img_label=tk.Label(window,image=img)
img_label.pack()
tk.mainloop()