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官網效果圖

