版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ResNet实现手势识别深度学习与图像处理实战知识要点7.1ResNet简介7.2数据集介绍及处理7.3主干网络搭建与训练7.4模型训练结果测试目录7.1ResNet简介VGG网络达到19层后再增加层数就会导致分类性能下降。而残差神经网络(ResidualNeuralNetwork,ResNet)的提出者何恺明等人在2015年提出了残差学习(ResidualLearning)的概念,以简化以前使用的网络,使之能够以更深的网络进行训练,并进一步将它应用在了CNN的构建当中,于是就有了基本的残差块(ResidualBlock)。ResNet通过使用多个带参数的层来学习输入与输出之间的残差表示(真实值与预测值之间的差),而非像一般CNN(如AlexNet和VGG)那样使用带参数的层来直接尝试学习输入与输出之间的映射关系。ResNet的残差块结构7.1ResNet简介在图中,可以看到在不使用残差结构的情况下,18层的神经网络反而比34层的神经网络效果好一点,而使用残差结构后,34层神经网络的错误率(error)比18层神经网络的错误率小得多。网络结构对比图7.2数据集介绍及处理数据集文件夹如左图所示。该数据集是由50位志愿者分别使用摄像头拍摄手势,并使用肤色提取获得的图片构成的。本数据集共有4个文件夹,数据集文件夹存放着4种手势的图片,分别为拳头、1、2以及手掌。数据集内容如右图所示。图
数据集内容图
数据集文件夹7.2数据集介绍及处理importcv2fromPILimportImageimportosfromtensorflow.keras.preprocessing.image\importImageDataGenerator,array_to_img,img_to_array,load_imgimportnumpyasnpfromkeras.utilsimportnp_utilsimportrandomDATASET_PATH=r'D:\下载\skin\skin'DATA_PATH='image_file'01OPTION本章中使用了tf.keras中自带的数据增强。首先,新建一个getimg.py文件,写入如下代码。#数据增强defgetimage():ifnotos.path.exists(DATA_PATH):os.mkdir(DATA_PATH)image_file_paths=[os.path.join(DATASET_PATH,path)forpathinos.listdir(DATASET_PATH)]image_paths=[]forimage_file_pathinimage_file_paths:image_paths.append([os.path.join(image_file_path,path)forpathinos.listdir(image_file_path)])datagen=ImageDataGenerator(rotation_range=30,width_shift_range=0.1,height_shift_range=0.2,shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')7.2数据集介绍及处理forimage_pathinimage_paths:foriinimage_path:print(i)dir_num=i.split('\\')[-2]img=load_img(i)x=img_to_array(img)x=x.reshape((1,)+x.shape)i=0forbatchindatagen.flow(x,batch_size=1,save_to_dir=DATA_PATH,save_prefix='%s'%dir_num,save_format='jpg'):i+=1ifi>7:break程序运行结果如图所示。当前目录中新增了一个image_file文件夹,里面存储的是进行数据增强之后的图片。可以看到,每种手势的图片量都增加了,而且手势的角度、方向也都发生了改变。程序运行结果(1)7.2数据集介绍及处理ImageDataGenerator函数的参数及其说明参数说明rotation_range指定旋转角度范围,只需输入一个整数即可,但并不是固定以这个角度进行旋转,而是在[0,指定角度]的范围内进行随机角度旋转width_shift_range和height_shift_range分别是水平位置平移和垂直位置平移,其参数可以是[0,1]的浮点数,也可以大于1,其最大平移距离为图片长或宽的尺寸乘参数。同样,平移距离并不固定为最大平移距离,而是在[0,最大平移距离]的区间内shear_range错切交换的角度zoom_range随机缩放范围,以使图片在尺寸的长或宽方向进行放大或缩小horizontal_flip随机对图片执行水平翻转操作。意味着不一定对所有图片都执行水平翻转,每次生成均是选取随机图片进行水平翻转fill_mode输入边界以外的点,根据给定的模式填充,默认为“nearest”7.2数据集介绍及处理02OPTION接着加载image_file文件夹中的图片,对其进行二值化、归一化,以及标签独热编码的处理,在最后返回结果的时候,还需要打乱数据集。该过程代码如下。#加载数据集defloaddata():ifos.listdir(DATA_PATH)==[]:#判断是否已经进行数据增强getimage()images_paths=[os.path.join(DATA_PATH,path)forpathinos.listdir(DATA_PATH)]print(images_paths)images=[]labels=[]forimages_pathinimages_paths:image=cv2.imread(images_path)#图像预处理blur=cv2.GaussianBlur(image,(3,3),1)gray=cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)ret,binary=cv2.threshold(gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)7.2数据集介绍及处理images.append(binary)labels.append(images_path.split('\\')[-1].split('_')[0])images=np.array(images)/255.0labels=np_utils.to_categorical(labels)#独热编码#打乱数据集index=[iforiinrange(len(images))]random.shuffle(index)images=images[index]labels=labels[index]print(images[0],labels[0])returnimages,labels这样就可以得到完整的图片数据和标签了。接下来搭建神经网络,并进行训练。7.3主干网络搭建与训练图中layername代表层名,outputsize代表输出层的大小,conv代表卷积层,stride代表卷积的步长,averagepool代表平均池化层,1000-dfc代表长度为1000的全连接层,Softmax代表使用Softmax激活函数,FLOPs代表计算量。图中分别是ResNet18、ResNet34、ResNet50、ResNet101以及ResNet152的结构,它们的输入都是一样的,而且都经过了卷积核为7×7,步长为2的卷积操作以及最大池化操作,并在输出层使用了平均池化代替Flatten层。ResNet结构7.3主干网络搭建与训练ResNet头部区域结构ResNet的结构中,读者可以一边理解图片一边写代码,以加深理解。首先是头部区域,结构如图所示。可以看见,在最大池化层之后,分出了2条支路,一条支路照常进行卷积操作,一条支路不做什么操作,只在输出部分与另一条支路结合。这就是前面提到的残差结构。7.3主干网络搭建与训练defResNet34(inpt):defconv(x,filters,kernel,stride,padding='same'):x=Conv2D(filters,kernel_size=kernel,strides=stride,padding=padding)(x)x=BatchNormalization()(x)x=Activation('relu')(x)returnx本节以ResNet34为例,首先定义一个函数ResNet34,然后将ResNet中重复的部分提取出来封装成一个conv函数,内容主要是卷积、批量标准化、激活函数。这是一个较为主流的组合,Python代码如下。ResNet中重复的部分7.3主干网络搭建与训练#残差结构defres_block(inpt,filters,kernel,stride=1,shortcut=False):x=conv(inpt,filters,kernel,stride)x=conv(x,filters,kernel,stride=1)ifshortcut:y=conv(inpt,filters,kernel,stride)x=add([x,y])else:x=add([x,inpt])returnx在残差结构中可以使用add函数来连接来自2个不同层的输出。注意,连接的2个层的形状必须是一致的。但是由于在残差块中会进行步长为2的卷积(长、宽减半)操作,因此在另一条支路中也要进行同样的操作以保证形状一致,如图所示。ResNet中的残差连接7.3主干网络搭建与训练
自此,一个基本的残差结构就搭建完成了。接着可以根据ResNet结构图的规律进行ResNet-34的搭建,具体代码如下。#224×224x=Conv2D(64,kernel_size=7,strides=2,activation='mish',padding='same')(inpt)#112×112x=MaxPool2D()(x)#56×56x=res_block(x,64,3)x=res_block(x,64,3)x=res_block(x,64,3)x=res_block(x,128,3,stride=2,shortcut=True)#28×28x=res_block(x,128,3)x=res_block(x,128,3)x=res_block(x,128,3)x=res_block(x,256,3,stride=2,shortcut=True)#14×14x=res_block(x,256,3)x=res_block(x,256,3)x=res_block(x,256,3)x=res_block(x,256,3)x=res_block(x,256,3)x=res_block(x,512,3,stride=2,shortcut=True)#7×7x=res_block(x,512,3)x=res_block(x,512,3)x=GlobalAveragePooling2D()(x)x=Dense(1000,activation='softmax')(x)returnk.models.Model(inpt,x)7.3主干网络搭建与训练
接下来开始训练,最后一层为1000个类别的输出,我们用不到这么多,按下面代码进行修改。x=GlobalAveragePooling2D()(x)x=Dropout(0.25)(x)x=Dense(4,activation='softmax')(x)returnk.models.Model(inpt,x)fromsklearn.model_selectionimporttrain_test_splitimages,labels=getimg.loaddata()images=images.reshape(-1,224,224,1)#分割测试集x_train,x_test,y_train,y_test=train_test_split(images,labels,test_size=0.25)#激活函数为Adam,学习率为0.0003adam=Adam(lr=0.0003)pile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])#开始训练model.fit(x_train,y_train,batch_size=16,epochs=30,verbose=1,validation_data=(x_test,y_test),callbacks=[TensorBoard(log_dir='./tmp/log')])score,accuracy=model.evaluate(x_test,y_test,batch_size=16)print('score:',score,'accuracy:',accuracy)model.save('Gesture1_0.h5')
接着就可以开始训练了,代码如下。7.4模型训练结果测试首先定义一个video.py文件,然后写入如下代码。01OPTION使用RGB进行肤色提取importcv2importnumpyasnpfromtensorflow.keras.modelsimportload_model#使用RGB进行肤色提取defskin_color(img):rows,cols,channels=img.shapeimgSkin=img.copy()#获得每个通道中R、G、B的值,并判断是否处于阈值内forrinrange(rows):forcinrange(cols):#分别获取各个通道的值B=img.item(r,c,0)G=img.item(r,c,1)R=img.item(r,c,2)skin=0#当通道的值在某个区间时像素取1if(abs(R-G)>15)and(R>G)and(R>B):if(R>95)and(G>40)and(B>20)and\(max(R,G,B)-min(R,G,B)>15):skin=1elif(R>220)and(G>210)and(B>170):skin=17.4模型训练结果测试代码如下。02OPTION加载训练好的模型#设置图片像素值(二值化)if0==skin:imgSkin.itemset((r,c,0),0)imgSkin.itemset((r,c,1),0)imgSkin.itemset((r,c,2),0)else:imgSkin.itemset((r,c,0),255)imgSkin.itemset((r,c,1),255)imgSkin.itemset((r,c,2),255)returnimgSkinmodel=load_model('Gesture1_0.h5')cam=cv2.VideoCapture(0)hand_label=['0','1','2','5']如肤色提取、高斯模糊、二值化、寻找最大连通区域等,代码如下。03OPTION打开摄像头,进行数据的实时处理whilecam:_,img=cam.read()img=cv2.resize(img,(224,224))#二值化cr=skin_color(img)#高斯滤波,cr是待滤波的源图像数据#(5,5)是指窗口大小,0是指根据窗口大小来计算高斯函数标准差cr1=cv2.GaussianBlur(cr,(5,5),0)#对cr通道分量进行高斯滤波cr1=cv2.cvtColor(cr1,cv2.COLOR_BGR2GRAY)#根据最大类间方差法(OTSU算法)求图像阈值,对图像进行二值化_,skin1=cv2.threshold(cr1,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)con=cv2.findContours(skin1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)7.4模型训练结果测试rect=[]#寻找最大连通区域fori,contourinenumerate(con):#print(i,contour)x,y,w,h=cv2.boundingRect(con[i])rect.append(w*h)#画出最大连通区域的矩形框iflen(rect)!=0:x,y,w,h=cv2.boundingRect(con[rect.index(max(rect))])w=h=int((w+h)/2)cv2.rectangle(img,(x-10,y
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- QC/T 2-2026汽车产品图样格式
- T/CPIA 0038-2022光伏硅片切割用电镀金刚石线
- T/TAC 13-2025本地化业务 术语
- T/FSBMEA 1-2023化妆品常用植物提取物中16种香豆素类化合物的测定 液质联用法
- T/CI 1382-2025智能电网用馈线自动调压装置通用要求
- T/CAAMTB 168-2023汽车用35MPa压缩天然气(CNG)加气枪
- T/COSHA 55-2025高原铁路隧道作业人员供氧和膳食指南
- AI在世界语中的应用
- 2025~2026学年安徽省亳州市涡阳县北师大版六年级上册阶段性练习(三)数学试卷【附答案】
- 2025-2026学年浙江省温岭市初中政治八年级期末下册提升黑金考题(附答案)
- 【MOOC】《医学心理学》(北京大学)章节期末中国大学慕课答案
- 拖欠工程款上访信范文
- 产品设计开发项目移交量产交付文件清单
- 2023年江苏省公考《申论》题(A卷)及参考答案
- 工程造价专业毕业外文文献、中英对照
- 2024年重庆市高考历史试卷(含答案)
- JGT233-2017 建筑门窗用通风器
- 关于要求XX人寿全额退还被误导保费的投诉信
- 麻醉手术期间液体治疗建议
- 垄断性产业的管制政策产业经济学
- 宝洁日化培训课件3-8-002 Clean design training start
评论
0/150
提交评论