Viola-Jones 人眼检测算法+meanshift跟踪算法
这次的代码是对视频中的人眼部分进行检测加跟踪,检测用的是matlab自带的人眼检测工具箱
下面是matlab官网介绍这个算法的一些东西:
Viola-Jones是人眼、人脸检测非常常用的算法,使用的特征是haar-like特征,分类器是级联adaboost分类器;
Viola Jones Face Detector是Paul viola 和 Michael J Jones共同提出的一种人脸检测框架。它极大的提高了人脸检测的速度和准确率。
- 速度提升方面:利用积分图像来提取图像特征值,所以非常快。同时,利用adaboost分类器的特征筛选特性,保留最有用特征,这也减少了检测时的运算复杂度。
- 准确率提升方面:将adaboost分类器进行改造,变成级联adaboost分类器,提高了人脸检测的准确率(降低漏检率和误检率)。
这个算法的具体介绍可以参考链接:
http://www.cnblogs.com/hrlnw/archive/2013/10/23/3374707.html
然后,跟踪方面是最普通的meanshift跟踪算法
meanShift,均值漂移,在聚类、图像平滑、分割、跟踪等方面有着广泛的应用。meanShift这个概念最早是由Fukunage在1975年提出的,其最初的含义正如其名:偏移的均值向量;但随着理论的发展,meanShift的含义已经发生了很多变化。如今,我们说的meanShift算法,一般是指一个迭代的步骤,即先算出当前点的偏移均值,然后以此为新的起始点,继续移动,直到满足一定的结束条件。
MeanShift算法正是属于核密度估计法,它不需要任何先验知识而完全依靠特征空间中样本点的计算其密度函数值。对于一组采样数据,直方图法通常把数据的值域分成若干相等的区间,数据按区间分成若干组,每组数据的个数与总参数个数的比率就是每个单元的概率值;核密度估计法的原理相似于直方图法,只是多了一个用于平滑数据的核函数。采用核函数估计法,在采样充分的情况下,能够渐进地收敛于任意的密度函数,即可以对服从任何分布的数据进行密度估计。这个算法的精髓,一张图片就可以解释,注意下图,即为均值漂移,非常形象。
图片及meanshift算法的进一步解释都可以参考链接:
http://blog.csdn.net/jinshengtao/article/details/30258833
下面贴出代码:
clc; clear all;close all;clf reset; %% %%%%%%%%%%%%%%%%%%%%%%%%--------人眼检测部分开始---------------------%%%%%%%%%%%%%%%%%%%%%% videoObj = VideoReader(\'eye.mp4\');%读视频文件 nframes = get(videoObj, \'NumberOfFrames\');%获取视频文件帧个数 img = read(videoObj, 1);%读取第1帧,用于人脸检测 Eye_Detect = vision.CascadeObjectDetector(\'EyePairBig\');%使用 Viola-Jones 算法,人脸检测工具箱中的人眼部分 Eyes=step(Eye_Detect,img);%从第一张照片中检测出人眼,函数返回的是人眼的位置 hold on; imshow(img);%显示第一张照片 for i = 1:size(Eyes,1) rectangle(\'Position\',Eyes(i,:),\'LineWidth\',1,\'LineStyle\',\'-\',\'EdgeColor\',\'r\');%将上面人眼的位置,用一个矩形框框起来,显示 end title(\'Eyes Detection\');%标注眼睛检测 hold off; pause(0.000001)%暂停一小会,休息一下,马上回来 rect=Eyes(1,:);%保存rect检测到的位置 temp=img(rect(2):rect(2)+rect(4),rect(1):rect(1)+rect(3),:);%将检测到的眼睛部分的图片提取出来 [a,b,c]=size(temp); %返回图片的维数 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%计算目标图像的权值矩阵%%%%%%%%%%%%%%%%%%%%%%% y(1)=a/2; y(2)=b/2; tic_x=rect(1)+rect(3)/2; tic_y=rect(2)+rect(4)/2; m_wei=zeros(a,b);%权值矩阵 h=y(1)^2+y(2)^2 ;%带宽 for i=1:a for j=1:b dist=(i-y(1))^2+(j-y(2))^2; m_wei(i,j)=1-dist/h; %epanechnikov profile 核函数 end end C=1/sum(sum(m_wei));%归一化系数 %计算目标权值直方图qu %hist1=C*wei_hist(temp,m_wei,a,b);%target model hist1=zeros(1,4096); for i=1:a for j=1:b %rgb颜色空间量化为16*16*16 bins q_r=fix(double(temp(i,j,1))/16); %fix为趋近0取整函数,红色 q_g=fix(double(temp(i,j,2))/16); %绿色 q_b=fix(double(temp(i,j,3))/16); %蓝色 q_temp=q_r*256+q_g*16+q_b; %设置每个像素点红色、绿色、蓝色分量所占比重 hist1(q_temp+1)= hist1(q_temp+1)+m_wei(i,j); %计算直方图统计中每个像素点占的权重 end end hist1=hist1*C; rect(3)=ceil(rect(3)); rect(4)=ceil(rect(4)); %% %%%%%%%%%%%%%%%%%%%%%%%%%读取序列图像%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for l=1:nframes Im= read(videoObj, l);%读取第i帧 num=0; Y=[2,2]; %%%%%%%mean shift迭代 while((Y(1)^2+Y(2)^2>0.5)&num<20) %迭代条件 num=num+1; temp1=imcrop(Im,rect); %计算侯选区域直方图 %hist2=C*wei_hist(temp1,m_wei,a,b);%target candidates pu hist2=zeros(1,4096); for i=1:a for j=1:b q_r=fix(double(temp1(i,j,1))/16); q_g=fix(double(temp1(i,j,2))/16); q_b=fix(double(temp1(i,j,3))/16); q_temp1(i,j)=q_r*256+q_g*16+q_b; hist2(q_temp1(i,j)+1)= hist2(q_temp1(i,j)+1)+m_wei(i,j); end end hist2=hist2*C; %figure(2); %subplot(1,2,1); %plot(hist2); % hold on; w=zeros(1,4096); for i=1:4096 if(hist2(i)~=0) %不等于 w(i)=sqrt(hist1(i)/hist2(i)); else w(i)=0; end end %变量初始化 sum_w=0; xw=[0,0]; for i=1:a; for j=1:b sum_w=sum_w+w(uint32(q_temp1(i,j))+1); xw=xw+w(uint32(q_temp1(i,j))+1)*[i-y(1)-0.5,j-y(2)-0.5]; end end Y=xw/sum_w; %中心点位置更新 rect(1)=rect(1)+Y(2); rect(2)=rect(2)+Y(1); end %%%跟踪轨迹矩阵%%% tic_x=[tic_x;rect(1)+rect(3)/2]; tic_y=[tic_y;rect(2)+rect(4)/2]; v1=rect(1); v2=rect(2); v3=rect(3); v4=rect(4); %% %%%显示跟踪结果%%% %subplot(1,2,2); imshow(uint8(Im)); title(\'目标跟踪结果及其运动轨迹\'); hold on; plot([v1,v1+v3],[v2,v2],[v1,v1],[v2,v2+v4],[v1,v1+v3],[v2+v4,v2+v4],[v1+v3,v1+v3],[v2,v2+v4],\'LineWidth\',2,\'Color\',\'r\'); plot(tic_x,tic_y,\'LineWidth\',2,\'Color\',\'b\'); hold off; pause(0.000001) end
最后盗一张matlab官网效果图