opencv舌头监测模型+keras神经网络(LeNet)

基于前面使用opencv实现舌头模型检测后,本次主要针对模型参数调优,提高图片识别率。

之前的模型精准率很高,但召回率不一定为1,有时候舌头图片并没有被圈出。所以我们需要调整参数让模型吧舌头都识别出来,再通过LeNet模型做后续识别,将不是舌头的剔除掉。

首先修改opencv训练后的模型参数,调低scaleFactor值,让模型更敏感,圈出更多的图片(舌头+额外的其他非舌头图片)

在默认参数(scaleFactor=1.38, minNeighbors=4, minSize=(20,20),),

Cascades模型的识别率偏低但精度高,

在该参数下,在数据规模为500的测试集中,一共切割出446张小图,覆盖了500张图片中的398张图片,剩余的48张小图为识别错误图片,或冗余图片。

修改为:(scaleFactor=1.002,, minNeighbors=3, minSize=(3,3),),

在该参数下,在数据规模为500的测试集中,一共切割出4823张小图,覆盖了500张图片中的499张图片,剩余的4324张小图为识别错误图片,或冗余图片。

对比发现,前者的精准率很高,但召回率低于后者。所以我们在加上LeNet模型对后者进行再次过来筛选。

收集整理数据集

在上一个步骤中,我们通过Cascades算法共获得4823切割后的小图,首先我们需要人工把这些图片分为正样本(是舌头)和图样本(非舌头)。

考虑到后期神经网络模型的计算量,在载入数据时,我们会将图片标化为200 * 200的灰度图片,分完后的效果如下:

正样本:

9da2c8d9a714abb3b2009531aa4424113e4.jpg
负样本:

d196ffd60b9f2b14d60613131398d2c7856.jpg

构建卷积神经网络并训练

为了提高模型的判别准确率,我们构建了一个深度为15层的卷积神经网络,

卷积网络的输入是以200 * 200 的灰度图片,输出是一个0-1之前的值,该值是一个概率值,

f597dcd42bdefc02ef72228f4f62449b260.jpg

import cv2
import os
import numpy as np
import tensorflow as tf

import keras.backend as K
from keras.datasets import mnist
from keras.layers import *
from keras.models import *
from keras.optimizers import *
from keras.initializers import *
from keras.callbacks import *
from keras.utils.vis_utils import plot_model#显示层级图
from tqdm import tqdm


def loadGrayImg(path, shape=(200, 200, 1)):
    """
    获取灰度值图片
    :param path:
    :return:
    """
    img = cv2.imread(path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = cv2.resize(img, (shape[0], shape[1]))
    return np.reshape(img, shape)


def loadData(dir, shape=(200, 200, 1)):
    """
    加载数据集
    :param dir:
    :return:
    """
    imgs = []
    for fn in os.listdir(dir):
        if fn.endswith('jpg'):
            imgs.append(loadGrayImg(os.path.join(dir, fn), shape=(200, 200, 1)))
    return np.array(imgs)#转换为numpy矩阵


def net():
    """卷及网络模型"""
    inputs = Input(shape=(200, 200, 1))
    model = Lambda(lambda x: (x - 127.5) / 127.5)(inputs)#将像素值变为(-1,-1)----灰度值是从0-255
    #卷积层--16个特征图,关机过滤器(5*5),步长2*2,特征图大小:(200-5+2)/2=98
    model = Conv2D(16, 5, strides=(2, 2))(model)
    #激活层--高级激活层Advanced Activation-----LeakyReLU层,LeakyRelU是修正线性单元(Rectified Linear Unit,ReLU)的特殊版本,当不激活时,
    # LeakyReLU仍然会有非零输出值,从而获得一个小梯度,避免ReLU可能出现的神经元“死亡”现象。即,f(x)=alpha * x for x < 0, f(x) = x for x>=0

    #  sigmoid和tanh在x趋于无穷的两侧,都出现导数为0的现象,成为软饱和激活函数。也就是造成梯度消失的情况,从而无法更新网络状态。
  # relu的主要特点就是:单侧抑制,相对宽阔的兴奋边界,稀疏激活性。稀疏激活性,是指使得部分神经元输出为0,造成网络的稀疏性,
  #缓解过拟合现象。但是当稀疏过大的时候,出现大部分神经元死亡的状态,因此后面还有出现改进版的prelu.就是改进左侧的分布
    model = LeakyReLU()(model)
    #池化层----输出49*49*16
    model = MaxPooling2D(strides=2)(model)
    #卷积层---32个特征图,(49-5+2)/2=23-------输出23*23*32
    model = Conv2D(32, 5, strides=(2, 2))(model)
    #激活层
    model = LeakyReLU()(model)
    #池化层--输出11*11*32
    model = MaxPooling2D(strides=2)(model)
    #卷积层--64个特征图feature map,输出(11-5+2)/2=4*4*64
    model = Conv2D(64, 5, strides=(2, 2))(model)
    #激活层
    model = LeakyReLU()(model)
    #池化层---输出2*2*64
    model = MaxPooling2D(strides=2)(model)
    #展开层--输出256
    model = Flatten()(model)
    #drop层,默认0.5最好
    model = Dropout(0.2)(model)
    #全连接层,压缩为需要的维度128,如果本层的输入数据的维度大于2,则会先被压为与kernel相匹配的大小。
    model = Dense(128)(model)
    # 全连接层,压缩为需要的维度128
    model = Dense(units=1, activation='sigmoid')(model)#使用simgod输出0-1之间的值 ,二分类
    #生成模型
    model = Model(inputs=inputs, outputs=model)
    #运行模型,开始训练
    model.compile(optimizer='nadam', loss='binary_crossentropy', metrics=['accuracy'])
    return model


def train(echos=500, batch_size=128):
    """训练模型"""
    model = net()
    model.summary()
    plot_model(model, show_shapes=True, show_layer_names=True)

    positive = loadData('train/positive')#加载正数据
    negtive = loadData('train/negtive')#加载负数据
    #合并两个矩阵----相当于拼接到前面一个数组的后面
    x = np.concatenate([positive, negtive])
    y = np.zeros(len(x))
    #赋值标签
    y[0:len(positive)] = 1.
    y[len(positive):] = 0.

#进度条
    for i in tqdm(range(int(echos))):
        model.fit(x, y, batch_size=batch_size)#训练传入数据和标签
        model.save('model/tongue_%d.model' % i)


if __name__ == '__main__':
    train()

最后整合Cascades模型和卷积网络模型,做图像切割

在识别和切割舌头头图片时,主要用到了Cascades模型和卷积网络模型两种算法模型。

其中Cascades模型主完成于舌头的坐标定位;随后我们会根据这个鞋坐标切割出一组图像,而卷积网络模型则用于计算这一组图像中每一个图片属于舌头的概率,最终选取概率最高的一张作为输出。

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
<p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;"> <p> <span style="color:#E53333;">购买课程后,添加小助手微信微信号:csdnxy68回复【唐宇迪】</span> </p> <p> 进入学习群,获取唐宇迪老师答疑 </p> <div> </div> </span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">深度学习经典论文解读与项目实战课程旨在帮助同学们掌握当下深度学习领域最核心论文思想及其源码实现。所选论文均是计算机视觉与自然语言处理领域主流通用算法,主要内容包括四大核心部分:1.论文核心思想解读;2.论文细节知识点精讲;3.论文代码复现与应用;4.大型开源项目源码解读;整体风格通俗易懂,所有论文均结合实战项目展开,理论与实战应用**结合,适合进阶提升与转行就业的同学们。</span> </p> <br /> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">课程特色:</span><br /> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">1、深度学习领域经典和通用算法精讲,提升与面试必备!</span><br /> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">2、通俗易懂,核心知识点全面覆盖,算法与代码结合!</span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">3、大型开源项目实战,Google,Facebook等核心算法实战!</span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">4、提供全部数据,代码,PPT,持续更新,永久有效!</span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;"><br /> </span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;">讲师卡更优惠,可加入全部课程包括后续更细那内容</span> </p> <p> <span style="font-size:14px;color:#666666;background-color:#FFFFFF;"><br /> </span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页