数字图像处理课程设计-疲劳检测系统

2023-11-18

数字图像处理课程设计-疲劳检测系统

前言

  • 此系统基于MATLAB设计,核心思想是PERCLOS算法.

  • 参考文章MATLAB疲劳检测系统 - 知乎

  • 需要源码的,私信或者留下邮箱

    一、课程设计任务

应用数字图像处理相关知识和技术实现某一应用,如人脸识别、动物识别、水果识别等综合性任务,题目自选。

本文在matlab R2018b开发环境下,实现人脸检测系统。

疲劳检测可以应用于大巴车司机,货车司机疲劳驾驶监测,现在很多情况下大巴车或者货车等司机都由于休息不好,疲劳上路,这就给安全造成了及其大的隐患。如果有一套系统,可以实时接入车辆摄像头,摄像头对准司机,当检测到司机疲劳状态的时候,则提醒后台并且语音提醒,以做出正确决策,避免车祸等悲剧的发生。该系统也可以应用于上课学生专注度分析,进行疲劳预警。

二、设计框图

在这里插入图片描述

三、准备工作

  • 开发环境:windows 10,matlab R2018b
  • 制图软件:visio 2013
  • 素材示意:人脸图像/视频
    在这里插入图片描述

四、任务流程

4.1视频预处理

  1. 首先将彩色视频video.avi读入,将图像分帧。
obj = VideoReader(uigetfile('*.avi','选择视频'));%输入视频位置
setappdata(0,'obj',obj);%设置全局变量
Show_Frames=read(obj,1);%显示第一帧作为封面
axes(handles.axes1);
imshow(Show_Frames);
set(handles.listbox1,'String','分帧开始...');

prompt={'输入图片名是几位数:'};
	defans={'2'};%默认两位数
	p=inputdlg(prompt,'输入位数',1,defans);
	numzeros=str2num(p{1});
   nz = strcat('%0',num2str(numzeros),'d');

numFrames = obj.NumberOfFrames;% 帧的总数
for k = 1 :5  % 读取前5帧  numFrames
frame = read(obj,k);%读取第几帧
id=sprintf(nz,k);
imwrite(frame,strcat('video_images/',id,'.jpg'),'jpg');% 保存帧
end
set(handles.listbox1,'String','分帧结束');
  1. 利用MATLAB函数rgb2gray转换成灰度图像。

  2. 去除视频黑边,定位有效图像区域。

  3. 将结果输出到指定路径images下。

function [Irect, rect] = GetValideImage(Img, flag)
% 获取有效图像区域
if nargin < 2
    flag = 1;
end

% 灰度化
if ndims(Img) == 3
    I = rgb2gray(Img);
else
    I = Img;
end
% 去除视频黑边,定位有效图像区域
tol = 1000;
sz = size(I);
cs = sum(I, 1);
c = find(cs > tol);
cmin = min(c);
cmax = max(c);
rect = [cmin 1 cmax-cmin sz(1)];
% 图像切割,获取有效区域图像
Irect = imcrop(Img, rect);
% 显示中间处理过程图像
if flag
    figure;
    subplot(2, 2, 1); imshow(Img, []); title('原图像');
    subplot(2, 2, 2); imshow(I, []); title('灰度图像');
    subplot(2, 2, 3); imshow(Img, []); title('有效区域图像标记');
    hold on;
    rectangle('Position', rect, 'EdgeColor', 'r', 'LineWidth', 2);
    hold off;
    subplot(2, 2, 4); imshow(Irect, []); title('有效区域图像');
end

4.2图片分割

4.2.1 人脸定位

  1. 读入images路径下所有jpg图像。

  2. 利用MATLAB函数rgb2hsv将RGB颜色转换为HSV。

% 颜色空间转换
hsv = rgb2hsv(Img);
h = hsv(:, :, 1);
s = hsv(:, :, 2);
v = hsv(:, :, 3);
% 区域数据范围
hsp = [0.01 0.5];
ssp = [0.1 0.85];
vsp = [0.25 0.85];
sz = size(h);
  1. 根据HSV对肤色定位,提取人脸区域。
% 初始化模板
mask = zeros(sz);
% 肤色定位
for i = 1 : sz(1)
    for j = 1 : sz(2)
        if h(i, j) > hsp(1) && h(i, j) < hsp(2) && ...
                s(i, j) > ssp(1) && s(i, j) < ssp(2) && ...
                v(i, j) > vsp(1) && v(i, j) < vsp(2)
            mask(i, j) = 1;
        end
    end
end
% 形态学处理
mask = logical(mask);
mask = imclose(mask, strel('disk', 15));
mask = imopen(mask, strel('disk', 15));
mask = imfill(mask, 'holes');
% 提取人脸区域
[L, num] = bwlabel(mask);
stats = regionprops(L);
Ar = cat(1, stats.Area);
[Ar, ind] = sort(Ar, 'descend');
bw = mask;
bw(L ~= ind(1)) = 0;

4.2.2人眼定位

  1. 先对图像预处理,利用MATLAB函数rgb2gray转换成灰度图像。利用函数medfilt2对图像中值滤波,利用灰度积分find进行投影。
% 灰度化
if ndims(Img) == 3
    I = rgb2gray(Img);
else
    I = Img;
end
% 中值滤波
I = medfilt2(I, [5 5]);
% 灰度积分投影
sz = size(I);
[r, c] = find(I > 0);
rmin = min(r);
rmax = max(r);
cs = sum(I, 1);
rs = sum(I, 2);
[maxcs, indmaxcs] = max(cs);
[maxrs, indmaxrs] = max(rs);
  1. 对人眼区域定位。
% 人眼区域定位
cstart = max(sz(2)-indmaxcs-35, 8);
csend = min(indmaxcs + 15, sz(2)-20);
rstart = max(indmaxrs-40, 25);
rsend = indmaxrs;
rect = [cstart rstart csend-cstart rsend-rstart];
  1. 裁掉多余的区域。
% 人眼区域裁剪
Im = imcrop(Img, rect);
if flag
    figure;
    subplot(2, 2, 1); imshow(Img, []); title('原图像');
    subplot(2, 2, 2); imshow(I, []); hold on;
    rectangle('Position', rect, 'EdgeColor', 'r');
    hold off;
    title('灰度图像');
    subplot(2, 2, 3); plot(1:sz(2), cs);  title('列投影曲线');
    subplot(2, 2, 4); plot(rs, 1:sz(1)); title('行投影曲线');
end

4.2.3人眼精确定位

  1. 图像预处理,利用MATLAB函数rgb2gray对图像进行灰度化。利用函数graythresh进行二值化。提取图像边缘。
% 获取精确人眼区域
if nargin < 2
    flag = 1;
end

% 灰度化
if ndims(Img) == 3
    I = rgb2gray(Img);
else
    I = Img;
end
% 二值化
th = max(graythresh(I)*0.4, 0.1);
bw = im2bw(I, th);
% 提取边缘
bwe = edge(bw, 'canny');
% 填孔处理
bwd = imfill(bwe, 'holes');
bwf = bwd;
bwf = imdilate(bwf, strel('square', 3));
bwf = imfill(bwf, 'holes');
% 去掉边缘噪声
[L, num] = bwlabel(bwf);
stats = regionprops(L);
Ar = cat(1, stats.Area);
[Ar, ind] = sort(Ar, 'descend');
if num > 2
    for j = 3 : num
        bwf(L == ind(j)) = 0;
    end
end
  1. 提取定位结果。
% 提取定位结果
rect1 = stats(ind(1)).BoundingBox;
rect2 = stats(ind(2)).BoundingBox;
rect1(2) = rect1(2) - 2;
rect2(2) = rect2(2) - 2;
rect{1} = rect1;
rect{2} = rect2;

4.3疲劳检测

  1. 利用PERCLOS算法,计算人眼在单位时间内闭合所占比。
data = cat(1, Nv.nv);
Nmin = min(data);
Nmax = max(data);
rate = (data-Nmin)./(Nmax-Nmin);
set(handles.listbox3,'string',rate)
pause(5) %%%%每间隔2s时间处理下一帧图像
  1. 输出结果, 计算的perclos值与tol做比较判断是否疲劳
tol = 0.4;  %%%归一化判断标准
status = '正常';
for i = 1 : N
    if rate(i) < tol && isequal(status, '正常')
        status = '疲劳';
        start = i;
    end
    if rate(i) < tol && isequal(status, '疲劳') && i - start > 1
        status = '睡着';
        start = i;
    end
    if rate(i) < tol && isequal(status, '睡着') && i - start > 2
        status = '疲劳';
        start = i;
    end
    if rate(i) > tol
        status = '正常';
    end
    Nv(i).status = status;
      
end

五、结果

  1. GUI界面
    在这里插入图片描述

  2. 输入视频,分帧处理,分割图像

在这里插入图片描述

  1. 输出结果
    在这里插入图片描述

六、项目总结

使用图像预处理技术得到灰度分配较为均匀的图像,然后分别利用水平和垂直灰度积分投影曲线结合人脸的结构特征找到眼睛的位置坐标,实现了准确的眼睛定位,通过perclos技术技术眨眼率,根据先验值得到是否疲劳。完成了疲劳检测系统的设计。

通过本次项目设计,不仅熟练应用了MATLAB的基本函数,也学到了PERCLOS算法。

PERCLOS算法(Percentage of Eyelid Closure Over the Pupil Time的缩写,意为单位时间里眼睛闭合时间所占的百分比)

PERCLOS原理: F= t   3   − t   2   t   4   − t   1   \frac{t~3~-t~2~}{t~4~-t~1~} t 4 t 1 t 3 t 2 *100%

F是一的话就是睁眼;连续N帧后便可获取关于01之间的序列,然后分析0在该序列中所占比例来描述疲劳状态。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数字图像处理课程设计-疲劳检测系统 的相关文章

  • 如何在matlab中使矩阵图平滑

    就像上图一样 怎样才能让画面更流畅呢 或者缩小y轴的范围 数据来自二维矩阵 然后我用plot data 请随意提出任何想法 平滑线条的一种方法涉及样本点之间数据的非线性插值 当你这样做时plot x y o http www mathwor
  • MATLAB 子图标题和轴标签

    我有以下脚本来最终绘制 4 x 2 子图 files getAllFiles preliminaries n size files cases cell 1 n m cell 1 n for i 1 1 n S load files i c
  • matlab中简单正弦波的傅里叶变换

    我尝试显示简单正弦波的频谱 因为我们知道具有固定频率的单个正弦波必须在其频谱中出现峰值我编写了这段代码 但我无法得到这个峰值我的代码中有什么问题 clc nsteps 200 number of signal elements in tim
  • MATLAB 符号替换

    我知道在 MATLAB 中如果声明了 syms x y f x 2 y 2 grad gradient f 然后grad会存储值 2 x 2 y 如果我想评估梯度 2 2 I use subs f x y 2 2 这返回 4 4 我正在编写
  • MATLAB 图形渲染:OpenGL 与 Painters?

    当谈到使用哪个渲染器来处理 MATLAB 图形或何时它很重要时 我一无所知 但我遇到过某些示例 其中does matter plot 0 0 ko markersize 50 linewidth 8 set gcf renderer ope
  • 静态时序数据的数据库解决方案

    我们拥有一个庞大且不断增长的实验数据集 该数据集取自约 30 000 名受试者 对于每个主题 都有多个数据记录 在每个记录中 收集了多个生理数据时间序列 每个时间序列约 90 秒长 并以 250Hz 采样 我应该注意到 时间序列的任何给定实
  • MATLAB:MEX 矩阵除法给出的结果与 m 文件不同

    我使用 MATLAB 的编码器工具创建了矩阵指数函数的 MEX 版本 以在另一组函数中使用 问题是 MEX 版本给出的结果与原始 m 文件不同 经过调试 我认为这是因为MEX文件和m文件没有做相同的矩阵除法 或者 MEX 文件首先就有问题
  • 如何在 MATLAB 的 for 循环中读取多个图像?

    我已将结果分段放在一个文件夹中 这些需要在 for 循环中读取并在循环中进一步处理 我尝试阅读如下 for i 1 10 file name dir strcat C Users adminp Desktop dinosaurs im im
  • Matlab 中是否有相当于 R 的 dput() 的函数?

    Matlab 中是否有相当于 R 的 dput 的函数 dput 将 R 对象的 ASCII 文本表示形式写入文件或连接 UPDATE 1 添加了递归和对单元格的支持 UPDATE 2 添加了对结构的支持 UPDATE 3 增加了对逻辑 整
  • 有没有办法在 MATLAB 中查看 pcode 文件 (.p) 的源代码?

    有没有办法在 MATLAB 中打开 pcode 文件 p 如果 开放 是指edit 那么当然不是 pcode 中的 p 代表 受保护 其主要设计目标是在保护其源代码的同时部署功能组件 如果 开放 是指run 那么当然是的 引用手册 http
  • ODE 时间 Matlab 与 R

    如果在 matlab 中使用可变时间步长求解器 例如 ODE45 我会定义输出的时间跨度 即times 0 50 matlab 将返回 0 到 50 之间不同时间步长的结果 然而在 R 中 我似乎必须定义我希望 ODE 返回结果的时间点 即
  • 图像分析-光纤识别

    我是图像分析新手 您知道如何以仅获取纤维的方式对该图像进行二值化吗 我尝试过不同的阈值技术等 但没有成功 我不介意应该使用什么工具 但我更喜欢 NET or Matlab PS 我不知道该把答案放在哪里 所以我把它放在StackOverfl
  • Matlab-如何在曲线上绘制切线

    我在 matlab 中绘制了一个图表 plot x y 我的图表有不同的斜率 我如何在每个斜率上绘制切线并计算斜率的系数 如果您没有用于绘制点的显式函数 您可以使用有限差分 http en wikipedia org wiki Finite
  • 在 3d 空间中的两个平面之间进行插值

    我正在开发一种工具 可以让您在 3D 体积 上圈出 包围事物 我想通过标记 切片 1 和 3 并从该信息 填充 切片 2 来节省时间 两个简单的解决方案是 1 slice2 slice1 AND slice3 gets the overla
  • 在 Excel 中打印 MATLAB 图窗并调整其大小

    我在 MATLAB 中有两个带有手柄的图形hFig1 and hFig2 我想将它们打印到 Excel 中的特定单元格 单元格 E3 和 I3 并将它们重新调整为 2 英寸 x 3 英寸 我尝试过使用 AddPictures对象处理程序和使
  • 在 MATLAB 中使用 FFT 的频率响应

    这是场景 使用频谱分析仪 我有输入值和输出值 样本数是32000采样率为2000样本 秒 输入是正弦波50 hz 输入为电流 输出为压力 单位 psi 我如何使用 MATLAB 根据这些数据计算频率响应 使用 MATLAB 中的 FFT 函
  • 检查Matlab中脚本需要使用的函数

    我有一个别人写的代码包 我正在运行一个脚本 它调用一些函数 这些函数又调用更多函数 等等 我想获取不是 MATLAB 内置函数但属于包的一部分的函数列表 我尝试使用matlab codetools requiredFilesAndProdu
  • Matlab Mex文件编译

    我正在尝试编译一个 mex 文件以在 matlab 中使用套接字连接 问题是它总是说我没有安装sdk或编译器 但我已经安装了 Visual Studio 2010 Express Visual Studio 2012 Express Vis
  • MATLAB 中最有效的矩阵求逆

    在 MATLAB 中计算某个方阵 A 的逆矩阵时 使用 Ai inv A should be the same as Ai A 1 MATLAB 通常会通知我这不是最有效的求逆方法 那么什么是更有效率的呢 如果我有一个方程系统 可能会使用
  • 在 matlab 中求 3d 峰的体积

    现在我有一个带有峰值的 3D 散点图 我需要找到其体积 我的数据来自图像 因此 x 和 y 值表示 xy 平面上的像素位置 z 值是每个像素的像素值 这是我的散点图 scatter3 x y z 20 z filled 我试图找到数据峰值的

随机推荐

  • BigDecimal的常用方法

    一 BigDecimal概述 Java在java math包中提供的API类BigDecimal 用来对超过16位有效位的数进行精确的运算 双精度浮点型变量double可以处理16位有效数 但在实际应用中 可能需要对更大或者更小的数进行运算
  • Python学习笔记(基础篇)

    目录 一 Python编程基础 1 1print 1 2 input 1 3 ASC 码 1 4注释 二 数据类型与基本运算符 2 1变量 2 2数值类型 整数 浮点数 复数 2 3字符串 2 4布尔类型 2 5数据类型转换 2 6算数运算
  • 【mysql】mysql group by分组后取每组的最小值

    方法一 非严格模式下 group by后 会取分组后多个create time 的其中一个 由于我们的 create time 时间是有序的 会取第一条 如果是无序字段 很可能取的顺序会有问题 可以在create time 前面加上grou
  • 苹果系统 macOS Mojave 10.14.4上安装 Ubuntu 18.04 双系统

    macOS Mojave 10 14 4 安装Ubuntu 18 04 双系统 0 准备工作 系统情况 1 制作Ubuntu安装盘 U盘 2 硬盘分区 3 安装Ubuntu 4 正常使用GRUB 5 调整Ubuntu设置 2019 07 1
  • Tomcat开启远程调试端口

    部署环境 Linux 亲测成功 tomcat7 bin startup sh的文件开头位置添加 declare x CATALINA OPTS server Xdebug Xnoagent Djava compiler NONE Xrunj
  • JavaWeb JDBC

    1 实现第一个JDBC程序 在MySQL中创建一个名称为jdbc的数据库 然后在该数据库中创建一个users表 创建 数据库和表的SQL语句如下所示 CREATE DATABASE jdbc USE jdbc CREATE TABLE us
  • html前后端缓存,前后端分离系列-缓存篇

    1 我们需要在静态文件返回给浏览器的时候header中的缓存变长 这样就可以在本地秒加载 省去了带宽和加载时间 修改server js const path require path const Koa require koa const
  • 内存泄露原因和解决方案

    资料参考出自 http blog chinaunix net uid 26930580 id 3844811 html http www jianshu com p 90caf813682d 为什么会产生内存泄漏 当一个对象已经不需要再使用
  • 基于Matlab应用DBSCAN

    基于Matlab应用DBSCAN Density Based Spatial Clustering of Applications with Noise 具有噪声的基于密度的聚类方法 一 算法原理 Matlab中的统计与机器学习工具箱 Th
  • SuperSocket实战手把手教程:一个完整的SocketServer项目

    SuperSocket系列教程 1 SuperSocket基础 一 基本概念 2 SuperSocket实战手把手教程 一个完整的SocketServer项目 目录 一 项目场景 1 Visual Studio新建项目 2 自定义自己服务器
  • pre loader简单分析

    ZZ from http blog csdn net ly601579033 article details 48318239 大致的流程图如下 上电后RESET ARM核开始执行Boot ROM 具体操作有 代码固化在ROM中 1 初始化
  • 【软件硬件】相机标定(Camera calibration)原理、步骤

    转载来源 https blog csdn net lql0716 article details 71973318 locationNum 8 fps 1 在图像测量过程以及机器视觉应用中 为确定空间物体表面某点的三维几何位置与其在图像中对
  • 使用OpenGL实现的光线追踪器示例

    使用OpenGL实现的光线追踪器示例 光线追踪是一种计算机图形学中常用的方法 它可以模拟光线在三维空间中的传播和反射 在本文中 我们将介绍如何使用OpenGL实现一个简单的光线追踪器 在本例中 我们将创建一个场景 其中包含一个球体和一个平面
  • flutter a .dex file cannot exceed 64K

    第一步 添加multidex 第二部 添加multiDexEnabled 构建运行完事
  • 获取下拉菜单值

    function getSelectVal ele var selectedIndex ele selectedIndex var value ele options selectedIndex value return value
  • oracle生成编号(首字母+YYYY-DD-MM+4位序号)自动增长,4位序号达到9999,在从1001开始。

    今天写业务的时候遇见需要系统生成13位的编号 规则编号按一个大写字母 YYYY MM DD 4位序号组成 数据库用的oracle 所以就打算用序列实现 下面是实现方式 1 先创建序列 create sequence contact seq
  • vue2.x 插件的开发

    前言 第一次好好学习插件的开发 有什么不正确的地方麻烦指正 另外写这篇文章 纯粹是当作自己的学习笔记 插件 插件通常用来为 Vue 添加全局功能 插件的功能范围没有严格的限制 一般有下面几种 添加全局方法或者 property 如 vue
  • 如何查看和修改操作系统字符集

    在Windows平台下查看和修改字符集 一 查看字符集 chcp 二 修改字符集为936 chcp 936 简体中文 可以得到操作系统的代码页信息 你可以从控制面板的语言选项中 可以查看代码页对应的详细的字符集信息 linux下查看和修改字
  • JavaScript 手写深拷贝

    深拷贝 深拷贝就是要拷贝的对象内的所有引用类型的属性进行完整的拷贝 也就是说拷贝出来的对象和原对象之间没有任何数据是共享的 所有的东西都是自己独占的一份 三步实现深拷贝 第一步 判断入参是值类型还是引用类型 值类型直接返回 if typeo
  • 数字图像处理课程设计-疲劳检测系统

    文章目录 数字图像处理课程设计 疲劳检测系统 前言 一 课程设计任务 二 设计框图 三 准备工作 四 任务流程 视频预处理 4 2图片分割 五 结果 六 项目总结 数字图像处理课程设计 疲劳检测系统 前言 此系统基于MATLAB设计 核心思