一:图片收集

收集训练图片、测试图片

调用摄像头获取图像 -> 肤色检测处理图像 -> 轮廓查找获取手势图片并保存

import cv2 as cvif __name__ == "__main__":m_0 = 0  #剪刀m_1 = 0  #石头m_2 = 0  #布m_3 = 0  #人脸(加个人脸标签用于避免将人脸错误识别)flag = 0cap = cv.VideoCapture(0) # 调用摄像头while True:success, frame = cap.read() # 读取每一帧new_img = cv.flip(frame, 1) # 翻转roi = new_img# YCrCb之Cr分量 + OTSU二值化(肤色检测)ycrcb = cv.cvtColor(roi, cv.COLOR_BGR2YCrCb)  # 把图像转换到YUV色域(y, cr, cb) = cv.split(ycrcb)  # 图像分割, 分别获取y, cr, br通道图像# 高斯滤波, cr 是待滤波的源图像数据, (5,5)是值窗口大小, 0 是指根据窗口大小来计算高斯函数标准差cr1 = cv.GaussianBlur(cr, (5, 5), 0)  # 对cr通道分量进行高斯滤波# 根据OTSU算法求图像阈值, 对图像进行二值化_, skin1 = cv.threshold(cr1, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)cv.imshow('skin1', skin1)  # 展示处理后的图片# 轮廓查找image, contours, hierarchy = cv.findContours(skin1, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)for item in contours:  # 遍历所有轮廓(x, y, w, h) = cv.boundingRect(item) # 获得最小矩形框架if w >= 50 and h >= 50: # 在较大的框架中查找img = skin1[y : y + h, x : x + w]  # 获得矩形轮廓图cv.imshow('img', img)  # 展示矩形轮廓图cv.rectangle(new_img, (x, y), (x + w, y + h), (255, 0, 0), 0) # 在new_img中用矩形框出k = cv.waitKey(1) # 等待键盘促发if k == ord(' '):  # 按下空格退出flag = 1breakelif k == ord('a'): # 按A收集剪刀图片# 按下后将图片保存到指定路径(imencode函数可以有中文路径)cv.imencode('.jpg', img)[1].tofile("D:\\pythonfile\\人工智能\\手势识别\\gesture_data\\0\\{}.png".format(m_0))m_0 += 1print('正在保存0-roi图片,本次图片数量:', m_0)elif k == ord('s'): # 按S收集石头图片cv.imencode('.jpg', img)[1].tofile("D:\\pythonfile\\人工智能\\手势识别\\gesture_data\\1\\{}.png".format(m_1))m_1 += 1print('正在保存1-roi图片,本次图片数量:', m_1)elif k == ord('d'): # 按D收集布图片cv.imencode('.jpg', img)[1].tofile("D:\\pythonfile\\人工智能\\手势识别\\gesture_data\\2\\{}.png".format(m_2))m_2 += 1print('正在保存2-roi图片,本次图片数量:', m_2)elif k == ord('f'): # 按F收集人脸图片cv.imencode('.jpg', img)[1].tofile("D:\\pythonfile\\人工智能\\手势识别\\gesture_data\\3\\{}.png".format(m_3))m_3 += 1print('正在保存3-roi图片,本次图片数量:', m_3)cv.imshow("frame", new_img) # 展示new_img图像if flag == 1:breakcap.release() #释放占用资源cv.destroyAllWindows() #释放opencv创建的所有窗口





二:训练模型

获取所收集的图像并转为numpy数组 -> 处理数据(修改大小、归一化、one-hot)-> 将数据放入所创建的模型中进行训练 -> 评估模型、保存模型

import numpy as np
import os
import cv2 as cv
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend
from PIL import Image
backend.set_image_data_format('channels_first')# 更改动态分配内存
import tensorflow as tf
import keras
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
keras.backend.tensorflow_backend.set_session(tf.Session(config=config))# 设定随机种子
seed = 7
np.random.seed(seed)# 读取图片,调整大小(100*100),转为numpy数组
def pre_pic(picName):# 先打开传入的原始图片img = Image.open(picName)# 使用消除锯齿的方法resize图片reIm = img.resize((100,100),Image.ANTIALIAS)# 变成灰度图,转换成矩阵im_arr = np.array(reIm.convert("L"))return im_arr# 用pre_pic函数将图片转为numpy数组,并将所有图片的数组合并为一个数组
def get_files(file_dir):flag = 0for file in os.listdir(file_dir):image_file_path = os.path.join(file_dir,file)if file == '0':  # 文件名为‘0’表示剪刀temp = 0  # 设置标签temp=0elif file == '1':  # 文件名为‘1’表示石头temp = 1  # 设置标签temp=1elif file == '2':  # 文件名为‘2’表示布temp = 2  # 设置标签temp=2elif file == '3':  # 文件名为‘3’表示人脸temp = 3  # 设置标签temp=3for image_name in os.listdir(image_file_path):image_name_path = os.path.join(image_file_path,image_name)img = pre_pic(image_name_path)  # 将图片通过pre_pic函数转为numpy数组,例如img.shape=(100,100)if flag == 0:  # 第一次处理X_image = img[np.newaxis,:]  # X_image.shape=(1,100,100)Y_image = np.array([temp])  # Y_image.shape=(1,)flag = 1else:  # 第n次处理(n!=1)#将(n-1,100,100)与(1,100,100)合并为(n,100,100)X_image = np.vstack((X_image,img[np.newaxis,:]))#将(n-1,)与(1,)合并为(n,)Y_image = np.hstack((Y_image,np.array([temp])))return X_image,Y_image  # X_image为图片数据,Y_image为标签# 创建、编译模型
def create_model():model = Sequential()model.add(Conv2D(filters=8, kernel_size=(3,3),strides=(1,1),padding='same',input_shape=(1,100,100),activation='relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Conv2D(filters=16, kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'))model.add(Dropout(0.5))model.add(MaxPooling2D(pool_size=(4,4)))model.add(Dense(128,activation='relu'))model.add(Flatten())model.add(Dense(4,activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])return modelif __name__ == "__main__":filetrain = "D:\\pythonfile\\人工智能\\手势识别\\gesture_data"filetest = "D:\\pythonfile\\人工智能\\手势识别\\gesturetest"print('start')X_train,Y_train = get_files(filetrain)X_test,Y_test = get_files(filetrain)print(X_train.shape)print(Y_train.shape)# 修改数据格式X_train = X_train.reshape(X_train.shape[0], 1, 100, 100).astype('float32')X_test = X_test.reshape(X_test.shape[0], 1, 100, 100).astype('float32')# 格式化数据到0-1之前X_train = X_train / 255X_test = X_test / 255# one-hot编码Y_train = np_utils.to_categorical(Y_train)Y_test = np_utils.to_categorical(Y_test)#  创建、编译模型model = create_model()#  训练模型model.fit(X_train, Y_train, epochs=10, batch_size=300, verbose=2)#  评估模型score = model.evaluate(X_test, Y_test, verbose=0)print('acc: %.2f%%' % (score[1] * 100))#  保存模型model.save('my_model')

三:动态识别

调用摄像头获取图像 -> 肤色检测处理图像 -> 轮廓查找获取手势图片 -> 将图片转为numpy数组并处理(修改大小、归一化)-> 调用前面所训练的模型进行预测 -> 预测结果在图像中展示

import numpy as np
import cv2 as cv
from keras.models import load_model
import matplotlib.pyplot as plt
from PIL import Imagemodel = load_model('my_model') # 调用所训练的模型# 读取图片,调整大小(100*100),转为numpy数组
def pre_pic(picName):# 先打开传入的原始图片img = Image.open(picName)# 使用消除锯齿的方法resize图片reIm = img.resize((100,100),Image.ANTIALIAS)# 变成灰度图,转换成矩阵im_arr = np.array(reIm.convert("L"))return im_arrif __name__ == '__main__':cap = cv.VideoCapture(0) # 调用摄像头filename = '00.jpg'while True:success,frame = cap.read() # 读取每一帧new_img = cv.flip(frame, 1) # 翻转roi = new_img# YCrCb之Cr分量 + OTSU二值化(肤色检测)ycrcb = cv.cvtColor(roi, cv.COLOR_BGR2YCrCb)  # 把图像转换到YUV色域(y, cr, cb) = cv.split(ycrcb)  # 图像分割, 分别获取y, cr, br通道图像# 高斯滤波, cr 是待滤波的源图像数据, (5,5)是值窗口大小, 0 是指根据窗口大小来计算高斯函数标准差cr1 = cv.GaussianBlur(cr, (5, 5), 0)  # 对cr通道分量进行高斯滤波# 根据OTSU算法求图像阈值, 对图像进行二值化_, skin1 = cv.threshold(cr1, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)cv.imshow('skin',skin1)  # 展示处理后的图片# 轮廓查找image, contours, hierarchy = cv.findContours(skin1, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)  # 轮廓查找for item in contours:(x, y, w, h) = cv.boundingRect(item) # 获得最小矩形框架if w >= 50 and h >= 50: # 在较大的框架中查找img = skin1[y : y + h, x : x + w] # 获得矩形轮廓图cv.imshow('img',img) # 展示矩形轮廓图cv.imwrite(filename, img) # 将矩形轮廓图保存img = pre_pic(filename)img = img.reshape(1, 1, 100, 100).astype('float32')  # 修改数据格式img = img / 255  # 归一化predictions = model.predict_classes(img)  # 预测结果flag = model.predict(img) # 预测概率if max(flag[0]) > 0.5:  # 概率大于0.5才框出print(predictions)if predictions[0] == 0:s = "jiandao"elif predictions[0] == 1:s = "shitou"elif predictions[0] == 2:s = "bu"elif predictions[0] == 3: # 预测为人脸则跳过continuecv.rectangle(new_img, (x, y), (x + w, y + h), (255, 0, 0), 0) # 用矩形框出cv.putText(new_img, s, (x, y), cv.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 2, 8) # 在矩形上方显示文字cv.imshow('image', new_img)Key = cv.waitKey(1)if Key == ord(' '):  #按下空格键退出breakcap.release() #释放占用资源cv.destroyAllWindows() #释放opencv创建的所有窗口

CNN实现剪刀石头布手势识别(python)相关推荐

  1. 从参数数量视角理解深度学习神经网络算法 DNN, CNN, RNN, LSTM 以python为工具

    从参数数量视角理解深度学习神经网络算法 DNN, CNN, RNN, LSTM 以python为工具 文章目录 1. 神经网络数据预处理 1.1 常规预测情景 1.2 文本预测场景 2.全连接神经网络 ...

  2. 基于CNN的动态手势识别:Real-time Hand Gesture Detection and Classification Using Convolutional Neural Networks

    Real-time Hand Gesture Detection and Classification Using Convolutional Neural Networks论文解读 1. 概述 2. ...

  3. 人工智能:深度学习算法及应用——简单理解CNN卷积神经网络并python实现(带源码)

    深度学习算法及应用 一. 实验目的 二. 实验要求 三. 实验的硬件.软件平台 四. 实验原理 1.1. 深度学习概述 1.2. 深度学习的常见结构 1.3. 卷积神经网络(CNN) **卷积** * ...

  4. python基础代码库-CNN详解-基于python基础库实现的简单CNN

    CNN,即卷积神经网络,主要用于图像识别,分类.由输入层,卷积层,池化层,全连接层(Affline层),Softmax层叠加而成.卷积神经网络中还有一个非常重要的结构:过滤器,它作用于层与层之间(卷积 ...

  5. Linux实现剪刀石头布游戏,Python剪刀石头布游戏

    srpgame.py #!/urs/bin/env python import random all_choice = ['石头','剪刀','布'] win_list = [['石头','剪刀'], ...

  6. python循环剪刀石头布_剪刀石头布用python怎么写

    实现一个人与计算机玩猜拳--石头剪刀布的小游戏,学会Python的循环控制语句和条件判断语句. 假如把石头.剪刀.布分别用数字0.1.2表示.那么如何判定谁胜谁负呢?(推荐学习:Python视频教程) ...

  7. python cnn 实例_学习python的算法-Faster RCNN算法复现

    [实例简介]Faster RCNN算法复现 [实例截图] [核心代码]详细见压缩包 ssdetection-master ├── LICENSE ├── README.md ├── cfgs │    ...

  8. CNN卷积神经网络案例程序源代码合集matlab/Python等

    CNN卷积神经网络案例程序源代码合集matlab/Python等 1.深入理解CNN(包括CNN的过程显示和前向后向推倒,以及CNN的应用举例.) 2.kerasttensorflowCNN(CNN_ ...

  9. 卷积神经网络手势识别之剪刀石头布

    剪刀石头布手势识别 1.加载数据并解压 (1)使用wget下载训练样本和测试样本的压缩文件 !wget https://storage.googleapis.com/laurencemoroney-b ...

最新文章

  1. 肠·道 | 邱琇:靓汤/烧香影响母婴健康?看巨大出生队列如何揭秘!
  2. NYOJ 单调递增子序列(二)
  3. P1525关押罪犯(并查集补集)
  4. cad打印字体颜色很淡_收藏|50个CAD技巧,常画电路图的你一定得知道
  5. Leetcode题解(十七)
  6. python创建包含双引号的字符串代码_python 字符串组成MySql 命令时,字符串含有单引号或者双引号导致出错解决办法...
  7. linux中逻辑块大小为,Linux 文件系统相关的基本概念
  8. android媒体--stagefright概述
  9. 浙江大学计算机专业选考要求,浙大等招办主任解读2020年选考科目要求!各专业有调整!...
  10. 能源管理系统—能源在线监测平台搭建
  11. android布局置顶_android linearlayout imageview置顶摆放
  12. PR免费转场 PR剪辑视频图形转场PR动态图形模板MOGRT
  13. 多线程ADSL切换IP
  14. Word里面的大括号怎么打出来?
  15. LUA提取免费迅雷账号
  16. 【黑金原创教程】【Modelsim】【第五章】仿真就是人生
  17. 【STM32】BootLoader介绍、编写 以及 OTA常见方案分析(差分升级 全量升级 AB面升级)
  18. 有道云笔记不同步_有道云笔记同步失败,同步不了怎么办
  19. SQL查询语句(从单表到多表、从简单到复杂)
  20. 什么是中台系统以及挑战和解决方案?

热门文章

  1. GNSS/INS组合导航笔记
  2. 【转】科普知识普及 - 桥接VS中继
  3. Dancing Links中文版
  4. MIDI文件深入剖析
  5. VS问题:该依赖项是由项目系统添加的,不能删除。
  6. iOS 添加ttf字体
  7. 5800p计算机公式,我的5800p测量程序及公式-20210324065951.docx-原创力文档
  8. 【Vivado使用误区与进阶】XDC约束技巧之时钟篇
  9. 有人说计算机心理测验更科学,计算机心理动态测验方法及心理测评系统研究探讨...
  10. 听说技术大佬们离不开这些App