本文主要內(nèi)容
對通過相機(jī)參數(shù)計(jì)算圖像上的二維坐標(biāo)到三維坐標(biāo)的映射進(jìn)行簡單探討。
參考資料:
????????學(xué)習(xí)的話直接看他們的就好,我僅是拾人牙慧,拿GPT寫給自己看的,圖也是直接搬運(yùn)的別人畫的,以下鏈接有很完善的理論研究和代碼提供。
https://medium.com/@susanne.thierfelder/head-pose-estimation-with-mediapipe-and-opencv-in-javascript-c87980df3acbhttps://medium.com/@susanne.thierfelder/head-pose-estimation-with-mediapipe-and-opencv-in-javascript-c87980df3acbGitHub - itsvaibhav01/3D-Viewing-Angle-from-Face-Mesh: Monitor viewing angle using Mediapipe Face meshMonitor viewing angle using Mediapipe Face mesh. Contribute to itsvaibhav01/3D-Viewing-Angle-from-Face-Mesh development by creating an account on GitHub.https://github.com/itsvaibhav01/3D-Viewing-Angle-from-Face-Meshhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.py????? ????? ?? ?? ??????? ?? Mediapipe - ???????? ??? ???? ?? ????? ????? ????? ????? ?? ?????????? ? ??? ?? ?? ?? ?? ???? ???????????? ?????? ?????????? ?????? ???.https://virgool.io/@shenasa/%D8%AA%D8%AE%D9%85%DB%8C%D9%86-%D9%88%D8%B6%D8%B9%DB%8C%D8%AA-%D8%B3%D8%B1-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-mediapipe-jiwmpml2mxag
正文
概念介紹
The camera matrix
????????在計(jì)算機(jī)視覺中,相機(jī)矩陣(Camera Matrix)是一個(gè)重要的參數(shù),它描述了相機(jī)的內(nèi)部參數(shù)。相機(jī)矩陣通常用于將三維空間中的點(diǎn)投影到二維圖像平面上。它定義了圖像坐標(biāo)系和相機(jī)坐標(biāo)系之間的轉(zhuǎn)換關(guān)系。
[ fx 0 cx ]
[ 0 fy cy ]
[ 0 0 1 ]
-
fx
和fy
是焦距(focal length)在圖像坐標(biāo)系中的縮放因子。它們表示相機(jī)在X和Y軸上的焦距,通常以像素為單位。 -
cx
和cy
是主點(diǎn)(principal point)在圖像坐標(biāo)系中的坐標(biāo)。主點(diǎn)是圖像平面上的光學(xué)中心,它通常是圖像的中心點(diǎn),也以像素為單位。
????????相機(jī)矩陣的具體值與相機(jī)硬件相關(guān),并且可以通過相機(jī)校準(zhǔn)(Camera Calibration)來獲得。相機(jī)校準(zhǔn)是一個(gè)重要的過程,它通過拍攝特定的校準(zhǔn)板圖案,并結(jié)合一些幾何和優(yōu)化算法,來確定相機(jī)矩陣和畸變參數(shù),從而提供準(zhǔn)確的相機(jī)參數(shù),以便進(jìn)行準(zhǔn)確的圖像測量和姿態(tài)估計(jì)等任務(wù)。
????????在給定了相機(jī)矩陣后,可以使用它進(jìn)行圖像點(diǎn)到相機(jī)坐標(biāo)系點(diǎn)的轉(zhuǎn)換,或者相機(jī)坐標(biāo)系點(diǎn)到圖像點(diǎn)的投影。這在計(jì)算機(jī)視覺和計(jì)算機(jī)圖形學(xué)中都是常見的操作。
相機(jī)矩陣與三維坐標(biāo)
????????通過使用線性代數(shù)并將該矩陣乘以物體的三維坐標(biāo),就可以在圖像中找到它們的坐標(biāo)。
圖像來自最后一個(gè)鏈接:????? ????? ?? ?? ??????? ?? Mediapipe - ??????。
三維坐標(biāo)的空間變換:旋轉(zhuǎn)矩陣和平移矩陣
????????三維空間中的任何點(diǎn)都可以通過三分量向量移動(dòng),或者繞三個(gè)坐標(biāo)軸旋轉(zhuǎn)三個(gè)角度。為此,使用變換矩陣。將變換矩陣乘以點(diǎn)的初始坐標(biāo),即可得到變換后的坐標(biāo)。
?????????例如繞X軸平移或旋轉(zhuǎn)的變換矩陣如下:

? ? ? ? ?這兩個(gè)矩陣分別是平移矩陣(Translation Matrix)和旋轉(zhuǎn)矩陣(Rotation Matrix),它們一起描述了相機(jī)相對于某個(gè)參考坐標(biāo)系的位置和方向。
-
平移矩陣(Translation Matrix): 平移矩陣是一個(gè)3x1的矩陣,用來描述相機(jī)坐標(biāo)系的原點(diǎn)在參考坐標(biāo)系(如現(xiàn)實(shí)世界坐標(biāo)系)中的位置。平移矩陣通常用 t 或 T 表示,其中 t = [tx, ty, tz],表示相機(jī)坐標(biāo)系原點(diǎn)相對于參考坐標(biāo)系原點(diǎn)在X、Y、Z軸方向上的平移量。
-
旋轉(zhuǎn)矩陣(Rotation Matrix): 旋轉(zhuǎn)矩陣是一個(gè)3x3的正交矩陣,用來描述相機(jī)坐標(biāo)系相對于參考坐標(biāo)系的旋轉(zhuǎn)變換。旋轉(zhuǎn)矩陣通常用 R 表示,它將相機(jī)坐標(biāo)系中的向量映射到參考坐標(biāo)系中的向量。旋轉(zhuǎn)矩陣有以下幾個(gè)重要性質(zhì):
- 它的行和列是單位向量,表示相機(jī)坐標(biāo)系的三個(gè)軸在參考坐標(biāo)系中的方向。
- 它的行和列是正交的,即彼此之間互相垂直。
- 它的行和列的模長都為1,因?yàn)樗硎玖诵D(zhuǎn)變換而不改變向量的長度。
????????可以通過矩陣乘法同時(shí)執(zhí)行繞所有三個(gè)軸的平移和旋轉(zhuǎn)操作,如下所示:
?計(jì)算的實(shí)現(xiàn):opencv庫
success, rotation_vec, translation_vec = cv2.solvePnP(
face_coordination_in_real_world,
face_coordination_in_image,
cam_matrix, dist_matrix)
????????顯而易見,完成這一套計(jì)算最重要的就是得到這些參數(shù),參數(shù)的獲取方式將在下面講述。
頭部姿態(tài)估計(jì)問題
????????頭部姿態(tài)問題涉及的是對多個(gè)坐標(biāo)系之間映射的處理問題,這些坐標(biāo)系分別是:
-
現(xiàn)實(shí)世界坐標(biāo)系:由 U、V 和 W 軸構(gòu)成,代表現(xiàn)實(shí)世界中的物體坐標(biāo)。這是物體在現(xiàn)實(shí)世界的真實(shí)坐標(biāo),可以是任意單位,例如米(m)。
-
相機(jī)坐標(biāo)系:由 X、Y 和 Z 軸構(gòu)成,代表相機(jī)的坐標(biāo)系。相機(jī)坐標(biāo)系是相對于相機(jī)本身的坐標(biāo)系,其中 X 軸指向右側(cè),Y 軸指向下方,Z 軸指向相機(jī)的觀察方向。這個(gè)坐標(biāo)系通常用于描述相機(jī)內(nèi)部的幾何屬性,如焦距、畸變等。點(diǎn) P 在相機(jī)坐標(biāo)系中的坐標(biāo)可以用來描述物體相對于相機(jī)的位置。
-
二維圖像坐標(biāo)系:由 x 軸和 y 軸構(gòu)成,代表相機(jī)拍攝到的二維圖像坐標(biāo)。二維圖像坐標(biāo)是將三維空間中的點(diǎn)投影到相機(jī)成像平面上得到的,通常以像素為單位。
將圖像中的 3D 坐標(biāo)轉(zhuǎn)換為 2D 坐標(biāo)的公式:
????????我們的目標(biāo)是找到現(xiàn)實(shí)世界中頭部的角度或方向。我們知道,當(dāng)我們將頭轉(zhuǎn)向兩側(cè)時(shí),實(shí)際上相機(jī)處于固定位置和方向,頭部會改變位置;但我們可以假設(shè)頭部是固定的,變化的是相機(jī)相對于頭部的位置和方向。在這種情況下,我們的目標(biāo)變?yōu)閷ふ倚D(zhuǎn)矩陣 R。
參數(shù)獲取
????????如果我們想要估計(jì)現(xiàn)實(shí)世界中頭部的位置,可以使用一個(gè)假設(shè)的人臉模型,并將一些關(guān)鍵點(diǎn)的坐標(biāo)作為現(xiàn)實(shí)世界中的參考點(diǎn)。這些關(guān)鍵點(diǎn)的坐標(biāo)需要在所有三個(gè)坐標(biāo)軸上都有變化,以確保估計(jì)的準(zhǔn)確性。
????????實(shí)現(xiàn)方法所需要使用的點(diǎn)以及他們分別對應(yīng)的mediapipe mesh坐標(biāo),這也是2D世界坐標(biāo)。
- 鼻尖
- 右眼外角
- 左眼外角
- 眉間
- 右唇角
- 左唇角
head = [landmark[1], landmark[9], landmark[57],
landmark[130], landmark[287], landmark[359]]
相機(jī)參數(shù)矩陣和失真系數(shù)
相機(jī)參數(shù)矩陣與焦距
????????相機(jī)參數(shù)通常是與相機(jī)類型和相機(jī)規(guī)格相關(guān)的,并且可以通過相機(jī)校準(zhǔn)來獲得。但是,如果沒有提供準(zhǔn)確的相機(jī)參數(shù),我們可以利用圖像的長度和寬度作為焦距值,并將圖像中心的坐標(biāo)作為光學(xué)焦點(diǎn)的值,來進(jìn)行一個(gè)簡單的估計(jì),當(dāng)然,這是不夠嚴(yán)謹(jǐn)?shù)?,僅僅是為了表達(dá)思想。
# Approximate focal length as half of the image width or height
focal_length = (w + h) / 2
# Approximate optical center as the center of the image
optical_center = (w / 2, h / 2)
# Construct an approximate camera matrix
cam_matrix = np.array([[focal_length, 0, optical_center[0]],
[0, focal_length, optical_center[1]],
[0, 0, 1]])
focal_length = 1 * w
cam_matrix = np.array([[focal_length, 0, w / 2],
[0, focal_length, h / 2],
[0, 0, 1]])
????????以上提供了兩種估計(jì)方法,在第一種估計(jì)中,假設(shè)相機(jī)的焦距在水平和垂直方向上相等,可以使用圖像的寬度(w)和高度(h)的一半來估計(jì)焦距(focal_length)。這個(gè)假設(shè)的焦距值可以用于構(gòu)造一個(gè)近似的相機(jī)矩陣(Camera Matrix),第二種則使用圖像寬度的一倍作為焦距。
焦距估計(jì)的方法評價(jià):
-
使用圖像寬度的一倍作為焦距(
focal_length = 1 * w
):- 優(yōu)點(diǎn):這種方法簡單快速,不需要額外的相機(jī)校準(zhǔn)步驟,適用于快速原型或簡單的應(yīng)用場景。
- 缺點(diǎn):這種方法忽略了相機(jī)的真實(shí)參數(shù)和畸變,是一個(gè)近似值,可能導(dǎo)致估計(jì)的精度較低,尤其在復(fù)雜場景中。
-
使用相機(jī)校準(zhǔn)得到的準(zhǔn)確焦距值:
- 優(yōu)點(diǎn):通過相機(jī)校準(zhǔn)可以得到相機(jī)的準(zhǔn)確內(nèi)部參數(shù)和外部參數(shù),提供了更精確的相機(jī)矩陣,估計(jì)結(jié)果更可靠和精確。
- 缺點(diǎn):相機(jī)校準(zhǔn)過程可能相對復(fù)雜,需要拍攝特定的校準(zhǔn)板圖案,對于某些應(yīng)用可能增加了額外的工作和成本。
????????如果需要高精度的位姿估計(jì),尤其在復(fù)雜場景或精密測量中,建議使用第二種方法,即使用相機(jī)校準(zhǔn)得到的準(zhǔn)確焦距值和相機(jī)參數(shù)。相機(jī)校準(zhǔn)可以提供更準(zhǔn)確的相機(jī)內(nèi)部參數(shù)和外部參數(shù),對于頭部姿態(tài)估計(jì)等任務(wù)會有更可靠的結(jié)果。
????????但如果只是進(jìn)行簡單的頭部姿態(tài)估計(jì)、目標(biāo)跟蹤等應(yīng)用,并且對于精度要求不是非常高,第一種方法即使用圖像寬度的一倍作為焦距值可能足夠滿足需求,而且更加簡便快捷。
失真系數(shù)(畸變系數(shù))矩陣的估計(jì)
dist_matrix = np.zeros((4, 1), dtype=np.float64)
????????畸變系數(shù)矩陣是一個(gè)4x1的矩陣,它包含相機(jī)的徑向和切向畸變系數(shù)。在這里,畸變系數(shù)矩陣被初始化為零,表示沒有考慮畸變。如果相機(jī)存在畸變,可以通過相機(jī)校準(zhǔn)等方法來估計(jì)得到畸變系數(shù)。?
????????這里矩陣的規(guī)格是根據(jù)之前的計(jì)算公式來確立的,也是追求了理想情況做了簡化。
圖像中的二維坐標(biāo)矩陣
????????為了給這個(gè)矩陣賦值,需要找到圖像中的坐標(biāo),比如現(xiàn)實(shí)世界中的指定點(diǎn)。為此,我們可以使用mediapipe進(jìn)行實(shí)現(xiàn)。
????????通過指定上述所有矩陣的值,可以使用Lunberg-Marquardt優(yōu)化找到R和t的最佳值。
真實(shí)世界坐標(biāo)的設(shè)置
face_coordination_in_real_world = np.array([
[285, 528, 200],
[285, 371, 152],
[197, 574, 128],
[173, 425, 108],
[360, 574, 128],
[391, 425, 108]
], dtype=np.float64)
????????在 Mediapipe
庫中,它返回的關(guān)鍵點(diǎn)坐標(biāo)是相對于圖像尺寸的歸一化坐標(biāo)(介于 0 和 1 之間),為了將這些歸一化坐標(biāo)轉(zhuǎn)換為像素坐標(biāo),需要將它們乘以圖像的長度和寬度。
def detect_face_landmarks(image):
fps_time = time.time()
results = face_mesh.process(image)
now = time.time()
process_time = (now - fps_time)
print('mesh_time:', process_time)
face_landmarks = []
if results.multi_face_landmarks:
for face in results.multi_face_landmarks:
landmarks = []
for landmark in face.landmark:
x = int(landmark.x * image.shape[1])
y = int(landmark.y * image.shape[0])
landmarks.append((x, y))
face_landmarks.append(landmarks)
return face_landmarks
而我們只做頭部姿態(tài)則只需要這些點(diǎn):這些也是面部圖像中所需點(diǎn)的二維坐標(biāo)。
head = [landmark[1], landmark[9], landmark[57],
landmark[130], landmark[287], landmark[359]]
通過cv2計(jì)算旋轉(zhuǎn)矩陣和平移矩陣
通過以上數(shù)據(jù)可以計(jì)算旋轉(zhuǎn)矩陣和平移矩陣。
for (landmark_x, landmark_y) in head:
x, y = (x1 + landmark_x, y1 + landmark_y)
face_coordination_in_image.append([x, y])
face_coordination_in_image = np.array(face_coordination_in_image,
dtype=np.float64)
success, rotation_vec, transition_vec = cv2.solvePnP(
face_coordination_in_real_world, face_coordination_in_image,
cam_matrix, dist_matrix)
cv2.solvePnP
是 OpenCV 庫中的一個(gè)函數(shù),用于解決透視投影問題。該函數(shù)可以用于估計(jì)相機(jī)的旋轉(zhuǎn)向量和平移向量,從而得到相機(jī)在現(xiàn)實(shí)世界中的位姿信息。文章來源:http://www.zghlxwxcb.cn/news/detail-766061.html
retval, rotation_vec, translation_vec = cv2.solvePnP(object_points, image_points, camera_matrix, dist_coeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]])文章來源地址http://www.zghlxwxcb.cn/news/detail-766061.html
-
object_points
: 真實(shí)世界中待估計(jì)物體的三維坐標(biāo)矩陣,是一個(gè) Nx3 的 NumPy 數(shù)組,其中 N 是點(diǎn)的數(shù)量,每一行包含一個(gè)點(diǎn)的 X、Y、Z 坐標(biāo)。 -
image_points
: 相機(jī)圖像中檢測到的物體特征點(diǎn)的二維像素坐標(biāo)矩陣,是一個(gè) Nx2 的 NumPy 數(shù)組,其中 N 是點(diǎn)的數(shù)量,每一行包含一個(gè)點(diǎn)的像素坐標(biāo) (x, y)。 -
camera_matrix
: 相機(jī)矩陣,它是一個(gè)3x3的矩陣,包含了相機(jī)的內(nèi)部參數(shù),如焦距和光學(xué)中心。 -
dist_coeffs
: 畸變系數(shù)矩陣,它是一個(gè)4x1的矩陣,包含了相機(jī)的徑向和切向畸變系數(shù)。 -
rvec
: 輸出的旋轉(zhuǎn)向量,是一個(gè)3x1的矩陣,表示相機(jī)坐標(biāo)系相對于現(xiàn)實(shí)世界坐標(biāo)系的旋轉(zhuǎn)。 -
tvec
: 輸出的平移向量,是一個(gè)3x1的矩陣,表示相機(jī)坐標(biāo)系原點(diǎn)相對于現(xiàn)實(shí)世界坐標(biāo)系原點(diǎn)的平移。 -
useExtrinsicGuess
: 布爾值,表示是否使用輸入的rvec
和tvec
作為初始估計(jì)值,默認(rèn)為 False。 -
flags
: 用于指定求解 PnP 問題的標(biāo)志,可以是cv2.SOLVEPNP_ITERATIVE
、cv2.SOLVEPNP_EPNP
、cv2.SOLVEPNP_P3P
、cv2.SOLVEPNP_DLS
或cv2.SOLVEPNP_UPNP
,具體選擇哪個(gè)取決于問題的類型和需求。
到了這里,關(guān)于2D人臉關(guān)鍵點(diǎn)轉(zhuǎn)3D人臉關(guān)鍵點(diǎn)的映射~頭部姿態(tài)筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!