第一阶段总结
提示:主要涉及梳理每节课的思路和总结python的用法
文章目录
前言
在学习的过程中遇到和很多函数,并不晓得如何使用,查资料当时了解了,后续又忘记了,所以把学过的从头记录下,以备查看。
一、课程开发工具
第一阶段课程主要使用的语言是Python,故需要对Python编程环境进行配置
软件安装采用 Anaconda 和Pycharm
提示:Anaconda自带 Jupyter Notebooks, 所以课程里的例子可用Jupyter Notebooks打开
Anaconda负责配置python的库,Python和Jupyter是可视化界面,用于编程
首先安装Anaconda,参照教程,注意课程里用的比较老的Python3.6以下,tensonflow1.xx版本,所以配置的时候注意版本的选择,Anaconda的版本很多都没有,需要自己pip安装软件,安装方式是打开Anaconda的prompt,然后activate相应的配置,在进行pip install XXX==x.x.x(XXX是软件,x.x.x是版本)
此处附上常见的版本
python3.6之sklearn 的安装
numpy-1.16.0
pillow-5.0.0
scipy-1.1.0
scikit_learn-0.19.1
matplotlib-2.2.2
imgaug-0.2.7
tensorflow-1.14
Keras2.2.5
bleach-3.3.0
flask-1.1.2
pandas-1.0.5
moviopy-1.0.0
为了方便起见,添加Anaconda的prompt和Jupyter到右键菜单,不用每次重新敲命令,参考将 Anaconda Prompt 加入右键菜单,最后需要修改 \“title Anaconda3\” 为"title Anaconda3"
打开Jupyter切换核的时候,可以参考在jupyter notebook导入tensorflow出错:No module named tensorflow 解决办法,从而切换成自己的配置的环境;出现安装Shapely:OSError:[WinError 126]找不到指定的模块,参考here的答复,亲测有用,直接pip安装的shapely缺少一个geos.dll文件,在这个网址可以找到对应python版本的shapely库, 还有后续的一个软件安装问题,就是自动驾驶交互界面不能自动驾驶,原因是通讯的socketio版本不一致,参考here
pip install Flask-SocketIO==4.3.1
pip install python-engineio==3.13.2
pip install python-socketio==4.6.0
二、python函数
1.sess.run()
当构建完图后,需要在一个session会话中启动图,第一步是创建一个Session对象。
为了取回(Fetch)操作的输出内容, 可以在使用 Session 对象的 run()调用执行图时,传入一些 tensor, 这些 tensor 会帮助你取回结果。
在python语言中,返回的tensor是numpy ndarray对象
用sess.run()有两种情况:
(1)想要获取某个变量的时候:
(2)执行某种操作的时候,这个操作不是一个变量,没有值,如下图n这个更新操作,还包括神经网络训练的时候的optimizer:
函数说明
2.NumPy(axis=0 与axis=1)区分
其实问题理解axis有问题,df.mean其实是在每一行上取所有列的均值,而不是保留每一列的均值。也许简单的来记就是axis=0代表往跨行(down),而axis=1代表跨列(across),作为方法动作的副词(译者注)
换句话说:
• 使用0值表示沿着每一列或行标签\索引值向下执行方法
• 使用1值表示沿着每一行或者列标签模向执行对应的方法
下图代表在DataFrame当中axis为0和1时分别代表的含义:
a.sum()是算a中每一元素之和
a.sum(axis=0)是计算a中每一列元素之和 ,提示:就是按照axis=0 的方向做加法
a.sum(axis=1)是计算a中每一行元素之和
函数说明
3.tf.matmul() 和tf.multiply()区分
1.tf.multiply()两个矩阵中对应元素各自相乘
2.tf.matmul()将矩阵a乘以矩阵b,生成a * b
函数说明
4.tf.truncated_normal()
释义:截断的产生正态分布的随机数,即随机数与均值的差值若大于两倍的标准差,则重新生成。
• shape,生成张量的维度
• mean,均值
• stddev,标准差
函数说明
5.tf.placeholder()
Tensorflow的设计理念称之为计算流图,在编写程序时,首先构筑整个系统的graph,代码并不会直接生效,这一点和python的其他数值计算库(如Numpy等)不同,graph为静态的,类似于docker中的镜像。然后,在实际的运行时,启动一个session,程序才会真正的运行。这样做的好处就是:避免反复地切换底层程序实际运行的上下文,tensorflow帮你优化整个系统的代码。我们知道,很多python程序的底层为C语言或者其他语言,执行一行脚本,就要切换一次,是有成本的,tensorflow通过计算流图的方式,帮你优化整个session需要执行的代码,还是很有优势的。
所以placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
函数说明
6.np.argmax()
取出元素最大值所对应的索引,返回的是最大值对应的索引,并非最大值
函数说明
项目一:
1.区分出蓝色和白色
2.转变成灰度图像
3.高斯滤波:光滑边缘,减少噪声
4.边缘检测
5.感兴趣的区域
6.霍夫变换
项目二:
主要就是设置深度神经网络各层的参数
项目三:
1.相机标定,获得真实和图像中点的对应关系ret, corners = cv2.findChessboardCorners()
2.矫正畸变,ret, mtx, dist, rvecs, tvecs =cv2.calibrateCamera()标定出摄像机矩阵,畸变参数。旋转和平移向量等,dst = cv2.undistort(img, mtx, dist, None, mtx) 矫正畸变
3.通过颜色,梯度等选择图片中的特征(道路线):颜色阈值(黄色和白色),梯度阈值(X,Y,XY),方向梯度(dir)。利用多种进行合并生成combined
4.视角变换:提取路线的梯形图,变换成矩形特征的道路图
5.通过计算y方向的和,找出道路线的中心点,然后在窗口中不断迭代,找出全部的点二阶拟合np.polyfit(lefty, leftx, 2)
6.画出拓宽的道路线和道路绿色区域
7.结合视频处理
# ffmpeg 负责提取视频0-4之间的图片,利用一个detector作实时监测,此处主要问题是如何把全局参数穿进去
# 所以建立AdvancedLaneDetectorWithMemory的类
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
ffmpeg_extract_subclip(challenge_video_path, 0, 4, targetname=challenge_video_path)
detector = AdvancedLaneDetectorWithMemory(opts, ipts, src_pts, dst_pts, 20, 100, 10)
clip1 = VideoFileClip(challenge_video_sample_path)
challenge_video_clip = clip1.fl_image(detector.process_image) # NOTE: this function expects color images!!
challenge_video_clip.write_videofile(challenge_video_sample_output_path, audio=False)
项目四:
1.特征提取:rsize简化图片->(手动)颜色,方向梯度,提取的一张图片的所有特征,作为一个vector,然后对所有图片垂直排列
2.分类器:总共三种分类器,都可以尝试:获得图片,提取特征后->打乱图片-> z = (x - u) / s数据标准化
X_scaler = StandardScaler().fit(X_train)
Apply the scaler to XX_train = X_scaler.transform(X_train)
训练分类器
3.滑动窗口:对每张图片利用滑动窗口,提取窗口特征,然后用训练的分类器进行预测(识别),预测=1就记录下来
4.最后将窗口显示出来
以下程序不可直接运行
第二章
此程序不可直接运行
读入图片,选择颜色
mpimg.imread('test.jpg')
ysize = image.shape[0]
xsize = image.shape[1]
color_select = np.copy(image)
thresholds = (image[:,:,0] < rgb_threshold[0]) \
| (image[:,:,1] < rgb_threshold[1]) \ 对于X[:,:,1]是取三维矩阵中第一维的所有数据
| (image[:,:,2] < rgb_threshold[2])
color_select[thresholds] = [0,0,0]
画三角形
fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
(YY > (XX*fit_right[0] + fit_right[1])) & \
(YY < (XX*fit_bottom[0] + fit_bottom[1]))
先转成灰度图
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) #grayscale conversion
先进行高斯滤波
kernel_size = 3 # Must be an odd number (3, 5, 7...)
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
然后边缘检测
edges = cv2.Canny(gray, low_threshold, high_threshold) [参考文档](https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html)
取出要拟合的点
cv2.fillPoly(mask, vertices, ignore_mask_color) # vertices被画到mask上,颜色为ignore_mask_color
masked_edges = cv2.bitwise_and(edges, mask)
最后霍夫变换,找到拟合的路线
lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
np.dstack((edges, edges, edges))
# addWeighted 实际上也是加法,只不过是按比例混合起来,有不同的权重 ,给人一种混合的或者透明的感觉
lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0)
第三章
# and 逻辑运算
test_inputs = [(0, 0), (0, 1), (1, 0), (1, 1)]
correct_outputs = [False, False, False, True]
outputs = []
for test_input, correct_output in zip(test_inputs, correct_outputs):
linear_combination = weight1 * test_input[0] + weight2 * test_input[1] + bias
output = int(linear_combination >= 0)
is_correct_string = 'Yes' if output == correct_output else 'No'
outputs.append([test_input[0], test_input[1], linear_combination, output, is_correct_string])
# Print output 以列表形式 返回output[4] == 'No'时的output[4]
num_wrong = len([output[4] for output in outputs if output[4] == 'No'])
output_frame = pd.DataFrame(outputs, columns=['Input 1', ' Input 2', ' Linear Combination', ' Activation Output', ' Is Correct']) #利用panda的dataframe方便读写
# OR 改成这样
test_inputs = [(0, 0), (0, 1), (1, 0), (1, 1)]
correct_outputs = [True, False, True, False]
outputs = []
第四章
# miniflow 主要参数
import numpy as np
class Node:
def __init__(self, inbound_nodes=[]):
self.inbound_nodes = inbound_nodes
self.value = None
self.outbound_nodes = []
self.gradients = {}
for node in inbound_nodes:
node.outbound_nodes.append(self
def forward(self):
raise NotImplementedError
def backward(self):
raise NotImplementedError
class Input(Node):
"""
A generic input into the network.
"""
def __init__(self):
Node.__init__(self)
def forward(self):
pass
def backward(self):
self.gradients = {self: 0}
for n in self.outbound_nodes:
self.gradients[self] += n.gradients[self]
class Linear(Node):
"""
Represents a node that performs a linear transform.
"""
def __init__(self, X, W, b):
Node.__init__(self, [X, W, b])
def forward(self):
X = self.inbound_nodes[0].value
W = self.inbound_nodes[1].value
b = self.inbound_nodes[2].value
self.value = np.dot(X, W) + b
def backward(self):
self.gradients = {n: np.zeros_like(n.value) for n in self.inbound_nodes}
for n in self.outbound_nodes:
grad_cost = n.gradients[self]
self.gradients[self.inbound_nodes[0]] += np.dot(grad_cost, self.inbound_nodes[1].value.T)
self.gradients[self.inbound_nodes[1]] += np.dot(self.inbound_nodes[0].value.T, grad_cost)
self.gradients[self.inbound_nodes[2]] += np.sum(grad_cost, axis=0, keepdims=False)
class Sigmoid(Node):
"""
Represents a node that performs the sigmoid activation function.
"""
def __init__(self, node):
Node.__init__(self, [node])
def _sigmoid(self, x):
return 1. / (1. + np.exp(-x))
def forward(self):
input_value = self.inbound_nodes[0].value
self.value = self._sigmoid(input_value)
def backward(self):
self.gradients = {n: np.zeros_like(n.value) for n in self.inbound_nodes}
for n in self.outbound_nodes:
grad_cost = n.gradients[self]
sigmoid = self.value
self.gradients[self.inbound_nodes[0]] += sigmoid * (1 - sigmoid) * grad_cost
class MSE(Node):
def __init__(self, y, a):
"""
The mean squared error cost function.
Should be used as the last node for a network.
"""
Node.__init__(self, [y, a])
def forward(self):
y = self.inbound_nodes[0].value.reshape(-1, 1)
a = self.inbound_nodes[1].value.reshape(-1, 1)
self.m = self.inbound_nodes[0].value.shape[0]
self.diff = y - a
self.value = np.mean(self.diff**2)
def backward(self):
self.gradients[self.inbound_nodes[0]] = (2 / self.m) * self.diff
self.gradients[self.inbound_nodes[1]] = (-2 / self.m) * self.diff
def forward_and_backward(graph):
"""
Performs a forward pass and a backward pass through a list of sorted Nodes.
Arguments: `graph`: The result of calling `topological_sort`.
"""
for n in graph:
n.forward()
for n in graph[::-1]:
n.backward()
def sgd_update(trainables, learning_rate=1e-2):
"""
Updates the value of each trainable with SGD Arguments:
`trainables`: A list of `Input` Nodes representing weights/biases.
`learning_rate`: The learning rate.
"""
for t in trainables:
partial = t.gradients[t]
t.value -= learning_rate * partial
第五章
read_data_sets('', one_hot=True) # 热键标签,每个只用一个1,其余为0表示
astype(np.float32) #转换类型
tf.compat.v1.placeholder() # 预先定义个参数
tf.Variable() #TF2.0赋值方法
logits = tf.add(tf.matmul(features, weights), bias) #矩阵乘
cost = tf.reduce_mean() #张量的平均值
optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost) # minimize() 函数处理了梯度计算和参数更新两个操作
tf.equal()
tf.argmax()
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.compat.v1.Session() as sess:
sess.run(init)
for batch_features, batch_labels in batches(batch_size, train_features, train_labels):
sess.run(optimizer, feed_dict={features: batch_features, labels: batch_labels})
test_accuracy = sess.run( accuracy,feed_dict={features: test_features, labels: test_labels})
print('Test Accuracy: {}'.format(test_accuracy))
第六章
with ZipFile(file) as zipf: # 不用手动关闭文件。当执行完内容后,自动关闭文件。
filenames_pbar = tqdm(zipf.namelist(), unit='files') # 可以用ZipFile.namelist()返回整个压缩文件的名字列表,然后逐个解压,返回进度条
if not filename.endswith('/'): # 判断文件名是否以/ 结束,如果不是则继续
with zipf.open(filename) as image_file: # 打开一个文件
image = Image.open(image_file) # 图片读取
feature = np.array().flatten() # 先变成矩阵 然后降成一位维
label = os.path.split(filename)[1][0] # 按照路径符将文件名和路径分隔开
encoder.fit(train_labels) # 将lebals标签二值化
train_labels = encoder.transform(train_labels) # :在Fit的基础上,进行标准化,降维,归一化等操作
train_test_split(
train_features,
train_labels,
test_size=0.05, # 若为浮点时,表示测试集占总样本的百分比
random_state=832289) # 若为整数时,每次生成的数据都相同
assert features._op.name.startswith('Placeholder'), 'features must be a placeholder' # 检查特征是否以placeholder开头
assert labels._op.name.startswith('Placeholder'), 'labels must be a placeholder' # 检查特征是否以placeholder开头
assert isinstance(weights, Variable), 'weights must be a TensorFlow variable' # isinstance() 用于判断一个对象是不是指定的类型
cross_entropy = -tf.reduce_sum(labels * tf.math.log(prediction), axis=1) # 把 axis=1 对应的维度压缩掉,降维
loss = tf.reduce_mean(cross_entropy) # 求解降维后的平均值
assert not np.count_nonzero(biases_data), 'biases must be zeros' # 计算非0元素个数,及全非0
math.ceil(len(train_features) / batch_size)) # “向上取整” math.floor 向下取整 math.around四舍五入
batches[-1] # batches[-1]数组最后一位
acc_plot.set_ylim([0, 1.0]) # y轴范围
acc_plot.set_xlim([batches[0], batches[-1]]) # x轴范围
第七章
np.pad(X_validation, ((0, 0), (2, 2), (2, 2), (0, 0)), 'constant') # 首尾各增加两行和两列0(28+2+2 = 32)达到32*32的输入。
index = random.randint(0, len(X_train)) #返回参数1和参数2之间的任意整数
image = X_train[index].squeeze() #去掉单维度的条目,去掉空的[]外壳
X_train, y_train = shuffle(X_train, y_train) #打乱次序
conv1 = tf.nn.conv2d(x, conv1_W, strides=[1, 1, 1, 1], padding='VALID') + conv1_b
# 卷积 matmul用于灰度图片 一维图片 x:input;conv1_W: filter,卷积核,strides[1,height,weight,1] padding= valid不补0
conv1 = tf.nn.relu(conv1) #激活函数
conv1 = tf.nn.max_pool2d(conv1, ksize=[1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'VALID') #池化函数,取最大值
fc0 = tf.layers.flatten(conv2) #扁平化
one_hot_y = tf.one_hot(y, 10) #用一个特征值1表征不同的情况,只有一个热值
cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=one_hot_y, logits=logits) #:1.将logits按照公式转换成概率;2.计算交叉熵损失 结果为[0,0,1,0]lebal标签形式
loss_operation = tf.reduce_mean(cross_entropy) #计算平均数
optimizer = tf.train.AdamOptimizer(learning_rate = rate) #个名字来源于自适应矩估计(Adaptive Moment Estimation),也是梯度下降算法的一种变形。优点是稳定
tf.nn.top_k(tf.nn.softmax(self.logits), k=5, sorted=True, name=None) # 为了找到输入的张量的最后的一个维度的最大的k个值和它的下标!
第九章
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Flatten
from keras.layers.convolutional import Convolution2D
# TODO: Build Convolutional Neural Network in Keras Here
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(32, 32, 3))) #
# model.add(Convolution2D(64, 3, 3, border_mode='same', input_shape=(3, 256, 256)))
# 参数意思是 取64个3 * 3的卷积核,保留边界处的卷积结果(即输出shape和输入shape一样),对3 * 256 * 256的输入数据进行卷积。
model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2))) # stride 默认等于pool_size
model.add(Dropout(0.5)) # 使得一些神经网络节点失效,避免过拟合
model.add(Activation('relu')) # a ReLU activation layer
model.add(Flatten())
model.add(Dense(128)) # a fully connected layer
model.add(Activation('relu')) # a ReLU activation layer
model.add(Dense(5))
model.add(Activation('softmax'))
# Preprocess data
X_normalized = np.array(X_train / 255.0 - 0.5 )
from sklearn.preprocessing import LabelBinarizer
label_binarizer = LabelBinarizer()
y_one_hot = label_binarizer.fit_transform(y_train)
model.compile('adam', 'categorical_crossentropy', ['accuracy'])
history = model.fit(X_normalized, y_one_hot, nb_epoch=3, validation_split=0.2) #分割和shuffle的顺序不一致,导致每次结果不一致
第十章
# 迁移学习,用AlexNet网络
fc7 = AlexNet(resized, feature_extract=True) #倒数第二部停止
fc7 = tf.stop_gradient(fc7) #避免梯度函数反向传递
shape = (fc7.get_shape().as_list()[-1], nb_classes) # 最后一个代表其输出的维度 [?, 4096]
fc8W = tf.Variable(tf.truncated_normal(shape, stddev=1e-2))
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
loss_op = tf.reduce_mean(cross_entropy)
opt = tf.train.AdamOptimizer()
train_op = opt.minimize(loss_op, var_list=[fc8W, fc8b])
# 梯度更新fc8W和fc8b
# 1、Optimizer.minimize(loss, var_list)中,计算loss所涉及的变量(假设为var(loss)) 包含在var_list中,也就是var_list中含有多余的变量,并不影响程序的运行,而且优化过程中不改变var_list里多出变量的值;
# 2、若var_list中的变量个数少于var(loss),则优化过程中只会更新var_list中的那些变量的值,var(loss)里多出的变量值 并不会改变,相当于固定了网络的某一部分的参数值。
print("%s: %.3f" % (sign_names.loc[inds[-1 - i]][1], output[input_im_ind, inds[-1 - i]])) #ix 用loc替代,代表取出对应的index
第十二章
images = glob.glob('calibration_wide/GO*.jpg') # 返回所有匹配的文件路径列表 目录下的路径最为列表返回
for idx, fname in enumerate(images): # index 索引 fname 名称路径
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 变成灰度图
g = gray.shape[::-1] # 倒序排列
ret, corners = cv2.findChessboardCorners(gray, (8,6), None) # cornors 角点,找到标定的角点
cv2.drawChessboardCorners(img, (8,6), corners, ret) # 绘制角点
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size,None,None) # 它返回摄像机矩阵,畸变参数。旋转和平移向量等
# mtx:内参数矩阵
# dist:畸变系数 distortion cofficients =
# rvecs:旋转向量 # 外参数
# tvecs:平移向量 # 外参数
v2.imwrite('calibration_wide/test_undist.jpg',dst) # 保存图片
dist_pickle["dist"] = dist
pickle.dump( dist_pickle, open( "calibration_wide/wide_dist_pickle.p", "wb" ) ) # 写入.p文件
dist_pickle = pickle.load(open( "wide_dist_pickle.p", "rb" )) #读取p文件
objpoints = dist_pickle["objpoints"]
M = cv2.getPerspectiveTransform(src, dst) # 获得变换参数
Minv = cv2.getPerspectiveTransform(dst, src)
warped = cv2.warpPerspective(img, M, img_size,flags=cv2.INTER_LINEAR) 进行视角变换
src = np.float32([corners[0],corners[nx-1],corners[-1],corners[-nx]]).reshape(4,2) #reshape改变形状,不改变大小, resize 改变元素多少
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=sobel_kernel) #用来计算图像灰度的近似梯度,梯度越大越有可能是边缘。Soble算子的功能集合了高斯平滑和微分求导,又被称为一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到的是图像在X方法与Y方向梯度图像。缺点:比较敏感,容易受影响,要通过高斯模糊(平滑)来降噪
hls = cv2.cvtColor(image, cv2.COLOR_RGB2HLS) # 转换成HLS空间
f, ([ax1, ax2], [ax3, ax4]) = plt.subplots(nrows=2, ncols=2, figsize=(24, 8)) # 2x2显示
f.tight_layout() #紧凑适应
ax1.imshow(binary, cmap='gray') #轴1 2 3 4
ax1.set_title('gray', fontsize=25)
plt.subplots_adjust(left=0., right=1, top=0.9, bottom=0.) # 调整边缘
plt.show() # 显示, 不写则python不显示
nonzero = binary_warped.nonzero() # 返回非0元素下标,(x,y,z)分在两个矩阵里
good_left_inds = ((nonzeroy >= win_y_low) & (nonzeroy < win_y_high) & (nonzerox >= win_xleft_low) & (nonzerox < win_xleft_high)).nonzero()[0] # 把tupe元素取出来
# 数组和元素比较,每个元素比较,提取True,将方框里的x下标和y下标满足的
left_fit = np.polyfit(lefty, leftx, 2) # 2阶多项式拟合
out_img[nonzeroy[left_lane_inds], nonzerox[left_lane_inds]] = [255, 0, 0] # 相应的位置附上颜色:红色
left_line_window1 = np.array([np.transpose(np.vstack([left_fitx - margin, ploty]))]) # transpose 调换行列值,类似于转置
left_line_window2 = np.array([np.flipud(np.transpose(np.vstack([left_fitx + margin, ploty])))]) # 转化成后续填充颜色, y 首尾相连
left_fit_cr = np.polyfit(ploty*ym_per_pix, leftx*xm_per_pix, 2)
right_fit_cr = np.polyfit(ploty*ym_per_pix, rightx*xm_per_pix, 2)
# Calculate the new radii of curvature
left_curverad = ((1 + (2*left_fit_cr[0]*y_eval*ym_per_pix + left_fit_cr[1])**2)**1.5) / np.absolute(2*left_fit_cr[0])
right_curverad = ((1 + (2*right_fit_cr[0]*y_eval*ym_per_pix + right_fit_cr[1])**2)**1.5) / np.absolute(2*right_fit_cr[0]) #曲率求解公式
第十三、十四、十五章
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) # 划分网格点xx 和 yy 分别是 100x100的矩阵
Z1 = np.c_[xx.ravel(), yy.ravel()] # ravel 数组扁平化
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # np.c_按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等
plt.pcolormesh(xx, yy, Z, cmap=pl.cm.seismic) # Z 范围[0,1] 对应颜色空间
output_image("test.png", "png", open("test.png", "rb").read())
def output_image(name, format, bytes):
image_start = "BEGIN_IMAGE_f9825uweof8jw9fj4r8"
image_end = "END_IMAGE_0238jfw08fjsiufhw8frs"
data = {}
data['name'] = name
data['format'] = format
data['bytes'] = base64.encodebytes(bytes).decode('utf-8') # 二进制文件必须这样处理才能用json
print(image_start+json.dumps(data)+image_end)
grade_sig = [X_train[ii][0] for ii in range(0, len(X_train)) if y_train[ii]==0] # list 每个单元两个, 分别列出grade和bunpy单独的数据,此时y=0
random.seed(42) #产生随机数种子
grade = [random.random() for ii in range(0,n_points)] # 在 grade bumpy 和 error 中产生随机数种子 每个产生1000个随机数
# 朴素贝叶斯
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
clf = GaussianNB()
clf.fit(features_train,labels_train)
pred = clf.predict(features_test)
accuracy = accuracy_score(labels_test, pred)
# 支持向量机
from sklearn.svm import SVC
clf = SVC(C=10,kernel='linear')
clf.fit(features_train, labels_train)
pred = clf.predict(features_test)
acc = accuracy_score(pred, labels_test)
# 搜索最佳
from sklearn import svm
from sklearn.model_selection import GridSearchCV
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svr = svm.SVC()
clf1 = GridSearchCV(svr, parameters)
clf1.fit(features_train, labels_train)
print(clf1.best_params_, clf1.best_score_)
#决策树
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf.fit(features_train, labels_train)
pred = clf.predict(features_test)
第十六章
result = cv2.matchTemplate(imcopy, temp, method=cv2.TM_CCOEFF_NORMED)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(result) # 搜寻匹配的图片,并应用 TM_CCOEFF返回最大角点
# 分别计算RGB通道的直方图
rhist = np.histogram(img[:,:,0], bins=nbins, range=bins_range) # 然后返回一个元组(频数,分箱的边界),如上所示。要注意的是:这个边界的数量是要比分箱数多一个的,可以简单通过下面代码证实。
# 生成 bin 中心
bin_edges = rhist[1]
bin_centers = (bin_edges[1:] + bin_edges[0:len(bin_edges) - 1]) / 2
# 将直方图连接成单个特征向量
hist_features = np.concatenate((rhist[0], ghist[0], bhist[0]))
#绘制直方图
fig = plt.figure(figsize=(12,3))
plt.subplot(131)
plt.bar(bincen, rh[0]) # 以bin_center作为中心显示直方图
plt.xlim(0, 256)
plt.title('R Histogram')
features = cv2.resize(feature_image, size).ravel() # 简化大小,并特征为向量
features, hog_image=hog(img, orient, (pix_per_cell,pix_per_cell), (cell_per_block,cell_per_block),block_norm='L1', visualize=vis, feature_vector=feature_vec) # 获得梯度
X = np.vstack((car_features, notcar_features)).astype(np.float64) # 将每个list垂直叠放,得到矩阵
np.concatenate(img_features) # 变成一行
cv2.rectangle(draw_img,(xbox_left, ytop_draw+ystart),(xbox_left+win_draw,ytop_draw+win_draw+ystart),(0,0,255),6) # 画矩形
X_train = X_scaler.transform(X_train) # 找出X_train的均值和标准差,并应用在X_train上 z = (x - u) / s 对于每个属性/每列来说所有数据都聚集在0附近,标准差为1,使得新的X数据集方差为1,均值为0
heatmap = np.clip(heat, 0, 255) #意思是把小于min的数全部置换为min,大于max的数全部置换为max,在[min,max]之间的数则不变
**注意**
matplotlib image will read these in on a scale of 0 to 1, but cv2.imread() will scale them from 0 to 255,if you take an image that is scaled from 0 to 1 and change color spaces using cv2.cvtColor() you'll get back an image scaled from 0 to 255
# 生成器是处理大量数据的好方法。使用生成器可以提取数据片段并仅在需要时动态处理它们,而不是一次性将预处理过的数据全部存储在内存中,这样内存效率更高。生成器就像一个协程,一个可以与另一个主程序分开运行的进程,这使它成为一个有用的 Python 函数。return生成器没有使用yield
def fibonacci():
numbers_list = []
while 1:
if(len(numbers_list) < 2):
numbers_list.append(1)
else:
numbers_list.append(numbers_list[-1] + numbers_list[-2])
yield 1 # change this line so it yields its list instead of 1
our_generator = fibonacci()
my_output = []
for i in range(10):
my_output = (next(our_generator))
# 使用方法
def generator(samples, batch_size=32)
train_generator = generator(train_samples, batch_size=32)
model.fit_generator(train_generator, samples_per_epoch= len(train_samples),
validation_data=validation_generator,nb_val_samples=len(validation_samples), nb_epoch=3)
np.asarray(list(map(lambda path: load_image(path), np.asarray(project_vehicle_img_paths)[np.random.randint(0, high=len(project_vehicle_img_paths), size=5)]) # lambda, 简化对每个元素执行函数
引入的库
import matplotlib.pyplot as plt # 导入绘图库
import matplotlib.image as mpimg #图像处理
import hashlib # 哈希算法
import os # 导入标准库
import pickle # 数据持久化
from urllib.request import urlretrieve # 远程数据下载到本地
import numpy as np # 数组处理库
from PIL import Image # 图像处理库
from sklearn.model_selection import train_test_split # 随机划分样本数据为训练集和测试集的
from sklearn.preprocessing import LabelBinarizer # 标签二值化
from sklearn.utils import resample # 重采样
from tqdm import tqdm # 进度条
from zipfile import ZipFile # zip格式编码的压缩和解压缩的