计算机视觉基础系列(python与opencv的操作与运用/tensorflow的基础介绍)(二十七)--- 完结篇-人脸识别完整流程

首先这个案例很简单,属于浅层次的神经网络,属于一个综合性案例。

分别需要以下几个步骤:

1.样本收集;2.图像预处理;3.tensorflow神经网络

这里对应的就是以下几个知识点:1.python图片的爬虫;2.opencv预处理;3.tensorflow卷积神经网络

一、样本收集

简单的爬虫使用;视频截取图片,ffmpeg命令行的使用。

1.理解爬虫原理,2.实现图片的爬虫:

1.了解http请求;2.了解html网页规则;3.正则表达式的过滤条件;4.其他

1.url;2.html网页的src路径;3.image图片;4.图片的url链接

对应的简单的爬虫代码如下:

import urllib
import urllib3
import os
from bs4 import BeautifulSoup
# 获取解析当前html的内容和图片
# 加载当前的urll
html = urllib.request.urlopen('https://class.imooc.com/?c=ios&mc_markin').read()
# 解析当前的url,解析的是url下的data数据;第一个参数:html整个页面,第二个参数:html.parser方法,第三个参数:编码方式
soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')
# 获取当前image的标签,使用findAll方法获取图片的所有标签
images = soup.findAll('img')
print(images)
# 拿到图片运用for循环的方式进行遍历图片,进行图像的预处理
imageName = 0
for image in images:
    # 遍历完后,我们通过src获取当前具体的一个url网址
    link = image.get('src')
    print('link=', link)
    # 获取的网址不完整,因为没有http请求,接下来就需要就加上http请求
    link = 'http:'+link
    # 这里获取的.svg;.png;.jpg等文件,我们这里爬虫的是图片,所以需要过滤一下:
    fileFormat = link[-3:]             # 获取文件名,获取文件名中最后的三个字符
    if fileFormat == 'png' or fileFormat == 'jpg':
        fileSavePath = 'minst/'+str(imageName)+'.jpg'
        imageName = imageName + 1
        # 通过request下的urlretrieve方法进行文件的下载和保存
        urllib.request.urlretrieve(link, fileSavePath)

结果的截图:

二、图像预处理

人脸的提取(haar+adaboost+xml文件)完成人脸的采集。这样得到的图片就是我们需要的数据。

ffmpeg的图片的处理:

样本采集车在某些路段进行视频的采集,然后运用利用视频分解图片。

之前有说过运用opencv的包来进行视频的截取,在这里,运用ffmpeg工具进行图片的截取。opencv截取视频的库的本质其实也是ffmpeg来做的。

ffmpeg是一个具有处理音视频功能的软件库。它是由一系列的音视频处理的编解码的api组成,源码开放,绝大部分的视频播放器要基于这个库来完成,可以完成文件格式的转换,编解码的转换等等,同时,还可以对视频的剪切,录制,提取和复用等等功能,在这里只是简单介绍了解一下。

接下来就是图片的截取了,将人脸图片截取下来进行存储,这个代码是之前的代码改编过来的,可以点击这里看一下之前的博客,人脸的截取部分的学习就可以知道了:

import cv2
import numpy as np
# 1.load xml文件   2.夹在图片  3.haar特征,灰度处理(所有的haar特征基于灰度图的),4.检测人脸  5.绘制标注
# 加载引入xml文件
face_xml = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_xml = cv2.CascadeClassifier('haarcascade_eye.xml')
img = cv2.imread('face.png')
cv2.imshow('src', img)
# 计算haar特征,但是opencv自带的已经解决,所以只需要转换成灰度图即可
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测;cv2中有自带的检测方法
faces = face_xml.detectMultiScale(gray, 1.3, 5)
# 检测图像中的人脸,第一个参数,灰度图片的数据,缩放系数,harr特征需要的比例缩放的操作;目标大小,人脸不能小于5
print('face=', len(faces))
# 绘制人脸,给人脸画宽高
index = 0
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
    roi_face = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    fileName = str(index)+'.jpg'
    cv2.imwrite(fileName, roi_color)    # 存储的是人脸像
    index = index + 1
    # 也必须是灰度图
    eyes = eye_xml.detectMultiScale(roi_face)
    print('eye=', len(eyes))
    # for (x2, y2, w2, h2) in eyes:
    #     cv2.rectangle(img, (x2, y2), (x2+w2, y2+h2), (0, 255, 0), 2)
    # 人脸识别之后需要做的是提取处理然后保存在本地进行训练,因为是一系列的样本,所以需要给他们一个下标
cv2.imshow('dst', img)
cv2.waitKey(0)

三、神经网络的搭建

主要是CNN的卷积神经网络,实现某个人脸的识别:

1.完成数据的准备,我们使用的是耶鲁大学的一i个人脸库

2.准备训练数据和训练的标签,完成label的标签的加载

3.搭建cnn网络进行训练

4.检测人脸识别是否可以运用

这里,我们主要是做第二步和第三步的准备

import tensorflow as tf
import numpy as np
import scipy.io as sio
f = open('Data.mat', 'rb')        # 加载进来之后是一个字典的形式,所以我们将它存在字典里面
mdict = sio.loadmat(f)            # 将当前文件的文件句柄加载进来,这里就会有训练数据和训练标签
# 训练数据的key是fea,value的key是gnd
train_data = mdict['fea']
train_label = mdict['gnd']
# 因为我们用的是网上的耶鲁大学的数据,所以我们需要抽取一部分数据来形成测试数据,所以在这里,我们还需要将其顺序打乱,组成新的训练数据
train_data = np.random.permutation(train_data)     # 使得整个数据进行无序排列
train_label = np.random.permutation(train_label)
test_data = train_data[0: 64]
test_label = train_label[0: 64]
# 提取数据的前64个作为测试数据,然后再将训练数据和测试数据进行打乱
np.random.seed(100)
test_data = np.random.permutation(test_data)     # 使得整个数据进行无序排列
test_label = np.random.permutation(test_label)
# 第一步数据的准备完成了,接下来就是其他步骤,准备train_label和train_data
# 读取进来之后,图片的大小是64x64的,灰度等级是0-255的,所以我们需要归一化处理
train_data = train_data.reshape(train_data.shape[0], 64, 64, 1).astype(np.flloat32)/255
# 这样处理完之后,训练数据就算归一化成功了
# 在训练进行数字识别的时候,它的数组是Nx10维度的数组,因为有10个数(0-9),所以耶鲁大学的数据里面,有15个人脸,所以标签数据就是15xN了
# 构建标签:
train_label_new = np.zeros((165, 15))
# 新建这个数组的原因是:耶鲁大学的数据库有165张图片,分别描述了15个人,所以这样定义的
# 对每一个维度进行赋值,刚刚开始所有的维度都为0,同理2这个标签表示为:[0,0,1,0,0,0,0,0,0,0],这里是类似的方式进行标签的制作
# 总共165组数据,
for i in range(0, 165):
    # j表明当前train_label,这个train_label中的输入数据全部放到第i行,我们首先要根据train_label获取得到当前的这个图片描述的是哪个人
    j = int(train_label[i, 0]) - 1                    # 标签转换成0-14
    train_label_new[i, j] = 1
test_data_input = test_data.reshape(train_data.shape[0], 64, 64, 1).astype(np.flloat32)/255
test_label_input = np.zeros((64, 15))
for i in range(0, 64):
    # j表明当前train_label,这个train_label中的输入数据全部放到第i行,我们首先要根据train_label获取得到当前的这个图片描述的是哪个人
    j = int(test_label[i, 0]) - 1                    # 标签转换成0-14
    test_label_input[i, j] = 1
# 接下来就是构建简单的神经网络
# 卷积神经网络,测试训练的检测概率,之前的方式是tf.nn的方法,这里是运用tf.layer,通过这个方法可以直接实现一个人工神经网络的搭建
data_input = tf.placeholder(tf.float32, [None, 64, 64, 1])
label_input = tf.placeholder(tf.float32, [None, 64, 64, 1])
layer1 = tf.layers.conv2d(inputs = data_input, filters=32, kernel_size=2, strides=1, padding='SAME', activation=tf.nn.relu)
layer1_pool = tf.layers.max_pooling2d(layer1, pool_size=2, strides=2)    # 池化层,行列均减小一半
layer2 = tf.reshape(layer1_pool, [-1, 32*32*32])    # 池化层作为输入,我们想要实现一个n行的
layer2_relu = tf.layers.dense(layer2, 1024, tf.nn.relu)                                        # 激励层
output = tf.layers.dense(layer2_relu, 15)                # 全连接层,维度15,因为是15个人
# 让神经网络跑起来,然后计算预测的概率,交叉商
loss = tf.losses.softmax_cross_entropy(onehot_labels=label_input, logits=output)
train = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
accuracy = tf.metrics.accuracy(labels=tf.arg_max(label_input, axis=1), predictions=tf.argmax(output, axis=1))[1]
# run
init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer)
with tf.Session() as sess:
    sess.run(init)
    for i in range(0, 200):
        train_data_input = np.array(train_data)
        train_label_input = np.array(train_label_new)
        sess.run([train, loss], feed_dict={data_input: train_data_input, label_input: train_label_input})
        acc = sess.run(accuracy, feed_dict={data_input: test_data_input, label_input: test_label_input})
        print('acc:%.2f', accuracy)

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值