数字图像处理课程设计-疲劳检测系统 前言 应用数字图像处理相关知识和技术实现某一应用,如人脸识别、动物识别、水果识别等综合性任务,题目自选。
本文在matlab R2018b开发环境下,实现人脸检测系统。
疲劳检测可以应用于大巴车司机,货车司机疲劳驾驶监测,现在很多情况下大巴车或者货车等司机都由于休息不好,疲劳上路,这就给安全造成了及其大的隐患。如果有一套系统,可以实时接入车辆摄像头,摄像头对准司机,当检测到司机疲劳状态的时候,则提醒后台并且语音提醒,以做出正确决策,避免车祸等悲剧的发生。该系统也可以应用于上课学生专注度分析,进行疲劳预警。
二、设计框图 三、准备工作 开发环境:windows 10,matlab R2018b 制图软件:visio 2013 素材示意:人脸图像/视频 四、任务流程 4.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 frame = read(obj,k); id=sprintf(nz,k); imwrite(frame,strcat('video_images/' ,id,'.jpg' ),'jpg' ); end set(handles.listbox1,'String' ,'分帧结束' );
利用MATLAB函数rgb2gray转换成灰度图像。
去除视频黑边,定位有效图像区域。
将结果输出到指定路径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 人脸定位
读入images路径下所有jpg图像。
利用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);
根据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人眼定位
先对图像预处理,利用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);
对人眼区域定位。 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];
裁掉多余的区域。 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人眼精确定位
图像预处理,利用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
提取定位结果。 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疲劳检测
利用PERCLOS算法,计算人眼在单位时间内闭合所占比。 data = cat (1 , Nv.nv); Nmin = min (data); Nmax = max (data); rate = (data-Nmin)./(Nmax-Nmin); set(handles.listbox3,'string' ,rate) pause(5 )
输出结果, 计算的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
五、结果 GUI界面 输入视频,分帧处理,分割图像 输出结果 六、项目总结 使用图像预处理技术得到灰度分配较为均匀的图像,然后分别利用水平和垂直灰度积分投影曲线结合人脸的结构特征找到眼睛的位置坐标,实现了准确的眼睛定位,通过perclos技术技术眨眼率,根据先验值得到是否疲劳。完成了疲劳检测系统的设计。
通过本次项目设计,不仅熟练应用了MATLAB的基本函数,也学到了PERCLOS算法。
PERCLOS算法(Percentage of Eyelid Closure Over the Pupil Time的缩写,意为单位时间里眼睛闭合时间所占的百分比)
PERCLOS原理:F=$\frac{t3-t2}{t4-t1}$*100%
F是一的话就是睁眼;连续N帧后便可获取关于01之间的序列,然后分析0在该序列中所占比例来描述疲劳状态。