Save_Generate_Video模块:(用来检测视频并将检测之后的视频保存):
import cv2
import dlib
import tkinter
import numpy as np
from tqdm import tqdm
from PIL import Image,ImageTk
detector=dlib.get_frontal_face_detector()
#设置显示的图像大小
img_width=500
img_height=400
def TKImages(frame):
#摄像头翻转
# frame=cv2.flip(frame,1)
image=cv2.cvtColor(frame,cv2.COLOR_BGR2RGBA)
image=image.astype(np.uint8)
PILimage=Image.fromarray(image)
PILimage=PILimage.resize((img_width,img_height),Image.ANTIALIAS)
try:
tkImage=ImageTk.PhotoImage(image=PILimage)
except:
return 0
return tkImage
def Canvas_(root):
# 创建画布
canvas = tkinter.Canvas(root, bg='white', width=img_width, height=img_height)
canvas.place(x=150, y=50)
# 创建标签
label = tkinter.Label(root, text='人脸检测', font=('黑体', 14), width=15, height=1)
# `anchor=nw`则是把图片的左上角作为锚定点
label.place(x=300, y=20, anchor='nw')
return canvas
# 将视频检测的视频保存起来
image_path='hometown.jpg'
tkimage=''
def generate_video(input_path):
global tkimage
#获取视频名称
filehead = input_path.split('/')[-1]
#保存的位置
output_path = 'Output_Video/'+'out_'+filehead
print('视频开始处理')
# 获取视频总帧数
cap = cv2.VideoCapture(input_path)
frame_count = 0
while cap.isOpened():
success, frame = cap.read()
frame_count += 1
if not success:
break
cap.release()
# fps=cap.get(cv2.CAP_PROP_FPS)
# frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('视频总的帧数: {}'.format(frame_count))
cap = cv2.VideoCapture(input_path)
#获取帧的高度和宽度
frame_size = (cap.get(cv2.CAP_PROP_FRAME_WIDTH), cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
#获取保存的视频格式
fource = cv2.VideoWriter_fourcc(*'mp4v')
#获取视频帧
fps = cap.get(cv2.CAP_PROP_FPS)
#视频的保存
out = cv2.VideoWriter(output_path, fource, fps, (int(frame_size[0]), int(frame_size[1])))
margin = 0.2
# 设置显示的字体
font = cv2.FONT_HERSHEY_SIMPLEX
try:
#进度条功能
with tqdm(total=frame_count) as pbar:
for i in range(frame_count):
success, frame = cap.read()
try:
#获取帧的高宽
img_h, img_w, _ = np.shape(frame)
detected = detector(frame)
#如果检测的帧中有人脸则进行画框和检测
if len(detected) > 0:
for i, locate in enumerate(detected):
x1, y1, x2, y2, w, h = locate.left(), locate.top(), locate.right() + 1, locate.bottom() + 1, locate.width(), locate.height()
xw1 = max(int(x1 - margin * w), 0)
yw1 = max(int(y1 - margin * h), 0)
xw2 = min(int(x2 + margin * w), img_w - 1)
yw2 = min(int(y2 + margin * h), img_h - 1)
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, 'person', (x1, y1 - 10), font, 1.2, (0, 255, 0), 3)
pic=TKImages(frame)
canvas.create_image(0,0,anchor='nw',image=pic)
root.updata()
root.after(1)
except Exception as e:
# print('error',e)
pass
if success == True:
out.write(frame)
pbar.update(1)
except:
print('中途中断')
pass
img=cv2.imread(image_path)
tkimage=TKImages(img)
canvas.create_image(0,0,anchor='nw',image=tkimage)
cv2.destroyAllWindows()
out.release()
cap.release()
print('视频已保存至{}'.format(output_path))
主程序:
import os
import cv2
import dlib
import tkinter
import threading
import numpy as np
import Save_Generate_Video
from PIL import Image,ImageTk
from tkinter import filedialog
from tkinter import messagebox
from tensorflow.keras.preprocessing.image import img_to_array
detector=dlib.get_frontal_face_detector()
root=tkinter.Tk()
#设置窗体的高宽
# root.geometry('200x200')
root['height']=600
root['width']=800
#设置显示的图像大小
img_width=500
img_height=400
#设置窗体的标题
root.title('Detect')
#设置标题为图像形式,第一个参数设置为True,表示该图标适用于所有的窗口
#这里注意图像格式为.png,就算是从.jpg到.png的格式转换也不能,只能是.png格式
root.iconphoto(True,tkinter.PhotoImage(file='title.png'))
def TKImages(frame):
#摄像头翻转
# frame=cv2.flip(frame,1)
image=cv2.cvtColor(frame,cv2.COLOR_BGR2RGBA)
image=image.astype(np.uint8)
PILimage=Image.fromarray(image)
PILimage=PILimage.resize((img_width,img_height),Image.ANTIALIAS)
try:
tkImage=ImageTk.PhotoImage(image=PILimage)
except:
return 0
return tkImage
def Canvas_():
# 创建画布
canvas = tkinter.Canvas(root, bg='white', width=img_width, height=img_height)
canvas.place(x=150, y=50)
# 创建标签
label = tkinter.Label(root, text='人脸检测', font=('黑体', 14), width=15, height=1)
# `anchor=nw`则是把图片的左上角作为锚定点
label.place(x=300, y=20, anchor='nw')
return canvas
#关闭主界面时弹出的确认窗口
def closeEvent(root):
# root.withdraw() # 仅显示对话框,隐藏主窗口
btn_close=tkinter.Button(root,text='退出检测',font=('黑体', 14), height=1, width=30,command=root.destroy)
btn_close.place(x=260,y=560)
image_path = 'hometown.jpg'
#这里需要将tkImage设置为全局变量,不然显示不图片
tkImage=''
def set_BackGround(image_path):
global tkImage
image_path = 'hometown.jpg'
canvas = Canvas_()
img = cv2.imread(image_path)
tkImage = TKImages(img)
canvas.create_image(0, 0, anchor='nw', image=tkImage)
#初始化整个界面
def Init(root,image_path):
set_BackGround(image_path)
btn_2 = tkinter.Button(root, text='打开摄像头检测', font=('黑体', 14), height=1, width=30,
command=lambda: Detect_Real_Time(0, root))
btn_2.place(x=260, y=455)
bnt_File = tkinter.Button(root, text='打开视频进行检测', font=('黑体', 14), width=30,
height=1, command=lambda :Select_File_Detect(root))
bnt_File.place(x=260, y=490)
bnt_Save = tkinter.Button(root, text='视频进行检测并保存', font=('黑体', 14), width=30, height=1,
command=lambda: Select_File_Detect_Save(root))
bnt_Save.place(x=260, y=525)
#关闭检测函数
def Close_Video(cap,root,image_path):
cap.release()
cv2.destroyAllWindows()
Init(root,image_path)
def Detect_Real_Time(parameter,root):
##第二个参数表示捕获的图像分辨率
# cap=cv2.VideoCapture(parameter,cv2.CAP_DSHOW)
cap=cv2.VideoCapture(parameter)
#这句是关闭摄像头
btn = tkinter.Button(root, text='停止检测', font=('黑体',14),width=15,height=1,command=lambda :Close_Video(cap,root,image_path))
btn.place(x=350, y=455)
canvas=Canvas_()
margin = 0.2
frame_count = 0
face_count = 0
# 设置显示的字体
font = cv2.FONT_HERSHEY_SIMPLEX
while True:
OK,frame=cap.read()
if OK==False and parameter==0:
print('请面对摄像头')
break
elif OK==False and parameter!=0:
print('结束视频检测')
Init(root,image_path)
break
img_h, img_w, _ = np.shape(frame)
detected = detector(frame)
#如果检测的帧中有人脸则进行画框和检测
if len(detected) > 0:
for i, locate in enumerate(detected):
face_count += 1
x1, y1, x2, y2, w, h = locate.left(), locate.top(), locate.right() + 1, locate.bottom() + 1, locate.width(), locate.height()
xw1 = max(int(x1 - margin * w), 0)
yw1 = max(int(y1 - margin * h), 0)
xw2 = min(int(x2 + margin * w), img_w - 1)
yw2 = min(int(y2 + margin * h), img_h - 1)
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, 'person', (x1, y1 - 10), font, 1.2, (0, 255, 0), 3)
pic=TKImages(frame)
canvas.create_image(0,0,anchor='nw',image=pic)
root.update()
root.after(1)
cap.release()
cv2.destroyAllWindows()
def Select_File_Detect(root):
#选择open文件进行识别
filename=filedialog.askopenfilename(title='选择文件进行识别')
if filename:
print('进行视频人脸检测')
Detect_Real_Time(filename,root)
#将检测的视频进行保存
def Select_File_Detect_Save(root):
#选择open文件进行识别
filename=filedialog.askopenfilename(title='选择文件进行识别')
if filename:
print('进行视频人脸检测')
#放在线程中不会出现卡顿,并且速度更快
#这个地方注意args中的参数如果只有一个的话,后面需要加一个','
thread_generate=threading.Thread(target=Save_Generate_Video.generate_video,args=(filename,root))
thread_generate.start()
if __name__=='__main__':
# Detect_Real_Time(0)
# Detect_Video(root)
Init(root,image_path)
closeEvent(root)
root.mainloop()
关于这个程序要说明的地方和函数功能已经在程序中说明,如果读者还有什么不懂之处,请留言。