opencv dlib 总

编程入门 行业动态 更新时间:2024-10-21 19:08:17

<a href=https://www.elefans.com/category/jswz/34/1769967.html style=opencv dlib 总"/>

opencv dlib 总

test.py

import cv2 as cv
import dlib
import imutils
import numpy as np
from imutils import face_utils as fu# 计算眼睛的纵横比
def eye_aspect_ratio(eye):# 计算上下的欧式距离a = np.linalg.norm(eye[1] - eye[5])b = np.linalg.norm(eye[2] - eye[4])# 计算左右的欧式距离c = np.linalg.norm(eye[0] - eye[3])# 计算纵横比并返回d = (a + b) / (2.0 * c)return d# 计算嘴巴的纵横比
def mouth_aspect_ratio(mouth):# 计算上下的欧式距离a = np.linalg.norm(mouth[3] - mouth[9])  # 52, 59b = np.linalg.norm(mouth[14] - mouth[18])  # 63, 67# 计算左右的欧式距离c = np.linalg.norm(mouth[0] - mouth[6])  # 49, 55d = np.linalg.norm(mouth[12] - mouth[16])  # 61, 65# 计算纵横比并返回e = (a + b) / (c + d)return e# 连续3帧眨眼次数
EYE_COUNTER = 0
# 总共眨眼次数
EYE_TOTAL = 0# 连续3帧张嘴次数
MOUTH_COUNTER = 0
# 总共张嘴次数
MOUTH_TOTAL = 0# 打开摄像头
cap = cv.VideoCapture(0, cv.CAP_DSHOW)
# 建立人脸检测器
detector = dlib.get_frontal_face_detector()
# 建立68关键点检测器
predictor = dlib.shape_predictor('./1.dat')# 返回人脸的左眼和右眼在68关键点中的起始和结束
(lStart, lEnd) = fu.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = fu.FACIAL_LANDMARKS_IDXS["right_eye"]# 返回人脸的嘴巴在68关键点中的起始和结束
(mStart, mEnd) = fu.FACIAL_LANDMARKS_IDXS["mouth"]# 只要能正确打开摄像头
while cap.isOpened():# 获取每一帧_, frame = cap.read()# 设置输出宽度frame = imutils.resize(frame, width=750)# 转变为灰度图加快识别gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)# 返回这一帧的所有人脸框faces = detector(gray, 0)# 遍历所有框框for face in faces:# 返回该框的68个坐标shape = predictor(gray, face)# 转变为坐标矩阵shape = fu.shape_to_np(shape)# 返回左眼和右眼的坐标leftEye = shape[lStart:lEnd]rightEye = shape[rStart:rEnd]# 计算左眼和右眼的纵横比leftEAR = eye_aspect_ratio(leftEye)rightEAR = eye_aspect_ratio(rightEye)# 取平均值earAVG = (leftEAR + rightEAR) / 2.0# 计算左眼和右眼的凸包leftEyeHull = cv.convexHull(leftEye)rightEyeHull = cv.convexHull(rightEye)# 圈出凸包,即眼睛的范围cv.drawContours(frame, [leftEyeHull], -1, (255, 255, 255), 1)cv.drawContours(frame, [rightEyeHull], -1, (255, 255, 255), 1)# 返回嘴巴的坐标Mouth = shape[mStart:mEnd]# 计算嘴巴的纵横比mar = mouth_aspect_ratio(Mouth)# 计算嘴巴的凸包MouthHull = cv.convexHull(Mouth)# 圈出凸包,即嘴巴的范围cv.drawContours(frame, [MouthHull], -1, (255, 255, 255), 1)'''若眼睛纵横比小于0.3 且 连续3帧则认为闭眼'''if earAVG < 0.3:EYE_COUNTER += 1else:if EYE_COUNTER >= 3:EYE_TOTAL += 1EYE_COUNTER = 0'''若嘴巴纵横比大于0.5 且 连续3帧则认为打哈欠'''if mar > 0.5:MOUTH_COUNTER += 1else:if MOUTH_COUNTER >= 3:MOUTH_TOTAL += 1MOUTH_COUNTER = 0# 接下来是对输出的处理# 左上角输出眨眼次数cv.putText(frame,"Blinks:{0}".format(EYE_TOTAL),(10, 20),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 255, 255),2,cv.LINE_AA)# 紧接实时earAVGcv.putText(frame,"earAVG:{0}".format(earAVG),(200, 20),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 255, 255),2,cv.LINE_AA)# 左上角输出打哈欠次数cv.putText(frame,"Yawning:{0}".format(MOUTH_TOTAL),(10, 50),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 255, 255),2,cv.LINE_AA)# 紧接实时marcv.putText(frame,"mar:{0}".format(mar),(200, 50),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 255, 255),2,cv.LINE_AA)# 右下角提示退出信息cv.putText(frame,"Press 'Esc' to Quit",(515, 550),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 255, 255),2,cv.LINE_AA)# 输出每一帧cv.imshow('camera', frame)# 按Esc退出if cv.waitKey(1) & 0xff == 27:break# 关闭所有窗口
cv.destroyAllWindows()
# 释放摄像头
cap.release()

main.py

import cv2 as cv
import dlib
import imutils
from imutils import face_utils as fuimport eye
import head
import mouth# 连续3帧眨眼次数
EYE_COUNTER = 0
# 总共眨眼次数
EYE_TOTAL = 0
# 持续闭眼计数(单位为帧)
ALWAYS_CLOSE_EYES_COUNTER = 0
# 持续闭眼警告标志
AL_eye_flag = False# 初始化帧计数器和点头总数
hCOUNTER = 0
hTOTAL = 0
# 持续低头计数(单位为帧)
ALWAYS_CLOSE_HEAD_COUNTER = 0
# 持续低头警告标志
AL_head_flag = False# 连续3帧张嘴次数
MOUTH_COUNTER = 0
# 总共张嘴次数
MOUTH_TOTAL = 0# 打开摄像头
cap = cv.VideoCapture(0, cv.CAP_DSHOW)
# 建立人脸检测器
detector = dlib.get_frontal_face_detector()
# 建立68关键点检测器
predictor = dlib.shape_predictor('./1.dat')while cap.isOpened():# 获取每一帧_, frame = cap.read()# 设置输出宽度frame = imutils.resize(frame, width=750)# 转变为灰度图加快识别gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)# 返回这一帧的所有人脸框faces = detector(gray, 0)# 遍历所有框框for face in faces:# 返回该框的68个坐标shape = predictor(gray, face)# 转变为坐标矩阵shape = fu.shape_to_np(shape)# 计算左右眼纵横比的平均值earAVG = eye.eye_detecting(frame, shape)# 计算嘴巴的纵横比mar = mouth.mouth_detecting(frame, shape)# 获取头部姿态reprojectdst, euler_angle = head.get_head_pose(shape)'''若眼睛纵横比小于0.3 且 连续3帧则认为闭眼'''if earAVG < 0.3:EYE_COUNTER += 1ALWAYS_CLOSE_EYES_COUNTER += 1else:if EYE_COUNTER >= 3:EYE_TOTAL += 1EYE_COUNTER = 0ALWAYS_CLOSE_EYES_COUNTER = 0# 持续闭眼判断if ALWAYS_CLOSE_EYES_COUNTER >= 18:AL_eye_flag = Trueelse:AL_eye_flag = False'''若嘴巴纵横比大于0.5 且 连续3帧则认为打哈欠'''if mar > 0.5:MOUTH_COUNTER += 1else:if MOUTH_COUNTER >= 3:MOUTH_TOTAL += 1MOUTH_COUNTER = 0'''头部pitch大于0.3 且 连续3帧则认为点头一次'''har = euler_angle[0, 0]  # 取pitch旋转角度if har > 15:  # 点头阈值15hCOUNTER += 1ALWAYS_CLOSE_HEAD_COUNTER += 1else:# 如果连续3次都小于阈值,则表示瞌睡点头一次if hCOUNTER >= 3:  # 阈值:3hTOTAL += 1# 重置点头帧计数器hCOUNTER = 0ALWAYS_CLOSE_HEAD_COUNTER = 0if ALWAYS_CLOSE_HEAD_COUNTER >= 18:AL_head_flag = Trueelse:AL_head_flag = False# 接下来是对输出的处理# 左上角输出眨眼次数cv.putText(frame,"Blinks:{0}".format(EYE_TOTAL),(10, 20),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(0, 0, 255),2,cv.LINE_AA)# 紧接实时earAVGcv.putText(frame,"earAVG:{0}".format(earAVG),(200, 20),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(0, 0, 255),2,cv.LINE_AA)# 如果检测到超过2秒的持续闭眼则告警if AL_eye_flag:cv.putText(frame,"WARNING EYE",(200, 150),cv.FONT_HERSHEY_COMPLEX_SMALL,2,(100, 100, 255),2,cv.LINE_AA)# 左上角输出打哈欠次数cv.putText(frame,"Yawning:{0}".format(MOUTH_TOTAL),(10, 50),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(0, 0, 255),2,cv.LINE_AA)# 紧接实时marcv.putText(frame,"mar:{0}".format(mar),(200, 50),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(0, 0, 255),2,cv.LINE_AA)for start, end in head.line_pairs:a = reprojectdst[start]b = reprojectdst[end]x1 = int(a[0])y1 = int(a[1])x2 = int(b[0])y2 = int(b[1])cv.line(frame, (x1, y1), (x2, y2), (0, 0, 255), 1)# 显示角度结果cv.putText(frame,"X: " + "{:7.2f}".format(euler_angle[0, 0]),(10, 90),cv.FONT_HERSHEY_SIMPLEX,0.75,(0, 255, 0),2)cv.putText(frame,"Y: " + "{:7.2f}".format(euler_angle[1, 0]),(150, 90),cv.FONT_HERSHEY_SIMPLEX,0.75,(255, 0, 0),2)cv.putText(frame,"Z: " + "{:7.2f}".format(euler_angle[2, 0]),(300, 90),cv.FONT_HERSHEY_SIMPLEX,0.75,(0, 0, 255),2)cv.putText(frame,"Nod: {}".format(hTOTAL),(450, 90),cv.FONT_HERSHEY_SIMPLEX,0.7,(255, 255, 0),2)cv.putText(frame,"har: {}".format(har),(10, 120),cv.FONT_HERSHEY_SIMPLEX,0.7,(255, 255, 0),2)# 如果检测到超过2秒的持续低头则告警if AL_head_flag:cv.putText(frame,"WARNING HEAD",(200, 250),cv.FONT_HERSHEY_COMPLEX_SMALL,2,(100, 100, 255),2,cv.LINE_AA)# 右下角提示退出信息cv.putText(frame,"Press 'Esc' to Quit",(515, 550),cv.FONT_HERSHEY_COMPLEX_SMALL,1,(255, 0, 0),2,cv.LINE_AA)# 输出每一帧cv.imshow('camera', frame)# 按Esc退出if cv.waitKey(1) & 0xff == 27:break# 关闭所有窗口
cv.destroyAllWindows()
# 释放摄像头
cap.release()

head.py

import mathimport cv2 as cv
import numpy as np# 世界坐标系(UVW):填写3D参考点,该模型参考.cpp
object_pts = np.float32([[6.825897, 6.760612, 4.402142],  # 33左眉左上角[1.330353, 7.122144, 6.903745],  # 29左眉右角[-1.330353, 7.122144, 6.903745],  # 34右眉左角[-6.825897, 6.760612, 4.402142],  # 38右眉右上角[5.311432, 5.485328, 3.987654],  # 13左眼左上角[1.789930, 5.393625, 4.413414],  # 17左眼右上角[-1.789930, 5.393625, 4.413414],  # 25右眼左上角[-5.311432, 5.485328, 3.987654],  # 21右眼右上角[2.005628, 1.409845, 6.165652],  # 55鼻子左上角[-2.005628, 1.409845, 6.165652],  # 49鼻子右上角[2.774015, -2.080775, 5.048531],  # 43嘴左上角[-2.774015, -2.080775, 5.048531],  # 39嘴右上角[0.000000, -3.116408, 6.097667],  # 45嘴中央下角[0.000000, -7.415691, 4.070434]])  # 6下巴角# 相机坐标系(XYZ):添加相机内参
K = [6.5308391993466671e+002, 0.0, 3.1950000000000000e+002,0.0, 6.5308391993466671e+002, 2.3950000000000000e+002,0.0, 0.0, 1.0]  # 等价于矩阵[fx, 0, cx; 0, fy, cy; 0, 0, 1]
# 图像中心坐标系(uv):相机畸变参数[k1, k2, p1, p2, k3]
D = [7.0834633684407095e-002, 6.9140193737175351e-002, 0.0, 0.0, -1.3073460323689292e+000]# 像素坐标系(xy):填写凸轮的本征和畸变系数
cam_matrix = np.array(K).reshape(3, 3).astype(np.float32)
dist_coeffs = np.array(D).reshape(5, 1).astype(np.float32)# 重新投影3D点的世界坐标轴以验证结果姿势
reprojectsrc = np.float32([[10.0, 10.0, 10.0],[10.0, 10.0, -10.0],[10.0, -10.0, -10.0],[10.0, -10.0, 10.0],[-10.0, 10.0, 10.0],[-10.0, 10.0, -10.0],[-10.0, -10.0, -10.0],[-10.0, -10.0, 10.0]])
# 绘制正方体12轴
line_pairs = [[0, 1], [1, 2], [2, 3], [3, 0],[4, 5], [5, 6], [6, 7], [7, 4],[0, 4], [1, 5], [2, 6], [3, 7]]def get_head_pose(shape):  # 头部姿态估计# (像素坐标集合)填写2D参考点,注释遵循 17左眉左上角/21左眉右角/22右眉左上角/26右眉右上角/36左眼左上角/39左眼右上角/42右眼左上角/# 45右眼右上角/31鼻子左上角/35鼻子右上角/48左上角/54嘴右上角/57嘴中央下角/8下巴角image_pts = np.float32([shape[17], shape[21], shape[22], shape[26], shape[36],shape[39], shape[42], shape[45], shape[31], shape[35],shape[48], shape[54], shape[57], shape[8]])# solvePnP计算姿势——求解旋转和平移矩阵:# rotation_vec表示旋转矩阵,translation_vec表示平移矩阵,cam_matrix与K矩阵对应,dist_coeffs与D矩阵对应。_, rotation_vec, translation_vec = cv.solvePnP(object_pts, image_pts, cam_matrix, dist_coeffs)# projectPoints重新投影误差:原2d点和重投影2d点的距离(输入3d点、相机内参、相机畸变、r、t,输出重投影2d点)reprojectdst, _ = cv.projectPoints(reprojectsrc, rotation_vec, translation_vec, cam_matrix, dist_coeffs)reprojectdst = tuple(map(tuple, reprojectdst.reshape(8, 2)))  # 以8行2列显示# print(type(reprojectdst))# print("repro = {0}".format(reprojectdst))# 计算欧拉角calc euler angle# 参考.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#decomposeprojectionmatrixrotation_mat, _ = cv.Rodrigues(rotation_vec)  # 罗德里格斯公式(将旋转矩阵转换为旋转向量)pose_mat = cv.hconcat((rotation_mat, translation_vec))  # 水平拼接,vconcat垂直拼接# decomposeProjectionMatrix将投影矩阵分解为旋转矩阵和相机矩阵_, _, _, _, _, _, euler_angle = cv.decomposeProjectionMatrix(pose_mat)pitch, yaw, roll = [math.radians(_) for _ in euler_angle]pitch = math.degrees(math.asin(math.sin(pitch)))roll = -math.degrees(math.asin(math.sin(roll)))yaw = math.degrees(math.asin(math.sin(yaw)))# print('pitch:{}, yaw:{}, roll:{}'.format(pitch, yaw, roll))return reprojectdst, euler_angle  # 投影误差,欧拉角

eye.py

import cv2 as cv
import numpy as np
from imutils import face_utils as fu# # 连续3帧眨眼次数
# EYE_COUNTER = 0
# # 总共眨眼次数
# EYE_TOTAL = 0# 计算眼睛的纵横比
def eye_aspect_ratio(eye):# 计算上下的欧式距离a = np.linalg.norm(eye[1] - eye[5])b = np.linalg.norm(eye[2] - eye[4])# 计算左右的欧式距离c = np.linalg.norm(eye[0] - eye[3])# 计算纵横比并返回d = (a + b) / (2.0 * c)return d# 返回左右眼纵横比的平均值
def eye_detecting(frame, shape):# 返回人脸的左眼和右眼在68关键点中的起始和结束(lStart, lEnd) = fu.FACIAL_LANDMARKS_IDXS["left_eye"](rStart, rEnd) = fu.FACIAL_LANDMARKS_IDXS["right_eye"]# 返回左眼和右眼的坐标leftEye = shape[lStart:lEnd]rightEye = shape[rStart:rEnd]# 计算左眼和右眼的纵横比leftEAR = eye_aspect_ratio(leftEye)rightEAR = eye_aspect_ratio(rightEye)# 取平均值earAVG = (leftEAR + rightEAR) / 2.0# 计算左眼和右眼的凸包leftEyeHull = cv.convexHull(leftEye)rightEyeHull = cv.convexHull(rightEye)# 圈出凸包,即眼睛的范围cv.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)cv.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)return earAVG

mouth.py

import cv2 as cv
import numpy as np
from imutils import face_utils as fu# # 连续3帧张嘴次数
# MOUTH_COUNTER = 0
# # 总共张嘴次数
# MOUTH_TOTAL = 0# 计算嘴巴的纵横比
def mouth_aspect_ratio(mouth):# 计算上下的欧式距离a = np.linalg.norm(mouth[3] - mouth[9])  # 52, 59b = np.linalg.norm(mouth[14] - mouth[18])  # 63, 67# 计算左右的欧式距离c = np.linalg.norm(mouth[0] - mouth[6])  # 49, 55d = np.linalg.norm(mouth[12] - mouth[16])  # 61, 65# 计算纵横比并返回e = (a + b) / (c + d)return e# 返回嘴巴的纵横比
def mouth_detecting(frame, shape):# 返回人脸的嘴巴在68关键点中的起始和结束(mStart, mEnd) = fu.FACIAL_LANDMARKS_IDXS["mouth"]# 返回嘴巴的坐标Mouth = shape[mStart:mEnd]# 计算嘴巴的纵横比mar = mouth_aspect_ratio(Mouth)# 计算嘴巴的凸包MouthHull = cv.convexHull(Mouth)# 圈出凸包,即嘴巴的范围cv.drawContours(frame, [MouthHull], -1, (0, 255, 0), 1)return mar

更多推荐

opencv dlib 总

本文发布于:2024-02-10 21:57:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1677508.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:opencv   dlib

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!