《OpenCV》——dlib(人臉應用實例)

文章目錄

    • dlib庫
    • dlib庫——人臉應用實例——表情識別
    • dlib庫——人臉應用實例——疲勞檢測

dlib庫

dlib庫的基礎用法介紹可以參考這篇文章:https://blog.csdn.net/lou0720/article/details/145968062?spm=1011.2415.3001.5331,故此這篇文章只介紹dlib的人臉應用實例。

dlib庫——人臉應用實例——表情識別

在這里插入圖片描述
代碼:

import numpy as np
import cv2
import dlib
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFontdef cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=20):""" 向圖片中添加中文 """# 判斷輸入的 img 是否為 OpenCV 格式的圖片(即 numpy.ndarray 類型)if isinstance(img, np.ndarray):# 如果是 OpenCV 格式,將其從 BGR 顏色空間轉換為 RGB 顏色空間,# 因為 PIL 庫使用 RGB 顏色空間,而 OpenCV 使用 BGR 顏色空間img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 在 img 圖片上創建一個繪圖對象,用于后續繪制文本draw = ImageDraw.Draw(img)# 定義字體的格式,使用 "simsun.ttc" 字體文件,指定字體大小為 textSize,# 并設置編碼為 UTF - 8 以支持中文顯示fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")# 在指定的 position 位置,使用指定的 textColor 顏色和 fontStyle 字體繪制文本draw.text(position, text, textColor, font=fontStyle)# 將繪制好文本的 PIL 圖片轉換回 numpy.ndarray 類型,并將顏色空間從 RGB 轉換回 BGR,# 以符合 OpenCV 的要求return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)def MAR(shape):"""計算嘴巴縱橫比(Mouth Aspect Ratio):param shape: 68 個人臉特征點的坐標數組:return: 嘴巴縱橫比"""# 計算嘴巴上下部分特定點之間的歐氏距離A = euclidean_distances(shape[50].reshape(1, 2), shape[58].reshape(1, 2))B = euclidean_distances(shape[51].reshape(1, 2), shape[57].reshape(1, 2))C = euclidean_distances(shape[52].reshape(1, 2), shape[56].reshape(1, 2))# 計算嘴巴左右兩側特定點之間的歐氏距離D = euclidean_distances(shape[48].reshape(1, 2), shape[54].reshape(1, 2))# 計算嘴巴縱橫比,即上下部分平均距離與左右距離的比值return ((A + B + C) / 3) / Ddef MJR(shape):"""計算嘴巴與下巴寬度比(Mouth to Jaw Ratio):param shape: 68 個人臉特征點的坐標數組:return: 嘴巴與下巴寬度比"""# 計算嘴巴左右兩側特定點之間的歐氏距離M = euclidean_distances(shape[48].reshape(1, 2), shape[54].reshape(1, 2))# 計算下巴左右兩側特定點之間的歐氏距離J = euclidean_distances(shape[3].reshape(1, 2), shape[13].reshape(1, 2))# 計算嘴巴與下巴寬度比return M / Jdef MBR(shape):"""計算眉毛間距比(Mouth to Brow Ratio):param shape: 68 個人臉特征點的坐標數組:return: 眉毛間距比"""# 計算左右眉毛內側特定點之間的歐氏距離F = euclidean_distances(shape[21].reshape(1, 2), shape[22].reshape(1, 2))# 計算左右眉毛外側特定點之間的歐氏距離I = euclidean_distances(shape[17].reshape(1, 2), shape[26].reshape(1, 2))# 計算眉毛間距比return F / I# 打開默認攝像頭,用于實時視頻捕獲
cap = cv2.VideoCapture(0)
# 加載預訓練的 68 點人臉特征預測模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 創建人臉檢測器對象
detector = dlib.get_frontal_face_detector()while True:# 從攝像頭讀取一幀視頻ret, frame = cap.read()# 水平翻轉視頻幀,使畫面看起來更自然frame = cv2.flip(frame, 1)# 如果讀取失敗,跳出循環if ret is None:break# 檢測視頻幀中的人臉faces = detector(frame, 0)for face in faces:# 預測人臉的 68 個特征點shape = predictor(frame, face)# 將特征點轉換為 numpy 數組shape = np.array([[p.x, p.y] for p in shape.parts()])# 計算嘴巴縱橫比mar = MAR(shape)# 計算嘴巴與下巴寬度比mjr = MJR(shape)# 計算眉毛間距比mbr = MBR(shape)# 初始化表情結果為正常result = '正常'# 打印各個比值print("mar", mar, '\tmjr', mjr, 'mbr', mbr)# 根據比值判斷表情if mar > 0.5:result = "大笑"elif mjr > 0.45:result = '微笑'elif mbr < 0.15:result = '生氣'# 計算嘴巴輪廓的凸包mouthHull = cv2.convexHull(shape[48:61])# 在視頻幀上添加中文表情結果frame = cv2AddChineseText(frame, result, mouthHull[0, 0])# 在視頻幀上繪制嘴巴輪廓cv2.drawContours(frame, [mouthHull], -1, (0, 255, 0), 1)# 顯示處理后的視頻幀cv2.imshow('img', frame)# 等待用戶按鍵,等待時間為 1 毫秒key = cv2.waitKey(1)# 如果用戶按下 ESC 鍵(ASCII 碼為 27),跳出循環if key == 27:break
# 釋放攝像頭資源
cap.release()
# 關閉所有 OpenCV 窗口
cv2.destroyAllWindows()

在這里插入圖片描述

dlib庫——人臉應用實例——疲勞檢測

在這里插入圖片描述

當閉眼時間長時,發出危險警告。

代碼:

import numpy as np
import cv2
import dlib
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFontdef cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=20):""" 向圖片中添加中文 """# 判斷輸入的 img 是否為 OpenCV 格式的圖片(即 numpy.ndarray 類型)if isinstance(img, np.ndarray):# 如果是 OpenCV 格式,將其從 BGR 顏色空間轉換為 RGB 顏色空間,# 因為 PIL 庫使用 RGB 顏色空間,而 OpenCV 使用 BGR 顏色空間img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 在 img 圖片上創建一個繪圖對象,用于后續繪制文本draw = ImageDraw.Draw(img)# 定義字體的格式,使用 "simsun.ttc" 字體文件,指定字體大小為 textSize,# 并設置編碼為 UTF - 8 以支持中文顯示fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")# 在指定的 position 位置,使用指定的 textColor 顏色和 fontStyle 字體繪制文本draw.text(position, text, textColor, font=fontStyle)# 將繪制好文本的 PIL 圖片轉換回 numpy.ndarray 類型,并將顏色空間從 RGB 轉換回 BGR,# 以符合 OpenCV 的要求return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)def eye_aspect_ratio(eye):"""計算眼睛的縱橫比(Eye Aspect Ratio,EAR):param eye: 眼睛的特征點坐標數組:return: 眼睛的縱橫比"""# 計算眼睛垂直方向上的距離A = euclidean_distances(eye[1].reshape(1, 2), eye[5].reshape(1, 2))B = euclidean_distances(eye[2].reshape(1, 2), eye[4].reshape(1, 2))# 計算眼睛水平方向上的距離C = euclidean_distances(eye[0].reshape(1, 2), eye[3].reshape(1, 2))# 計算眼睛縱橫比,即垂直方向平均距離與水平距離的比值ear = ((A + B) / 2) / Creturn eardef drawEye(eye):"""在圖像上繪制眼睛的輪廓:param eye: 眼睛的特征點坐標數組"""# 計算眼睛特征點的凸包eyeHull = cv2.convexHull(eye)# 在圖像 frame 上繪制眼睛的輪廓cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0), 1)# 初始化計數器,用于記錄眼睛閉合的幀數
COUNTER = 0
# 創建人臉檢測器對象,用于檢測圖像中的人臉
detector = dlib.get_frontal_face_detector()
# 打開默認攝像頭,用于實時視頻捕獲
cap = cv2.VideoCapture(0)
# 加載預訓練的 68 點人臉特征預測模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')while True:# 從攝像頭讀取一幀視頻ret, frame = cap.read()# 水平翻轉視頻幀,使畫面看起來更自然frame = cv2.flip(frame, 1)# 如果讀取失敗,跳出循環if ret is None:break# 檢測視頻幀中的人臉faces = detector(frame, 0)for face in faces:# 預測人臉的 68 個特征點shape = predictor(frame, face)# 將特征點轉換為 numpy 數組shape = np.array([[p.x, p.y] for p in shape.parts()])# 提取右眼的特征點rightEye = shape[36:42]# 提取左眼的特征點leftEye = shape[42:48]# 計算右眼的縱橫比rightEAR = eye_aspect_ratio(rightEye)# 計算左眼的縱橫比leftEAR = eye_aspect_ratio(leftEye)# 計算左右眼縱橫比的平均值ear = (leftEAR + rightEAR) / 2# 如果眼睛縱橫比小于 0.3,認為眼睛處于閉合狀態if ear < 0.3:# 閉合幀數計數器加 1COUNTER += 1# 如果閉合幀數超過 50 幀,認為可能存在危險情況if COUNTER >= 50:# 在視頻幀上添加中文提示信息frame = cv2AddChineseText(frame, "!!!危險!!!", (250, 250))else:# 如果眼睛處于睜開狀態,將閉合幀數計數器重置為 0COUNTER = 0# 繪制左眼的輪廓drawEye(leftEye)# 繪制右眼的輪廓drawEye(rightEye)# 格式化眼睛縱橫比信息,保留兩位小數info = "EAR:{:.2f}".format(ear[0][0])# 在視頻幀上添加眼睛縱橫比信息frame = cv2AddChineseText(frame, info, (0, 30))# 顯示處理后的視頻幀cv2.imshow('Frame', frame)# 等待用戶按鍵,等待時間為 1 毫秒key = cv2.waitKey(1)# 如果用戶按下 ESC 鍵(ASCII 碼為 27),跳出循環if key == 27:break# 釋放攝像頭資源
cap.release()
# 關閉所有 OpenCV 窗口
cv2.destroyAllWindows()

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896977.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896977.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

學習日記-250305

閱讀論文&#xff1a;Leveraging Pedagogical Theories to Understand Student Learning Process with Graph-based Reasonable Knowledge Tracing ps:代碼邏輯最后一點還沒理順&#xff0c;明天繼續 4.2 Knowledge Memory & Knowledge Tracing 代碼研究&#xff1a; 一般…

【AI大模型】DeepSeek + Kimi 高效制作PPT實戰詳解

目錄 一、前言 二、傳統 PPT 制作問題 2.1 傳統方式制作 PPT 2.2 AI 大模型輔助制作 PPT 2.3 適用場景對比分析 2.4 最佳實踐與推薦 三、DeepSeek Kimi 高效制作PPT操作實踐 3.1 Kimi 簡介 3.2 DeepSeek Kimi 制作PPT優勢 3.2.1 DeepSeek 優勢 3.2.2 Kimi 制作PPT優…

【ESP-ADF】在 VSCode 安裝 ESP-ADF 注意事項

1.檢查網絡 如果您在中國大陸安裝&#xff0c;請使用魔法上網&#xff0c;避免無法 clone ESP-ADF 倉庫。 2.VSCode 安裝 ESP-ADF 在 VSCode 左側活動欄選擇 ESP-IDF:explorer&#xff0c;展開 advanced 并點擊 Install ESP-ADF 然后會出現選擇 ESP-ADF 安裝目錄。 如果出現…

關于2023新版PyCharm的使用

考慮到大家AI編程的需要&#xff0c;建議大家安裝新版Python解釋器和新版PyCharm&#xff0c;下載地址都可以官網進行&#xff1a; Python&#xff1a;Download Python | Python.org&#xff08;可以根據需要自行選擇&#xff0c;建議選擇3.11&#xff0c;保持交流版本一致&am…

輕松部署 Stable Diffusion WebUI 并實現局域網共享訪問:解決 Conda Python 版本不為 3.10.6 的難題

這篇博文主要為大家講解關于sd webui的部署問題&#xff0c;大家有什么不懂的可以隨時問我&#xff0c;如果沒有及時回復&#xff0c;可聯系&#xff1a;1198965922 如果后續大家需要了解怎么用代碼調用部署好的webui的接口&#xff0c;可以在評論區留言哦&#xff0c;博主可以…

Leetcode 103: 二叉樹的鋸齒形層序遍歷

Leetcode 103: 二叉樹的鋸齒形層序遍歷 問題描述&#xff1a; 給定一個二叉樹&#xff0c;返回其節點值的鋸齒形層序遍歷&#xff08;即第一層從左到右&#xff0c;第二層從右到左&#xff0c;第三層從左到右&#xff0c;依此類推&#xff09;。 適合面試的解法&#xff1a;廣…

Linux中的進程間通信的方式及其使用場景

在 Linux 系統中&#xff0c;進程間通信&#xff08;Inter-Process Communication, IPC&#xff09;是指不同進程之間傳遞數據、共享信息的機制。Linux 提供了多種進程間通信的方式&#xff0c;每種方式都有不同的特點和使用場景。以下是常見的幾種進程間通信方式及其應用場景&…

springBoot集成emqx 實現mqtt消息的發送訂閱

介紹 我們可以想象這么一個場景&#xff0c;我們java應用想要采集到電表a的每小時的用電信息&#xff0c;我們怎么拿到電表的數據&#xff1f;一般我們會想 直接 java 后臺發送請求給電表&#xff0c;然后讓電表返回數據就可以了&#xff0c;事實上&#xff0c;我們java應用發…

vue Table 表格自適應窗口高度,表頭固定

當表格內縱向內容過多時&#xff0c;可選擇固定表頭。 代碼很簡單&#xff0c;其實就是在table 里面定一個 height 屬性即可。 <template><el-table:data"tableData"height"250"borderstyle"width: 100%"><el-table-columnprop…

多線程-JUC

簡介 juc&#xff0c;java.util.concurrent包的簡稱&#xff0c;java1.5時引入。juc中提供了一系列的工具&#xff0c;可以更好地支持高并發任務 juc中提供的工具 可重入鎖 ReentrantLock 可重入鎖&#xff1a;ReentrantLock&#xff0c;可重入是指當一個線程獲取到鎖之后&…

【每日學點HarmonyOS Next知識】Web Header更新、狀態變量嵌套問題、自定義彈窗、stack圓角、Flex換行問題

【每日學點HarmonyOS Next知識】Web Header更新、狀態變量嵌套問題、自定義彈窗、stack圓角、Flex換行問題 1、HarmonyOS 有關webview Header無法更新的問題&#xff1f; 業務A頁面 打開 webivew B頁面&#xff0c;第一次打開帶了header請求&#xff0c;然后退出webview B頁面…

【ATXServer2】Android無法正確顯示手機屏幕

文章目錄 現象原因分析與解決排查手機內部minicap 解決minicap問題查看移動端Android SDK版本查看minicap支持版本單次方案多次方案 最后問題-如何支持Android SDK 32 現象 原因分析與解決 由于atxserver2在與Android動終端的鏈接過程中使用了agent&#xff1a;atxserver2-and…

【前端跨域】CORS:跨域資源共享的機制與實現

在現代Web開發中&#xff0c;跨域資源共享&#xff08;Cross-Origin Resource Sharing&#xff0c;簡稱CORS&#xff09;是一種非常重要的技術&#xff0c;用于解決瀏覽器跨域請求的限制 CORS允許服務器明確指定哪些外部源可以訪問其資源&#xff0c;從而在保證安全的前提下實…

【設計模式】單例模式|餓漢模式|懶漢模式|指令重排序

目錄 1.什么是單例模式&#xff1f; 2.如何保證單例&#xff1f; 3.兩種寫法 &#xff08;1&#xff09;餓漢模式&#xff08;早創建&#xff09; &#xff08;2&#xff09;懶漢模式&#xff08;緩執行&#xff0c;可能不執行&#xff09; 4.應用場景 &#x1f525;5.多…

RocketMQ順序消費機制

RocketMQ的順序消費機制通過生產端和消費端的協同設計實現&#xff0c;其核心在于局部順序性&#xff0c;即保證同一隊列&#xff08;MessageQueue&#xff09;內的消息嚴格按發送順序消費。以下是詳細機制解析及關鍵源碼實現&#xff1a; 一、順序消費的核心機制 1. 生產端路…

【JavaEE】-- 多線程(初階)4

文章目錄 8.多線程案例8.1 單例模式8.1.1 餓漢模式8.1.2 懶漢模式 8.2 阻塞隊列8.2.1 什么是阻塞隊列8.2.2 生產者消費者模型8.2.3 標準庫中的阻塞隊列8.2.4 阻塞隊列的應用場景8.2.4.1 消息隊列 8.2.5 異步操作8.2.5 自定義實現阻塞隊列8.2.6 阻塞隊列--生產者消費者模型 8.3 …

【C++設計模式】第四篇:建造者模式(Builder)

注意&#xff1a;復現代碼時&#xff0c;確保 VS2022 使用 C17/20 標準以支持現代特性。 分步驟構造復雜對象&#xff0c;實現靈活裝配 1. 模式定義與用途 核心目標&#xff1a;將復雜對象的構建過程分離&#xff0c;使得同樣的構建步驟可以創建不同的表示形式。 常見場景&am…

vuex中的state是響應式的嗎?

在 Vue.js 中&#xff0c;Vuex 的 state 是響應式的。這意味著當你更改 state 中的數據時&#xff0c;依賴于這些數據的 Vue 組件會自動更新。這是通過 Vue 的響應式系統實現的&#xff0c;該系統使用了 ES6 的 Proxy 對象來監聽數據的變化。 當你在 Vuex 中定義了一個 state …

若依框架中的崗位與角色詳解

若依框架中的崗位與角色詳解 一、核心概念與定位 崗位&#xff08;Post&#xff09; 業務職能導向&#xff1a;崗位是用戶在組織架構中的職務標識&#xff08;如“開發人員”“項目經理”&#xff09;&#xff0c;用于描述工作職責而非直接控制權限。崗位與部門關聯&#xff…

SQL經典常用查詢語句

1. 基礎查詢語句 1.1 查詢表中所有數據 在SQL中&#xff0c;查詢表中所有數據是最基本的操作之一。通過使用SELECT * FROM table_name;語句&#xff0c;可以獲取指定表中的所有記錄和列。例如&#xff0c;假設有一個名為employees的表&#xff0c;包含員工的基本信息&#xf…