目錄
1 概述
本文將介紹單目相機基本概念及其內參矩陣和外參矩陣在MATLAB下的表示方法,並分析車體座標系到相機座標系、相機座標系的像素座標系的轉換關係,再給出在MATLAB中的相關類和函數,最後由簡入難給出相關實用案例。
2 單目相機(Mono camera)
2.1 基本概念
通常來說,單目相機是指只有一個鏡頭且無法直接測量深度信息的相機。相對而言還有雙目相機,具備深度測量的RGB-D相機等種類。
2.2 車體座標系到相機座標系
在博文《自車座標系下的物體相對和絕對位置和速度計算》已經闡述了車體座標系的基本概念,最常用的座標系是“座標系–前-左-上(FLU)”,如下圖所示:
但是車體座標系的座標原點可選,一般不會限定,《自車座標系下的物體相對和絕對位置和速度計算》中提到通常來說會選在車輛後軸中心。
相機座標系通常是指以相機光學焦點爲原點,鏡頭朝前爲x軸方向,面向鏡頭右方爲y軸防線,上方爲z軸方向。這裏,可以把車輛座標系簡單理解爲世界座標系,相機座標系與車體座標系的轉換參數即爲相機的外參(Camera Extrinsics),描述的相機位姿特徵,與相機內參相對。相機的外參可以調整,而內參在相機定型後則已經固定了。
相機座標系與車輛座標系之間存在三個平移和三個旋轉的關係。因此爲了進行座標系轉換,需要知道相機在車輛座標系中的位姿,即座標和姿態。平移相對好理解,旋轉的表示方法有多種,一般可以用歐式變換、旋轉軸和歐拉角度或者四元數來表示。由於這塊內容屬於基礎理論,理論成熟且篇幅有限,這裏不作展開,總之在已知x、y、z三個方向位置和姿態(旋轉角度)的情況下,可以求出兩個座標系下座標點的轉換關係。詳細可以參考w維基百科《Rotation matrix》,或者中文版的《旋轉矩陣》。
2.3 相機座標系到像素座標系
相機座標系到像素座標系的變換參見博文《相機內參座標系及其在MATLAB 中的表示》。
MATLAB中採用類 cameraIntrinsics描述相機內參矩陣——相機座標系到像素座標系之間的關係。
2.4 相關類和函數
2.4.1 monoCamera類
在MATLAB中表述單目相機的類是monoCamera類,該類的語法如下:
sensor = monoCamera(intrinsics,height);
sensor = monoCamera(intrinsics,height,Name,Value)
提供了兩種常用的構造函數。
主要的屬性如下:
Intrinsic即爲相機的內參類,Height、SensorLocation描述了在車體座標系中的三維座標,Pictch、Yaw、Roll分別爲Y、Z、X方向軸上的旋轉角度,以上六個參數實際就是描述了相機的外參矩陣。
2.4.2 變換函數
函數 | 解釋 |
---|---|
vehicleToImage | Convert image coordinates to vehicle coordinates |
vehicleToImage | Convert vehicle coordinates to image coordinates |
提供的兩個函數vehicleToImage 和vehicleToImage可以將座標點從車輛座標系轉換到像素座標系,也可以將座標點從像素座標系轉換到車輛座標系,具體的轉換代碼其實我們在理解2.2和2.3節中相關變換的數學原理上其實可以不用去關注,只要知道有這個過程就可以了(這也是我個人比較喜歡的模式,對於成熟的原理只要理解數學推導,在有相關庫例如OPENCV和語言知識的基礎上,詳細的代碼設計可以不用關心,當然如果用於學習代碼知識可以另當別論)。
3 實例分析
示例 1 重合
已知內參矩陣,且車輛座標系與相機座標系重合。求:車體正前方10m 遠處的點在像素座標系下的座標。示例代碼如下:
focalLength = [800 800];
principalPoint = [320 240];
imageSize = [480 640];
intrinsics = cameraIntrinsics(focalLength,principalPoint,imageSize);
height = 0.000001 ; % 高度無法設置爲0,這裏用0.000001代替
sensor = monoCamera(intrinsics,height);
xyVehicleLoc1 = [10 0]; % 車體正前方10m 遠處的點
xyImageLoc1 = vehicleToImage(sensor,xyVehicleLoc1)
運行結果如下:
xyImageLoc1 =
319.9999 240.0001
可見,正前方10m的點,在像素座標系下的位置爲:(320,240)即principalPoint,位於圖像的中心位置。
示例2 平移
在示例1的基礎上,只改變車輛座標系與相機座標系在z軸上的差異:
focalLength = [800 800];
principalPoint = [320 240];
imageSize = [480 640];
intrinsics = cameraIntrinsics(focalLength,principalPoint,imageSize);
height = 1; % 高度設置爲1m
sensor = monoCamera(intrinsics,height);
xyVehicleLoc1 = [10 0 1]; % 車體正前方10m 遠處高度爲1m的點
xyImageLoc1 = vehicleToImage(sensor,xyVehicleLoc1)
運行結果如下:
xyImageLoc1 =
240.0000 160.0000
y方向設置爲1m,高度(z方向)設置爲2m,
xyVehicleLoc1 = [10 1 2]; % 車體正前方10m 遠處高度爲1m的點
xyImageLoc1 = vehicleToImage(sensor,xyVehicleLoc1)
示例3 旋轉
相機位置相對車輛座標系在y軸方向上有14°的旋轉角度(直接拿的Help例子)。
focalLength = [800 800];
principalPoint = [320 240];
imageSize = [480 640];
intrinsics = cameraIntrinsics(focalLength,principalPoint,imageSize);
height = 2.18;
pitch = 14;
sensor = monoCamera(intrinsics,height,'Pitch',pitch);
xyVehicleLoc1 = [10 0];
xyImageLoc1 = vehicleToImage(sensor,xyVehicleLoc1)
運行結果如下:
xyImageLoc1 =
320.0000 216.2296
進一步,將該座標點xyImageLoc1繪製到像素座標系,結果如下:
Ioriginal = imread('road.png');
figure
imshow(Ioriginal)
title('Original Image')
IvehicleToImage = insertMarker(Ioriginal,xyImageLoc1);
IvehicleToImage = insertText(IvehicleToImage,xyImageLoc1 + 5,'10 meters');
figure
imshow(IvehicleToImage)
title('Vehicle-to-Image Point')
運行結果如下:
更進一步,假設地面上某點在像素座標系下的x、y座標爲(300 300),求在車輛座標系下的座標值。
注意這裏求的是地面某點,因此實際z座標值已知,爲-height即-2.18,代碼如下:
xyImageLoc2 = [300 300];
xyVehicleLoc2 = imageToVehicle(sensor,xyImageLoc2)
運行結果如下:
xyVehicleLoc2 = 1×2
6.5959 0.1732
因此圖像中x、y座標爲(300 300)的點對應到車輛座標系下的實際位置爲(6.5959 0.1732),距離車輛原點前方6.6m,左手放方向0.17m處。
參考
MATLAB官網《monocamera》:https://www.mathworks.com/help/driving/ref/monocamera.html#bvoy54v:
高翔:《視覺SLAM14講》
維基百科《Rotation_matrix》:https://en.wikipedia.org/wiki/Rotation_matrix