《三維點如何映射到圖像像素?——相機投影模型詳解》

?引言

以三維投影介紹大多比較分散,不少小伙伴再面對諸多的坐標系轉換中容易弄混,特別是再寫代碼的時候可能搞錯,所有這篇文章幫大家完整的梳理3D視覺中的投影變換的全流程,一文弄清楚這個過程,幫助大家搞清坐標系轉換。

想象你正站在一個空房間里,腳下是地板,面前是墻。

  1. ?在紙上畫一個直角坐標系,標記原點為墻角(左下角),X向右,Y向前,Z向上。
  2. 相機位于[2, 4, 1.5]位置。
  3. ?在[4, 2, 1.5]處點一個點——這是我們要投影到相機圖像的三維點。

接下來,我會帶你一步步推導:?這個點如何變成相機照片中的一個像素

第一章:從3D到2D的四大步驟

在計算機視覺和三維重建領域,將三維空間中的點映射到二維圖像平面是相機成像過程的核心。這個過程可以抽象為一個投影模型(Projection Model),它描述了如何將真實世界中的點通過一系列變換最終落在圖像傳感器上,成為我們看到的像素點。

整個過程可以分為四個關鍵步驟:


步驟一:世界坐標系 → 相機坐標系(剛體變換)

三維空間中的點通常以**世界坐標系(World Coordinate System)表示,記為P_w = (X_w, Y_w, Z_w)^T,為了模擬相機的視角,我們需要將其轉換到相機坐標系(Camera Coordinate System)中。這一步是通過剛體變換(Rigid Transformation)**完成的,包括旋轉和平移操作:

投影公式如下:

\mathbf{P}_c = \mathbf{R} \cdot \mathbf{P}_w + \mathbf{t}

中:

  • R?是旋轉矩陣(3x3);
  • t?是平移向量(3x1);
  • P_c?是點在相機坐標系下的表示。

也可以用齊次坐標寫成一個變換矩陣:

\begin{bmatrix} \mathbf{P}_c \\ 1 \end{bmatrix} = \begin{bmatrix} \mathbf{R} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{bmatrix} \cdot \begin{bmatrix} \mathbf{P}_w \\ 1 \end{bmatrix}


步驟二:相機坐標系 → 歸一化圖像坐標系(透視投影)

接下來,我們將三維相機坐標系中的點通過透視投影(Perspective Projection)映射到二維的歸一化圖像坐標系中。這一步模擬了光線穿過針孔相機的過程。

設相機焦距為 f,則投影公式如下:

\begin{bmatrix} x \\ y \end{bmatrix} = \frac{f}{Z_c} \cdot \begin{bmatrix} X_c \\ Y_c \end{bmatrix}

這里的 (x, y) 表示歸一化圖像平面上的坐標,與實際像素無關。


步驟三:歸一化圖像坐標 → 像素坐標(內參變換)

為了得到最終的像素坐標,還需要考慮相機的內部參數,例如像素尺寸、主點偏移等。這些信息被包含在一個稱為相機內參矩陣(Intrinsic Matrix)的矩陣中:

\mathbf{K} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

其中:

  • f_x,?f_y?是以像素為單位的焦距;
  • (c_x, c_y)?是圖像主點(principal point),通常是圖像中心。

于是,歸一化坐標 (x, y) 到像素坐標 (u, v) 的變換為:

\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \mathbf{K} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}

步驟四:像素坐標 → 圖像坐標系(圖像裁剪與翻轉)

最后一步是將像素坐標 (u, v) 映射到圖像的實際坐標系統中。通常圖像坐標原點位于左上角,而之前計算的 (u, v) 是浮點數,需要進行取整或插值處理。

此外,還要注意圖像可能會有縮放、裁剪、翻轉等后處理操作,這會影響最終的像素位置。

第二章:從世界坐標系到相機坐標系的剛體變換詳解

——坐標系定義、旋轉矩陣與平移矩陣的構建全過程


一、相機坐標系(CCS)的定義與物理意義

在計算機視覺中,相機坐標系(Camera Coordinate System, CCS) 是以相機為中心建立的右手坐標系。其定義如下:

  • 原點(O?):位于相機光心(光學中心);
  • Z軸(Z?):指向相機拍攝方向(即光軸方向);
  • X軸(X?):指向圖像右側;
  • Y軸(Y?):指向圖像下方,滿足右手系規則:X? × Y? = Z?。

二、世界坐標系(WCS)與相機坐標系的關系

我們考慮一個具體例子:

  • 世界坐標系(WCS)
    • 原點位于房間角落;
    • X軸向右;
    • Y軸向前;
    • Z軸向上。
  • 相機位置
    • 在 WCS 中的位置為:t =[2, 4, 1.5]?;
    • 表示相機在房間中位于 x=2, y=4, z=1.5 的位置(單位:米);
  • 相機朝向
    • 光軸(Z?)指向 WCS 的??Y 方向
    • 即相機背對世界前方(Y軸正方向),面朝后方。

這個設定常見于室內監控場景中,例如相機安裝在房間中央,面朝墻壁。


三、剛體變換公式

將一個三維點 P_w 從世界坐標系轉換到相機坐標系的過程如下:

四、分步構建變換過程

步驟 1:平移變換(Translation)

目標:將世界坐標點“移動”到以相機為原點的相對位置。

公式:

\mathbf{P}_{rel} = \mathbf{P}_w - \mathbf{t}

示例:

P_w = np.array([4, 2, 1.5]) # 修改后的世界點位置

t = np.array([2, 4, 1.5])

則:

?\mathbf{P}_{rel} = \begin{bmatrix}4 - 2 \\ 2- 4 \\ 1.5 - 1.5 \end{bmatrix} = \begin{bmatrix} 2 \\ -2 \\ 0 \end{bmatrix}

物理意義:該點相對于相機的位置是向右 2 米、向前 -2 米、下方 0 米(相機沒有旋轉前)。


步驟 2:旋轉變換(Rotation)

目標:將相對向量 PrelPrel? 轉換到相機坐標系的方向中去。

(1)確定相機坐標系的三個單位向量

根據設定,相機光軸指向 WCS 的 ?Y 方向:

  • Z?(光軸方向):[0, ?1, 0]
  • X?(右側方向):選擇與 Z? 垂直的世界 X 軸方向:[1, 0, 0]
  • Y?(下方方向):由叉積得到:Y? = Z? × X? = [0, 0, ?1]

這三個向量構成了相機坐標系的基底。

(2)構造旋轉矩陣 R

將上述三個單位向量作為列向量,組成旋轉矩陣:

?\mathbf{R} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & -1 & 0 \end{bmatrix}

解釋每一列含義:

  • 第1列:世界 X 軸在 CCS 中的方向;
  • 第2列:世界 Y 軸在 CCS 中的方向;
  • 第3列:世界 Z 軸在 CCS 中的方向。

五、完整變換計算

繼續使用上面的例子:

import numpy as npP_w = np.array([2, 3, 0.5])
t = np.array([1, 2, 1.5])R = np.array([[1, 0, 0],[0, 0, -1],[0, -1, 0]
])P_rel = P_w - t
P_c = R @ P_rel

結果:

\mathbf{P}_c = \begin{bmatrix} 2 \\ 0 \\ 2 \end{bmatrix}

解釋:

  • Xc = 2:點在相機右側 2 米;
  • Yc = 0:點在相機下方 0 米(Y軸向下);
  • Zc = 2:點在相機前方2米。


六、為什么是 ?Y 方向而不是 +Y?

這是由以下兩個因素決定的:

1. 相機坐標系的定義要求

為了保持右手系結構(X? × Y? = Z?),如果 X? 對齊世界 X 軸、Y? 對齊世界 Z 軸,則 Z? 必須指向世界 ?Y。

2. 圖像坐標系的一致性

在圖像坐標系中,通常定義:

  • u 軸(列)向右;
  • v 軸(行)向下;

這與相機坐標系中 Y? 向下一致,因此相機朝向 ?Y 可以自然地映射到圖像平面。

第三章:旋轉矩陣 R 的數學構建與相機坐標系的構建原理詳解

在第二章中,我們已經介紹了如何從世界坐標系(WCS)到相機坐標系(CCS)進行剛體變換,并通過一個具體示例演示了平移和旋轉的具體計算過程。本章將深入講解旋轉矩陣 R 的數學構造方法、其物理意義以及相機坐標系構建背后的幾何邏輯


一、旋轉矩陣 R 的數學定義與性質

1.1 基本定義

旋轉矩陣是一個 3×3 的正交矩陣,滿足以下兩個重要性質:

  • 正交性

?\mathbf{R}^T \mathbf{R} = \mathbf{I}

  • 行列式為 1:

\det(\mathbf{R}) = 1

這兩個條件保證了旋轉操作只改變方向而不改變長度或形狀。


1.2 旋轉矩陣的列向量解釋

設世界坐標系中的三個標準基向量為:

\mathbf{e}_x = [1,0,0]^T,\quad \mathbf{e}_y = [0,1,0]^T,\quad \mathbf{e}_z = [0,0,1]^T

而相機坐標系的三個單位基向量為:

\mathbf{x}_c,\quad \mathbf{y}_c,\quad \mathbf{z}_c

?則旋轉矩陣 R 可以表示為:

\mathbf{R} = \begin{bmatrix} | & | & | \\ \mathbf{x}_c & \mathbf{y}_c & \mathbf{z}_c \\ | & | & | \end{bmatrix}\mathbf{z}_c = [0, 0, 1]^T

換句話說,旋轉矩陣的每一列是相機坐標系在世界坐標系下的方向向量。

? 通俗理解:旋轉矩陣 R 描述了“世界坐標軸在相機坐標系中的方向”。

1.3 構造 R 的通用步驟

步驟 1:確定相機光軸方向(Z?)

這是最重要的一步,決定了相機的拍攝方向。例如:

  • 若希望相機朝向世界 ?Y 方向,則:

\mathbf{z}_c = [0, -1, 0]^T

  • 若希望相機朝向世界 +Z 方向,則:

\mathbf{z}_c = [0, 0, 1]^T

步驟 2:選擇 X? 向量(與 Z? 垂直)

通常優先對齊世界坐標系中的某個軸(如 X 軸),但必須確保與 Z? 垂直:

  • 設定:

\mathbf{x}_c = [1, 0, 0]^T \quad (\text{if } \mathbf{z}_c \text{ not parallel to } X \text{ axis})

  • 或者使用 Gram-Schmidt 正交化法調整方向。
步驟 3:由叉積得到 Y? 向量

根據右手系規則

\mathbf{y}_c = \mathbf{z}_c \times \mathbf{x}_c

這確保了整個坐標系保持右手結構。

步驟 4:歸一化所有向量

確保每個向量都是單位向量:

\mathbf{x}_c \leftarrow \frac{\mathbf{x}_c}{\|\mathbf{x}_c\|},\quad \text{deal with in the same way } \mathbf{y}_c, \mathbf{z}_c

步驟 5:構造旋轉矩陣 R

將三個單位向量作為列向量排列成矩陣:

\mathbf{R} = \begin{bmatrix} x_{cx} & y_{cx} & z_{cx} \\ x_{cy} & y_{cy} & z_{cy} \\ x_{cz} & y_{cz} & z_{cz} \end{bmatrix}

二、相機坐標系為什么這么構建?

相機坐標系的設計并不是隨意的,而是為了滿足以下幾個關鍵目標:

2.1 圖像坐標的自然映射

圖像坐標系通常定義如下:

  • u 軸(列方向)→ 相機右側;
  • v 軸(行方向)→ 相機下方;
  • 原點位于圖像左上角。

因此,相機坐標系的 X? 向右、Y? 向下可以自然地映射到圖像坐標。

2.2 保持右手系結構

三維空間建模和渲染中廣泛使用右手系,這樣便于統一處理旋轉、投影等操作。如果 Y? 指向上方,則會導致圖像坐標的行方向與 Y? 方向相反,增加轉換復雜度。

2.3 簡化后續投影模型

相機坐標系的 Z? 軸指向拍攝方向,使得后續的透視投影公式簡潔且直觀:

x = f \cdot \frac{X_c}{Z_c}, \quad y = f \cdot \frac{Y_c}{Z_c}

其中 f?是焦距。


三、構建相機坐標系的完整數學流程示例

假設:

  • 相機位置:t=[1,2,1.5]T,表示相機在世界坐標系中的位置為 x=1, y=2, z=1.5。
  • 相機光軸指向:世界 ?Y 方向(即面朝房間后方)。

步驟 1:確定 Z?

Z? 是相機坐標系的 Z 軸方向,表示相機的拍攝方向。在這個例子中

? 相機朝向世界 ?Y 方向,因此:

?\mathbf{z}_c = [0, -1, 0]^T

這是單位向量,無需歸一化。

📌 注意:Z? 并不是相機的位置向量,而是指向相機“看的方向”。在這里,“看向 ?Y”意味著相機背對世界 +Y 軸。

步驟 2:確定 X?

X? 應該與 Z? 垂直,并且盡可能與世界坐標系的某個軸對齊(通常選 X 或 Y),以便簡化后續計算和理解。

在這個例子中,我們可以選擇:

\mathbf{x}_c = [1, 0, 0]^T

因為:

  • 它是單位向量;
  • 與 Z? 垂直(點積為零):

步驟 3:由叉積得 Y?

\mathbf{y}_c = \mathbf{z}_c \times \mathbf{x}_c = \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 0 & -1 & 0 \\ 1 & 0 & 0 \end{vmatrix} = (0 \cdot 0 - 0 \cdot 0)\mathbf{i} - (0 \cdot 0 - 0 \cdot 1)\mathbf{j} + (0 \cdot 0 - (-1) \cdot 1)\mathbf{k} = [0, 0, 1]^T

步驟 4:歸一化各向量(此處已是單位向量)

步驟 5:構造旋轉矩陣 R

\mathbf{R} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & 1 & 0 \end{bmatrix}

第四章:相機坐標系 → 歸一化圖像坐標系(透視投影)

在第三章中,我們完成了從世界坐標系到相機坐標系的變換,即通過旋轉和平移將一個點 PwPw? 轉換為相機坐標 Pc=[Xc,Yc,Zc]TPc?=[Xc?,Yc?,Zc?]T。

本章將繼續這一流程,介紹如何將三維空間中的點 投影到二維歸一化圖像平面,完成:

相機坐標系(CCS)歸一化圖像坐標系(Normalized Image Coordinates) 的變換。


一、什么是歸一化圖像坐標?

歸一化圖像坐標是針孔相機模型下的中間圖像坐標系統。它是一個無單位的二維坐標系,原點位于圖像中心,Z 軸與相機光軸重合。

它的定義如下:

設相機焦距為 f,則對于相機坐標系下的點 Pc=[Xc,Yc,Zc]T,其對應的歸一化圖像坐標 (x,y)為:

x = f * \frac{X_c}{Z_c}

y = f * \frac{Y_c}{Z_c}

這個過程稱為透視投影(Perspective Projection),它模擬了真實相機成像的基本原理 —— 遠小近大。

? 注意:這里的 (x,y)是歸一化的坐標,還沒有考慮圖像分辨率、主點偏移等參數。這是后續章節會討論的內容。


二、沿用之前的示例進行推導

示例設定:

  • 相機位置:\mathbf{t} = [2, 4, 1.5]^T
  • 旋轉矩陣:\mathbf{R} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & -1 & 0 \end{bmatrix}
  • 焦距: f=1

該旋轉矩陣表示相機的光軸指向世界 ?Z 方向(向下看),Y? 向下,X? 向右。


舉例說明:選取幾個3D點進行投影

我們在相機坐標系中選取了五個點,它們分別是:

點編號X_cY_cZ_c
P00.50.51.5
P1-0.50.32
P20.2-0.43
P3005
P40.80.80.8

這些點都位于相機前方(Z? > 0),因此可以被正確投影到圖像平面上。


投影計算示例(以 P0 為例)

對于點 P0:

Xc=0.5,Yc=0.5,Zc=1.5

代入公式得:

x = \frac{0.5}{1.5} = 0.333??y = \frac{0.5}{1.5} = 0.333

所以歸一化圖像坐標為:?(x, y) = (0.333, 0.333)

類似地,我們可以計算其他點的歸一化圖像坐標。


投影結果匯總(部分)

點編號X_cY_cZ_cxy
P00.50.51.50.3330.333
P1-0.50.32-0.250.15
P20.2-0.430.067-0.133
P300500
P40.80.80.81.01.0

可以看到,隨著 Z 值變小(靠近相機),投影點變得更大;而遠離相機的點(如 P3)則更接近圖像中心。

三、物理意義解釋

參數數值范圍物理意義
Z_c > 0所有點都在相機前方可以被正常投影到圖像上
Z_c < 0未出現在示例中表示點在相機背后,不會出現在圖像中
Z_c = 0未出現表示點在相機正前方無窮遠處,無法投影
x/y 接近 0如 P3表示點位于圖像中心附近
x/y 絕對值較大如 P4表示點靠近圖像邊緣或超出視野

四、注意事項

  • 當?Zc=0時,表示點在相機正前方無窮遠處,無法投影;
  • 當?Zc<0時,點在相機背后,不會出現在圖像中;
  • 實際圖像坐標還需結合內參矩陣(焦距、主點、畸變)進一步映射;
  • 本章只討論理想情況下的歸一化圖像坐標。

第五章:歸一化圖像坐標 → 像素坐標(內參變換)

在第四章中,我們完成了從相機坐標系歸一化圖像坐標系的投影過程,得到了一個無單位的二維坐標 (x,y)。

本章將介紹如何將這個歸一化圖像坐標進一步轉換為像素坐標 (u,v),這一步是通過引入**相機內參矩陣(Intrinsic Camera Matrix)**來實現的。


一、什么是相機內參矩陣?

相機內參矩陣 KK 是一個 3×3的上三角矩陣,它包含了以下物理參數:

參數物理意義
fx,fy焦距(以像素為單位),通常?fx=fy=f,但在非正方形像素時可以不同
cx,cy主點(Principal Point),即圖像中心在像素坐標中的位置(通常為圖像分辨率的一半)
s圖像的斜切因子(Skew Factor),表示像素是否正交排列,默認為 0

?完整的相機內參矩陣形式如下:

\mathbf{K} = \begin{bmatrix} f_x & s & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

實際使用中,大多數情況下 s=0s=0,所以常簡化為:

\mathbf{K} = \begin{bmatrix} f & 0 & c_x \\ 0 & f & c_y \\ 0 & 0 & 1 \end{bmatrix}

二、歸一化圖像坐標 → 像素坐標的公式

設歸一化圖像坐標為 (x,y),則對應的像素坐標 (u,v)可由下式計算:

\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \mathbf{K} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}

展開后得到:

u = f_x \cdot x + c_x    v = f_y \cdot y + c_y

這個過程稱為 “內參變換”,它不依賴于相機的位置或朝向,只與相機本身的成像特性有關。


三、延續最開始的例子進行推導

示例設定:

  • 相機位置:\mathbf{t} = [2, 4, 1.5]^T
  • 點的世界坐標:\mathbf{P}_w = [4, 2, 1.5]^T
  • 旋轉矩陣(沿用之前例子):\mathbf{R} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & -1 & 0 \end{bmatrix}

步驟 1:計算相機坐標

先求相對坐標:

\mathbf{P}_{rel} = \mathbf{P}_w - \mathbf{t} = [2, -2, 0]^T

再應用旋轉:

\mathbf{P}_c = \mathbf{R} \cdot \mathbf{P}_{rel} = [2, 0, 2]^T

所以:

X_c = 2,\quad Y_c = 0,\quad Z_c = 2

步驟 2:透視投影(歸一化圖像坐標)

焦距設為 f=200

x = f \cdot \frac{X_c}{Z_c} = 200 \cdot \frac{2}{2} = 200

y = f \cdot \frac{Y_c}{Z_c} = 200 \cdot \frac{0}{2} = 0

所以歸一化圖像坐標為:

(x, y) = (200, 0)

步驟 3:假設一個內參矩陣

設相機分辨率為 640×480,則主點為:

c_x = 320,\quad c_y = 240

構建內參矩陣:

\mathbf{K} = \begin{bmatrix} f_x & s & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

\mathbf{K} = \begin{bmatrix} 200& 0 & 320 \\ 0 & 200& 240 \\ 0 & 0 & 1 \end{bmatrix}

步驟 4:計算像素坐標

代入公式:

u = f \cdot x + c_x = 200+ 320 = 520

v = f \cdot y + c_y = 0 + 240 = 240

所以最終像素坐標為:

(u, v) = (520, 240)

? 注意事項

  • 若像素坐標超出圖像范圍則該點不在圖像視野范圍內;
  • 調整焦距?ff或相機姿態可以改變點是否出現在圖像中;
  • 如果?Zc<0,即使計算出像素坐標也無法顯示,因為該點在相機背后。

四、參數總結與物理意義

參數單位物理意義
ff(焦距)像素控制圖像放大倍數,越大視角越小,物體顯得更大
cx,cycx?,cy?像素主點偏移量,通常是圖像中心,控制圖像原點位置
Xc,Yc,ZcXc?,Yc?,Zc?米或任意單位點在相機坐標系下的三維坐標
x,y無量綱歸一化圖像坐標,反映點相對于圖像中心的位置
u,v像素最終圖像坐標,可用于繪制或識別目標位置

第六章:更復雜的案例 —— 相機與世界坐標系存在夾角(完整流程詳解)

在本章中,我們將以一個更復雜的案例為例,詳細推導從世界坐標 → 像素坐標的完整變換流程。這個案例的特點是:

? 相機姿態不平行于世界坐標軸 —— 即相機與世界坐標系之間存在夾角。


🎯 示例設定

1. 點的世界坐標:

P_w = np.array([4, 2, 1.5])

表示某個物體在世界坐標中的位置。


2. 相機參數

(1)相機位置(平移向量):
t = np.array([2, 4, 1.5])

相機位于世界坐標系中的 (2, 4, 1.5) 位置。

(2)原始旋轉矩陣(將世界坐標轉換為相機坐標):
R_original = np.array([[1, 0, 0],[0, 0, -1],[0, -1, 0]
])

3. 新增旋轉:繞相機 Y? 軸向右旋轉 30°

我們希望讓相機繞其自身的 Z軸偏轉 30°(X->Y),從而看到右側空間。

    在三維空間中,繞 Y 軸 旋轉一個角度 θ 的標準旋轉矩陣為:

    \mathbf{R}_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}

    物理意義:

    • 表示繞?Y 軸旋轉角度?θ;
    • 相當于“轉頭”動作:向左或向右看;
    • X 和 Z 坐標發生變化,Y 不變

    繞 X 軸旋轉(Pitch)一個角度 θ 的標準旋轉矩陣為:

    \mathbf{R}_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix}

    物理意義:

    • 表示繞?X 軸旋轉角度?θ;
    • 相當于“點頭”動作:向上或向下看;
    • Y 和 Z 坐標發生變化,X 不變。

    繞 Z 軸旋轉(Roll)一個角度 θ 的標準旋轉矩陣為:

    \mathbf{R}_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}

    物理意義:

    • 表示繞?Y 軸旋轉角度?θ;
    • 相當于“轉頭”動作:向左或向右看;
    • X 和 Z 坐標發生變化,Y 不變。
      構造繞相機 z? 軸的旋轉矩陣:
      theta = np.radians(30)
      R_y_camera =  np.array([[np.cos(theta), -np.sin(theta), 0],[np.sin(theta), np.cos(theta), 0],[0, 0, 1]
      ])

      代入數值近似為:

      array([[ 0.8660254, -0.5      ,  0.       ],[ 0.5      ,  0.8660254,  0.       ],[ 0.       ,  0.       ,  1.       ]])

      4. 新的旋轉矩陣(合成后的相機姿態)

      我們將新增的局部旋轉應用到原旋轉上,得到新的整體旋轉矩陣,實際應該過程中,會很容易忽略掉原始相機坐標系R_original從而導致出錯

      R_new = R_y_camera @ R_original

      代入計算得:

      array([[ 0.8660254,  0.       ,  0.5      ],[ 0.5      ,  0.       , -0.8660254],[ 0.       , -1.       ,  0.       ]])

      🔁 完整變換流程(公式代碼格式)


      ? 步驟 1:世界坐標 → 相機坐標

      \mathbf{P}_c = \mathbf{R}_{\text{new}} \cdot (\mathbf{P}_w - \mathbf{t})

      ?代入數值:

      P_rel = P_w - t  
      P_c = R_new @ P_rel

      結果為:

      p_c = array([1.73205081, 1.        , 2.        ])

      即:

      X_c = 1.732,\quad Y_c = 1,\quad Z_c =2

      X_w = np.array([1, 0, 0])  # 世界X軸
      Y_w = np.array([0, 1, 0])  # 世界Y軸
      Z_w = np.array([0, 0, 1])  # 世界Z軸t = np.array([2, 4, 1.5])  # 新相機位置(Y值更大,更靠后)
      P_w = np.array([4, 2, 1.5])  
      # 旋轉矩陣(光軸 Z_c = -Y_w)
      R = np.array([[1, 0,0],[0, 0, -1],[0, -1, 0]
      ])theta = np.radians(30)
      R_z = np.array([[np.cos(theta), -np.sin(theta), 0],[np.sin(theta), np.cos(theta), 0],[0, 0, 1]
      ])R = R_z @ R# 轉換到相機坐標系
      P_c = R @ (P_w - t) 

      ? 步驟 2:透視投影(相機坐標 → 歸一化圖像坐標)

      設焦距 f=200:

      x = f \cdot \frac{X_c}{Z_c} = 200 \cdot \frac{1.732}{2} =173.2

      y = f \cdot \frac{Y_c}{Z_c} = 200 \cdot \frac{0}{2} = 0

      歸一化圖像坐標為:

      (x, y) = (718, 0)

      ? 步驟 3:應用內參矩陣(歸一化圖像坐標 → 像素坐標)

      設相機分辨率為 640×480,則主點為:

      c_x = 320,\quad c_y = 240

      內參矩陣為:

      \mathbf{K} = \begin{bmatrix} 200& 0 & 320 \\ 0 & 200& 240 \\ 0 & 0 & 1 \end{bmatrix}

      ?像素坐標為:u = f \cdot x + c_x = 173 + 320 = 493

      v = f \cdot y + c_y = 0 + 240 = 240

      ?最終像素坐標為:(u, v) = (493, 240)

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

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

      相關文章

      Ini配置文件讀寫,增加備注功能

      1.增加備注項寫入 例: #節點備注 [A] #項備注 bbb1 ccc2 [B] bbb1 IniConfig2 ic new IniConfig2(); //首次寫入 if (!ic.CanRead()) { ic.AddSectionReMarke("A", "節點備注"); ic.SetValue("A&qu…

      OpenHarmony 5.0中狀態欄添加以太網狀態欄圖標以及功能實現

      目錄 1.前置條件 2.方案 1.前置條件 首先以太網接口是有問題的,如下按照如下流程將以太網接口進行修復 OpenHarmony 以太網卡熱插拔事件接口無效-CSDN博客 然后上述的接口可以了就可以通過這個接口獲取以太網是否連接狀態 要注意wifi連接的干擾和預置虛擬網口干擾 2.方案…

      RNN GRU LSTM 模型理解

      一、RNN 1. 在RNN中&#xff0c; 2. RNN是一個序列模型&#xff0c;與非序列模型不同&#xff0c;序列中的元素互相影響&#xff1a; 是由 計算得來的。 在前向傳播中&#xff1a; 用于計算 和 用于計算 和 因此&#xff0c;當進行反向鏈式法則求導時候&#xf…

      多路徑傳輸(比如 MPTCP)控制實時突發

      實時突發很難控制&#xff0c;因為 “實時” 和 “突發” 相互斥。實時要求避免排隊&#xff0c;而突發必然要排隊&#xff0c;最終的解決方案都指向找一個公說公有理&#xff0c;婆說婆有理的中間點&#xff0c;這并沒解決問題&#xff0c;只是權衡了問題。 這種局部解決問題的…

      函數式編程思想詳解

      函數式編程思想詳解 1. 核心概念 不可變數據 (Immutable Data) 數據一旦創建&#xff0c;不可修改。任何操作均生成新數據&#xff0c;而非修改原數據。 優點&#xff1a;避免副作用&#xff0c;提升并發安全&#xff0c;簡化調試。 Java實現&#xff1a;使用final字段、不可變…

      iOS 主要版本發布歷史

      截至 2025 年 5 月&#xff0c;iOS 的最新正式版本是 iOS 18&#xff0c;于 2024 年 9 月 16 日 正式發布。此前的 iOS 17 于 2023 年 9 月 18 日 發布&#xff0c;并在 2024 年被 iOS 18 取代。(維基百科) &#x1f4f1; iOS 主要版本發布歷史 以下是 iOS 各主要版本的發布日…

      矩陣詳解:線性代數在AI大模型中的核心支柱

      &#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…

      基于51單片機和8X8點陣屏、獨立按鍵的飛行躲閃類小游戲

      目錄 系列文章目錄前言一、效果展示二、原理分析三、各模塊代碼1、8X8點陣屏2、獨立按鍵3、定時器04、定時器1 四、主函數總結 系列文章目錄 前言 用的是普中A2開發板。 【單片機】STC89C52RC 【頻率】12T11.0592MHz 【外設】8X8點陣屏、獨立按鍵 效果查看/操作演示&#xff…

      區塊鏈可投會議CCF C--APSEC 2025 截止7.13 附錄用率

      Conference&#xff1a;32nd Asia-Pacific Software Engineering Conference (APSEC 2025) CCF level&#xff1a;CCF C Categories&#xff1a;軟件工程/系統軟件/程序設計語言 Year&#xff1a;2025 Conference time&#xff1a;December 2-5, 2025 in Macao SAR, China …

      pdf圖片導出(Visio\Origin\PPT)

      一、Visio 導入pdf格式圖片 1. 設計->大小&#xff0c;適應繪圖。 2. 文件->導出&#xff0c;導出為pdf格式。 上面兩部即可得到只包含圖的部分的pdf格式。 如果出現的有默認白邊&#xff0c;可以通過以下方式設置&#xff1a; 1. 文件->選項->自定義功能區->…

      vector的實現

      介紹 1. 本質與存儲結構 動態數組實現&#xff1a;vector 本質是動態分配的數組&#xff0c;采用連續內存空間存儲元素&#xff0c;支持下標訪問&#xff08;如 vec[i]&#xff09;&#xff0c;訪問效率與普通數組一致&#xff08;時間復雜度 O (1)&#xff09;。動態擴容機制&…

      【Linux筆記】防火墻firewall與相關實驗(iptables、firewall-cmd、firewalld)

      一、概念 1、防火墻firewall Linux 防火墻用于控制進出系統的網絡流量&#xff0c;保護系統免受未授權訪問。常見的防火墻工具包括 iptables、nftables、UFW 和 firewalld。 防火墻類型 包過濾防火墻&#xff1a;基于網絡層&#xff08;IP、端口、協議&#xff09;過濾流量&a…

      el-date-picker 前端時間范圍選擇器

      控制臺參數&#xff1a; 前端代碼&#xff1a;用數組去接受&#xff0c;同時用 value-format"YYYY-MM-DD" 格式化值為&#xff1a;年月日格式 <!-- 查詢區域 --><transition name"fade"><div class"search" v-show"showSe…

      在 macOS 上安裝 jenv 管理 JDK 版本

      在 macOS 上安裝 jenv 并管理 JDK 版本 在開發 Java 應用程序時&#xff0c;你可能需要在不同的項目中使用不同版本的 JDK。手動切換 JDK 版本可能會很繁瑣&#xff0c;但幸運的是&#xff0c;有一個工具可以簡化這個過程&#xff1a;jenv。jenv 是一個流行的 Java 版本管理工…

      2025年全國青少年信息素養大賽復賽C++集訓(16):吃糖果2(題目及解析)

      2025年全國青少年信息素養大賽復賽C集訓&#xff08;16&#xff09;&#xff1a;吃糖果2&#xff08;題目及解析&#xff09; 題目描述 現有n(50 > n > 0)個糖果,每天只能吃2個或者3個&#xff0c;請計算共有多少種不同的吃法吃完糖果。 時間限制&#xff1a;1000 內存…

      ARM筆記-嵌入式系統基礎

      第一章 嵌入式系統基礎 1.1嵌入式系統簡介 1.1.1嵌入式系統定義 嵌入式系統定義&#xff1a; 嵌入式系統是以應用為中心&#xff0c;以計算機技術為基礎&#xff0c;軟硬件可剪裁&#xff0c;對功能、可靠性、成本、體積、功耗等有嚴格要求的專用計算機系統 ------Any devic…

      大語言模型(LLM)入門項目推薦

      推薦大語言模型(LLM)的入門項目 TiaoYu-1。 https://github.com/tiaoyu1122/TiaoYu-1 項目優點&#xff1a; 幾乎每一行代碼(一些重復的代碼除外)都添加了注釋&#xff0c;詳細介紹了代碼的作用&#xff0c;方便閱讀與理解。基本上覆蓋了常見 LLM 模型的全部訓練流程&#x…

      Linux里more 和 less的區別

      在 Linux/Unix 系統中&#xff0c;more 和 less 都是用于分頁查看文本文件的命令&#xff0c;但 less 是 more 的增強版&#xff0c;功能更強大。以下是它們的核心區別和用法對比&#xff1a; 1. 基礎功能對比 特性moreless&#xff08;更強大&#xff09;向前翻頁? 僅支持向…

      基于PDF流式渲染的Word文檔在線預覽技術

      一、背景介紹 在系統開發中&#xff0c;實現在線文檔預覽與編輯功能是許多項目的核心需求&#xff0c;但在實際的開發過程中&#xff0c;我們經常會面臨以下難點&#xff1a; 1&#xff09;格式兼容性問題&#xff1a;瀏覽器原生不支持解析Word二進制格式&#xff0c;直接渲染會…

      ai學習--python部分-1.變量名及命名空間的存儲

      初學代碼時總有一個問題困擾我&#xff1a;a 10 # a指向地址0x1234&#xff08;存儲10&#xff09; 變量a的值10存儲在0x1234&#xff0c;那么變量a需要存儲嗎&#xff1f;a又存儲在什么地址呢 目錄 1. ??命名空間的本質?? 2. ??命名空間的內存占用?? 3. ??…