拍照+上传文件+调用摄像头

import dlib
import joblib
import numpy as np
import copy
import pandas as pd
import pygame
from imutils import face_utils
from scipy.spatial import distance
from tkinter import *
from PIL import Image, ImageTk
import tkinter.ttk
import numpy
from PIL import Image, ImageDraw, ImageFont
import cv2
from collections import OrderedDict
from tkinter import filedialog
import time

global canva_r, canva_l, FPS, root,switch,txt
upload_flag=0

眨眼最小阈值 触发报警的眼睛纵横比的最小阈值

eyes_blink = 0.2

眼睛比率低于触发警报阈值的最小连续帧

eyes_ratio = 30

眨眼次数检测

count = 0
eye_close = False
yawn = False
yawn_flag = 0
t=0
thresh_mouth = 0.65
num =1
switch=1
txt=‘’
(mStart, mEnd) = face_utils.FACIAL_LANDMARKS_68_IDXS[“mouth”] # 48~67
pygame.mixer.init() # 语音模块初始化
SHAPE_68_INDEX = OrderedDict([
(“left_eye”, (42, 48)),
(“right_eye”, (36, 42))
])

拿坐标

(lstart,lend) = SHAPE_68_INDEX[‘left_eye’]
(rstart,rend) = SHAPE_68_INDEX[‘right_eye’]

疲劳检测函数

def main_detect(cap):
print(“开始进行疲劳检测!!!”)
while switch == 1:

    start = cv2.getTickCount()
    #result_show.grid_forget()
    # result_show.grid_forget()#grid_forget()方法只是将控件隐藏
    canva_r.delete("all")#清屏
    global t, eye_close,count,yawn,yawn_flag
    ret, frame = cap.read()  # 读取摄像头 大小:(480x640)

    if ret is False:
        canva_r.create_text(200, 200, text="视频播放完成", font=("Lucida Console", 15), fill="red")
        print("视频播放完毕")
        break

    frame = frame[0:1080, 0:1440]#裁剪画幅
                                       #原始图像(0,0)-(1080,1440)
    #缩放大小
    frame = cv2.resize(frame, (int(frame.shape[1] / 2.25), int(frame.shape[0] / 2.25)))
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 转化为灰度图
   # 利用模型文件对脸型上的68个点进行定位寻找
    faces = detection(gray,0)

    for face in faces:
        shape = predictor(gray, face)
        shape = face_utils.shape_to_np(shape)
        # 左右眼坐标
        leftEye = shape[lstart:lend]
        rightEye = shape[rstart:rend]
        # 调用参数计算上眼皮和下眼皮的距离
        leftEyeDistance = calculate_EAR(leftEye)
        rightEyeDistance = calculate_EAR(rightEye)
        # 计算均值
        ER = (leftEyeDistance+rightEyeDistance) / 2
        # 利用cv2.convexhull 寻找图像凸包(凸包就是:打比方一个五角星,每一个尖点相连)
        leftEyeHull = cv2.convexHull(leftEye)
        rightEyeHull = cv2.convexHull(rightEye)
        # 将眼睛画线
        cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
        cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)


        #
        #
        # 计算嘴巴宽高比
        mouth = shape[mStart:mEnd]
        mouthRatio = mouth_aspect_ratio(mouth)
        #画出嘴巴
        mymouth = cv2.convexHull(mouth)
        cv2.drawContours(frame, [mymouth], -1, (0, 255, 0), 1)



        # 判断是否打哈欠
        if mouthRatio > thresh_mouth:
            yawn = True
            yawn_flag = 0
        if yawn == True and yawn_flag < 40:
            canva_r.create_text(200, 200, text="检测到您打了一个哈欠,\n请注意不要疲劳驾驶!", font=("Lucida Console", 15), fill="red")
            if yawn == True and t == 0:
                t = 1
                pygame.mixer.music.stop()
                pygame.mixer.music.load('sound\\yawn.mp3')
                pygame.mixer.music.play()
            yawn_flag = yawn_flag + 1
        elif yawn == True and yawn_flag == 40:
            yawn = False
            yawn_flag = 0
            t = 0


        # 判断是否闭上眼睛
        if (ER < eyes_blink):
            count +=1
            if count >= eyes_ratio:
                eye_close = True
                eye_flag = 0
        else:
            count = 0
        if eye_close == True and eye_flag < 40:
            # WARNING
            canva_r.create_text(200, 200, text="警告!!!\n检测到您的眼睛已经闭合,\n请注意不要疲劳驾驶!", justify=LEFT,
                                font=("Lucida Console", 15), fill="red")
            if eye_close == True and t == 0:
                t = 1
                pygame.mixer.music.stop()
                pygame.mixer.music.load('sound\\eyes.mp3')
                pygame.mixer.music.play()
            eye_flag = eye_flag + 1
        elif eye_close == True and eye_flag == 40:
            eye_close = False
            eye_flag = 0
            t = 0

    end = cv2.getTickCount()
    during1 = (end - start) / cv2.getTickFrequency()
    # 计算代码运行的时间消耗,其中最后一个参数是时钟周期

    FPS.set("FPS:" + str(round(1 / during1, 2)))
    Showimage(frame, canva_l, "fit")
    root.update()

def load_dlib():
global detection,predictor
# 加载dlib人脸分类器
detection = dlib.get_frontal_face_detector()
# 读取68点模型文件
predictor = dlib.shape_predictor(‘./shape_predictor_68_face_landmarks.dat’)

#EAR算法

计算眼睛宽高比

def eye_aspect_ratio(eye):
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ratio = (A + B) / (2.0 * C)
return ratio

计算嘴巴宽高比

def mouth_aspect_ratio(mouth):
A = distance.euclidean(mouth[2], mouth[10])
B = distance.euclidean(mouth[4], mouth[8])
C = distance.euclidean(mouth[0], mouth[6])
ratio = (A + B) / (2.0 * C)
return ratio

求ER值

def calculate_EAR(eye):
# 计算眼睛之间的距离,利用scipy distance 计算上眼皮和下眼皮之间欧氏距离
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear_aspect_ratio = (A + B) / (2.0 * C)
return ear_aspect_ratio

计MAR

def mouth_aspect_ratio(mouth):
A = distance.euclidean(mouth[2], mouth[10])
B = distance.euclidean(mouth[4], mouth[8])
C = distance.euclidean(mouth[0], mouth[6])
ratio = (A + B) / (2.0 * C)
return ratio

def upload_file():
global cap,txt,upload_flag,ret,frame
selectFile = tkinter.filedialog.askopenfilename() # askopenfilename 1次上传1个;askopenfilenames1次上传多个
entry1.insert(0, selectFile)
txt=entry1.get()
print(“上传的文件地址是:”)
print(txt)
cap = cv2.VideoCapture(txt)
print(“成功捕捉视频”)
upload_flag=1
if upload_flag==1:
canva_l.delete(‘all’)
canva_l.create_text(200, 200, text=“成功打开视频”, font=(“Lucida Console”, 15), fill=“red”)
main_detect(cap=cap)

def swi():
global num,cut
print(1111111)
if cap.isOpened():
ret,frame = cap.read() #按帧读取视频

    cv2.imwrite('./pic/'+str(num)+".jpg",frame) #保存视频帧图像
    print("已保存一张图片")
    num += 1
if ret is False:
        
        canva_r.create_text(200, 200, text="视频播放完成", font=("Lucida Console", 15), fill="red")
        print("视频播放完毕")

def open_camera():
canva_l.delete(‘all’)
canva_l.create_text(200, 200, text=“成功打开摄像头”, font=(“Lucida Console”, 15), fill=“red”)
cap=cap = cv2.VideoCapture(0)
main_detect(cap=cap)

def Showimage(imgCV_in, canva, layout=“null”):
global imgTK

canvawidth = int(canva.winfo_reqwidth())
canvaheight = int(canva.winfo_reqheight())

#获取cv图像的高度和宽度 sp(hight,width,通道)
sp = imgCV_in.shape
cvheight = sp[0]  # height(rows) of image
cvwidth = sp[1]  # width(colums) of image

if (layout == "fill"):
    imgCV = cv2.resize(imgCV_in, (canvawidth, canvaheight), interpolation=cv2.INTER_AREA)
elif (layout == "fit"):
    if (float(cvwidth / cvheight) > float(canvawidth / canvaheight)):
        imgCV = cv2.resize(imgCV_in, (canvawidth, int(canvawidth * cvheight / cvwidth)),
                           interpolation=cv2.INTER_AREA)
    else:
        imgCV = cv2.resize(imgCV_in, (int(canvaheight * cvwidth / cvheight), canvaheight),
                           interpolation=cv2.INTER_AREA)
else:
    imgCV = imgCV_in

imgCV2 = cv2.cvtColor(imgCV, cv2.COLOR_BGR2RGBA)  # 转换颜色从BGR到RGBA
current_image = Image.fromarray(imgCV2)  # 将图像转换成Image对象
imgTK = ImageTk.PhotoImage(image=current_image)  # 将image对象转换为imageTK对象
canva.create_image(0, 0, anchor=NW, image=imgTK)

def GUI_init():
global entry1,canva_l,canva_r,FPS,root
root = Tk() #主窗口
root.title(“姿态检测系统”)
root.minsize(710, 410)#大小
# 创建视频播放幕布
canva_l = Canvas(root, width=480, height=360, bg=“white”)
canva_l.grid(row=0, column=0) #row:第一行 column第一个位置
# 创建信息幕布
canva_r = Canvas(root, width=350, height=360, bg=“white”)
canva_r.grid(row=0, column=1) #row:第一行 column第二个位置
# 显示FPS
FPS = tkinter.StringVar()
FPS_show = tkinter.Label(root, textvariable=FPS, bg=“white”, font=(“Lucida Console”, 10))
FPS_show.grid(row=1, column=0)
if upload_flag==0:
canva_l.create_text(200, 200, text=“欢迎使用本系统”, font=(“Lucida Console”, 15), fill=“red”)

# 创建拍照按钮
cut = tkinter.Button(root, text="拍照",  font=("Lucida Console", 14),command=swi)
cut.grid(row=2,column=1)
cut.place(x=350, y=366)

#创建上传文件按钮
upload = tkinter.Button(root, text='上传文件',command=upload_file)
upload.grid(row=1,column=1)
entry1 = tkinter.Entry(root, width='40')
entry1.grid(row=2,column=1)

#创建实时摄像头按钮
camera = tkinter.Button(root,text="开启摄像头",command=open_camera)
camera.grid(row=3,column=1)


root.mainloop()

load_dlib()
GUI_init()

你可能感兴趣的:(python,pygame,开发语言)