首页 > Udacity机器人软件工程师课程笔记(二)-样本搜索和找回-基于漫游者号模拟器

Udacity机器人软件工程师课程笔记(二)-样本搜索和找回-基于漫游者号模拟器

Robotics Software engineer编程笔记(二)

5.确定漫游者号的行进方向

(1)漫游者号如何确定自己的行进方向?

我们已经有了一个由前置摄像头得到的图像,然后可以通过对图像进行处理,来确定漫游者号应该转动的方向。

通过将漫游者坐标转换成极坐标,我们就能确定小车应该前进的方向,其中每个像素位置由距离原点的距离和从正x方向逆时针的角度表示。

转向示例

如图所示, 漫游者号能行驶的范围只有在右边,所以漫游者号应该向右侧旋转,来找到正确的道路。我们通过平局角度来计算小车应该转动的方向。而角度应该可以使用极坐标来转换。

转换为极坐标是一个简单的两部过程:

def to_polar_coords(xpix, ypix):# 第一步: 计算距离 dist = np.sqrt(xpix**2 + ypix**2)# 第二步: 计算角度 angles = np.arctan2(ypix, xpix)return dist, angles

通过这个函数我们可以轻易的将直角坐标系转换成极坐标系,从而方便我们计算平均角度。

(二)相关程序

程序在原来项目上进行了更改,为了在matplotlib中输出一个4格图像,我使用了matplotlib.image.imread()函数来取代cv2.imread()函数。但是我在实际使用中,使用cv2.imread()读取出来的图像在matplotlib中会有颜色的改变。具体原因我也不是很清楚。

相比之前的程序,我还更改了输出部分的程序,将输出世界地图的程序删除了,添加了输出转向角度的代码。在定义函数上,为了方便以后使用,没有进行更改。

下面是示例程序

import matplotlib.pyplot as plt
import numpy as np
import cv2 as cv
import matplotlib.image as mpimg# 定义二值化图像函数
def color_thresh(img, thresh=160):img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)ret, img_thresh = cv.threshold(img_gray, thresh, 255, cv.THRESH_BINARY)return img_thresh# 定义图像映射函数,将摄像头的图像映射到平面坐标中去
def perspect_transform(img, src, dst):M = cv.getPerspectiveTransform(src, dst)  # 定义变换矩阵img_perspect = cv.warpPerspective(img, M, (img.shape[1], img.shape[0]))return img_perspect# 定义从图像坐标转换函数
def rover_coords(binary_img):ypos, xpos = binary_img.nonzero()x_pixel = -(ypos - binary_img.shape[0]).astype(np.float)y_pixel = -(xpos - binary_img.shape[1]/2 ).astype(np.float)return x_pixel, y_pixel# 定义旋转操作函数
def rotate_pix(xpix, ypix, yaw):yaw_rad = yaw * np.pi / 180xpix_rotated = (xpix * np.cos(yaw_rad)) - (ypix * np.sin(yaw_rad))ypix_rotated = (xpix * np.sin(yaw_rad)) + (ypix * np.cos(yaw_rad))return xpix_rotated, ypix_rotated# 定义平移操作函数
def translate_pix(xpix_rot, ypix_rot, xpos, ypos, scale):xpix_translated = (xpix_rot / scale) + xposypix_translated = (ypix_rot / scale) + yposreturn xpix_translated, ypix_translated# 定义综合函数,将旋转和平移函数进行结合,并限制了图像范围
def pix_to_world(xpix, ypix, xpos, ypos, yaw, world_size, scale):xpix_rot, ypix_rot = rotate_pix(xpix, ypix, yaw)xpix_tran, ypix_tran = translate_pix(xpix_rot, ypix_rot, xpos, ypos, scale)x_pix_world = np.clip(np.int_(xpix_tran), 0, world_size - 1)y_pix_world = np.clip(np.int_(ypix_tran), 0, world_size - 1)return x_pix_world, y_pix_world# 定义转换为极坐标函数
def to_polar_coords(xpix, ypix):dist = np.sqrt(xpix**2 + ypix ** 2)angles = np.arctan2(ypix, xpix)return dist, angles# Define the filename, read and plot the image
filename = '…/sample2.jpg'
image = mpimg.imread(filename)# 随机生成漫游者坐标和角度
rover_yaw = np.random.random(1)*360
rover_xpos = np.random.random(1)*160 + 20
rover_ypos = np.random.random(1)*160 + 20# 函数参数定义部分
# 映射的图片的一半边长
dst_size = 5
# 映射的点距离x轴的距离
bottom_offset = 0
# 将图像二值化
image_thresh = color_thresh(image)
# 定义原图像空间坐标和映射图像空间坐标
src = np.float32([[14, 140], [301, 140], [200, 96], [118, 96]])
dst = np.float32([[image.shape[1]/2 - dst_size, image.shape[0] - bottom_offset],[image.shape[1]/2 + dst_size, image.shape[0] - bottom_offset],[image.shape[1]/2 + dst_size, image.shape[0] - 2*dst_size - bottom_offset],[image.shape[1]/2 - dst_size, image.shape[0] - 2*dst_size - bottom_offset],])
# 映射图像
image_prespect = perspect_transform(image_thresh, src, dst)
# 在二值化图像寻找非零点
xpix, ypix = rover_coords(image_prespect)# 计算平局角度
dist, angles = to_polar_coords(xpix, ypix)
avg_angle = np.mean(angles)
avg_angle_degrees = avg_angle*180/np.pi
steering = np.clip(avg_angle_degrees, -15, 15)
print(steering)warped = perspect_transform(image, src, dst)
colorsel = color_thresh(image)
# 输出部分
fig = plt.figure(figsize=(12,9))
plt.subplot(221)
plt.imshow(image)
plt.subplot(222)
plt.imshow(warped)
plt.subplot(223)
plt.imshow(colorsel, cmap='gray')
plt.subplot(224)
plt.plot(xpix, ypix, '.')
plt.ylim(-160, 160)
plt.xlim(0, 160)
arrow_length = 100
x_arrow = arrow_length * np.cos(avg_angle)
y_arrow = arrow_length * np.sin(avg_angle)
plt.arrow(0, 0, x_arrow, y_arrow, color='red', zorder=2, head_width=10, width=2)
plt.show()
cv.imshow('image_prespect', image_prespect)
cv.imshow('thresh', image_thresh)
cv.waitKey()

下面是matplotlib的输出。可以看到程序正确输出了相应的方向。

在这里插入图片描述

更多相关:

  • 教程简介 OpenCV 是计算机视觉中经典的专用库,然而其中文版官方教程久久不来。近日,一款最新 OpenCV4.1 版本的完整中文版官方教程出炉,读者朋友可以更好的学习了解 OpenCV 相关细节。教程来自 objectdetection.cn 。 教程目录 OpenCV 简介 0_OpenCV-Python Tutorials O...

  • 公众号致力于分享点云处理,SLAM,三维视觉,高精地图相关的文章与技术,欢迎各位加入我们,一起每交流一起进步,有兴趣的可联系微信:920177957。本文来自点云PCL博主的分享,未经作者允许请勿转载,欢迎各位同学积极分享和交流。IPM模型在解释自适应的IPM模型之前,首先需要了解使用相机的物理参数来描述IPM的基本模型[1](这篇...

  • 公众号致力于分享点云处理,SLAM,三维视觉,高精地图相关的文章与技术,欢迎各位加入我们,一起每交流一起进步,有兴趣的可联系微信:920177957。本文来自点云PCL博主的分享,未经作者允许请勿转载,欢迎各位同学积极分享和交流。前言前段时间刚分享的AVP-SLAM文章中有一个知识点叫做IPM(逆透视变换)AVP-SLAM:自动泊车...

  • 标题:The algorithm to generate color point-cloud with the registration between panoramic imageand laser point-cloud作者:Fanyang ZENG, Ruofei ZHONG 编译:点云PCL来源: https://iops...

  • 目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基于不同视点的多幅深度图像的配准技术,基于深度数据的三维重建技术,基于三维深度图像的三维目标识别技术,深度图像的多分辨率建模和几何压缩技术...