python prediction machine_Python-OpenCV —— Machine Learning

前几天有同学问我关于物体识别的问题,问我是否能写一篇相关的教程,其实最近有在做这方面的事情,我做的是一个检测指定物体,画出框框出制定物体,并进行测距,具体的应用场景是检测红绿灯,自动通过路口,其中就用到了物体识别,当然还涉及到单目测距之类的知识,这些暂且不表,下次再说。

之前就知道OpenCV有一个专门的Machine Learning库,一直没有机会学习,想着通过这次机会,正好学习一下,没成想,进了一个巨大的坑,因为大家都知道,Python是胶水语言,所以Python-OpenCV的底层也都是C语言写的,而我C语言又比较差,网上的教程有比较少,所以看官方文档的时候真的是一番煎熬,下次有时间还是试一试主流的一下机器学习框架吧,正好做一个对比,看哪一个比较好。

CV.ml介绍

集成了许多优秀的机器学习算法,主要有:

cv2.ml.svm---------------------支持向量机

cv2.ml.knn---------------------K.近邻

cv2.ml.bayesian----------------正态贝叶斯分类器

cv2.ml.em----------------------期望最大化

cv2.ml.boost.tree--------------boost分类器

cv2.ml.tree--------------------决策树分类器

cv2.ml.ann.mlp-----------------感知器神经网络分类器

cv2.ml.cnn---------------------卷积神经网络

cv2.ml.random.trees-----------------随机树分类器

cv2.ml.extremely.randomized.trees---随机森林分类器

cv2.ml.gradient.boosting.trees------梯度boost分类器

具体的功能我就不一一介绍了,大家有兴趣的可以参看上面的官方文档,具体说说我用到的cv2.ml.ANN_MLP

cv2.ml.ANN_MLP

最好的学习一个新功能的方式就是去使用它,话不多说,直接上程序

1. 创建训练模型

这个模型是训练通过摄像头获取到的照片,来判断应该前进的方向,算是智能驾驶的一部分。

import cv2

model = cv2.ml.ANN_MLP_create()#建立模型

model.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM)#设置激活函数为SIGMOID,其实就这一个可以选

model.setLayerSizes(np.int32([38400,32,4]))#设置层数,输入38400层(像素320*240),输出层4(上下左右四个方向),以及中间层32

model.setTermCriteria(( cv2.TERM_CRITERIA_COUNT | cv2.TERM_CRITERIA_EPS, 500, 0.0001 ))#设置终止条件

model.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP)#设置训练方式为反向传播

model.setBackpropWeightScale(0.001) #设置反向传播中的一些参数

model.setBackpropMomentumScale(0.0) #设置反向传播中的一些参数

2.开始训练模型

载入数据

训练要有数据,数据是我之前拍好的,拍的时候获取两个参数,一是拍到的照片,二是拍照片的时候的前进方向,以此来进行训练,将拍好的照片以npz格式保存,然后进行读取。

import numpy as np

import glob

# load training data

image_array = np.zeros((1, 38400))

label_array = np.zeros((1, 4), 'float')

training_data = glob.glob('training_data/*.npz')

#开始一个个读取

for single_npz in training_data:

with np.load(single_npz) as data:

train_temp = data['train']#拍到的照片

train_labels_temp = data['train_labels']#照片对应的标签

image_array = np.vstack((image_array, train_temp))

label_array = np.vstack((label_array, train_labels_temp))

X = image_array[1:, :]

Y = label_array[1:, :]

数据分类

将数据按照一定的比例分为测试集和训练集,比例大概为2:8

from sklearn.model_selection import train_test_split

train, test, train_labels, test_labels = train_test_split(X, y, test_size=0.2)

开始训练

records = []

#建立一个列表,进行照片和标签的一一对应

for x in range(0, len(train)):

records.append(record(train[x], train_labels[x]))

#训练两个epoch

EPOCHS = 2

for e in range(0, EPOCHS):

print("Epoch %d:" % e)

for t, c in records:

#开始训练,cv2.ml.ROW_SAMPLE代表每一行是一个样本

num_iter = model.train(t, cv2.ml.ROW_SAMPLE, c)

3. 保存训练结果

# train data

ret_0, resp_0 = model.predict(train)

prediction_0 = resp_0.argmax(-1)

true_labels_0 = train_labels.argmax(-1)

train_rate = np.mean(prediction_0 == true_labels_0)

print('Train accuracy: ', "{0:.2f}%".format(train_rate * 100))

# test data

ret_1, resp_1 = model.predict(test)

prediction_1 = resp_1.argmax(-1)

true_labels_1 = test_labels.argmax(-1)

test_rate = np.mean(prediction_1 == true_labels_1)

print('Test accuracy: ', "{0:.2f}%".format(test_rate * 100))

# save model

model.save('mlp_xml/mlp.xml')

4. 模型的识别应用

#构建模型网络,一会进行调用

class NeuralNetwork(object):

def __init__(self, file_path):

self.model = cv2.ml.ANN_MLP_load(file_path)#载入训练好的模型

#预测拍的照片给出标签值

def predict(self, samples):

ret, resp = self.model.predict(samples)

return resp.argmax(-1)

下面进行调用,因为调用需要照片,因此我把它放在了另一个接收照片的类里面,照片的传递也可以写一篇教程,这次先不说

class VideoStream(object):

def __init__(self):

self.ct_socket = socket.socket()

self.ct_socket.bind(('0.0.0.0',collect_id))

self.ct_socket.listen(5)

self.connection = self.ct_socket.accept()[0].makefile('rb')

# 模型实例化,载入训练好的文件

self.model = NeuralNetwork('mlp_xml/mlp.xml')

def handle(self):

global prediction

stream_bytes = b' '

try:

while True:

stream_bytes += self.connection.read(1024)

first = stream_bytes.find(b'\xff\xd8')

last = stream_bytes.find(b'\xff\xd9')

if first != -1 and last != -1:

jpg = stream_bytes[first:last+2]

stream_bytes = stream_bytes[last+2:]

image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

print('接受照片中')

prediction = self.model.predict(image)

print(prediction)#这个输出的值就是检测过的标签,然后通过判断这个标签是什么,就可以执行下面的操作了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值