道路检测(python代码)
这段代码的主要流程涉及车道线检测模型的训练、加载和在视频上应用检测结果。以下是主要流程的简要概述:
-
导入库和组件:导入所需的库,包括NumPy、scikit-learn和Keras等。
-
定义模型结构:定义了一个卷积神经网络(CNN)模型的结构。模型采用卷积层、池化层、上采样层和反卷积层等来实现车道线检测。
-
加载训练数据:加载训练数据和标签数据,并进行数据预处理。将数据转换为NumPy数组,并对标签进行归一化。
-
构建和编译模型:使用定义的模型结构来构建CNN模型。使用ImageDataGenerator进行数据增强,然后编译模型,指定优化器和损失函数。
-
训练模型:使用生成器训练模型,其中数据流通过数据增强生成的批次。指定训练的回合数和批大小,对模型进行训练。
-
保存模型:冻结模型的层并重新编译,然后将模型结构和权重保存到文件中。
-
加载和使用模型:加载之前保存的模型文件。在视频中逐帧读取图像,将其传递给模型进行检测,并在原始图像上叠加检测结果。
-
视频处理循环:循环读取视频的每一帧,将其调整为模型所需的输入大小,进行模型推理,计算平均预测结果,并将检测结果叠加在原始图像上。
-
退出:通过按下"q"键来退出视频处理循环,并释放资源。
这段代码主要是针对车道线检测模型的训练和应用,通过使用CNN模型,可以实现在视频上检测并绘制车道线的功能。
2.代码
#!/usr/bin/env python
# coding: utf-8# # 实验:车道线检测
#实验过程
# 模型训练
# 首先导入需要的组件包,Numpy、keras、sklearn等,代码如下:
import numpy as np
import pickle
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
# Import necessary items from Keras
from keras.models import Sequential
from keras.layers import Activation, Dropout, UpSampling2D
from keras.layers import Conv2DTranspose, Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.preprocessing.image import ImageDataGenerator
from keras import regularizers
# 模型结构定义
# 网络输入层为80 x 160 x 3(RGB)形状的道路图像,标签为80 x 160 x 1,只有G通道重新绘制车道,实现代码如下:
def create_model(input_shape, pool_size):# 创建网络模型model = Sequential()# 对输入层进行归一化处理model.add(BatchNormalization(input_shape=input_shape))# 卷积层1,名为Conv1model.add(Conv2D(8, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv1'))# 卷积层2model.add(Conv2D(16, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv2'))# 最大化层model.add(MaxPooling2D(pool_size=pool_size))# 卷积层3model.add(Conv2D(16, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv3'))model.add(Dropout(0.2))# 卷积层4model.add(Conv2D(32, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv4'))model.add(Dropout(0.2))# 卷积层5model.add(Conv2D(32, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv5'))model.add(Dropout(0.2))# 最大化层2model.add(MaxPooling2D(pool_size=pool_size))# 卷积层6model.add(Conv2D(64, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv6'))model.add(Dropout(0.2))# 卷积层7model.add(Conv2D(64, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Conv7'))model.add(Dropout(0.2))# 最大化层3model.add(MaxPooling2D(pool_size=pool_size))# 上采样层1model.add(UpSampling2D(size=pool_size))# 反卷积层 1model.add(Conv2DTranspose(64, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv1'))model.add(Dropout(0.2))# 反卷积层 2model.add(Conv2DTranspose(64, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv2'))model.add(Dropout(0.2))# 上采样层 2model.add(UpSampling2D(size=pool_size))# 反卷积层 3model.add(Conv2DTranspose(32, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv3'))model.add(Dropout(0.2))# 反卷积层 4model.add(Conv2DTranspose(32, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv4'))model.add(Dropout(0.2))# 反卷积层 5model.add(Conv2DTranspose(16, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv5'))model.add(Dropout(0.2))# 上采样层 3model.add(UpSampling2D(size=pool_size))# 反卷积层 6model.add(Conv2DTranspose(16, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Deconv6'))# 输出层model.add(Conv2DTranspose(1, (3, 3), padding='valid', strides=(1,1), activation = 'relu', name = 'Final'))return model#加载数据# 加载训练数据
train_images = pickle.load(open("full_CNN_train.p", "rb" ))
# 加载标签数据
labels = pickle.load(open("full_CNN_labels.p", "rb" ))
# 对数据进行预处理
train_images = np.array(train_images)
labels = np.array(labels)
# 对标签进行归一化处理
labels = labels / 255
# 混淆数据
train_images, labels = shuffle(train_images, labels)
# 划分训练集和测试集
X_train, X_val, y_train, y_val = train_test_split(train_images, labels, test_size=0.1)
print("loaded train samples:", len(train_images))#构建并编译模型
# 定义超参
#批大小
batch_size = 128
#训练回合数
epochs = 10
#池化大小
pool_size = (2, 2)
#输入大小
input_shape = X_train.shape[1:]
# 构建模型
model = create_model(input_shape, pool_size)
# 构建数据生成器实现通道增强
datagen = ImageDataGenerator(channel_shift_range=0.2)
datagen.fit(X_train)
# 编译模型
model.compile(optimizer='Adam', loss='mean_squared_error')
# 可视化模型
model.summary()#训练模型
model.fit_generator(datagen.flow(X_train, y_train, batch_size=batch_size), steps_per_epoch=len(X_train)/batch_size,
epochs=epochs, verbose=1, validation_data=(X_val, y_val))
# #### 5)保存模型
# Freeze layers since training is done
model.trainable = False
model.compile(optimizer='Adam', loss='mean_squared_error')
# Save model architecture and weights
model.save('full_CNN_model_tiny.h5')
#加载并使用模型
#加载Python相关组件
import numpy
import numpy as np
import cv2
from PIL.Image import Image
from keras.models import load_model
from IPython.display import clear_output, Image, display, HTML#定义工具类
# 道路线类
class Lanes():def __init__(self):self.recent_fit = []self.avg_fit = []
#图像显示方法
def arrayShow(imageArray):ret, jpg = cv2.imencode('.jpg', imageArray)return Image(jpg)#加载检测模型
# 加载模型
model = load_model('full_CNN_model.h5')
# 读取视频文件和输出检测结果
# 读取input目录下的demo.mp4文件,逐帧读取并交给模型进行检测和识别,然后对检测结果计算其均值,并将检测结果绘制输出。#读取视频文件
vs = cv2.VideoCapture("input/demo1.mp4")
frameIndex = 0
lanes = Lanes()
#循环读取
while True:#读取视频帧(grabbed, frame_source) = vs.read()if not grabbed:break #将视频帧resize为模型的输入大小frame_show = cv2.resize(frame_source, (576, 288))frame = cv2.resize(frame_show, (160, 80))rgb_small_frame = frame[None,:,:,:]# 模型推理检测prediction = model.predict(rgb_small_frame)[0] * 255# 储存预测结果到列表中lanes.recent_fit.append(prediction)# 只使用最近的数据if len(lanes.recent_fit) > 5:lanes.recent_fit = lanes.recent_fit[1:]# 计算平均预测结果lanes.avg_fit = np.mean(np.array([i for i in lanes.recent_fit]), axis = 0)# Generate fake R & B color dimensions, stack with Gblanks = np.zeros_like(lanes.avg_fit).astype(np.uint8)lane_drawn = np.dstack((blanks, lanes.avg_fit, blanks)) #恢复成原始视频大小lane_image = cv2.resize(lane_drawn, (576, 288))#合并原始图像和检测结果img = cv2.addWeighted(frame_show, 0.3, lane_image, 0.7, 0,dtype = cv2.CV_32F) # 清空绘图空间clear_output(wait=True) # 显示处理结果display(arrayShow(img))#按键盘中的q键退出检测if cv2.waitKey(1) & 0xFF == ord('q'):break
# 释放资源
print("[INFO] cleaning up...")
vs.release()
cv2.destroyAllWindows()
3.视频在我的主页有,只需要放在对应的路径,就可以运行程序
demo-CSDN直播
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
