日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【机器视觉案例】(13) 脸部和摄像机间的距离测量,自适应文本大小,附python完整代码

發布時間:2023/11/27 生活经验 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器视觉案例】(13) 脸部和摄像机间的距离测量,自适应文本大小,附python完整代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

各位同學好,今天和大家分享一下如何使用 opencv+Mediapipe 測量人臉和攝像機鏡頭之間的距離,并創建一塊根據人臉距離變化的文本框。先放張圖看效果。

左圖是視頻圖像,顯示人臉和攝像機之間的距離distance;右圖是文本框,人臉和相機之間距離越近,則字體和行距越小,距離越遠,字體和行距越大。


1. 安裝工具包

pip install opencv_python==4.2.0.34  # 安裝opencv
pip install mediapipe  # 安裝mediapipe
# pip install mediapipe --user  #有user報錯的話試試這個
pip install cvzone  # 安裝cvzone# 導入工具包
import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector  # 臉部關鍵點檢測方法
import numpy as np  # 用來創建文本框

2. 臉部關鍵點檢測

(1)cvzone.FaceMeshModule.FaceMeshDetector() ?人臉關鍵點檢測方法

參數:

staticMode: 默認為 False,將輸入圖像視為視頻流。它將嘗試在第一個輸入圖像中檢測人臉,并在成功檢測后進一步定位468個關鍵點的坐標。在隨后的圖像中,一旦檢測到所有 maxFaces 張臉并定位了相應的關鍵點的坐標,它就會跟蹤這些坐標,而不會調用另一個檢測,直到它失去對任何一張臉的跟蹤。這減少了延遲,非常適合處理視頻幀。如果設置為 True,則在每個輸入圖像上運行臉部檢測,用于處理一批靜態的、可能不相關的圖像

maxFaces: 最多檢測幾張臉,默認為 2

minDetectionCon=0.5: 臉部關鍵點檢測模型的最小置信值(0-1之間),超過閾值則檢測成功。默認為 0.5

minTrackCon=0.5: 關鍵點坐標跟蹤模型的最小置信值 (0-1之間),用于將手部坐標視為成功跟蹤,不成功則在下一個輸入圖像上自動調用手部檢測。將其設置為更高的值可以提高解決方案的穩健性,但代價是更高的延遲。如果 mode 為 True,則忽略這個參數,手部檢測將在每個圖像上運行。默認為 0.5

(2)cvzone.FaceMeshModule.FaceMeshDetector.findFaceMesh() ?找到人臉關鍵點

參數:

img: 需要檢測關鍵點的幀圖像,格式為BGR

draw: 是否需要在原圖像上繪制關鍵點及連線

返回值:

img: 返回繪制了關鍵點及連線后的圖像

faces: 檢測到的臉部信息,三維列表,包含每張臉的468個關鍵點。

(3)距離測量方法

由下圖距離測量公式可知,現在要求實際距離 d,可通過相似三角形,利用人臉兩眼之間的距離來推算人臉距離攝像機的實際距離

人兩眼之間的實際距離為W=63mm,相機視角下圖像上人眼的兩個關鍵點之間的距離w

在求實時距離 d 之前我們需要知道相機焦距 f,又因為相機焦距 f 是固定不變的,那么我們先以固定的人臉和相機距離計算出 f ,取各個幀 f 的平均值,得到相機焦距

焦距計算公式,這里的d是一個固定值

實際距離計算公式使用估算出的焦距的平均值用來計算實時的距離

代碼如下:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector  # 臉部關鍵點檢測方法#(1)讀取視頻圖像
filepath = 'D:/deeplearning/video/eyes.mp4'  # 視頻文件位置
cap = cv2.VideoCapture(filepath)  # 參數填0代表電腦自帶攝像頭#(2)臉部關鍵點檢測方法
detector = FaceMeshDetector(maxFaces=1)  # 最多檢測一張臉#(3)處理視頻圖像
while True:# 圖像是否讀取成功success,讀入的幀圖像imgsuccess, img = cap.read()  # 每次讀取一幀# 檢測臉部關鍵點,返回繪制關鍵點后的圖像img和臉部關鍵點坐標facesimg, faces = detector.findFaceMesh(img, draw=False)  # 不繪制關鍵點print(faces)#(4)處理關鍵點if faces:  # 如果檢測到了,那就接下去執行face = faces[0]  # faces是三維列表,我們只需要第一張臉的所有關鍵點pointLeft = tuple(face[145])  # 左眼關鍵點坐標pointRight = tuple(face[374]) # 右眼坐標# 繪制兩個關鍵點之間的連線cv2.line(img, pointLeft, pointRight, (0,255,0), 3)# 在關鍵點坐標上繪制圓。注意圓心坐標是元組類型tuplecv2.circle(img, pointLeft, 5, (0,255,255), cv2.FILLED)cv2.circle(img, pointRight, 5, (0,255,255), cv2.FILLED)# 計算兩點之間的線段距離w,相當于勾股定理求距離w, _ = detector.findDistance(pointRight, pointLeft)  # 返回線段距離和線段信息(兩端點和中點的坐標)#print(w)# 計算焦距W = 6.3  # 人臉兩眼之間的平均距離是6.3cmd = 40  # 當前人臉距屏幕的距離f = (w*d)/W  # 根據公式計算焦距print(f'foucus:{f}')  # 打印所有焦距,取平均值,作為模型的焦距#(5)圖像展示cv2.imshow('img', img)k = cv2.waitKey(10)  # 每幀延遲1毫秒后消失if k & 0xFF == 27:  # 鍵盤上的ESC鍵退出循環break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()

效果圖如下:左圖是detector.findFaceMesh(img, draw=True)時檢測出的人臉關鍵點和連線,我們只需要用到兩眼之間的距離。如右圖,設置參數draw=True,不繪制人臉網,只繪制兩眼之間的連線。


3. 距離測量,制作自適應文本框

在上一節中我們以實際距離d=40cm,計算出了每一幀圖像的相機焦距,取其平均值 f=700 作為相機焦距計算實時的人臉距離?。使用 cvzone.putTextRect() 函數將距離值顯示在人臉額頭部位。

接下來創建一個和幀圖像相同size的,像素值全為0(黑色)的圖像 np.zeros_like(img),作為顯示文本的底板。

如下面代碼中的第(4)步,singleHeight = 50 + int(d/2) 每行文本初始距離為50,根據人臉距離實時變化。scale = 1 + int(d/20)? 文本字體的大小初始是1,根據人臉距離動態調整

在上述代碼中補充:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector  # 臉部關鍵點檢測方法
import numpy as np  # 用來創建文本框#(1)讀取視頻圖像
filepath = 'D:/deeplearning/video/eyes.mp4'  # 視頻文件位置
cap = cv2.VideoCapture(filepath)  # 參數填0代表電腦自帶攝像頭#(2)配置
# 臉部檢測方法
detector = FaceMeshDetector(maxFaces=1)  # 最多檢測一張臉
# 文本框中的內容
textList = ['anukbcxasxxa4525', 'xnsailcnau22222', 'xbuikuysalbxsalb','cinaxsabkcnaskmc','4861581816158151']#(3)處理視頻圖像
while True:# 圖像是否讀取成功success,讀入的幀圖像imgsuccess, img = cap.read()  # 每次讀取一幀# 創建文本圖像,一張黑板imgText = np.zeros_like(img)  # 創建一個size和img相同的黑色圖像# 檢測臉部關鍵點,返回繪制關鍵點后的圖像img和臉部關鍵點坐標facesimg, faces = detector.findFaceMesh(img, draw=False)  # 不繪制關鍵點#(4)處理關鍵點if faces:  # 如果檢測到了,那就接下去執行face = faces[0]  # faces是三維列表,我們只需要第一張臉的所有關鍵點pointLeft = tuple(face[145])  # 左眼關鍵點坐標pointRight = tuple(face[374]) # 右眼坐標# 計算兩點之間的線段距離w,相當于勾股定理求距離w, _ = detector.findDistance(pointRight, pointLeft)  # 返回線段距離和線段信息(兩端點和中點的坐標)W = 6.3  # 人臉兩眼之間的實際平均距離是6.3cmf = 700  # 上一節的代碼求焦距,估計一個平均值,作為當前的焦距# 計算人臉距離屏幕的距離d = (W*f)/wprint('distance face to screen:', d)# 將距離顯示在屏幕上,face[10]代表額頭的坐標點,scale矩形框大小,thickness文字大小cvzone.putTextRect(img, f'distace:{int(d)}cm', (face[10][0]-100,face[10][1]),scale=2, thickness=3, colorR=(255,255,0), colorT=(0,0,0))#(4)編寫文本for i, text in enumerate(textList):singleHeight = 50 + int(d/2)  # 動態調整文本每行之間的距離scale = 1 + int(d/20)  # 根據臉和攝像機之間的距離調整字體大小# 控制每條文本之間的行間距i*singleHeight,scale動態改變字體大小cv2.putText(imgText, text, (50,100+i*singleHeight), cv2.FONT_ITALIC, scale, (255,255,255), 2)#(5)圖像展示img = cv2.resize(img, (800,450))imgText = cv2.resize(imgText, (800,450))# 將兩張圖像組合在一起,排2列,組合后size不變imgStacked = cvzone.stackImages([img, imgText], cols=2, scale=1)cv2.imshow('imgStacked', imgStacked)k = cv2.waitKey(20)  # 每幀延遲1毫秒后消失if k & 0xFF == 27:  # 鍵盤上的ESC鍵退出循環break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()

效果圖如下,人臉距離攝像機越近,則文本越小;人臉距離攝像機越遠,則字體越大。

總結

以上是生活随笔為你收集整理的【机器视觉案例】(13) 脸部和摄像机间的距离测量,自适应文本大小,附python完整代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。