tensorflow入门教程(三十四)疲劳检测之开眼闭眼识别

本文主要是介绍tensorflow入门教程(三十四)疲劳检测之开眼闭眼识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#
#作者:韦访
#博客:https://blog.csdn.net/rookie_wei
#微信:1007895847
#添加微信的备注一下是CSDN的
#欢迎大家一起学习
#

------韦访 20190118

1、概述

想用tensorflow做个疲劳检测,那么,该怎么下手呢?首先,根据常识,疲劳的时候,眼睛总会想闭上吧?还打哈欠吧?那么,先从眼睛入手,那么,要做的工作就是,首先得识别出眼睛的位置,也就是人脸关键点检测,在人脸识别上的教程(https://blog.csdn.net/rookie_wei/article/details/81676177)中,我们讲过,使用MTCNN可以将人脸检测出来,并且识别出5个关键点(左眼、右眼、鼻子、左嘴角、右嘴角)的位置。检测出眼睛的位置以后,就可以将眼睛的框出来,然后,识别它是开眼还是闭眼。打哈欠的话,是不是也得先识别嘴巴的位置啊?识别出嘴巴以后怎办,后面再说。这一讲,先来对眼睛的开闭进行识别。首先说明一下,我可能并不会给出一个完整的疲劳检测系统的教程,做出来了我可能也不会全部开源,仅供部分参考,作为之前教程的一个回顾,你懂的。

2、下载数据集

下载链接:

http://parnec.nuaa.edu.cn/xtan/data/datasets/dataset_B_Eye_Images.rar

数据集很小,2.5M而已。下载完以后,解压,得到目录如下:

根据文件夹名称,可以猜出应该是将眼睛分为4种状态了,分别是左眼开,左眼闭,右眼开,右眼闭。现在来看看每个文件夹里的内容是否跟我们预想的一样。

 

 

果然哈。那么接下来的问题就是,怎么识别?看过我tensorflow系列教程的朋友们应该知道,在第16讲和20讲中,我们使用过slim模型来进行图片分类,如果没看过,出门左转,链接如下:

16讲:https://blog.csdn.net/rookie_wei/article/details/80639490

20讲:https://blog.csdn.net/rookie_wei/article/details/80796009

这一讲,其实就是这两讲的一样应用,如果看过这两讲的朋友,就此打住,别往下看了,自己根据这两讲的内容做一下开闭眼的识别。

3、将数据集转成TFRecord格式

slim模型的下载、验证和结构我就不再重复讲了,现在,我们来将数据集转成TFRecord格式。我试过就按数据集的默认分类去识别,即左眼开,左眼闭,右眼开,右眼闭,效果并不好,识别的准确率仅为50%多一点,这肯定不行的。而我们现在的目的是,能识别出开眼和闭眼即可,所以并不需要分的那么详细。因此,现在将closedRightEyes文件夹下的所有图片剪切到closedLeftEyes文件夹,将openRightEyes文件夹下的所有图片剪切到openLeftEyes文件夹。再把两个空的文件夹删除,剩下的如下图所示,

将这个两个文件夹放到slim/images_data/eye_open_and_close文件夹下。

好了,接着就来修改代码了,仿造第20讲的教程做即可,写博客或者笔记的好处就是这样了,随手一拿就可以开干。首先,复制download_and_convert_flowers.py并将文件名改为convert_eye.py。修改后的源码如下,

# encoding:utf-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_functionimport math
import os
import random
import sysimport tensorflow as tffrom datasets import dataset_utils# The URL where the Flowers data can be downloaded.
_DATA_URL = 'http://download.tensorflow.org/example_images/flower_photos.tgz'# The number of images in the validation set.
_NUM_VALIDATION = 350# Seed for repeatability.
_RANDOM_SEED = 0# The number of shards per dataset split.
_NUM_SHARDS = 4class ImageReader(object):"""Helper class that provides TensorFlow image coding utilities."""def __init__(self):# Initializes function that decodes RGB JPEG data.self._decode_jpeg_data = tf.placeholder(dtype=tf.string)self._decode_jpeg = tf.image.decode_jpeg(self._decode_jpeg_data, channels=3)def read_image_dims(self, sess, image_data):image = self.decode_jpeg(sess, image_data)return image.shape[0], image.shape[1]def decode_jpeg(self, sess, image_data):image = sess.run(self._decode_jpeg,feed_dict={self._decode_jpeg_data: image_data})assert len(image.shape) == 3assert image.shape[2] == 3return imagedef _get_filenames_and_classes(dataset_dir):"""Returns a list of filenames and inferred class names.Args:dataset_dir: A directory containing a set of subdirectories representingclass names. Each subdirectory should contain PNG or JPG encoded images.Returns:A list of image file paths, relative to `dataset_dir` and the list ofsubdirectories, representing class names."""# 将flower_photos改为eye_photosflower_root = os.path.join(dataset_dir, 'eye_open_and_close')directories = []class_names = []for filename in os.listdir(flower_root):path = os.path.join(flower_root, filename)if os.path.isdir(path):directories.append(path)class_names.append(filename)photo_filenames = []for directory in directories:for filename in os.listdir(directory):path = os.path.join(directory, filename)photo_filenames.append(path)return photo_filenames, sorted(class_names)def _get_dataset_filename(dataset_dir, split_name, shard_id):# 修改文件名,将flowersg改为eyeoutput_filename = 'eye_%s_%05d-of-%05d.tfrecord' % (split_name, shard_id, _NUM_SHARDS)return os.path.join(dataset_dir, output_filename)def _convert_dataset(split_name, filenames, class_names_to_ids, dataset_dir):"""Converts the given filenames to a TFRecord dataset.Args:split_name: The name of the dataset, either 'train' or 'validation'.filenames: A list of absolute paths to png or jpg images.class_names_to_ids: A dictionary from class names (strings) to ids(integers).dataset_dir: The directory where the converted datasets are stored."""assert split_name in ['train', 'validation']num_per_shard = int(math.ceil(len(filenames) / float(_NUM_SHARDS)))with tf.Graph().as_default():image_reader = ImageReader()with tf.Session('') as sess:for shard_id in range(_NUM_SHARDS):output_filename = _get_dataset_filename(dataset_dir, split_name, shard_id)with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer:start_ndx = shard_id * num_per_shardend_ndx = min((shard_id + 1) * num_per_shard, len(filenames))for i in range(start_ndx, end_ndx):sys.stdout.write('\r>> Converting image %d/%d shard %d' % (i + 1, len(filenames), shard_id))sys.stdout.flush()# Read the filename:image_data = tf.gfile.FastGFile(filenames[i], 'rb').read()height, width = image_reader.read_image_dims(sess, image_data)class_name = os.path.basename(os.path.dirname(filenames[i]))class_id = class_names_to_ids[class_name]example = dataset_utils.image_to_tfexample(image_data, b'jpg', height, width, class_id)tfrecord_writer.write(example.SerializeToString())sys.stdout.write('\n')sys.stdout.flush()def _clean_up_temporary_files(dataset_dir):"""Removes temporary files used to create the dataset.Args:dataset_dir: The directory where the temporary files are stored."""filename = _DATA_URL.split('/')[-1]filepath = os.path.join(dataset_dir, filename)tf.gfile.Remove(filepath)# 将flower_photos改为eye_photostmp_dir = os.path.join(dataset_dir, 'eye_photos')tf.gfile.DeleteRecursively(tmp_dir)def _dataset_exists(dataset_dir):for split_name in ['train', 'validation']:for shard_id in range(_NUM_SHARDS):output_filename = _get_dataset_filename(dataset_dir, split_name, shard_id)if not tf.gfile.Exists(output_filename):return Falsereturn Truedef run(dataset_dir):"""Runs the download and conversion operation.Args:dataset_dir: The dataset directory where the dataset is stored."""if not tf.gfile.Exists(dataset_dir):tf.gfile.MakeDirs(dataset_dir)if _dataset_exists(dataset_dir):print('Dataset files already exist. Exiting without re-creating them.')return# 因为我们不需要下载,所以这行注释掉# dataset_utils.download_and_uncompress_tarball(_DATA_URL, dataset_dir)photo_filenames, class_names = _get_filenames_and_classes(dataset_dir)class_names_to_ids = dict(zip(class_names, range(len(class_names))))# Divide into train and test:random.seed(_RANDOM_SEED)random.shuffle(photo_filenames)training_filenames = photo_filenames[_NUM_VALIDATION:]validation_filenames = photo_filenames[:_NUM_VALIDATION]# First, convert the training and validation sets._convert_dataset('train', training_filenames, class_names_to_ids,dataset_dir)_convert_dataset('validation', validation_filenames, class_names_to_ids,dataset_dir)# Finally, write the labels file:labels_to_class_names = dict(zip(range(len(class_names)), class_names))dataset_utils.write_label_file(labels_to_class_names, dataset_dir)# 将这行注释掉,要不然转换完以后,原始数据会被删除# _clean_up_temporary_files(dataset_dir)print('\nFinished converting the Flowers dataset!')

再修改download_and_convert_data.py,添加

from datasets import convert_eye

再在

elif FLAGS.dataset_name == 'mnist':
  download_and_convert_mnist.run(FLAGS.dataset_dir)

后添加

elif FLAGS.dataset_name == 'eye':
  convert_eye.run(FLAGS.dataset_dir)

如下图所示,

然后运行命令,

python download_and_convert_data.py --dataset_name=eye --dataset_dir=images_data/eye_open_and_close

运行结果,

Instructions for updating:

Use tf.gfile.GFile.

>> Converting image 143/4498 shard 0Traceback (most recent call last):

  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 1335, in _do_call

    return fn(*args)

  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 1320, in _run_fn

    options, feed_dict, fetch_list, target_list, run_metadata)

  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 1408, in _call_tf_sessionrun

    run_metadata)

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected image (JPEG, PNG, or GIF), got unknown format starting with '\320\317\021\340\241\261\032\341\000\000\000\000\000\000\000\000'

 [[{{node DecodeJpeg}}]]

 

报错,看这句,

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected image (JPEG, PNG, or GIF), got unknown format starting with

应该首先想到的是,我们数据集里是不是有不是图片的文件?

果然就看到了如下图这个文件,

删掉即可,注意,两个文件夹下都有这个文件啊。

再运行上面的命令,运行结果,

这就对了,当然,这个打印还是打印Flowsers数据集的,如果你有强迫症,也可以把它改了。去images_data/eye_open_and_close/文件夹下看看有没有TFRecord文件生成,

你也可以用第20讲的代码显示一张图片以验证这个TFRecord是否正确,我这里就不验证了。

4、定义datasets文件

继续修改代码,将datasets/flowers.py复制并重命名为eye.py ,将

_FILE_PATTERN = 'flowers_%s_*.tfrecord'

改为

_FILE_PATTERN = 'eye_%s_*.tfrecord'

SPLITS_TO_SIZES = {'train': 3320, 'validation': 350}

改为

SPLITS_TO_SIZES = {'train': 4496, 'validation': 350}

其中,train代表训练的图片张数,validation代表验证使用的图片张数。完整代码如下,

# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Provides data for the flowers dataset.The dataset scripts used to create the dataset can be found at:
tensorflow/models/research/slim/datasets/download_and_convert_flowers.py
"""from __future__ import absolute_import
from __future__ import division
from __future__ import print_functionimport os
import tensorflow as tffrom datasets import dataset_utilsslim = tf.contrib.slim_FILE_PATTERN = 'eye_%s_*.tfrecord'SPLITS_TO_SIZES = {'train': 4496, 'validation': 350}_NUM_CLASSES = 2_ITEMS_TO_DESCRIPTIONS = {'image': 'A color image of varying size.','label': 'A single integer between 0 and 4',
}def get_split(split_name, dataset_dir, file_pattern=None, reader=None):"""Gets a dataset tuple with instructions for reading flowers.Args:split_name: A train/validation split name.dataset_dir: The base directory of the dataset sources.file_pattern: The file pattern to use when matching the dataset sources.It is assumed that the pattern contains a '%s' string so that the splitname can be inserted.reader: The TensorFlow reader type.Returns:A `Dataset` namedtuple.Raises:ValueError: if `split_name` is not a valid train/validation split."""if split_name not in SPLITS_TO_SIZES:raise ValueError('split name %s was not recognized.' % split_name)if not file_pattern:file_pattern = _FILE_PATTERNfile_pattern = os.path.join(dataset_dir, file_pattern % split_name)# Allowing None in the signature so that dataset_factory can use the default.if reader is None:reader = tf.TFRecordReaderkeys_to_features = {'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),'image/format': tf.FixedLenFeature((), tf.string, default_value='png'),'image/class/label': tf.FixedLenFeature([], tf.int64, default_value=tf.zeros([], dtype=tf.int64)),}items_to_handlers = {'image': slim.tfexample_decoder.Image(),'label': slim.tfexample_decoder.Tensor('image/class/label'),}decoder = slim.tfexample_decoder.TFExampleDecoder(keys_to_features, items_to_handlers)labels_to_names = Noneif dataset_utils.has_labels(dataset_dir):labels_to_names = dataset_utils.read_label_file(dataset_dir)return slim.dataset.Dataset(data_sources=file_pattern,reader=reader,decoder=decoder,num_samples=SPLITS_TO_SIZES[split_name],items_to_descriptions=_ITEMS_TO_DESCRIPTIONS,num_classes=_NUM_CLASSES,labels_to_names=labels_to_names)

5、开始训练

接着,修改datasets/dataset_factory.py文件,

from datasets import cifar10
from datasets import flowers
from datasets import imagenet
from datasets import mnist

datasets_map = {
    'cifar10': cifar10,
    'flowers': flowers,
    'imagenet': imagenet,
    'mnist': mnist,
}

改成

from datasets import cifar10
from datasets import flowers
from datasets import imagenet
from datasets import mnist
from datasets import eye

datasets_map = {
    'cifar10': cifar10,
    'flowers': flowers,
    'imagenet': imagenet,
    'mnist': mnist,
    'eye': eye,
}

然后,运行以下代码进行训练,

python train_image_classifier.py   --train_dir=saver/inv3_eye_open_and_close   --dataset_name=eye   --dataset_split_name=train   --dataset_dir=images_data/eye_open_and_close   --model_name=inception_v3       --learning_rate_decay_type=fixed   --save_interval_secs=60  --save_summaries_secs=60   --log_every_n_steps=10   --optimizer=rmsprop   --learning_rate=0.0001

运行结果,

OK,跑起来就行了。

6、测试准确率

训练到感觉loss不怎么下降的时候,测试一下它的准确率,命令如下,

python eval_image_classifier.py   --checkpoint_path=saver/inv3_eye_open_and_close/   --eval_dir=saver/inv3_eye_open_and_close/   --dataset_name=eye  --dataset_split_name=validation  --dataset_dir=images_data/eye_open_and_close  --model_name=inception_v3   --batch_size=64

在测试集上的准确率为93.49%,在精度不是要求特别高的情况下还是可以了。

 

如果您感觉本篇博客对您有帮助,请打开支付宝,领个红包支持一下,祝您扫到99元,谢谢~~

这篇关于tensorflow入门教程(三十四)疲劳检测之开眼闭眼识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/214307

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Rust中的Option枚举快速入门教程

《Rust中的Option枚举快速入门教程》Rust中的Option枚举用于表示可能不存在的值,提供了多种方法来处理这些值,避免了空指针异常,文章介绍了Option的定义、常见方法、使用场景以及注意事... 目录引言Option介绍Option的常见方法Option使用场景场景一:函数返回可能不存在的值场景

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

Weex入门教程之4,获取当前全局环境变量和配置信息(屏幕高度、宽度等)

$getConfig() 获取当前全局环境变量和配置信息。 Returns: config (object): 配置对象;bundleUrl (string): bundle 的 url;debug (boolean): 是否是调试模式;env (object): 环境对象; weexVersion (string): Weex sdk 版本;appName (string): 应用名字;

Weex入门教程之3,使用 Vue 开发 Weex 页面

环境安装 在这里简略地介绍下,详细看官方教程 Node.js 环境 Node.js官网 通常,安装了 Node.js 环境,npm 包管理工具也随之安装了。因此,直接使用 npm 来安装 weex-toolkit。 npm 是一个 JavaScript 包管理工具,它可以让开发者轻松共享和重用代码。Weex 很多依赖来自社区,同样,Weex 也将很多工具发布到社区方便开发者使用。