Mitchy
今日もキラキラしていこう♪

为了成为计算机视觉专家,我们需要对图片的形状,颜色,地理等新元素有更多深入的认识和理解。

无人驾驶的循环三部曲:感知世界(计算机视觉!),做出决策,付诸行动

感知占了自动驾驶的百分之八十工作量。

雷达,激光雷达:空间分辨率低,3D,贵

摄像头:空间分辨率高,2D,便宜 --> 大势所趋

现在需要找到道路线,判断曲度,以及车是否在道中央,会有不同的阴影,不同颜色的人行道等干扰

下一步就是车辆检测和监测,以做出加速、减速、变道等决策

然后将二者结合起来~

 

首先需要判断道路线的曲度,需要将摄像头得到的图片转换成俯视的视角方便判断。

相机本质上是将3D的物品转换为2D的图像,所以这个转换肯定会改变3D物品的形状和大小。

所以第一步就是解决图像畸变的问题,把接收到的图像恢复成实际应有的样子。

最基本常见的扭曲:

径向畸变(radial distortion)

  因为相机不像小孔成像那样能把图片上下颠倒的完美保存下来,而是用了透镜,所以就会导致图片不平整

  相关系数:k1, k2, k3 (其中k3和镜面曲度有关,正常镜头的k3很接近0可以被忽略,但是广角镜头的就不行)

  x_{distorted} = x_{ideal} (1 + k_1r^2 + k_2r^4 + k_3r^6)
  y_{distorted} = y_{ideal} (1 + k_1r^2 + k_2r^4 + k_3r^6)

切向畸变(tangential distortion)

  相机放斜了所以图片的远近距离不对了

  相关系数:p1, p2

  x_{corrected} = x + [2p_1xy + p_2(r^2 + 2x^2)]
  y_{corrected} = y + [p_1(r^2 + 2y^2) + 2p_2xy]

所以我们需要获得5个和畸变相关的系数(有时候会大于5个)来复原图片

用OpenCV函数的话,参数就是[k1, k2, p1, p2, k3].

检测相机的图形畸变一般用象棋盘(黑白格子那种),因为分辨率高,图形简单,所以很容易就知道图形是怎么被扭曲的
找到棋盘角:cv2.findChessboardCorners(), cv2.drawChessboardCorners()
https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#cv2.findChessboardCorners
https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#cv2.drawChessboardCorners
一般来说需要准备>=20张图片来保证计算结果可靠,然后最后加一张测试图
有用的代码:
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
注:如果用的是mpimg.imread(),那么读出来的是RGB,上面应该改成cv2.COLOR_RGB2GRAY,如果是cv2.imread()或者glob API读进来的,那么应该和例子一样
ret, corners = cv2.findChessboardCorners(gray, (8,6), None)
img = cv2.drawChessboardCorners(img, (8,6), corners, ret)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
其中gray.shape[::-1]可替换为img.shape[1::-1] (只取3维数据中前两个并且倒过来)
dst = cv2.undistort(img, mtx, dist, None, mtx)
学会了复原之后你也可以尝试着计算和复原一下自己相机的畸变~
 
透视变换:2D图像表达3D情景时,远处物体小,近处物体大+有切向畸变(观看物体的角度不同)
 
回到自动驾驶上,我们需要根据道路线的曲度判断路的曲度,从而根据曲度,车辆特性,车速等计算出方向盘的角度。
而曲度是通过摄像头通过阈值之类的技术检测到道路线,然后通过畸变转换的方法把道路线转换为俯视图,然后求出图中曲线的近似抛物线,这样角度就很好得到了。
抛物线的f(y) = Ay^2 + By + C中,A表达了曲线的曲度,B表达了曲线的指向,C表达的是曲线和图像左侧的距离。
 
小练习:转换有切向畸变的图片使我们看起来像从正面观察图片
1. 读取图片以及图片的大小
2. 选择图片上4个在同一平面的点(此处我们手动选择,但是以后可以使用算法来检测边、角,分析颜色和周围像素等方法选择源图平面点)
3. 定义目标图上的4个能够组成长方形的点
4. 获得从源图转换到目标图的转换矩阵:M = cv2.getPerspectiveTransform(src, dst)
5. # 获得从目标图转换到源图的逆向转换矩阵:Minv = cv2.getPerspectiveTransform(dst, src)
6. 转换图片:warped = cv2.warpPerspective(img, M, img_size, flags=cv2.INTER_LINEAR)
 
总结:棋盘图像处理步骤
1. 去除畸变
2. 转换为灰度图
3. 找到棋盘角
4. 画出角
5. 定义4个源平面点
6. 定义4个目标平面点(顺序必须一样!)
7. 得到透视转换矩阵
8. 转换视角!
 
下一步:通过颜色和梯度的阈值来确定图片的角度是否正确,畸变是否消除,从而确定道路线
posted on 2020-11-30 00:36  Mitchy  阅读(386)  评论(0编辑  收藏  举报