day07

CNN.py

from keras.models import Sequential
from keras.layers import Conv2D, Activation
from keras.layers import MaxPooling2D, Dropout
from keras.layers import Flatten, Dense
from keras.layers.normalization import BatchNormalization
from keras.optimizers import SGD
from keras import optimizers
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import random
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import pandas as pd
import numpy as np
import cPickle

# 分割数据
class DateSet:
def __init__(self, path_name):
# 训练数据集

# 验证数据集

# 测试数据

pass

def load(self, img_rows = 64, img_cols = 64, img_channels=3, nb_classes=3):
# 图片的加载(自己完成)
# path_name 所对应的文件处理:
# 1. 将每一张图片转换为64*64*3;
# 2. 给图片赋予标签;
image_file = cbook.get_sample_data('E:\MyDownloads\FileRecv\menjin.png')
image = plt.imread(image_file)



# 分割数据:
train_test_split(images, labels, test_size=0.3, random_state=random.randint(0,100))


pass


# CNN 模型的搭建
class Model:
def __init__(self):
self.model = None # 定义类属性:模型

# 定义创建模型函数, train_data表示训练数据集, nb_class表示有几个人的人脸数据
def build_model(self, train_data, nb_class):
# 构建一个空的网络模型,线性模型
self.model = Sequential()
# 顺序添加网络层:
# 添加一个卷积层:有32个卷积核,卷积核的大小为3*3,卷积模式为same,
self.model.add(Conv2D(32, (3,3), padding='same', input_shape=train_data.input_shape))
self.model.add(BatchNormalization())
self.model.add(Activation('relu')) # 添加激活函数

# 添加池化层
self.model.add(MaxPooling2D(pool_size=(2,2)))
self.model.add(Dropout(0.25))

# 添加全连接层
self.model.add(Flatten())
self.model.add(Dense(512))
self.model.add(BatchNormalization())
self.model.add(Activation('relu')) # 添加激活函数
self.model.add(Dropout(0.5))
self.model.add(Dense(nb_class))
self.model.add(BatchNormalization())
self.model.add(Activation('softmax')) # 分类层,输出得到概率最大的结果

# 输出模型概况
self.model.summary()
pass

# 定义训练函数,进行训练
def train(self, train_data):
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
self.model.compile(loss='categorical_crossentropy', optimizer=sgd)

# 学习(自己完成)
pass
# 定义模型保存函数,保存模型
def save_model(self, file_path = 'me.face.model.h5'):
self.model.save(file_path)

# 加载模型
def load_model(self, file_path = 'me.face.model.h5'):
pass

img = Image.open(dataset_path)
img_ndarray = numpy.asarray(img, dtype='float64') / 256
faces = numpy.empty((400, 2679))
for row in range(20):
for column in range(20):
faces[row * 20 + column] = numpy.ndarray.flatten(
img_ndarray[row * 57:(row + 1) * 57, column * 47:(column + 1) * 47])

label = numpy.empty(400)
for i in range(40):
label[i * 10:i * 10 + 10] = i
label = label.astype(numpy.int)

# 分成训练集、验证集、测试集,大小如下
train_data = numpy.empty((320, 2679))
train_label = numpy.empty(320)
valid_data = numpy.empty((40, 2679))
valid_label = numpy.empty(40)
test_data = numpy.empty((40, 2679))
test_label = numpy.empty(40)

for i in range(40):
train_data[i * 8:i * 8 + 8] = faces[i * 10:i * 10 + 8]
train_label[i * 8:i * 8 + 8] = label[i * 10:i * 10 + 8]
valid_data[i] = faces[i * 10 + 8]
valid_label[i] = label[i * 10 + 8]
test_data[i] = faces[i * 10 + 9]
test_label[i] = label[i * 10 + 9]

write_file = open('params.pkl', 'wb')
cPickle.dump(param1, write_file, -1)
cPickle.dump(param2, write_file, -1)
cPickle.dump(param3, write_file, -1)
cPickle.dump(param4, write_file, -1)
write_file.close()

# 将数据集定义成shared类型,才能将数据复制进GPU,利用GPU加速程序
def shared_dataset(data_x, data_y, borrow=True):
shared_x = theano.shared(numpy.asarray(data_x,
dtype=theano.config.floatX),
borrow=borrow)
shared_y = theano.shared(numpy.asarray(data_y,
dtype=theano.config.floatX),
borrow=borrow)
return shared_x, T.cast(shared_y, 'int32')

train_set_x, train_set_y = shared_dataset(train_data, train_label)
valid_set_x, valid_set_y = shared_dataset(valid_data, valid_label)
test_set_x, test_set_y = shared_dataset(test_data, test_label)
rval = [(train_set_x, train_set_y), (valid_set_x, valid_set_y),
(test_set_x, test_set_y)]
return rval

# 查看模型
def evaluate(self, train_data):
pass

# 定义预测函数,进行人脸数据识别
def face_predict(self, image):
ret = 0

# 数据维度的处理:

# 浮点数归一化处理
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
data
Out[1]: [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

pd.DataFrame(data)
Out[2]:
0
1

0 - 1.0
2
1 - 0.5
6
2
0.0
10
3
1.0
18

scaler = MinMaxScaler() # 实例化
scaler = scaler.fit(data) # fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data) # 通过接口导出结果
result
Out[3]:
array([[0., 0.],
[0.25, 0.25],
[0.5, 0.5],
[1., 1.]])

# 训练和导出结果一步达成

result_ = scaler.fit_transform(data)

# 将归一化后的结果逆转
scaler.inverse_transform(result)
Out[4]:
array([[-1., 2.],
[-0.5, 6.],
[0., 10.],
[1., 18.]])

# 使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5, 10]) # 依然实例化
result = scaler.fit_transform(data) # fit_transform一步导出结果
result
Out[5]:
array([[5., 5.],
[6.25, 6.25],
[7.5, 7.5],
[10., 10.]])

X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])
# 归一化
X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_nor
Out[6]:
array([[0., 0.],
[0.25, 0.25],
[0.5, 0.5],
[1., 1.]])

X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
X_returned
Out[7]:
array([[-1., 2.],
[-0.5, 6.],
[0., 10.],
[1., 18.]])
# 查看出现类别的概率,根据概率,得到当前图片类型


# 返回类别预测结果
return ret


load_face_dataset.py
import os
import cv2
import numpy as np

images = []
labels = []

def resize_image(image, height=64, width=64):
top, bottom, left, right = (0, 0, 0, 0)
# 获取图像的尺寸
h, w, _ = image.shape

# 获取图片宽高的最大值(最长边)
longest_edge = max(h, w)

# 计算短边需要增加多少像素,和长边保持一致;
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass

# 给图像增加边界,
BALCK = [0, 0, 0]
constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BALCK)

return cv2.resize(image, (height, width))

def read_path(path_name):
for dir_item in os.listdir(path_name):
# 从初始路径开始叠加,合并成为可识别的操作路径
full_path = os.path.abspath(os.path.join(path_name, dir_item))
# 判断路径是否为目录
if os.path.isdir(full_path): #目录
print(dir_item, 'is dir')
read_path(full_path)
else: # 文件
if dir_item.endswith('.jpg'):
image = cv2.imread(full_path)
print(image.shape)
image = resize_image(image, 64, 64)

images.append(image)
labels.append(path_name)

print(labels)
return images, labels

def load_dataset(path_name):
images, labels = read_path(path_name)
images = np.array(images)
print(images)
for i, label in enumerate(labels):
if label.endswith('me'):
labels[i] = 0
elif label.endswith('tw'):
labels[i] = 1
else:
labels[i] = 2
return images, labels

if __name__ == '__main__':
images, labels = load_dataset('./mypic')
print(labels)


opencv-cam.py
import cv2
import time

path_name = 'mypic/tw'
# time_start = time.time()
cap = cv2.VideoCapture(0) # 使用摄像头
# fps = 0
num = 0

# 设置人脸分类器
classfier = cv2.CascadeClassifier("D:\ProgramData\Anaconda3\envs\\tf\Library\etc\haarcascades\haarcascade_frontalface_default.xml")

while cap.isOpened():
# print("摄像头开启成功")
ret, frame = cap.read() # 摄像头读取一帧数据
if not ret: # 失败,程序退出
exit(-1)
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 图像灰度处理
# 人脸检测
faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32,32))
# fps = 1/time.time() - time_start
if len(faceRects) > 0:
for faceRect in faceRects:
x, y, w, h = faceRect
cv2.putText(frame, 'kunkun', (100, 100), cv2.FONT_HERSHEY_SIMPLEX,0.5, (0, 0, 255), 2) # 文本显示
cv2.rectangle(frame, (x-10, y-10), (x+w+10, y+h+10), (255, 0, 0), 2) # 在图片上画框
image = frame[y-10:y+h+10, x-10:x+w+10]
img_name = '%s/%d.jpg'%(path_name, num)
cv2.imwrite(img_name, image)
num += 1

if num == 200:
exit(0)

cv2.imshow('cam', frame) # 图像在窗口显示
key = cv2.waitKey(30) & 0xff # 等待事件
if key == 27: # Esc键,循环结束
exit(0)
# time_start = time.time()
# time.sleep(0.001)

cap.release()
cv2.destroyAllWindows()



# 返回类别预测结果
return ret


face_train_use_keras.py
import os
import cv2
import numpy as np

images = []
labels = []

def resize_image(image, height=64, width=64):
top, bottom, left, right = (0, 0, 0, 0)
# 获取图像的尺寸
h, w, _ = image.shape

# 获取图片宽高的最大值(最长边)
longest_edge = max(h, w)

# 计算短边需要增加多少像素,和长边保持一致;
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass

# 给图像增加边界,
BALCK = [0, 0, 0]
constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BALCK)

return cv2.resize(image, (height, width))

def read_path(path_name):
for dir_item in os.listdir(path_name):
# 从初始路径开始叠加,合并成为可识别的操作路径
full_path = os.path.abspath(os.path.join(path_name, dir_item))
# 判断路径是否为目录
if os.path.isdir(full_path): #目录
print(dir_item, 'is dir')
read_path(full_path)
else: # 文件
if dir_item.endswith('.jpg'):
image = cv2.imread(full_path)
print(image.shape)
image = resize_image(image, 64, 64)

images.append(image)
labels.append(path_name)

print(labels)
return images, labels

def load_dataset(path_name):
images, labels = read_path(path_name)
images = np.array(images)
print(images)
for i, label in enumerate(labels):
if label.endswith('me'):
labels[i] = 0
elif label.endswith('tw'):
labels[i] = 1
else:
labels[i] = 2
return images, labels

if __name__ == '__main__':
images, labels = load_dataset('./mypic')
print(labels)

 

posted @ 2020-07-31 23:33  茯苓icmxkx  阅读(105)  评论(0编辑  收藏  举报