在这个部分我们要整体的测试我们的程序,对前面的知识和内容有一个整体的应用和概括。
这是Udacity提供的相应资料,在code文件夹中有一个Rover_Project_Test_Notebook.ipynb文件,提供了输出视频的笔记本文件。
由于个人喜好的原因,我选择了pycharm2019来运行此程序。
在这个部分我们需要完成的项目如下
首先我们需要获取ffmpeg工具
import imageioimageio.plugins.ffmpeg.download()
运行此程序以下载ffmpeg工具。
但我在运行这个程序时遇到了一个问题。
报错
imageio.ffmpeg.download() has been deprecated. Use 'pip install imageio-ffmpeg' instead.'‘
经查阅,该错误是由版本更新引起的错误,解决办法(在Windows上)为
pip install imageio==2.4.1
现在再一次运行我们的程序,如果imageio正确安装且电脑中没有安装ffmpeg,程序会自动下载安装
import imageioimageio.plugins.ffmpeg.download()
python会自动下载ffmpeg,如果下载不成功或者速度太慢可以选择到相应网站下载,单击这里进行下载。
ffmpeg应当放到AppData目录下。
我们定义一个名为 Databucket() 类来存储测量数据、图像路径和图像。
当我们实例化这个类时,我们将得到一个名为 data 的全局变量,我们将在之后的 process_image() 函数中来引用其中的数据。
其程序如下:
import pandas as pd
df = pd.read_csv('.../Roversim/Roverdata/robot_log.csv', delimiter=';', decimal='.')
csv_img_list = df["Path"].tolist()
# 读入世界地图并使用它创建一个3通道的图像
ground_truth = mpimg.imread('.../RoboND-Rover-Project-master/calibration_images/map_bw.png')
ground_truth_3d = np.dstack((ground_truth*0, ground_truth*255, ground_truth*0)).astype(np.float)# 创建一个类作为Databucket,读取csv文件中保存的数据并填充此对象。
# worldmap被实例化为200*200个网格,其对应200m*200m的空间。
class Databucket():def __init__(self):self.images = csv_img_list self.xpos = df["X_Position"].valuesself.ypos = df["Y_Position"].valuesself.yaw = df["Yaw"].valuesself.count = 0 # 运行索引self.worldmap = np.zeros((200, 200, 3)).astype(np.float)self.ground_truth = ground_truth_3d # Ground truth worldmap# 实例化一个databucket,这将是一个全局变量,
# 我们可以在接下来的process_image()函数中使用
data = Databucket()
编写process_image()函数,以执行图像分析和映射。我们只需要把对应漫游者号的位置等映射到worldmap上去就可以。
在之前的程序中,我们小车的位置和偏转角是随机生成的,但是这里就需要我们来读取csv文件中的数据,将相应的透视变换之后的图像映射到世界地图上去。
换句话说, 我们将各个图像传递到 process_image() 函数并以此来构建一个名为 output_image 的图像,该图像将存储为视频的一帧。
下面是经过更改后的 process_image() 函数:
# 定义图片处理函数
def process_image(img):output_image = np.zeros((img.shape[0] + data.worldmap.shape[0],img.shape[1] * 2, 3))# 定义第一张图为imgoutput_image[0:img.shape[0], 0:img.shape[1]] = img# 定义第二张图为img经过透视变换后的图像warped = perspect_transform(img, src, dst)output_image[0:img.shape[0], img.shape[1]:] = warpedgray_warped = cv2.cvtColor(warped, cv2.COLOR_RGB2GRAY)ret, img_thresh = cv2.threshold(gray_warped, 160, 255, cv2.THRESH_BINARY)test_image = np.expand_dims(img_thresh, axis=2)output_image[180:340, img.shape[1]:, 0] = img_threshxpix, ypix = rover_coords(img_thresh)worldmap = data.worldmapx_world, y_world = pix_to_world(xpix, ypix, data.xpos[data.count], data.ypos[data.count], data.yaw[data.count],data.worldmap.shape[0], 20 )worldmap[y_world, x_world] += 1map_add = cv2.addWeighted(ground_truth_3d, 1, worldmap, 0.2, 0)output_image[img.shape[0]:, 0:data.worldmap.shape[1]] = map_addcv2.putText(output_image, "Test!", (20, 20),cv2.FONT_HERSHEY_COMPLEX, 0.4, (255, 255, 255), 1)# 跟踪Databucket中的索引if data.count < len(data.images) - 1:data.count += 1return output_image
此函数是为了使两个图像叠加使用的,用在我们将小车的透视变换后的图像映射到世界地图上。
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
参数说明:
此函数可以用一下矩阵表达式来代替:
dst = src1 * alpha + src2 * beta + gamma;
因为我们要对特定的颜色进行图像颜色阈值处理,比如之后选择特定的黄色的岩石样本,所以我图像二值化选择使用numpy来完成而不是cv2。其程序如下:
def color_thresh(img, rgb_thresh=(160, 160, 160)):color_select = np.zeros_like(img[:,:,0])above_thresh = (img[:,:,0] > rgb_thresh[0]) & (img[:,:,1] > rgb_thresh[1]) & (img[:,:,2] > rgb_thresh[2])color_select[above_thresh] = 1return color_selectthreshed = color_thresh(warped)
plt.imshow(threshed, cmap='gray')
以下是最终程序
import numpy as np
import cv2
import pandas as pd
import matplotlib.image as mpimg
from moviepy.editor import VideoFileClip
from moviepy.editor import ImageSequenceClip##颜色阈值
# 使用Numpy定义二值化图像函数
def color_thresh(img, rgb_thresh=(160, 160, 160)):img_thresh = np.zeros_like(img[:, :, 0])above_thresh = (img[:, :, 0] > rgb_thresh[0]) & (img[:, :, 1] > rgb_thresh[1]) & (img[:, :, 2] > rgb_thresh[2])img_thresh[above_thresh] = 1return img_thresh##透视变换
# 定义图像映射函数,将摄像头的图像映射到平面坐标中去
def perspect_transform(img, src, dst):M = cv2.getPerspectiveTransform(src, dst) # 定义变换矩阵img_perspect = cv2.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# 参考图像,用作透视变换
filename = '.../RoboND-Rover-Project-master/calibration_images/example_grid1.jpg'
image = cv2.imread(filename)dst_size = 5
bottom_offset = 0src = 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
我觉得你的时间安排得很慢。也许你的安装出了问题?在我试过这个测试程序:#!/usr/bin/python3import sysimport numpy as npimport cv2from PIL import Imagefrom profilehooks import profile@profiledef try_numpy(im...
/*默认加载图片*/ .class-name { /*背景图片*/background: url(../../img/banner/banner-default.jpg) no-repeat center bottom;width: 100%;height: 861px; } .class-name:after { /*默认加载背景图...
函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界。 cv2.boundingRect(array) -> retval 参数: array - 灰度图像(gray-scale image)或 2D点集( 2D point s...
首先贴上代码原作者的github:https://github.com/chenyuntc/simple-faster-rcnn-pytorch(非代码作者,博文只解释代码) 今天看完了simple-faster-rcnn-pytorch-master代码的最后一个train.py文件,是时候认真的总结一下了,我打算一共总结四篇博客用...
#include
# 调整图像亮度input_image = cv2.cvtColor(input_image , cv2.COLOR_BGR2HSV)input_image [:, :, 2] = scale_value * input_image [:, :, 2]input_image [:, :, 2][input_image [:, :, 2...
area_center_gray ( Regions, Image : : : Area, Row, Column ) 计算Image图像中Region区域的面积Area和重心(Row,Column)。 cooc_feature_image ( Regions, Image : : LdGray, Direction : En...
1、显示一幅二值图像: >> bw = zeros(90,90); >> bw(2:2:88,2:2:88) = 1; >> imshow(bw); >> 2、利用image函数显示一幅索引图像: >> [X,MAP] = imread('E:STUDY_softwareMatlab2016images11.jp...
iOS 相册和网络图片的存取 保存 UIImage 到相册 UIKit UIKit 中一个古老的方法,Objective-C 的形式 void UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void...
教程简介 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...
目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基于不同视点的多幅深度图像的配准技术,基于深度数据的三维重建技术,基于三维深度图像的三维目标识别技术,深度图像的多分辨率建模和几何压缩技术...