视觉slam14讲——第5讲 相机与图像

来源:互联网 发布:mac 切换 输入法 编辑:程序博客网 时间:2024/06/07 06:24

本系列文章是记录学习高翔所著《视觉slam14讲》的内容总结,文中的主要文字和代码、图片都是引用自课本和高翔博士的博客。代码运行效果是在自己电脑上实际运行得出。手动记录主要是为了深入理解

  • 第5讲 相机与图像
    • 相机模型
      • 1 针孔相机模型
      • 2 畸变
      • 3 双目相机模型
      • 4 RGBD相机模型
    • 图像的存储和访问
      • 1 图像的存储
      • 2 图像的通道
      • 3 opencv图像像素的遍历

第5讲 相机与图像

1 相机模型

相机模型是用来描述将三维世界坐标系中的坐标点映射到二维图像平面的过程
使用针孔和畸变两个模型来描述整个投影过程。

1.1 针孔相机模型

这里写图片描述

(1) 相机坐标系内中物理坐标点Pc~=[X,Y,Z]T,
(2) 成像平面内成像坐标点P=[X,Y,Z]T, 焦距为f,
通过对称成像平面和归一化成像平面得到二者关系为

X=fXZY=fYZ

(3) 像素坐标系内像素坐标为[u,v]T,像素坐标系和成像平面相差了一个缩放(uαvβ)和一个原点的平移[cx,cy]T
p和像素坐标[u,v]T关系为
u=αX+cxv=βY+cy

代入上式得到像素坐标和相机坐标系内点的关系
u=fxXZ+cxv=fyYZ+cy

其中,
fx=αf,fy=βf

齐次化写成矩阵形式,
uv1=1Zfx000fy0cxcy1XYZ=1ZKPc~
按照传统习惯将Z挪到左侧,表达的就是相机坐标系中点和像素坐标系中像素的关系
Zuv1=fx000fy0cxcy1XYZ=KPc~

把中间量K称作相机内参。
K=fx000fy0cxcy1

相机坐标P是由它的世界坐标Pw变换而来,相机位姿由R,t决定。那么有下式成立,
ZPuv=Zuv1=K(RPw+t)=K(TPw)(1:3)

最后一个式子里面隐含着一次齐次坐标到非齐次坐标的转换(TPw的最后一维是1),也就是
Pc~=K(RPw+t)=(TPw)(1:3)=XYZ

两边除以Z, 所以,
Puv=1ZK(TPw)(1:3)=1ZKPc~=KXZYZ1=KPc

其中Pc=[XZ YZ 1]称为归一化坐标,二维的齐次坐标,它**位于相机前方z=1的平面上,叫做归一化平面**。

变换过程总结:
世界坐标系下点PwR,tTPc~=RPw+t=[X Y Z]Pc=XZYZ1Puv=KPc

1.2 畸变

  • 径向畸变
    透镜的形状引起,有桶形失真和枕形失真。
  • 切向畸变
    相机组装过程不能使透镜和成像平面严格平行引起

一般使用的去畸变处理方法:先对整张图像去畸变,得到去畸变后的图像,然后讨论图像上点的空间位置。

1.3 双目相机模型

这里写图片描述

根据三角形相似得到

zfz=buL+uRb

整理得到
z=fbd,d=uLuR

1.4 RGBD相机模型

原理

  • 红外结构光
  • 飞行时间法

2 图像的存储和访问

这里写图片描述

2.1 图像的存储

例如一张宽度为640像素,高度为480像素的灰度图(0~255)表示为

//unsigned char image[h][w];unsigned char image[480][640];

像素坐标原点位于图像的左上角,X轴向右。Y轴向下,Z轴向前(里)。

  • 数组的行图像的高度Y
  • 数组的列图像的宽度X
unsigned char pixel = image[y][x]

2.2 图像的通道

  • 灰度图使用一个unsigned char来表示8位数据(0~255)。
  • 彩色图像需要用到通道的概念。常见的彩色图像使用三个通道来表示,每个通道由8位整数来表示,这样的话一个像素占用24位空间。
  • 通道的顺序在opencv中是BGR的顺序,如果还想表达图像的透明度,可以使用RGBA四个通道。

2.3 opencv图像像素的遍历

先定位到某一行,在到某一列,再到某一个通道,最后是某一个像素。

cv::Mat image = cv::read("lena.png");for (size_t y=0; y<image.rows; y++){    for (size_t x=0; x<image.cols; x++)    {        unsigned char* row_ptr = image.ptr<unsigned char>(y);        unsigned char data_ptr = &row_ptr[x*image.channels()];        for(int c=0; c!=image.channels();c++)        {            unsigned char data = data_ptr[c];        }    }}
原创粉丝点击