阅读 202

计算机视觉大作业

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

基于Opencv+keras的手势识别系统

基于Opencv+keras的手势识别系统

技术

python3.6 + opencv + keras + numpy + PIL

图片处理

通过将照片的腐蚀,灰度处理,自适应阈值分割等操作将图片处理成易于机器识别图片。其中腐蚀操作将图片的中边缘白色噪点,再将三通道图像转化为灰度图片。最后通过使用自适应阈值分割,将背景和内容分离开来

   # 图像边缘处理--腐蚀
   fgmask = cv2.erode(bg, self.skinkernel, iterations=1)
   # 将原始图像与腐蚀处理后的图片做"与"操作
   bitwise_and = cv2.bitwise_and(frame, frame, mask=fgmask)
   # 灰度处理
   gray = cv2.cvtColor(bitwise_and, cv2.COLOR_BGR2GRAY)
   # 高斯滤波
   blur = cv2.GaussianBlur(gray, (self.blurValue, self.blurValue), 2)
   cv2.imshow('GaussianBlur', blur)
   # 使用自适应阈值分割(adaptiveThreshold)
   thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
  #图像阈值化的一般目的是从灰度图像中分享目标区域和背景区域
   cv2.imshow('thresh', thresh)
   Ges = cv2.resize(thresh, (100, 100))
         
复制代码

处理后的的图片:

数据增强

数据增强作用

使用数据增强技术(data augmentation),主要是在训练数据上增加微小的扰动或者变化,一方面可以增加训练数据,从而提升模型的泛化能力,另一方面可以增加噪声数据,从而增强模型的鲁棒性。主要的数据增强方法有:翻转变换 flip、随机修剪(random crop)、色彩抖动(color jittering)、平移变换(shift)、尺度变换(scale)、对比度变换(contrast)、噪声扰动(noise)、旋转变换/反射变换 (rotation/reflection)等。

数据增强操作有如下方面:

图像切割:生成比图像尺寸小一些的矩形框,对图像进行随机的切割,最终以矩形框内的图像作为训练数据。

图像翻转:对图像进行左右翻转。

图像白化:对图像进行白化操作,即将图像本身归一化成Gaussian(0,1)分布。

  test_datagen = ImageDataGenerator(rescale=1. / 255)
        train_datagen = ImageDataGenerator(
            rescale=1. / 255,
            rotation_range=40,
            width_shift_range=0.2,
            height_shift_range=0.2,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True)

        train_dir = r'Gesture_predict'
        validation_dir = r'Gesture_train'
        # train_img_list, test_img_list, train_lable_list, test_lable_list
        train_datagen.fit(train_img_list)
        train_generator = train_datagen.flow(train_img_list,train_lable_list,batch_size=10)
        validation_generator = test_datagen.flow(test_img_list,test_lable_list,batch_size=10)

复制代码

特征提取

        def extarct_features(flag, sample_count):
            features = np.zeros(shape=(sample_count, 3, 3, 512))
            labels = np.zeros(shape=(sample_count,5))
            if flag=="train":
                generator = datagen.flow(train_img_list,train_lable_list,batch_size=20)
            else:
                generator = datagen.flow(test_img_list,test_lable_list,batch_size=20)
            i = 0
            for inputs_batch, labels_batch in generator:
                if i * (batch_size+1 )>= sample_count:
                    break
                features_batch = conv_base.predict(inputs_batch)
                features[i * batch_size: (i + 1) * batch_size] = features_batch
                labels[i * batch_size: (i + 1) * batch_size] = labels_batch
                i += 1


            return features, labels

复制代码

模型改进

从模型入手,提高模型的泛化能力,使用一些改进方法 接下来的步骤是从模型角度进行一些改进,比如批正则化(batch normalization)、权重衰减(weight decay)。我这里实验了3种改进方法,接下来依次介绍。

权重衰减(weight decay):对于目标函数加入正则化项,限制权重参数的个数,这是一种防止过拟合的方法,这个方法其实就是机器学习中的l2正则化方法,只不过在神经网络中旧瓶装新酒改名为weight decay

dropout:在每次训练的时候,让某些的特征检测器停过工作,即让神经元以一定的概率不被激活,这样可以防止过拟合,提高泛化能力

批正则化(batch normalization):batch normalization对神经网络的每一层的输入数据都进行正则化处理,这样有利于让数据的分布更加均匀,不会出现所有数据都会导致神经元的激活,或者所有数据都不会导致神经元的激活,这是一种数据标准化方法,能够提升模型的拟合能力

模型的结构图

 # 批规范化处理
        model.add(BatchNormalization())
        # 激活函数relu
        model.add(Activation('relu', name='activation_1'))
        # 卷积层2,个数32,尺寸3*3,填充方式valid,步长默认1*1
        model.add(Convolution2D(
            filters=32,
            kernel_size=(3, 3),
            name='conv2d_2'
        ))
        model.add(BatchNormalization())
        model.add(Activation('relu', name='activation_2'))

        # 池化层,尺寸2*2,步长为2*2,填充方式为valid
        model.add(MaxPool2D(
            pool_size=(2, 2),
            strides=(2, 2),
            padding='valid',
            name='max_pooling2d_1'
        ))
        # dropout层,失活系数0.5
        model.add(Dropout(0.5, name='dropout_1'))
        # 转化为一维矩阵
        model.add(Flatten(name='flatten_1'))
        # 全连接层,128个神经元
        model.add(Dense(128, name='dense_1'))
        model.add(BatchNormalization())
        model.add(Activation('relu', name='activation_3'))
        # model.add(Dropout(0.5, name='dropout_2'))

        # 分类层,L2正则优化
        model.add(Dense(self.categories,
                        # kernel_regularizer=regularizers.l2(0.01),
                        name='dense_2'))
        # 分类层,激活函数sofomax
        model.add(Activation('softmax', name='activation_4'))
复制代码

结果分析:

结果分析:我们观察训练曲线和验证曲线,很明显地改进后效果好,不仅能使训练过程的loss更稳定,而且能使验证集的准确率提升至90%以上,提升效果十分明显。说明图像增强确实通过增加训练集数据量达到了提升模型泛化能力以及鲁棒性的效果,从准确率上看也带来了将近10%左右的提升,因此,数据增强确实有很大的作用。但是对于80%左右的识别准确率我们还是不够满意.

稿子

  1. 图片处理: 提取出照片的主体内容,去掉噪音和毕竟
  2. 数据增强:提高数据泛化能力
文章分类
人工智能
文章标签