Matlab人臉檢測方法(Face Parts Detection)具體解釋


  今天同學讓我幫忙制作一個人臉表情識別的樣本庫,當中主要是對人臉進行裁剪,這里用到了一個相對較新的Matlab人臉檢測方法Face Parts Detection。網上百度了一下發現關於Matlab人臉檢測的代碼和資源並不多。故此專門撰寫一篇博客來具體介紹這個人臉檢測方法的用途。

  一、下載相應的工具包

  首先下載相應的工具包。matlab最方便的地方莫過於此了。直接下載、配置簡單、而且能夠查看源代碼,這里給出相應的工具包下載地址:Face Parts Detection工具包

  點擊“Download Zip”下載button開始下載,下載完畢后解壓,得到例如以下文件:

  二、配置工具包

  下載完畢后開始配置工具箱。首先須要強調一點,這種方法須要依賴兩個Matlab圖像處理方面的工具箱Image Processing ToolboxComputer Vision System Toolbox。差點兒全部版本號的Matlab都默認集成了Image Processing工具箱。但對於Computer Vision System工具箱僅僅有相對較高版本號(Matlab2013及以上)的Matlab版本號才進行了集成,因此假設在程序運行過程中提示缺少相應的工具箱,則須要手動進行配置Computer Vision System。

  假設Matlab已經配置好了以上兩個工具箱,接下來開始配置Face Parts Detection工具包,方法極其簡單,僅僅需在Set Path對話框中將當前工具箱的目錄(這里是Face_detection_Parts目錄)路徑加入到系統的搜索路徑就可以:

  三、進行批量人臉檢測

  工具箱配置完畢后開始利用其進行人臉檢測。

  3.1、批量讀取圖片

  首先,須要對數據庫中的圖像進行批量讀取,讀取完之后再進行人臉檢測。首先給出批量讀取的代碼。稍后解釋:

clear;
stImageFilePath  = 'E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\';
stImageSavePath  = 'E:\Face_Detection\';
dirImagePathList = dir(strcat(stImageFilePath,'*.tif'));        %讀取該目錄下全部圖片的路徑(字符串格式)
iImageNum        = length(dirImagePathList);                    %獲取圖片的總數量
if iImageNum > 0                                                %批量讀入圖片,進行五官檢測,再批量檢測
    for i = 1 : iImageNum
        iSaveNum      = int2str(i);
        stImagePath   = dirImagePathList(i).name;
        mImageCurrent = imread(strcat(stImageFilePath,stImagePath));
    end
end

  這里採用dir()函數的方法來讀取目錄下全部文件的文件名稱,dirImagePathList(i).name中保存了目錄下的全部文件的名稱。

有關Matlab中dir()函數的使用方法大家能夠參考網絡資料。

stImageFilePath變量保存了當前圖片所在目錄的路徑(這里為E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\),stImageSavePath變量指定了裁剪之后的人臉圖像的保存路徑。

這里須要注意的一點就是保存裁剪結果的目錄須要事先創建好(或者在程序中通過mkdir等函數來提前創建)。通過strcat()函數來推斷當前圖像名稱中是否包括“.tif”來確定其是否為圖像文件(這里的數據庫中的圖像文件都是tif格式的),

  3.2、編寫人臉檢測函數

  批量讀取圖像完畢后。開始進行人臉檢測,這里選擇將人臉檢測封裝為一個腳本文件方便調用。這里暫且將其命名為face_segment.m文件。

  首先,須要推斷當前圖像的通道數,由於Face Parts Detection方法僅僅能針對三通道圖像進行人臉檢測,假設當前圖像為灰度圖(單通道圖)。則須要先將其轉換為三通道矩陣形式:

%%%%%%%%%%%%%%%%%%%%將灰度圖變為三通道圖%%%%%%%%%%%%%%%%%%%%
if(size(mImageSrc,3) == 1) 
    mImage2detect(:,:,1) = mImageSrc;
    mImage2detect(:,:,2) = mImageSrc;
    mImage2detect(:,:,3) = mImageSrc;
else
    mImage2detect = mImageSrc;
end

  然后開始調用工具箱進行人臉檢測。就兩句代碼就可以(可見作者將程序封裝得何其之好):

%%%%%%%%%%%%%%%%%%%%對圖像進行人臉檢測%%%%%%%%%%%%%%%%%%%%
FaceDetector               = buildDetector(); 
[bbox,bbimg,faces,bbfaces] = detectFaceParts(FaceDetector,mImage2detect,2);

  對於bbox,bbimg,faces,bbfaces這四個檢測結果的具體含義,在detectFaceParts.m文件的開頭部分作者給出了具體的解釋,我們這里僅僅用到bbox這個變量。它里面分別保存了所檢測出的人臉區域(一個矩形框)的左上角坐標以及寬度和高度。

  檢測完畢之后。再統一將圖像轉換為灰度圖,保證格式的統一。方便保存:

%%%%%%%%%%%%%%%%%%%%輸入圖像灰度化%%%%%%%%%%%%%%%%%%%%
if 1 ~= size(mImageSrc,3)
    mImageSrc = rgb2gray(mImageSrc);
    mImageSrc = double(mImageSrc);
elseif 1     == size(mImageSrc,3)
    mImageSrc = double(mImageSrc);
end

  接下來開始對人臉區域進行切割。這個有兩種切割策略,一種是直接使用檢測到的人臉框bbox對原圖進行截取,在不可控的採集條件下僅僅能用這樣的方法來切割人臉。另外一種策略是針對人臉框bbox首先確定人臉區域的中心點,然后再以中心點為基准向四周依照一定比例進行外擴,這樣的方法僅適合採集條件嚴格可控、人臉大致對齊的人臉數據庫,恰好我們所處理的數據庫滿足這樣的要求。因此在這里採用另外一種策略進行人臉區域切割,代碼例如以下:

%%%%%%%%%%%%%%%%%%%%得到人臉區域框的中心點%%%%%%%%%%%%%%%%%%%%
recFace.x          = bbox(1,1);
recFace.y          = bbox(1,2);
recFace.width      = bbox(1,3);
recFace.height     = bbox(1,4);

ptFaceCenter.x     = recFace.x + recFace.width / 2;
ptFaceCenter.y     = recFace.y + recFace.height / 2;

%%%%%%%%%%%%%%%%%%%%以中心點為基准進行外擴(即對人臉選框進行調整)%%%%%%%%%%%%%%%%%%%%
recFace.x         = ptFaceCenter.x - recFace.width * 0.4;
recFace.y         = ptFaceCenter.y - recFace.height * 0.35;
recFace.width     = recFace.width * 0.8 ;
recFace.height    = recFace.height * 0.8 ;

mFaceResult       = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));

  這里僅僅涉及到了簡單的幾何知識,因此不再贅述。確定好人臉矩形區域之后,使用imcrop()函數進行區域切割。這里給出face_segment.m文件的完整代碼:

%===============================================================================
%函數名稱:face_segment
%輸入參數:mImageSrc,待切割的人臉圖像。可能是灰度圖像,也可能是彩色圖像
%輸出參數:mFaceResult,切割后的人臉結果,應為灰度圖像
%主要步驟:1)進行人臉檢測,得到臉部區域的框框
%         2)得到臉部圖像框的中心點
%         3)依據中心點。對圖像進行等比例外擴,得到合適大小的人臉圖像
%注意事項:1)首先須要推斷該圖像是否為灰度圖。若為灰度圖,須要先將其轉換為三通道彩色圖
%===============================================================================
function mFaceResult = face_segment(mImageSrc)
%%%%%%%%%%%%%%%%%%%%將灰度圖變為三通道圖%%%%%%%%%%%%%%%%%%%%
if(size(mImageSrc,3) == 1)
    mImage2detect(:,:,1) = mImageSrc;
    mImage2detect(:,:,2) = mImageSrc;
    mImage2detect(:,:,3) = mImageSrc;
else
    mImage2detect = mImageSrc;
end

%%%%%%%%%%%%%%%%%%%%對圖像進行人臉檢測%%%%%%%%%%%%%%%%%%%%
FaceDetector               = buildDetector();
[bbox,bbimg,faces,bbfaces] = detectFaceParts(FaceDetector,mImage2detect,2);

%%%%%%%%%%%%%%%%%%%%輸入圖像灰度化%%%%%%%%%%%%%%%%%%%%
if 1 ~= size(mImageSrc,3)
    mImageSrc = rgb2gray(mImageSrc);
    mImageSrc = double(mImageSrc);
elseif 1     == size(mImageSrc,3)
    mImageSrc = double(mImageSrc);
end

%%%%%%%%%%%%%%%%%%%%得到人臉區域框的中心點%%%%%%%%%%%%%%%%%%%%
recFace.x          = bbox(1,1);
recFace.y          = bbox(1,2);
recFace.width      = bbox(1,3);
recFace.height     = bbox(1,4);

ptFaceCenter.x     = recFace.x + recFace.width / 2;
ptFaceCenter.y     = recFace.y + recFace.height / 2;

%%%%%%%%%%%%%%%%%%%%以中心點為基准進行外擴(即對人臉選框進行調整)%%%%%%%%%%%%%%%%%%%%
recFace.x         = ptFaceCenter.x - recFace.width * 0.4;
recFace.y         = ptFaceCenter.y - recFace.height * 0.35;
recFace.width     = recFace.width * 0.8 ;
recFace.height    = recFace.height * 0.8 ;

mFaceResult       = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));
end

  四、人臉批量保存

  在完畢人臉檢測函數之后,開始對人臉進行檢測切割和批量保存,這里直接給出代碼:

clear;
stImageFilePath  = 'E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\';
stImageSavePath  = 'E:\Face_Detection\';
dirImagePathList = dir(strcat(stImageFilePath,'*.tif'));        %讀取該目錄下全部圖片的路徑(字符串格式)
iImageNum        = length(dirImagePathList);                    %獲取圖片的總數量
if iImageNum > 0                                                %批量讀入圖片,進行五官檢測,再批量檢測
    for i = 1 : iImageNum
        iSaveNum      = int2str(i);
        stImagePath   = dirImagePathList(i).name;
        mImageCurrent = imread(strcat(stImageFilePath,stImagePath));
        mFaceResult   = face_segment(mImageCurrent);
        imwrite(mFaceResult,strcat(stImageSavePath,iSaveNum,'.bmp')); end end

  這段代碼的邏輯相對簡單。調用strcat()字符串拼接函數來完畢檢測結果的自己主動命名,考慮到版權問題,這里不粘貼終於的人臉切割結果,但程序親測可用,沒有問題。

  五、注意事項

  1、OpenCv人臉檢測函數

  進行人臉檢測是Matlab並非唯一選擇,OpenCv也相同封裝的人臉檢測函數,只是OpenCv中封裝的人臉檢測函數是基於AdaBoost算法。相對經典而古老。性能不如本文中所介紹的人臉檢測算法,而且OpenCv在讀取tif格式的圖像文件時顯得異常麻煩。

  2、原理介紹

  在這篇博文中我們僅僅介紹了Face Parts Detection算法的具體使用方法,至於去人臉檢測原理,將來有時間了我再專門寫博文進行介紹。

  3、打不開MathWork官網的話我能夠給發郵箱

  假設出現不能正常登陸MathWork站點,無法下載工具箱的情況。能夠給我發郵件,我會抓時間提供相應的工具箱

  4、灰度圖不等於單通道圖

  在這里再強調一個小問題。就是灰度圖與單通道圖的關系,理論上來說這兩個名詞全然屬於不同的概念。灰度圖不一定是單通道圖。由於三個通道的RGB值均相等的三通道圖在視覺上相同變現為灰度圖。只是單通道圖肯定是灰度圖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM