最近在看高翔的《视觉SLAM十四讲》,不由得衍生出许多问题,在此记录。
1、为什么视网膜呈倒像而我们看到的是正像?
因为我们要看到物体,不仅仅是在视网膜上成像,视网膜还要传到大脑,大脑再对图像信息做处理,在这个过程中倒像被纠正为正像。
2、彩色图如何转换为灰度图?
我们日常的环境通常获得的是彩色图像,很多时候我们常常需要将彩色图像转换成灰度图像。也就是3个通道(RGB)转换成1个通道。
(1)平均法
最简单的方法当然就是平均法,将同一个像素位置3个通道RGB的值进行平均。
I(x,y) = 1/3 * I_R(x,y) +1/3 * I_G(x,y)+ 1/3 * I_B(x,y)
import cv2
import numpy as np
lenna = cv2.imread("lenna.png")
row, col, channel = lenna.shape
lenna_gray = np.zeros((row, col))
for r in range(row):
for l in range(col):
lenna_gray[r, l] = 1 / 3 * lenna[r, l, 0] + 1 / 3 * lenna[r, l, 1] + 1 / 3 * lenna[r, l, 2]
cv2.imshow("lenna_gray", lenna_gray.astype("uint8"))
cv2.waitKey()
(2)最大最小平均法
取同一个像素位置的RGB中亮度最大的和最小的进行平均。
I(x,y) = 0.5 * max(I_R(x,y), I_G(x,y), I_B(x,y))+ 0.5 * min(I_R(x,y), I_G(x,y), I_B(x,y))
for r in range(row):
for l in range(col):
lenna_gray[r, l] = 1 / 2 * max(lenna[r, l, 0], lenna[r, l, 1], lenna[r, l, 2]) + 1 / 2 * min(lenna[r, l, 0], lenna[r, l, 1], lenna[r, l, 2])
cv2.imshow("lenna_maxmin", lenna_gray.astype("uint8"))
cv2.waitKey()
(3)加权平均法
I(x,y) = 0.3 * I_R(x,y) +0.59 * I_G(x,y)+ 0.11 * I_B(x,y)
这是最流行的方法。几个加权系数0.3,0.59,0.11是根据人的亮度感知系统调节出来的参数,是个广泛使用的标准化参数。
for r in range(row):
for l in range(col):
lenna_gray[r, l] = 0.11 * lenna[r, l, 0] + 0.59 * lenna[r, l, 1] + 0.3 * lenna[r, l, 2]
cv2.imshow("lenna_weighted", lenna_gray.astype("uint8"))
cv2.waitKey()
(4)二值图像
不严谨的时候,我们也可以把灰度图称为黑白图像,实际上除了灰度图,还有一种图像叫二值图,也就是灰度只有0和255,这才是“真正的黑白图像”,因为0代表黑色,255代表白色。我们设定一个阈值T,当某像素点的灰度值大于T时,设定该像素点的值为255,当小于T时,设定为0。
lenna_binary = np.zeros_like(lenna_gray)
threshold = 100
for r in range(row):
for l in range(col):
if lenna_gray[r, l] >= threshold:
lenna_binary[r, l] = 255
else:
lenna_binary[r, l] = 0
cv2.imshow("lenna_binary", lenna_binary.astype("uint8"))
cv2.waitKey()
(5)反转图像
反转图像也很简单:s = 255-r。反转图像特别适用于增强暗色图像中的白色或灰色细节。
x_ray = cv2.imread("x_ray.png", 0)
row, col = x_ray.shape
x_ray_inverse = np.zeros_like(x_ray)
for r in range(row):
for l in range(col):
x_ray_inverse[r, l] = 255 - x_ray[r, l]
cv2.imshow("x_ray", x_ray)
cv2.imshow("x_ray_inverse", x_ray_inverse)
cv2.waitKey()
3、TOF(time of flight)飞行时间原理
由于光的高速,很难直接精确测量光从发射到接收的时间,因此一种常用的方式是通过调制光源发射时间和传感器曝光时间调制来间接计算光的传播时间和目标距离。
调制型TOF成像的原理如图2。在示意图中,一个完整测量周期包括两次激光发射与像素曝光。第一次激光以脉冲波发射,宽度为Tpulse;接收器像素在同一时间开始曝光,曝光时间与发射脉冲相同,即光发射与像素曝光周期同步。像素仅在接收到从目标反射的激光的有效曝光时间段ΔT接收了反射光子数量,像素输出电压Vf1与ΔT成正比。
在第二个曝光脉冲时间段,激光发射脉冲时间段不变,但像素曝光时间增加,覆盖了第二次反射光的全过程,因此输出电压与光发射脉冲时间Tpluse成正比。两次对比,可得到:
从而可以得到光反射的时间T_travel = T_pulse-dT,目标与TOF相近的距离为:
实际应用中,会通过多次重复测量来提升测量精度并减少噪声。通过时序的控制,还可以产生其它的调制方式,但基本原理如上所述。
采用双脉冲调制方式,TOF深度相机理论上可测量最小深度为0,此时Ttravel=Tpulse,由公式(2)可计算的深度为0。但由于噪声、系统等原因,实际最小深度会大于0,具体值与调制方式、调制准确度、信噪比和测量精度相关。
TOF深度相机最大测量深度有激光脉冲宽度决定,即
c为光在媒介中的传播速度。在常规的应用中,光传播媒介为空气,光速30万千米每秒,那么50ns脉冲宽度对应最大深度为7.5m。显然增加脉冲宽度可增加最大可测量深度。此外,还可在激光脉冲和快门之间增加延时来增加最大深度,其代价是增加了最小测量深度。主动式TOF相机通过接收反射光测量。为保证信噪比,可测量深度增加意味着更大的光照强度和系统功耗。这是实际设计中需要平衡考虑的。
4、什么是图优化?
转载自https://www.cnblogs.com/gaoxiang12/p/5244828.html
预备知识:优化
图优化本质上是一个优化问题,所以我们先来看优化问题是什么。
优化问题有三个最重要的因素:目标函数、优化变量、优化约束。一个简单的优化问题可以描述如下:
其中x为优化变量,而F(x)为优化函数。此问题称为无约束优化问题,因为我们没有给出任何约束形式。由于slam中优化问题多为无约束优化,所以我们着重介绍无约束的形式。
当F(x)有一些特殊性质时,对应的优化问题也可以用一些特殊的解法。例如,F(x)为一个线性函数时,则为线性优化问题(不过线性优化问题通常在有约束情形下讨论)。反之则为非线性优化。对于无约束的非线性优化,如果我们知道它梯度的解析形式,就能直接求那些梯度为零的点,来解决这个优化:
梯度为零的地方可能是函数的极大值、极小值或者鞍点。由于现在F(x)的形式不确定,我们只好遍历所有的极值点,找到最小的作为最优解。
但是我们为什么不这样用呢?因为很多时候F(x)的形式太复杂,导致我们没法写出导数的解析形式,或者难以求解导数为零的方程。因此,多数时候我们使用迭代方式求解。从一个初值x0出发,不断地导致当前值附近的,能使目标函数下降的方式(反向梯度),然后沿着梯度方向走出一步,从而使得函数值下降一点。这样反复迭代,理论上对于任何函数,都能找到一个极小值点。
迭代的策略主要体现在如何选择下降方向,以及如何选择步长两个方面。主要有 Gauss-Newton (GN)法和 Levenberg-Marquardt (LM)法两种,它们的细节可以在维基上找到,我们不细说。请理解它们主要在迭代策略上有所不同,但是寻找梯度并迭代则是一样的。
图优化
所谓的图优化,就是把一个常规的优化问题,以图(Graph)的形式来表述。
图是什么呢?
图是由顶点(Vertex)和边(Edge)组成的结构,而图论则是研究图的理论。我们记一个图为G={V,E},其中V为顶点集,E为边集。
顶点没什么可说的,想象成普通的点即可。
边是什么呢?一条边连接着若干个顶点,表示顶点之间的一种关系。边可以是有向的或是无向的,对应的图称为有向图或无向图。边也可以连接一个顶点(Unary Edge,一元边)、两个顶点(Binary Edge,二元边)或多个顶点(Hyper Edge,多元边)。最常见的边连接两个顶点。当一个图中存在连接两个以上顶点的边时,称这个图为超图(Hyper Graph)。而SLAM问题就可以表示成一个超图(在不引起歧义的情况下,后文直接以图指代超图)。
怎么把SLAM问题表示成图呢?
SLAM的核心是根据已有的观测数据,计算机器人的运动轨迹和地图。假设在时刻k,机器人在位置xk处,用传感器进行了一次观测,得到了数据zk。传感器的观测方程为:
由于误差的存在,zk不可能精确地等于h(xk),于是就有了误差:
那么,如果我们以xk为优化变量,以minxFk(xk)=∥ek∥为目标函数,就可以求得xk的估计值,进而得到我们想要的东西了。这实际上就是用优化来求解SLAM的思路。
你说的优化变量xk,观测方程zk=h(xk)等等,它们具体是什么东西呢?
这个取决于我们的参数化(parameterazation)。x可以是一个机器人的Pose(6自由度下为 4×4的变换矩阵T 或者 3自由度下的位置与转角[x,y,θ],也可以是一个空间点(三维空间的[x,y,z]或二维空间的[x,y])。相应的,观测方程也有很多形式,如:
机器人两个Pose之间的变换;
机器人在某个Pose处用激光测量到了某个空间点,得到了它离自己的距离与角度;
机器人在某个Pose处用相机观测到了某个空间点,得到了它的像素坐标;
同样,它们的具体形式很多样化,这允许我们在讨论slam问题时,不局限于某种特定的传感器或姿态表达方式。
我明白优化是什么意思了,但是它们怎么表达成图呢?
在图中,以顶点表示优化变量,以边表示观测方程。由于边可以连接一个或多个顶点,所以我们把它的形式写成更广义的 zk=h(xk1,xk2,…),以表示不限制顶点数量的意思。对于刚才提到的三种观测方程,顶点和边是什么形式呢?
机器人两个Pose之间的变换;——一条Binary Edge(二元边),顶点为两个pose,边的方程为T1=ΔT⋅T2。机器人在某个Pose处用激光测量到了某个空间点,得到了它离自己的距离与角度;——Binary Edge,顶点为一个2D Pose:[x,y,θ]T和一个Point:[λx,λy]T,观测数据是距离r和角度b,那么观测方程为:
机器人在某个Pose处用相机观测到了某个空间点,得到了它的像素坐标;——Binary Edge,顶点为一个3D Pose:T和一个空间点x=[x,y,z]T,观测数据为像素坐标z=[u,v]T。那么观测方程为:
C为相机内参,R,t为旋转和平移。
举这些例子,是为了让读者更好地理解顶点和边是什么东西。由于机器人可能使用各种传感器,故我们不限制顶点和边的参数化之后的样子。比如我(丧心病狂地在小萝卜身上)既加了激光,也用相机,还用了IMU,轮式编码器,超声波等各种传感器来做slam。为了求解整个问题,我的图中就会有各种各样的顶点和边。但是不管如何,都是可以用图来优化的。
该博文后面还讲到了怎么做图优化、流形和核函数,写得非常非常好,有兴趣的可以参阅一些。
5、矩阵的基本知识
定义矩阵的基本运算
基本运算
矩阵乘法注意的地方
注意
矩阵的转置和行列式
转置和行列式
伴随矩阵
伴随矩阵
伴随矩阵的行列式和逆矩阵
伴随矩阵的行列式和逆矩阵
逆矩阵的性质
性质
一些特殊的性质
特殊性质
分块对角矩阵
分块对角矩阵
行列式
行列式
逆序
逆序
具体定义
具体定义
计算
计算
行列式的行变换
行列式的列变换
余子式和代数余子式
网友评论