人臉識(shí)別C++程序代碼 - 副本_第1頁
人臉識(shí)別C++程序代碼 - 副本_第2頁
人臉識(shí)別C++程序代碼 - 副本_第3頁
人臉識(shí)別C++程序代碼 - 副本_第4頁
人臉識(shí)別C++程序代碼 - 副本_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、/ AppDesignDlg.cpp : implementation file/#include "stdafx.h"#include "AppDesign.h"#include "AppDesignDlg.h"#include <string>#include <math.h>#include "Select.h"#include "CvvImage.h"#define MAX_POINT 200#ifdef _DEBUG#define new DEBUG_NEW#u

2、ndef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CAboutDlg dialog used for App Aboutusing namespace std;CvCapture * m_Video; / opencv庫的指針,從視頻獲取圖像int nFrmNum=0; /定義第nFrmNum幀,初始化為0,自動(dòng)增值,nFrmNum是幀控件的關(guān)聯(lián)變量,幀控件的ID為IDC_FRAMNUM/定義幾個(gè)重要的全局變量 int nTrainFaces =0; / 訓(xùn)練圖像的數(shù)目,即人臉庫中有n張人臉int nEigens =0

3、; / 自己取的主要特征值數(shù)目(在提取特征臉的時(shí)候用到的參數(shù))IplImage* faceImgArr =0; / 指向訓(xùn)練人臉和測(cè)試人臉的指針(在學(xué)習(xí)和識(shí)別階段指向不同)  CvMat* personNumTruthMat=0; / 人臉圖像的ID號(hào)IplImage* pAvgTrainImg =0; / 訓(xùn)練人臉數(shù)據(jù)的平均值IplImage* eigenVectArr =0; / 投影矩陣,也即主特征向量  CvMat* eigenValMat =0; / 特征值CvMat* project

4、edTrainFaceMat=0; / 訓(xùn)練圖像的投影 CvMat* trainPersonNumMat=0;/*以下是自定義函數(shù)的聲明,具體定義會(huì)在下方,cv開頭的是OPENCV自帶的庫函數(shù)*/void learn(); int loadFaceImgArr(char *filename);void recognize2(IplImage *img);void doPCA();void storeTrainingData();int loadTrainingData(CvMat* pTrainPersonNumMat);int findNearestNeighbor(fl

5、oat* projectedtestFace);/用字符串時(shí)一定要把using namespace std;寫在前面,否則不能用,下面是用于顯示的字符串CvHaarClassifierCascade* cascade=NULL; /OPENcv的分類器文件進(jìn)行人臉檢測(cè),此函數(shù)是一個(gè)匹配函數(shù),根據(jù)不同的分類器(tree、stump)進(jìn)行不同的匹配,返回整形值,具體參考/*以下是MFC框架代碼,在我們用鼠標(biāo)進(jìn)行搭建框架的時(shí)候自動(dòng)生成*/class CAboutDlg : public Cdialogpublic:CAboutDlg();/ Dialog Data/AFX_DATA(CAboutDl

6、g)enum IDD = IDD_ABOUTBOX ;/AFX_DATA/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV support/AFX_VIRTUAL/ Implementationprotected:/AFX_MSG(CAboutDlg)/AFX_MSGDECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDia

7、log(CAboutDlg:IDD)/AFX_DATA_INIT(CAboutDlg)/AFX_DATA_INITvoid CAboutDlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CAboutDlg)/AFX_DATA_MAPBEGIN_MESSAGE_MAP(CAboutDlg, CDialog)/AFX_MSG_MAP(CAboutDlg)/ No message handlers/AFX_MSG_MAPEND_MESSAGE_MAP()/ CAppDesignDlg dia

8、logCAppDesignDlg:CAppDesignDlg(CWnd* pParent /*=NULL*/): CDialog(CAppDesignDlg:IDD, pParent)/AFX_DATA_INIT(CAppDesignDlg)/ NOTE: the ClassWizard will add member initialization here/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(

9、IDR_MAINFRAME);pCapture = NULL;m_totalfrm = 0;m_curfrm = 0;m_stop = false;loadxml=false;m_src = NULL;m_times =0;void CAppDesignDlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CAppDesignDlg)/DDX_Control(pDX, IDC_PROGRESS1, m_progress);/AFX_DATA_MAPDDX_Control(pDX, IDC_

10、PROGRESS1, m_progress);BEGIN_MESSAGE_MAP(CAppDesignDlg, CDialog)/AFX_MSG_MAP(CAppDesignDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, OnOpenFile)ON_WM_TIMER()ON_BN_CLICKED(IDC_BUTTON5, OnStop)ON_WM_CTLCOLOR()/AFX_MSG_MAPON_BN_CLICKED(IDC_BUTTON2, &CAppDesignDl

11、g:OnBnClickedButton2)ON_BN_CLICKED(IDC_BUTTON3, &CAppDesignDlg:OnBnClickedButton3)END_MESSAGE_MAP()/ CAppDesignDlg message handlersBOOL CAppDesignDlg:OnInitDialog()CDialog:OnInitDialog();/ Add "About." menu item to system menu./ IDM_ABOUTBOX must be in the system command range.ASSERT(I

12、DM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL)CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_AB

13、OUTBOX, strAboutMenu);/ Set the icon for this dialog. The framework does this automatically/ when the application's main window is not a dialogSetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization herereturn TRUE; / return TRUE unless you s

14、et the focus to a controlvoid CAppDesignDlg:OnSysCommand(UINT nID, LPARAM lParam)if (nID & 0xFFF0) = IDM_ABOUTBOX)CAboutDlg dlgAbout;dlgAbout.DoModal();elseCDialog:OnSysCommand(nID, lParam);/ If you add a minimize button to your dialog, you will need the code below/ to draw the icon. For MFC app

15、lications using the document/view model,/ this is automatically done for you by the framework.void CAppDesignDlg:OnPaint() / OnPaint是WM_PAINT消息的消息處理函數(shù), 是CWnd的類成員,負(fù)責(zé)響應(yīng)WM_PAINT消息if (IsIconic()CPaintDC dc(this); / device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);/

16、Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;/ Draw the icondc.DrawIcon(x, y, m_hIcon);elseCDialog:OnPaint();/ The

17、system calls this to obtain the cursor to display while the user drags/ the minimized window.HCURSOR CAppDesignDlg:OnQueryDragIcon()return (HCURSOR) m_hIcon;/*這個(gè)程序的思路是,每33毫秒,就調(diào)用opencv獲取攝像頭的圖像資料,并更新到界面上,讓用戶看起來是錄像,實(shí)時(shí)的感覺,其實(shí)就是每33毫秒更新一次圖片,然后載入頭像資料進(jìn)行識(shí)別*/*“打開攝像頭”控件的相關(guān)代碼OnOpenFile() */void CAppDesignDlg:OnO

18、penFile() / OnOpenFile()是“打開攝像頭”這個(gè)控件的控制事件,也就是其函數(shù),m_Video是控件的變量 /* 調(diào)用opencv打開視頻*/m_Video = cvCaptureFromCAM(-1); / cvCaptureFromCAM(-1)是opencv的庫函數(shù),用來從視頻中獲取圖像,直接調(diào)用,這里也是界面與攝像頭的接口if (!m_Video)AfxMessageBox("無法打開攝像頭"); / AfxMessageBox這個(gè)函數(shù)是MFC中彈出消息框的函數(shù),直接調(diào)用return;/cascade是級(jí)聯(lián)if(!cascade)string ca

19、scade_name = "haarcascade_frontalface_alt.xml"cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name.c_str(), 0, 0, 0);/*啟動(dòng)計(jì)時(shí)器*/SetTimer(1,33,NULL);/*上面的內(nèi)容基本都是MFC的框架代碼,下面函數(shù)開始是自定義的函數(shù)了*/在控件中顯示圖片,第一個(gè)參數(shù)是要顯示的圖片,第二個(gè)參數(shù)是控件的IDvoid CAppDesignDlg:show_pic(IplImage *t,int nID) / int nID在這里是形參,而不是具體的

20、IDCDC *pDC = GetDlgItem(nID)->GetDC();HDC hDC= pDC->GetSafeHdc();CRect rect;GetDlgItem(nID)->GetClientRect(&rect);CvvImage img;img.CopyOf(t,3);img.DrawToHDC(hDC,&rect); ReleaseDC(pDC);/*獲得圖像興趣區(qū)域,并且保存為tmp.jpg, pImg是待處理圖像, CvRect roi是確定一個(gè)矩形區(qū)域roi */void GetSubImage(IplImage *pImg, CvRe

21、ct roi)/基于給定的矩形設(shè)置圖像的ROI,即獲取感興趣的圖像cvSetImageROI(pImg,roi);/保存圖像到指定文件tmp.jpgcvSaveImage("tmp.jpg",pImg);/ 釋放圖像pImg中被設(shè)定的感興趣區(qū)域ROI,與cvSetImageROI相對(duì)應(yīng)。cvResetImageROI(pImg);/這個(gè)函數(shù)主要是識(shí)別開始檢測(cè)到的人臉,是人臉識(shí)別的入口函數(shù)void RecgnizeRoi(IplImage *img,char *a)int i, nTestFaces=0; / 測(cè)試的人臉數(shù)float* projectedTestFa

22、ce=0; /訓(xùn)練的人臉數(shù)?projectedTestFace=(float*)cvAlloc(nEigens*sizeof(float); /cvAlloc是opencv中用于內(nèi)存管理的函數(shù)/for (i=0;i<nTestFaces;i+)/int iNearest, nearest, truth; / 定義iNearest為最相似的圖片/ cvEigenDecomposite()函數(shù)作用是將人臉圖像通過Eigenface變換矩陣,投射到子空間中,只有將待識(shí)別圖像投影到PCA空間,然后才能識(shí)別。函數(shù)的具體作用以及函數(shù)中的7個(gè)參數(shù)參見cvEigenDecomposite(img,nEi

23、gens,eigenVectArr, 0, 0, pAvgTrainImg, projectedTestFace);/得到最相似的圖片iNearest=findNearestNeighbor(projectedTestFace);nearest=trainPersonNumMat->data.iiNearest;/ char *itoa(int value, char *string, int radix);作用是把一整數(shù)轉(zhuǎn)換為字符串。value: 待轉(zhuǎn)化的整數(shù);radix: 是基數(shù)的意思,即先將value轉(zhuǎn)化為radix進(jìn)制的數(shù),范圍介于2-36,比如10表示10進(jìn)制,16表示16進(jìn)制

24、;* string: 保存轉(zhuǎn)換后得到的字符串,和函數(shù)返回值相同,也就是說,最后的圖片存儲(chǔ)稱aitoa(nearest,a,10); /檢測(cè)和識(shí)別的入口,頭像識(shí)別核心代碼void CAppDesignDlg:Detect_Draw(IplImage *pImg)bool bFirstFace = TRUE;string strFirstFace = ""/一個(gè)顏色數(shù)組,這個(gè)數(shù)組定義了一些顏色值 用這些顏色依次圈出不同的人臉,在最后畫圓來圈出人臉的那句代碼中 cvCircle( img, center, radius, colorsi%8, 3, 8, 0 );中的color的

25、數(shù)值。static CvScalar colors = 0,0,255, /藍(lán)色0,128,255,0,255,255,0,255,0,255,128,0,255,255,0,255,0,0,255,0,255;/先把識(shí)別到的學(xué)號(hào)初始化為空namelist="" 源代碼不知道有沒有/調(diào)用opencv創(chuàng)建存儲(chǔ)空間(為NAMELIST)CvMemStorage* storage = cvCreateMemStorage(0);double scale = 1.8;/函數(shù)IplImage* cvCreateImage( CvSize size, int depth, int ch

26、annels ); 創(chuàng)建頭并分配數(shù)據(jù),參數(shù)意義:size 圖像寬、高;depth 圖像元素的位深度;channels每個(gè)元素(像素)通道數(shù).可以是 1, 2, 3 或 4.通道是交叉存取的IplImage* gray = cvCreateImage( cvSize(pImg->width,pImg->height), 8, 1 );/仍然是這個(gè)函數(shù),對(duì)目標(biāo)圖進(jìn)行設(shè)置和分配空間(gray是原圖)IplImage* small_img = cvCreateImage( cvSize( cvRound (pImg->width/scale),/int cvRound (double

27、 value)對(duì)一個(gè)double型的數(shù)進(jìn)行四舍五入,并返回一個(gè)整型數(shù)!cvRound (pImg->height/scale),8, 1 );int i;/灰度化,cvCvtColor 是Opencv里的顏色空間轉(zhuǎn)換函數(shù),可以實(shí)現(xiàn)RGB顏色向HSV,HSI等顏色空間的轉(zhuǎn)換,也可以轉(zhuǎn)換為灰度圖像。具體參見cvCvtColor( pImg, gray, CV_BGR2GRAY );/歸一化尺度,函數(shù)cvResize 重新調(diào)整圖像src(或它的ROI),使它精確匹配目標(biāo)dst(或其ROI),src 源圖像;dst 目標(biāo)圖;interpolation 修改、插補(bǔ)的方法,取值如下:CV_

28、INTER_LINEAR 是其 默認(rèn)方法,為雙線性插值。cvResize( gray, small_img, CV_INTER_LINEAR );/直方圖均衡,函數(shù)原型為void cvEqualizeHist( const CvArr* src, CvArr* dst ); 用來使灰度圖象直方圖均衡化。具體見cvEqualizeHist( small_img, small_img );/刪除存儲(chǔ)空間,與上面創(chuàng)建空間對(duì)應(yīng)。cvClearMemStorage( storage ); /如果識(shí)別成功,就標(biāo)識(shí)出來。if( cascade ) 又是級(jí)聯(lián)/人臉檢測(cè)函數(shù),cvHaarDetectO

29、bjects函數(shù)用來檢測(cè)圖像中的目標(biāo),具體見/*級(jí)聯(lián)分類器訓(xùn)練中采用的檢測(cè)目標(biāo)的尺寸*/);/檢測(cè)人臉返回矩形人臉 /*使用針對(duì)某目標(biāo)物體訓(xùn)練的級(jí)聯(lián)分類器在圖像中找到包含目標(biāo)物體的矩形區(qū)域,并且將這些區(qū)域作為一序列的矩形框返回。CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(40, 40) );for( i = 0; i < (faces ? faces->total : 0); i+ ) CvRect* r,通過

30、方形左上角坐標(biāo)和方形的高和寬來確定一個(gè)矩形區(qū)域,nt x; /* 方形的左上角的x-坐標(biāo) */ ;int y; /* 方形的左上角的y-坐標(biāo)*/ ;int width; /* 寬 */ ;int height; /* 高 */ CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); /訪問人臉庫中的第i個(gè)元素CvPoint pt1, pt2; /OpenCV的基本數(shù)據(jù)類型之一,表示坐標(biāo)為整數(shù)的二維點(diǎn)r->x = r->x * scale;r->y = r->y * scale;r->wi

31、dth = r->width * scale;r->height = r->height * scale;pt1.x = r->x;pt1.y = r->y;pt2.x = r->x + r->width;pt2.y = r->y + r->height;/矩形將人臉框起來。cvRectangle是 OpenCV里面的繪圖函數(shù),四個(gè)參數(shù)分別代表(圖像,矩形的兩個(gè)點(diǎn),線條顏色,線條粗細(xì),線條類型,小數(shù)點(diǎn)位數(shù))cvRectangle( pImg, pt1, pt2, colorsi%8, 3, 8, 0);GetSubImage(gray, *

32、r);/獲取圖片/讀入圖像,參數(shù)分別為(被讀入圖像的文件名(包括后綴),指定讀入圖像的顏色和深度,CV_LOAD_IMAGE_GRAYSCALE是單通道),具體見IplImage *gray1=cvLoadImage("tmp.jpg",CV_LOAD_IMAGE_GRAYSCALE);/創(chuàng)建頭并分配數(shù)據(jù)(圖像寬,高,depth 圖像元素的位深度,每個(gè)元素(像素)通道數(shù))IplImage *dst=cvCreateImage(cvSize(96,96),8,1);/函數(shù)cvResize 重新調(diào)整圖像src(或它的ROI),使它精確匹配目標(biāo)dst(或其ROI) cvResiz

33、e(gray1,dst,CV_INTER_NN); / ·CV_INTER_NN - 最近-鄰居插補(bǔ)的修改方法 char a20="" /識(shí)別檢測(cè)到的人臉,調(diào)用了之前定義的函數(shù)RecgnizeRoi(dst,a);/ 應(yīng)該是有關(guān)輸出的對(duì)齊方式的CvFont font1;CvPoint wp;wp.x = pt1.x ;wp.y = pt1.y-10 ; cvInitFont(&font1, CV_FONT_ITALIC, 0.75F, 0.75F, 0, 3, 8);/將識(shí)別結(jié)果顯示出來/函數(shù) cvPutText 將具有指定字體的和指定顏色的文本加載到圖像

34、中。加載到圖像中的文本被感興趣的矩形框圈定。 (輸入圖像,顯示字符串,第一個(gè)字符左下角的坐標(biāo),字體結(jié)構(gòu)初始化,文本的字體顏色)cvPutText(pImg, a, wp, &font1, colors2);/在控件上顯示出識(shí)別了幾個(gè)人CString str;/Format是CString類的一個(gè)成員函數(shù),它通過格式操作使任意類型的數(shù)據(jù)轉(zhuǎn)換成一個(gè)字符串。str.Format("%d",faces->total);/返回窗口中指定參數(shù)ID的子元素的句柄,可以通過返回的句柄對(duì)窗口內(nèi)的子元素進(jìn)行操作。GetDlgItem(IDC_PEOPLENUM)->

35、;SetWindowText(str);/系統(tǒng)釋放存儲(chǔ)空間cvReleaseImage( &gray );cvReleaseImage( &small_img );每33毫秒調(diào)用一下這個(gè)模塊/定時(shí)器函數(shù),nIDEvent是定時(shí)器標(biāo)識(shí)符void CAppDesignDlg:OnTimer(UINT nIDEvent) IplImage* image; IplImage* motion = 0; /*調(diào)用opencv 提取視頻圖像數(shù)據(jù)*/讀取攝像頭一幀, cvQueryFrame(m_Video)從攝像頭或者文件中抓取并返回一幀image=cvQueryFrame(m_Video)

36、;/*幀數(shù)計(jì)算器*/下面四行代碼是將幀數(shù)顯示在控件上/*幀數(shù)計(jì)算器*/nFrmNum+;CString str; /str就是那個(gè)變化的幀值,同str幾個(gè)人是一樣一樣的/*把幀數(shù)在界面顯示出來*/str.Format("%d",nFrmNum); /顯示函數(shù)/返回窗口中指定參數(shù)ID的子元素的句柄,可以通過返回的句柄對(duì)窗口內(nèi)的子元素進(jìn)行操作。上面共識(shí)別幾個(gè)人的那個(gè)控件也用到了這條語句,功能是一樣的。GetDlgItem(IDC_FRAMNUM)->SetWindowText(str);/ cvGetTickCount()是測(cè)量運(yùn)行時(shí)間的函數(shù),在程序段的開始和結(jié)束時(shí)兩次使

37、用cvGetTickCount(),然后將兩次的差除以cvGetTickFrequency()后就可以獲得程序段的以微秒us為單位的運(yùn)行時(shí)間,而 *1000表示精確到ms double tt =(double)cvGetTickCount();/如果加載了訓(xùn)練結(jié)果,則可以開始檢測(cè)識(shí)別了,調(diào)用函數(shù)Detect_Draw, Detect_Draw這個(gè)函數(shù)是頭像識(shí)別函數(shù)if(loadxml)Detect_Draw(image);/得到?jīng)]幀的時(shí)間消耗tt=(double)cvGetTickCount()-tt;str.Format("%lf",tt/(cvGetTickFreque

38、ncy()*1000.); /把處理耗時(shí)顯示在界面上GetDlgItem(IDC_TIME)->SetWindowText(str);/ 把識(shí)別到的人的學(xué)號(hào)顯示在界面的列表中GetDlgItem(IDC_NAMELIST)->SetWindowText(namelist);/控件上顯示圖片/*把攝像頭的圖像顯示到圖片空間上*/show_pic(image,IDC_SHOWIMG);CDialog:OnTimer(nIDEvent);/ /OnTimer(UINT nIDEvent)是定時(shí)器的函數(shù),為什么要在這里寫這句?/這個(gè)暫停按鈕的代碼void CAppDesignDlg:OnS

39、top() / TODO: Add your control notification handler code herem_stop=!m_stop;if (m_stop)KillTimer(1); /銷毀定時(shí)器 else SetTimer(1,33,NULL); /創(chuàng)建定時(shí)器,這里是一個(gè)33毫秒觸發(fā)1次的定時(shí)器/繼續(xù)void CAppDesignDlg:OnOK()/ TODO: Add extra validation herecvReleaseCapture( &pCapture );CDialog:OnOK();/控制控件的顯示顏色,OnCtlColor有關(guān)參見pDC是一個(gè)C

40、DC指針,是用來繪圖和顯示的pWnd是一個(gè)cWnd指針,指向控件(不確定)nCtlColor則是用來區(qū)別不同的調(diào)用的HBRUSH CAppDesignDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd->GetDlgCtrlID() = IDC_FRAMNUM)pDC->SetTextColor(RGB(255,0, 0); /幀控件的字體顏色 if (pWnd->GetDlgCtrlID() =

41、IDC_TIME)pDC->SetTextColor(RGB(255, 0, 0); /時(shí)間控件的字體顏色 / TODO: Return a different brush if the default is not desiredreturn hbr;/訓(xùn)練樣本的函數(shù)void CAppDesignDlg:Train()int i;/文件解析,得到文件列表或者稱,加載訓(xùn)練圖像集nTrainFaces為訓(xùn)練圖像的數(shù)目;導(dǎo)入faceImgArr(指向訓(xùn)練人臉的指針),解析得到train.txtnTrainFaces=loadFaceImgArr("train.txt");

42、if(nTrainFaces<2)fprintf(stderr,"Need 2 or more training facesn","Input file contains only %dn", nTrainFaces);return;/設(shè)置進(jìn)度條,m_progress是進(jìn)度條的關(guān)聯(lián)參數(shù), 1和 nTrainFaces分別是起始和結(jié)束的位置m_progress.SetRange(1, nTrainFaces);/PCA 提取特征,進(jìn)行主成分分析/*int nTrainFaces =0; / 訓(xùn)練圖像的數(shù)目,即人臉庫中有n張人臉int nEi

43、gens =0; / 自己取的主要特征值數(shù)目(在提取特征臉的時(shí)候用到的參數(shù))IplImage* faceImgArr =0; / 指向訓(xùn)練人臉和測(cè)試人臉的指針(在學(xué)習(xí)和識(shí)別階段指向不同)  CvMat* personNumTruthMat=0; / 人臉圖像的ID號(hào)IplImage* pAvgTrainImg =0; / 訓(xùn)練人臉數(shù)據(jù)的平均值IplImage* eigenVectArr =0; / 投影矩陣,也即主特征向量  CvMat* eigenValMat =0; / 特征值CvMat*

44、projectedTrainFaceMat=0; / 訓(xùn)練圖像的投影 CvMat* trainPersonNumMat=0;*/doPCA();/ projectedTrainFaceMat是訓(xùn)練圖像的投影;cvCreateMat是創(chuàng)建矩陣函數(shù),參數(shù)分別為(矩陣行數(shù),矩陣列數(shù),元素類型),下面的分別是(訓(xùn)練圖像數(shù)目,特征值數(shù)目,32位數(shù)據(jù))projectedTrainFaceMat=cvCreateMat(nTrainFaces,nEigens,CV_32FC1);for (i=0;i<nTrainFaces;i+)/將PCA特征保存到投影矩陣cvEigenDecom

45、posite()函數(shù)作用是將人臉圖像通過Eigenface變換矩陣,投射到子空間中。子空間中的人臉向量,是一個(gè)1×nEigens(nEigens由自己取得)的行向量,極大地降低了數(shù)據(jù)維度,便于下一步的聚類、識(shí)別。具體見cvEigenDecomposite(faceImgArri,nEigens,eigenVectArr,0,0,pAvgTrainImg,projectedTrainFaceMat->data.fl+i*nEigens); m_progress.SetPos(i+1); /進(jìn)度條的位置加1Sleep(100); /程序暫停1毫秒/將訓(xùn)練結(jié)果保存到文件storeTr

46、ainingData();/解析文件列表,就是讀文件 /加載txt文件的列舉的圖像int loadFaceImgArr(char *filename)FILE* imgListFile=0;char imgFilename512;int iFace, nFaces=0;/open the input fileimgListFile=fopen(filename,"r");/ 統(tǒng)計(jì)人臉數(shù) while(fgets(imgFilename,512,imgListFile) +nFaces;/fgets: read a line of file's st

47、rings to store in imgFilename/function fgets stops if meets a line break or read number of parameter 2rewind(imgListFile);/get the pointer to the start position of a file/ 分配人臉圖像存儲(chǔ)空間和人臉I(yè)D號(hào)存儲(chǔ)空間faceImgArr=(IplImage*)cvAlloc(nFaces*sizeof(IplImage*);personNumTruthMat=cvCreateMat(1,nFaces,CV_32SC1)

48、;for (iFace=0;iFace<nFaces;iFace+)/讀取圖片的路徑名稱/ 從文件中讀取序號(hào)和人臉名稱  fscanf(imgListFile,"%d %s",personNumTruthMat->data.i+iFace,imgFilename);/將圖片保存在數(shù)組中 / 加載人臉圖像 faceImgArriFace=cvLoadImage(imgFilename,CV_LOAD_IMAGE_GRAYSCALE);fclose(imgListFile);return nFaces;/P

49、CA提取人臉特征void doPCA()int i;CvTermCriteria calcLimit; / CvTermCriteria criteria:停止迭代的標(biāo)準(zhǔn),傳入;CvSize faceImgSize; /人臉框的大小/set the number of eigenvalues to usenEigens=nTrainFaces-1; /特增值的數(shù)目/分配內(nèi)存空間faceImgSize.width=faceImgArr0->width; / faceImgArr測(cè)試人臉的寬faceImgSize.height=faceImgArr0->height; / faceIm

50、gArr測(cè)試人臉的高eigenVectArr=(IplImage*)cvAlloc(sizeof(IplImage*)*nEigens); /分配個(gè)數(shù)為住特征值個(gè)數(shù)  /按照設(shè)定的特征值,從小到大,依次給主特征向量分配內(nèi)存空間(測(cè)試人臉框的大小,深度,通道數(shù))for (i=0;i<nEigens;i+)eigenVectArri=cvCreateImage(faceImgSize,IPL_DEPTH_32F,1);/分配主特征值存儲(chǔ)空間eigenValMat=cvCreateMat(1,nEigens,CV_32FC1);/ 分配平均圖像存儲(chǔ)空間 

51、(人臉框的大小,深度,通道數(shù))pAvgTrainImg=cvCreateImage(faceImgSize,IPL_DEPTH_32F,1);/設(shè)定PCA分析結(jié)束條件  calcLimit=cvTermCriteria(CV_TERMCRIT_ITER,nEigens,1); / 計(jì)算平均圖像,特征值,特征向量  cvCalcEigenObjects(nTrainFaces, (void*)faceImgArr, (void*)eigenVectArr,CV_EIGOBJ_NO_CALLBACK, 0, 0, &calcLim

52、it, pAvgTrainImg, eigenValMat->data.fl);/保存訓(xùn)練結(jié)果函數(shù)void storeTrainingData()CvFileStorage* fileStorage;int i;/create a file-storage interface cvOpenFileStorage:為讀寫數(shù)據(jù)打開文件存儲(chǔ)器fileStorage=cvOpenFileStorage("facedata.xml",0,CV_STORAGE_WRITE); /存儲(chǔ)特征值,投影矩陣,平均矩陣等訓(xùn)練結(jié)果cvWriteInt(fileStorage,&qu

53、ot;nEigens",nEigens); 特征值數(shù)目cvWriteInt(fileStorage,"nTrainFaces",nTrainFaces); 訓(xùn)練圖像數(shù)目cvWrite(fileStorage,"trainPersonNumMat",personNumTruthMat,cvAttrList(0,0); 人臉圖像ID號(hào)cvWrite(fileStorage,"eigenValMat",eigenValMat,cvAttrList(0,0); 特征值cvWrite(fileStorage,"projectedTrainFaceM

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論