Unity模拟自动驾驶方向盘角度预测
Unity模拟器是一款模拟汽车行驶的赛车游戏。这个模拟器是一个可以收集游戏中数据图片,以及游戏中你控制赛车的角度。
1数据介绍
游戏中模拟了赛车上安装左中右三个摄像头,数据就是这些摄像头截取的画面。
模拟器关于方向盘的角度只有中间摄像头对应的转动角度。
实现
1对图像进行水平翻 有扩充数据的效果
def horizontal_filp(img, degree): ''' :param img: :param degree: :return: cv2.flip 值为1代表水平翻转 翻转之后角度正负变反 ''' choice = np.random.choice([0,1]) if choice == 1: img, degree = cv2.flip(img, 1), -degree return (img, degree)
2随机调成图片的亮度
def randonm_brightness(img, degree): ''' 随机调整输入图像的亮度 调整强度于 0.1(变黑)和1(无变化)之间 :param img: :param degree: :return: ''' hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #调整亮度V: alpha×V alpha = np.random.uniform(low=0.1, high=1, size=None) v = hsv[:, :, 2] v = v * alpha hsv[:, :, 2] = v.astype('uint8') rgb = cv2.cvtColor(hsv.astype('uint8'), cv2.COLOR_HSV2RGB) return (rgb, degree)
3左右摄像头角度的转换
def left_right_random_swap(img_address, degree, degree_corr=1.0/4): ''' 随机从左, 中, 右图像中选择一张图像, 并相应的调整转动的角度。 :param img_address: 中间图像的文件路径 :param degree: 中间图像对于方向盘转动角度 :param degree_corr: 左中右关系的值 :return: ''' swap = np.random.choice(['L', 'R', 'C']) if swap == 'L': img_address = img_address.replace('center', 'left') corrected_label = np.arctan(math.tan(degree)+degree_corr) return (img_address, corrected_label) elif swap == 'R': img_address = img_address.replace('center', 'right') corrected_label = np.arctan(math.tan(degree) - degree_corr) return (img_address, corrected_label) else: return (img_address, degree)
4数据平衡 以一定概率丢弃角度为0的图片
def discard_zero_steering(degrees, rate): ''' 以一定概率丢弃转动角度为0的数据 :param degrees: 转动角度的list :param rate: 丢弃系数 若 = 0.8 则80%保丢 :return: ''' steering_zero_idx = np.where(degrees == 0) steering_zero_idx = steering_zero_idx[0] size_del = int(len(steering_zero_idx)*rate) return np.random.choice(steering_zero_idx, size=size_del, replace=False)
5网络结构的实现
def get_model(shape): ''' 预测方向盘角度: 以图像为输入, 预测方向盘的转动角度 shape: 输入图像的尺寸, 例如(128, 128, 3) ''' model = Sequential() model.add(Conv2D(8, (5, 5), strides=(1, 1), padding="valid", activation='relu', input_shape=shape)) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Dropout(0.5)) model.add(Conv2D(16, (4, 4), strides=(1, 1), padding="valid", activation='relu', kernel_regularizer=l2(0.01), activity_regularizer=l1(0.01))) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Conv2D(16, (4, 4), strides=(1, 1), padding="valid", activation='relu', kernel_regularizer=l2(0.01), activity_regularizer=l1(0.01))) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Conv2D(16, (5, 5), strides=(1, 1), padding="valid", activation='relu', kernel_regularizer=l2(0.01), activity_regularizer=l1(0.01))) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(50, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(10, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1, activation='linear')) sgd = SGD(lr=0.01) adm=Adamax(lr=0.02, beta_1=0.9, beta_2=0.999) model.compile(optimizer=sgd, loss='mean_squared_error') return model
6截取了图片的部分图片并对我们的图片进行归一化操作
X[example,:,:,:] = cv2.resize(img[80:140, 0:320], (shape[0], shape[1]) ) / 255 - 0.5
7训练结果