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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

相机模型内参推导

發布時間:2023/12/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 相机模型内参推导 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相機模型

符號定義:CPa^CP_aCPa?表示PaP_aPa?點在坐標系CCC中的坐標,ICT^C_ITIC?T表示坐標系III相對于坐標系CCC的坐標變換。設B點為主軸與相平面之間的交點,相機坐標系CCC中點PoP_oPo?坐標為:(Pox,Poy,Poz)T(P_{ox}, P_{oy}, P_{oz})^T(Pox?,Poy?,Poz?)T,P點為線段PoCP_oCPo?C與相平面的交點,則易得PB⊥BCPB \perp BCPBBCΔPoAC\Delta P_oACΔPo?ACΔPBC\Delta PBCΔPBC相似,得P點在相機坐標系C中的坐標CP^CPCPfPoz(Pox,Poy,Poz)T\frac{f}{P_{oz}}(P_{ox}, P_{oy}, P_{oz})^TPoz?f?(Pox?,Poy?,Poz?)T,設IP=(u,v,0)^IP=(u, v, 0)IP=(u,v,0)

推導1. 當相平面原點在主軸上

相平面原點在主軸上即,相平面原點在相機坐標為(0,0,f)T(0, 0, f)^T(0,0,f)T,容易得到:
CTI=(10000100001f0001)CTI?1=(10000100001?f0001)^CT_I = \left( \begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & f \\ 0 & 0 & 0 & 1 \end{array} \right) \\ ^CT_I^{-1} = \left( \begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & -f \\ 0 & 0 & 0 & 1 \end{array} \right) CTI?=?????1000?0100?0010?00f1??????CTI?1?=?????1000?0100?0010?00?f1??????
則由坐標變換得:IP=CITCP^IP=^I_CT^CPIP=CI?TCP,計算得:
(uv0)=fPoz(PoxPoy0)\left( \begin{array}{c} u \\ v \\ 0 \end{array} \right) = \frac{f}{P_{oz}} \left( \begin{array}{c} P_{ox} \\ P_{oy} \\ 0 \end{array} \right) ???uv0????=Poz?f????Pox?Poy?0????

推導2. 當相平面原點不在主軸上

設相平面原點在相機坐標為(cx,cy,f)T(c_x, c_y, f)^T(cx?,cy?,f)T,注意cx,cyc_x, c_ycx?,cy?的定義,容易得到:
CTI=(100cx010cy001f0001)CTI?1=(100?cx010?cy001?f0001)^CT_I = \left( \begin{array}{cccc} 1 & 0 & 0 & c_x \\ 0 & 1 & 0 & c_y \\ 0 & 0 & 1 & f \\ 0 & 0 & 0 & 1 \end{array} \right) \\ ^CT_I^{-1} = \left( \begin{array}{cccc} 1 & 0 & 0 & -c_x \\ 0 & 1 & 0 & -c_y \\ 0 & 0 & 1 & -f \\ 0 & 0 & 0 & 1 \end{array} \right) CTI?=?????1000?0100?0010?cx?cy?f1??????CTI?1?=?????1000?0100?0010??cx??cy??f1??????
同理推導得到:
(uv0)=fPoz(PoxPoy0)+(?cx?cy0)\left( \begin{array}{c} u \\ v \\ 0 \end{array} \right) = \frac{f}{P_{oz}} \left( \begin{array}{c} P_{ox} \\ P_{oy} \\ 0 \end{array} \right) + \left( \begin{array}{c} -c_x \\ -c_y \\ 0 \end{array} \right) ???uv0????=Poz?f????Pox?Poy?0????+????cx??cy?0????
反之由坐標變換得:CP=ICTIP^CP=^C_IT^IPCP=IC?TIP,計算得:
(PoxPoyPoz)=Pozf(u+cxv+cyf)\left( \begin{array}{c} P_{ox} \\ P_{oy} \\ P_{oz} \end{array} \right) = \frac{P_{oz}}{f} \left( \begin{array}{c} u + c_x\\ v + c_y \\ f \end{array} \right) ???Pox?Poy?Poz?????=fPoz?????u+cx?v+cy?f????
整理為矩陣形式得:
Poz(uv1)=(f0?cx0f?cy001)?K(100001000010)?(I∣0)(PoxPoyPoz1)P_{oz}\left( \begin{array}{c} u \\ v \\ 1 \end{array} \right) = \underbrace{\left(\begin{array}{ccc} f & 0 & -c_{x} \\ 0 & f & -c_{y} \\ 0 & 0 & 1 \end{array}\right)}_{K} \underbrace{\left(\begin{array}{llll} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{array}\right)}_{(I \mid 0)} \left( \begin{array}{c} P_{ox} \\ P_{oy} \\ P_{oz} \\ 1 \end{array} \right) Poz????uv1????=K???f00?0f0??cx??cy?1??????(I0)???100?010?001?000???????????Pox?Poy?Poz?1??????
矩陣K稱為相機內參矩陣。若考慮世界坐標與相機坐標的坐標變換WCT^C_WTWC?T,則世界坐標的點WP=(X,Y,Z,1)T^WP=(X, Y, Z, 1)^TWP=(X,Y,Z,1)T與相平面點坐標的關系可表示為:
CZ(uv1)=[f0?cx0f?cy001][WCR∣WCt](XYZ1)^CZ \left( \begin{array}{c} u \\ v \\ 1 \end{array} \right) = \left[\begin{array}{ccc} f & 0 & -c_{x} \\ 0 & f & -c_{y} \\ 0 & 0 & 1 \end{array}\right][^C_WR \mid ^C_Wt]\left(\begin{array}{l} X \\ Y \\ Z \\ 1 \end{array}\right) CZ???uv1????=???f00?0f0??cx??cy?1????[WC?RWC?t]?????XYZ1??????
CZ^CZCZ為相機坐標系的坐標表示。到這里所有的坐標系都表征物理單位,如果將像平面的坐標變換到像素平面,設像平面坐標系與像素平面坐標系重合,需要做再做一次尺度變換。設每行/每列像素對應的像坐標系的物理間隔分別為su,svs_u, s_vsu?,sv?,則存在以下變換:
(ij1)=[1su0001sv0001](uv1)\left( \begin{array}{c} i \\ j \\ 1 \end{array} \right) = \left[\begin{array}{ccc} \frac{1}{s_u} & 0 & 0 \\ 0 & \frac{1}{s_v} & 0 \\ 0 & 0 & 1 \end{array}\right] \left( \begin{array}{c} u \\ v \\ 1 \end{array} \right) ???ij1????=???su?1?00?0sv?1?0?001???????uv1????
綜上,最終的像素坐標與世界坐標間的變換關系為:
CZ(ij1)=[1su0001sv0001][f0?cx0f?cy001][WCR∣WCt](XYZ1)^CZ \left( \begin{array}{c} i \\ j \\ 1 \end{array} \right) = \left[\begin{array}{ccc} \frac{1}{s_u} & 0 & 0 \\ 0 & \frac{1}{s_v} & 0 \\ 0 & 0 & 1 \end{array}\right] \left[\begin{array}{ccc} f & 0 & -c_{x} \\ 0 & f & -c_{y} \\ 0 & 0 & 1 \end{array}\right][^C_WR \mid ^C_Wt]\left(\begin{array}{l} X \\ Y \\ Z \\ 1 \end{array}\right) CZ???ij1????=???su?1?00?0sv?1?0?001???????f00?0f0??cx??cy?1????[WC?RWC?t]?????XYZ1??????


若與其他推導出現公式上的差異,請注意這里的cx,cyc_x, c_ycx?,cy?定義。

相機標定之張正友標定法數學原理詳解
手眼標定之基本原理

pybullet中camera實現

camera在世界坐標系中放置位置如下圖所示

代碼參考:panda_grasp_sim_2

class Camera:def __init__(self):"""初始化相機參數,計算相機內參"""self.fov = 60*math.pi/180self.length = 0.7 # 焦距self.H = self.length * math.tan(0.5*self.fov) # 圖像上方點的到中心點的實際距離(height) m# 計算 f/su和 f/svself.A = (HEIGHT / 2) * self.length / self.H# 計算內參矩陣(注意上文中Cx, Cy單位為m)self.InMatrix = np.array([[self.A, 0, WIDTH/2 - 0.5], [0, self.A, HEIGHT/2 - 0.5], [0, 0, 1]], dtype=np.float)# 計算相機坐標系相對于世界坐標系的變換矩陣# 歐拉角xyz: (pi, 0, 0) 平移(0, 0, 0.7)rotMat = eulerAnglesToRotationMatrix([math.pi, 0, 0])self.transMat = getTransfMat([0, 0, 0.7], rotMat)"""helper functions""" def img2camera(self, pt, dep):"""獲取像素點pt在相機坐標系中的坐標pt: [x, y]dep: 深度值return: [x, y, z]"""pt_in_img = np.array([[pt[0]], [pt[1]], [1]], dtype=np.float)ret = np.matmul(np.linalg.inv(self.InMatrix), pt_in_img) * depreturn list(ret.reshape((3,)))# print('坐標 = ', ret)def camera2img(self, coord):"""將相機坐標系中的點轉換至圖像coord: [x, y, z]return: [row, col]"""z = coord[2]coord = np.array(coord).reshape((3, 1))rc = (np.matmul(self.InMatrix, coord) / z).reshape((3,))return list(rc)[:-1]def camera2world(self, coord):"""獲取相機坐標系中的點在世界坐標系中的坐標corrd: [x, y, z]return: [x, y, z]"""coord.append(1.)coord = np.array(coord).reshape((4, 1))coord_new = np.matmul(self.transMat, coord).reshape((4,))return list(coord_new)[:-1]def world2camera(self, coord):"""獲取世界坐標系中的點在相機坐標系中的坐標corrd: [x, y, z]return: [x, y, z]"""coord.append(1.)coord = np.array(coord).reshape((4, 1))coord_new = np.matmul(np.linalg.inv(self.transMat), coord).reshape((4,))return list(coord_new)[:-1]def world2img(self, coord):"""獲取世界坐標系中的點在圖像中的坐標corrd: [x, y, z]return: [row, col]"""# 轉到相機坐標系coord = self.world2camera(coord)# 轉到圖像pt = self.camera2img(coord) # [y, x]return [int(pt[1]), int(pt[0])]def img2world(self, pt, dep):"""獲取像素點的世界坐標pt: [x, y]dep: 深度值 m"""coordInCamera = self.img2camera(pt, dep)return self.camera2world(coordInCamera)

總結

以上是生活随笔為你收集整理的相机模型内参推导的全部內容,希望文章能夠幫你解決所遇到的問題。

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