單目相機(Mono camera)在MATLAB中的表示與實例

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章