




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
2教育部國家大學(xué)生創(chuàng)新性實(shí)驗(yàn)計(jì)劃項(xiàng)目類別:國家創(chuàng)新基金基于圖像處理的疲勞檢測系統(tǒng)結(jié)題論文項(xiàng)目時(shí)間:2009年11月~2010年11月項(xiàng)目負(fù)責(zé)人:肖永龍:空天科學(xué)技術(shù)研究院任玉琢摘要疲勞駕駛是當(dāng)今交通安全的重要隱患之一。駕駛?cè)嗽谄跁r(shí),其對周圍環(huán)境的感知能力、形勢判斷能力和對車輛的操控能力都有不同程度的下降,因此很容易發(fā)生交通事故。因此,研究開發(fā)高性能的駕駛?cè)似跔顟B(tài)實(shí)時(shí)監(jiān)測及預(yù)警技術(shù),對改善我國交通安全狀況意義重大。本系統(tǒng)旨在準(zhǔn)確判斷得到駕駛員的疲勞程度,判斷PERCLOS值是最具有潛力和最準(zhǔn)確的疲勞測定方法之一,其中PERCLOS指在一定的時(shí)間內(nèi)眼睛閉合時(shí)所占的時(shí)間比例,通過對駕駛室中的駕駛員快速準(zhǔn)確的定位其眼部區(qū)域,接著得到其眼睛狀態(tài),最后計(jì)算得到PERCLOS值。根據(jù)PERCLOS值的判斷標(biāo)準(zhǔn)得到駕駛員的疲勞程度,用以警示駕駛員。關(guān)鍵詞:司機(jī)疲勞;疲勞檢測;PERCLOS目錄目錄第一章 引言 整體該疲勞檢測系統(tǒng)如圖2-1:圖2-SEQ圖2-\*ARABIC1主要有視頻圖像區(qū),參數(shù)區(qū),操作區(qū)及人眼面積波形顯示區(qū)組成,當(dāng)操作者打開程序,單擊開始按鈕后,程序便自動(dòng)進(jìn)行疲勞檢測,定位人臉,定位人眼,計(jì)算人眼面積,計(jì)算perclos值,如果單擊打開波形按鈕,則會打開人眼面積波形窗口,實(shí)時(shí)顯示當(dāng)前人眼面積的波形。另外,該系統(tǒng)還提供暫停功能,零時(shí)關(guān)閉系統(tǒng)中正在運(yùn)行的線程,以降低程序?qū)ο到y(tǒng)的消耗。圖像獲取圖2-SEQ圖2-\*ARABIC2當(dāng)程序打開后,單擊開始按鈕,系統(tǒng)自動(dòng)從攝像頭中讀取圖像,并實(shí)時(shí)顯示在圖像區(qū),直到系統(tǒng)暫?;蜿P(guān)閉。人眼面積的顯示圖2-SEQ圖2-\*ARABIC3當(dāng)系統(tǒng)開始工作之后,單擊打開波形按鈕,系統(tǒng)會另開一個(gè)窗口,用于實(shí)時(shí)顯示當(dāng)前人眼面積的波形,其中橫軸為時(shí)間軸,縱軸為經(jīng)過處理的面積軸。圖像中每一個(gè)波谷都代表著一次眨眼。當(dāng)單擊關(guān)閉波形按鈕時(shí),系統(tǒng)會關(guān)閉該窗口,暫時(shí)關(guān)閉波形的顯示。參數(shù)的顯示圖2-SEQ圖2-\*ARABIC4當(dāng)正常工作時(shí),系統(tǒng)會對人眼的面積進(jìn)行實(shí)時(shí)的計(jì)算和統(tǒng)計(jì),實(shí)時(shí)計(jì)算perclos值,并在參數(shù)區(qū)進(jìn)行顯示,系統(tǒng)會取5次perclos值作為一次有效的perclos值,當(dāng)該perclos值>0.15時(shí),便認(rèn)為是疲勞狀態(tài),并給出相應(yīng)的提示和警告。狀態(tài)信息圖2-5圖2-6圖2-7圖2-8在狀態(tài)欄中,顯示當(dāng)前檢測到的狀態(tài)信息。當(dāng)剛開始檢測時(shí),狀態(tài)欄顯示灰色,提示信息為:正在檢測(如圖2-6);如果檢測信息正常,則狀態(tài)中顯示為綠色,提示信息為:正常(如圖2-7);如果當(dāng)前人perclos值大于0.15,則狀態(tài)中顯示為紅色,并給出提示,請注意休息(如圖2-8)。系統(tǒng)的功能圖2-SEQ圖2-\*ARABIC9為方便操作,系統(tǒng)提供了4個(gè)基本功能,開始、暫停、結(jié)束、和波形顯示。其中當(dāng)系統(tǒng)開啟時(shí),僅有開始按鈕有效,單擊開始按鈕后,系統(tǒng)進(jìn)入工作狀態(tài),將其余按鈕使能,可進(jìn)行暫停、波形顯示、結(jié)束等操作;單擊打開波形按鈕,系統(tǒng)開啟一個(gè)波形顯示窗口,提供實(shí)時(shí)人眼面積波形,按鈕提示文字變?yōu)殛P(guān)閉波形;單擊暫停按鈕,系統(tǒng)將關(guān)閉除主線程外的所有線程,系統(tǒng)進(jìn)入暫停工作狀態(tài)。第三章讀取視頻模塊讀取視頻模塊為了使系統(tǒng)的后續(xù)操作能夠順利進(jìn)行,在初始化時(shí),程序需要對系統(tǒng)是否具有攝像頭,有多少個(gè)攝像頭進(jìn)行統(tǒng)計(jì),如果沒有攝像頭,則進(jìn)行提醒,如果有多個(gè)攝像頭,便提醒使用者進(jìn)行選擇,以使系統(tǒng)能夠正確的進(jìn)行配置。同時(shí),由于待處理的視頻圖像數(shù)據(jù)量巨大,而圖像的大小直接關(guān)系到待處理的數(shù)據(jù)量,為此,在對攝像頭進(jìn)行設(shè)置時(shí),需要將讀入的視頻幀的大小為320x240。其設(shè)置如下:cvCapturecapture=cvCaptureFromCAM(0);cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,320);cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,240);當(dāng)初始化設(shè)置完成后,使用者選擇開始時(shí),通過IplImage*cvQueryFrame(cvCapturecapture)的調(diào)用,程序便進(jìn)行一次視頻幀的讀取,并通過CvvImageimg;IplImage*Image2=(IplImage*)wParam;if(Image2){img.CopyOf(Image2);//從IplImage拷貝圖像數(shù)據(jù)到CvvImageimg.DrawToHDC(hDC,&rect);//在控件上繪制圖像}將圖顯示在句柄hDC指向的控件上;不斷重復(fù)讀視頻幀,顯示視頻幀,便可以看到一個(gè)連續(xù)的視頻。第四章圖像處理模塊第四章圖像處理模塊圖像處理模塊圖4-SEQ圖4-\*ARABIC1圖像識別方法膚色識別膚色是人臉的重要信息,不依賴于面部的細(xì)節(jié)特征,對于旋轉(zhuǎn)、表情變化等情況都能適用,具有相對的穩(wěn)定性并且和大多數(shù)背景物體的顏色相區(qū)別。利用膚色分割檢測人臉的方法,聚類緊湊.選用YCbCr空間易于實(shí)現(xiàn)聚類算法。經(jīng)分析可知滿足二維高斯分布,則對于像素的色度C=[CbCr]T,膚色像素的概率分布如圖4-2:圖4-SEQ圖4-\*ARABIC2對獲得的每一幀的圖像采用0.4<Cb<0.6同時(shí)0.5<Cr<0.7進(jìn)行膚色分割得到膚色圖;如圖4-3(原圖),圖4-4(處理后的圖像):圖4-SEQ圖4-\*ARABIC3圖4-SEQ圖4-\*ARABIC4將膚色圖區(qū)域化形成膚色區(qū)域(如圖4-5),以便在膚色區(qū)域進(jìn)行下一步處理。圖4-SEQ圖4-\*ARABIC5AdaBoost算法AdaBoost算法是一種迭代方法,它本身是通過改變數(shù)據(jù)分布來實(shí)現(xiàn)的。它根據(jù)每輪訓(xùn)練中每個(gè)樣本的分類是否正確,以及上輪的總體分類準(zhǔn)確率,來確定每個(gè)樣本的權(quán)值。將每次訓(xùn)練得到的分類器融合起來,作為最后的決策分類器。在AdaBoost算法中,每一個(gè)訓(xùn)練樣本都被賦予一個(gè)權(quán)重,表明它被某個(gè)弱分類器選入訓(xùn)練集的概率。如果某個(gè)樣本沒有被正確的分類,那么在構(gòu)造下一個(gè)訓(xùn)練集時(shí),它被選中的概率就會增加:相反,如果某個(gè)樣本已經(jīng)被正確的分類,那么在構(gòu)造下一個(gè)訓(xùn)練集時(shí),它被選中的概率就會降低。通過這樣的方式,AdaBoost算法能夠“聚焦于”那些較困難(更富信息)的樣本上。在具體的實(shí)現(xiàn)上,最初令每個(gè)樣本的權(quán)重都相等,對于第t次迭代操作,就根據(jù)這些權(quán)重來選取樣本點(diǎn),進(jìn)而訓(xùn)練分類器。然后就根據(jù)這個(gè)分類器,來提高被它錯(cuò)分的那些樣本點(diǎn)的權(quán)重,并降低被正確分類的樣本權(quán)重。然后,權(quán)重更新后的樣本集被用來訓(xùn)練下一個(gè)分類器,整個(gè)訓(xùn)練過程如此循環(huán)下去。AdaBoost算法具有很強(qiáng)的實(shí)用性,表現(xiàn)在:1)算法的速度快;.2)除了訓(xùn)練輪數(shù)T外,不需要調(diào)節(jié)任何參數(shù);3)不需要知道任何關(guān)于弱分類器的先驗(yàn)知識;4)對弱分類器的性能要求不高,只需要比隨機(jī)猜測性能稍好即可,這種弱分類器在實(shí)際情況下是很容易獲得的,從而降低了算法的復(fù)雜度,提高了效率5)在弱分類器的構(gòu)成上可以兼容多種方法,這些弱分類器可以是神經(jīng)網(wǎng)絡(luò),決策樹,最近鄰域分類器,經(jīng)驗(yàn)規(guī)則等;.6)訓(xùn)練數(shù)據(jù)可以是文本、數(shù)字、離散值等等,并且AdaBoost算法很容易被推廣到多類目標(biāo)的分類問題中去。AdaBoost算法訓(xùn)練Adaboost學(xué)習(xí)算法的學(xué)習(xí)過程,可以理解為“貪婪的特征選擇過程”。對一個(gè)問題,通過加權(quán)投票機(jī)制,用大量的分類函數(shù)的加權(quán)組合來判斷。算法的關(guān)鍵就是,當(dāng)分類器對某些樣本正確分類時(shí),則減少這些樣本的權(quán)值;當(dāng)錯(cuò)誤分類時(shí),則增加這些樣本的權(quán)值,讓學(xué)習(xí)算法在后續(xù)的學(xué)習(xí)中集中對比較難的訓(xùn)練樣本進(jìn)行學(xué)習(xí),最終得到一個(gè)識別準(zhǔn)確率理想的分類器。每個(gè)矩形特征對應(yīng)一個(gè)弱分類器,利用AdaBoost算法生成強(qiáng)分類器的過程就是尋找那些對人臉和非人臉區(qū)分性最好的那些矩形特征,由這些特征所對應(yīng)的弱分類器組合生成的強(qiáng)分類器對人臉的區(qū)分度達(dá)到最優(yōu)。訓(xùn)練過程的意義可以表述為:每一次迭代過程在當(dāng)前的概率分布上找到一個(gè)具有最小錯(cuò)誤率的弱分類器,然后調(diào)整概率分布,增大當(dāng)前弱分類器分類錯(cuò)誤的樣本的概率值,降低當(dāng)前弱分類器分類正確的樣本的概率值,以突出分類錯(cuò)誤的樣本,使下一次迭代更加針對本次的不正確分類,即針對更“困難”的樣本,使得那些被錯(cuò)分的樣本得到進(jìn)一步重視。這樣,后面訓(xùn)練提取的若分類器就會更加強(qiáng)化對這些分類錯(cuò)誤樣本的訓(xùn)練。通過AdaBoost算法生成了由重要特征組成的強(qiáng)分類器。對于一個(gè)200特征的強(qiáng)分類器,可以將之用于人臉檢測,但由于檢測過程要掃描待檢測圖像的每個(gè)位置的各個(gè)規(guī)模的每個(gè)窗口,所以要檢測的窗口數(shù)量很多,這種條件下,如果每個(gè)窗口都進(jìn)行200個(gè)特征的特征值計(jì)算,檢測工作的整個(gè)過程將花費(fèi)很多的時(shí)間。在實(shí)際的人臉檢測過程中可以采用“先重后輕”的級聯(lián)分類器的思想。它首先使用更重要的特征構(gòu)成的結(jié)構(gòu)較簡單的強(qiáng)分類器進(jìn)行非人臉窗口的排除,隨著特征的重要性的逐漸降低,分類器的數(shù)目越來越多,但同時(shí)待檢測窗口也越來越少。.PaulViola和MichaelJones于2001年提出了級聯(lián)AdaBoost人臉檢測方法,該方法采用一種“積分圖”的圖像表示方法,可以快速計(jì)算出haar-like特征,利用AdaBoost學(xué)習(xí)算法將由haar-like特征生成的簡單分類器疊加成為強(qiáng)分類器,再將強(qiáng)分類器級聯(lián)而成為分級分類器用于檢測入臉,該方法可使圖像的背景區(qū)域快速地丟棄,而在有可能存在人臉的區(qū)域花費(fèi)更多的計(jì)算。級聯(lián)分類器結(jié)構(gòu)如圖4-6所示:圖4-SEQ圖4-\*ARABIC6“級聯(lián)分類器”的每一“層”是一個(gè)由連續(xù)AdaBoost算法訓(xùn)練得到的強(qiáng)分類器。設(shè)置每層的閾值,使得大多數(shù)人臉都能通過,在此基礎(chǔ)上盡量拋棄負(fù)樣本。位置越靠后的層越復(fù)雜,即包含越多的弱分類器,因而也具有更強(qiáng)的分類能力。這樣做是因?yàn)榉侨四槝颖就ㄟ^的層數(shù)越多就越像人臉,因而越接近分類邊界。級聯(lián)分類器就像一系列篩孔大小遞減的篩子,每一步都能篩除一些前面篩子漏下的負(fù)樣本,最終通過所有篩子的樣本才被接受為人臉。級聯(lián)分類器串連的級數(shù)依賴于系統(tǒng)的錯(cuò)誤率和響應(yīng)速度。前面的幾層強(qiáng)分類器通常結(jié)構(gòu)簡單,通常一層僅由一到兩個(gè)弱分類器組成,但這些結(jié)構(gòu)簡單的強(qiáng)分類器可以在早期達(dá)到近100%的檢測率,同時(shí)誤檢率也很高,我們可以利用它們快速的篩選掉那些顯然不是人臉的子窗口,從而大大減少需要后續(xù)處理的子窗口。Haar-like生成簡單分類器直接利用haar-like特征構(gòu)成的分類器稱為簡單分類器,簡單分類器與矩形特征一一對應(yīng)。一般來說,簡單分類器的性能比隨機(jī)分類略好一些,它的優(yōu)點(diǎn)是設(shè)計(jì)簡單、計(jì)算量小、實(shí)時(shí)性強(qiáng),但是分類能力弱。對于Haar-llke特征而言,一個(gè)24*24的矩形區(qū)域,可能的特征達(dá)幾萬種,遠(yuǎn)遠(yuǎn)超過了24*24的象素的個(gè)數(shù)。即使每個(gè)特征都可以快速的計(jì)算,整個(gè)計(jì)算過程也非常耗時(shí)。在實(shí)際計(jì)算中,必須找到那些對于分類比較重要的特征,AdaBoost算法是選取這些特征的有效手段。分類器訓(xùn)練完以后,就可以應(yīng)用于輸入圖像中的感興趣區(qū)域(與訓(xùn)練樣本相同的尺寸)的檢測。檢測到目標(biāo)區(qū)域(汽車或人臉)分類器輸出為1,否則輸出為0。為了檢測整副圖像,可以在圖像中移動(dòng)搜索窗口,檢測每一個(gè)位置來確定可能的目標(biāo)。為了搜索不同大小的目標(biāo)物體,分類器被設(shè)計(jì)為可以進(jìn)行尺寸改變,這樣比改變待檢圖像的尺寸大小更為有效。所以,為了在圖像中檢測未知大小的目標(biāo)物體,掃描程序通常需要用不同比例大小的搜索窗口對圖片進(jìn)行幾次掃描。分類器中的“級聯(lián)”是指最終的分類器是由幾個(gè)簡單分類器級聯(lián)組成。在圖像檢測中,被檢窗口依次通過每一級分類器,這樣在前面幾層的檢測中大部分的候選區(qū)域就被排除了,全部通過每一級分類器檢測的區(qū)域即為目標(biāo)區(qū)域?;A(chǔ)分類器是至少有兩個(gè)葉結(jié)點(diǎn)的決策樹分類器訓(xùn)練自己的分類器利用分類器識別人臉區(qū)域通過訓(xùn)練人臉20X20的2000張正例和2000張反例圖片,我們可以得到一個(gè)比較好的級聯(lián)分類器。分類器訓(xùn)練完以后,就可以應(yīng)用于輸入圖像中的感興趣區(qū)域的檢測。要訓(xùn)練一個(gè)Haar分類器,總體上包括3步:1)準(zhǔn)備正負(fù)樣本;2)用CreateSamples程序建正樣本集;3)用HaarTraining程序訓(xùn)練,得到最終的分類器模型(xml文件)。圖4-SEQ圖4-\*ARABIC7樣本準(zhǔn)備:HaarTraining需要使用正樣本和負(fù)樣本進(jìn)行訓(xùn)練。本訓(xùn)練選擇2000張正樣本,2000張負(fù)樣本。大小裁剪到20X20樣本訓(xùn)練的總體流程:圖4-8是HaarTraining訓(xùn)練的一個(gè)簡單流程。這個(gè)流程之所以是簡單流程,因?yàn)橹挥挟?dāng)用戶是要建一個(gè)簡單的級聯(lián)分類器時(shí)才是這么一個(gè)流程。對于建樹形強(qiáng)分類器,其流程比這個(gè)要復(fù)雜。圖4-SEQ圖4-\*ARABIC8識別人臉模塊為了提高系統(tǒng)對人眼檢測的準(zhǔn)確性,系統(tǒng)先定位人臉,再在定位到的人臉基礎(chǔ)上定位人眼。圖4-SEQ圖4-\*ARABIC9系統(tǒng)先采用傳統(tǒng)的膚色識別,定位速度很快,但是精確度不太高,為此,當(dāng)采用膚色識別之后,便在小區(qū)域中進(jìn)行模式識別,得到非常精確的人臉區(qū)域,若膚色識別得到的區(qū)域小于既定值,則說明膚色識別失敗,得對全部區(qū)域進(jìn)行模式識別,得到人臉區(qū)域。為了檢測整副圖像,可以在圖像中移動(dòng)搜索窗口,檢測每一個(gè)位置來確定可能的目標(biāo)。為了搜索不同大小的目標(biāo)物體,分類器被設(shè)計(jì)為可以進(jìn)行尺寸改變。為了在圖像中檢測未知大小的目標(biāo)物體,掃描程序通常需要用不同比例大小的搜索窗口對圖片進(jìn)行幾次掃描。檢測人臉需要對單通道的圖像進(jìn)行模式識別,而此時(shí)傳過來的膚色區(qū)域是三通道RGB圖像。因此在進(jìn)行人臉檢測的之前我們必須進(jìn)行圖像預(yù)處理。三通道圖像到單通道圖像的轉(zhuǎn)換公式如下:Y=0.299R+0.587G+0.114B;同時(shí)單通道的亮度信息可能會對檢測過程造成很大的影響,預(yù)處理過程還需對單通道圖像均衡化。均衡化效果如下:圖4-SEQ圖4-\*ARABIC10圖4-SEQ圖4-\*ARABIC11由于人臉區(qū)域的大小未知,需要程序按照1.3比例對傳進(jìn)來的膚色區(qū)域圖像縮放后掃描幾次,最終得到的是膚色區(qū)域中是否還有人臉區(qū)域,有的話返回的是人臉區(qū)域的相關(guān)信息,包括人臉區(qū)域的大小,位置信息。定位人眼模塊檢測人眼區(qū)域和檢測人臉區(qū)域差不多,通過訓(xùn)練人臉20X20的2000張正例和2000張反例圖片,我們得到一個(gè)比較好的級聯(lián)分類器。分類器訓(xùn)練完以后,就可以應(yīng)用于輸入圖像中的感興趣區(qū)域的檢測。由于人臉大小未知,可能傳過來的感興趣區(qū)域比較小,導(dǎo)致檢測程序檢測不到人眼區(qū)域。利用Gaussian金字塔分解對人臉區(qū)域圖像向上采樣。首先通過在圖像中插入偶數(shù)行和偶數(shù)列,然后對得到的圖像用指定的指定的濾波器進(jìn)行高斯卷積,其中濾波器乘以4做插值。所以輸出的圖像為原輸入人臉區(qū)域的4倍大小。效果如圖4-12和圖4-13:圖4-SEQ圖4-\*ARABIC12圖4-SEQ圖4-\*ARABIC13得到了上采樣之后的圖像,利用和之前人臉區(qū)域檢測相同的算法,只是人眼區(qū)域檢測的級聯(lián)器有所不同而已。第五章參數(shù)計(jì)算模塊第五章參數(shù)計(jì)算模塊15參數(shù)計(jì)算模塊計(jì)算人眼面積模塊計(jì)算人眼面積是得到perclos值的前提,為了得到盡可能準(zhǔn)確的人眼面積,有必要對圖像進(jìn)行一些列的處理。在該系統(tǒng)中,計(jì)算人眼面積的流程如圖5-1:圖5-SEQ圖5-\*ARABIC1先計(jì)算出得到的人眼面積區(qū)域圖像的空間和中心矩,并提取出x一階矩M10和y一階矩M01;然后再計(jì)算出圖像的重心,并根據(jù)重心的位置估計(jì)出人眼的區(qū)域,再畫出人眼區(qū)域圖像的輪廓,經(jīng)過腐蝕,就可以計(jì)算出人眼的面積了。當(dāng)經(jīng)過一定的時(shí)間處理后,得到人眼面積系列,其波形如圖5-2:圖5-SEQ圖5-\*ARABIC2在該波形中,縱軸表示人眼面積,橫軸表示時(shí)間;包含了一定量的噪聲;但在眨眼時(shí),人眼面積最小,在波形中以波谷形式存在,而在波形中出現(xiàn)頻數(shù)最多的,應(yīng)該是人眼處于平常睜開狀態(tài)。perclos值計(jì)算1996年,美國Knipling,Wang和Kanianthra[5]等人測量開閉、運(yùn)動(dòng)和眼睛的生理學(xué)表現(xiàn)形態(tài)來研究機(jī)動(dòng)車駕駛員的疲勞問題。他們認(rèn)為利用眼睛來判斷疲勞是非常恰當(dāng)?shù)?,并且也是行之有效的方法。Dinges認(rèn)為,PERCLOS(單位時(shí)間內(nèi)眼睛閉合時(shí)間所占的百分率)能相當(dāng)準(zhǔn)確地反映疲勞狀態(tài)。1999年4月,美國聯(lián)邦公路管理局(FederalHighwayAdministration)10%[2]。的技術(shù)論壇上發(fā)表題為“OcularMeasuresofDriv-erAlertness”的文章,首先提出了把PERCLOS作為預(yù)測機(jī)動(dòng)車駕駛員駕駛疲勞的可行方法。JohnStern博士是研究眼睛部位運(yùn)動(dòng)狀態(tài)與駕駛疲勞之間的關(guān)系的權(quán)威人士。由他領(lǐng)導(dǎo)的美國聯(lián)邦公路管理局和汽車聯(lián)合會資助的研究所,通過開發(fā)專用的照相機(jī)、腦電圖儀和其他儀器來精確測量眼睛瞳孔的直徑變化、眨眼頻率和頭部運(yùn)動(dòng),以此來研究駕駛疲勞問題。弗吉尼亞大學(xué)[8]的精神生理學(xué)教授WaltWierwille博士提出的疲勞測量(psychoph-ysiologicalfatiguedetectiondevicesandmeasures)方法是采用PERCLOS作為疲勞測量指標(biāo)。目前,PERCLOS方法已被公認(rèn)為最有效的、車載的、實(shí)時(shí)的駕駛疲勞測評方法。perclos的原理或概念PERCLOS是PercentageofEyelidClosureOverthePupilOverTime的縮寫,即:眼睛閉合時(shí)間占某一特定時(shí)間的百分率。如圖1,只要測出t1~t4的值,就可計(jì)算出PERCLOS的值。公式為:其中t1是眼睛最大瞳孔閉合到80%瞳孔所用時(shí)間;t2是眼睛80%瞳孔閉合到20%瞳孔所用時(shí)間;t3是眼睛20%瞳孔閉合到20%瞳孔睜開所用時(shí)間;t4是眼睛20%瞳孔睜開到80%瞳孔所用時(shí)間;f為眼睛閉合時(shí)間占某一特定時(shí)間的百分率,即為PERCLOS值。圖5-SEQ圖5-\*ARABIC3在具體試驗(yàn)中有P70、P80、EYEMEA(EM)3種度量標(biāo)準(zhǔn)。P70:眼睛閉合面積70%以上的時(shí)間百分比;P80:眼睛閉合面積80%以上的時(shí)間百分比,該指標(biāo)是最常用的;我們計(jì)算perclos的方法當(dāng)?shù)玫饺搜鄣拿娣e時(shí),一方面,系統(tǒng)通過一定的方法將其顯示在人眼面積波形上(如圖1),圖5-SEQ圖5-\*ARABIC4另一方面,系統(tǒng)會將該面積記錄在緩存中,當(dāng)緩存中數(shù)據(jù)記錄滿300個(gè)時(shí),便進(jìn)行頻數(shù)統(tǒng)計(jì),將面積在4000-11500間的數(shù)據(jù)間隔500進(jìn)行統(tǒng)計(jì),如下:圖5-SEQ圖5-\*ARABIC5由于采集過程中存在噪聲,取頻數(shù)最大的面積為人眼的最大面積,再對大于最大面積80%、小于最大面積20%的記錄分別進(jìn)行統(tǒng)計(jì),設(shè)為大于最大面積80%的頻數(shù)為N1,小于最大面積20%的頻數(shù)為N2;頻數(shù)總和為N,則這樣,通過對300個(gè)人眼面積進(jìn)行統(tǒng)計(jì),減小了由于噪聲等造成的誤差,使得計(jì)算出來的結(jié)果更為科學(xué),為了進(jìn)一步減小誤差,可取五個(gè)perclos值進(jìn)行平均,并將這個(gè)平均值作為perclos值,通過對這個(gè)perclos值的判斷,若perclos值>0.15,則被測試人已經(jīng)處于疲勞狀態(tài),系統(tǒng)便會進(jìn)行一些相關(guān)處理,如提醒等。第六章線程管理模塊第六章線程管理模塊18線程管理模塊在系統(tǒng)中,讀取視頻,顯示視頻模塊均采用的是無限循環(huán)策略,若是直接放在主線程,則整個(gè)應(yīng)用程序就會出現(xiàn)假死,對所有的系統(tǒng)操作都失效,為此,我們采用了多線程的策略,將讀取視頻放在了一個(gè)新線程中,同時(shí),為了提高系統(tǒng)處理視頻的速度,我們?yōu)閳D像處理,人眼面積的記錄、perclos值的計(jì)算分別開了一個(gè)新線程。一般而言,應(yīng)用程序中的一個(gè)次要線程總是為主線程執(zhí)行特定的任務(wù),這樣,主線程和次要線程間必定有一個(gè)信息傳遞的渠道,也就是主線程和次要線程間要進(jìn)行通信。這種線程間的通信不但是難以避免的,而且在多線程編程中也是復(fù)雜和頻繁的,一般線程進(jìn)行通訊有兩種方式:1、使用全局變量進(jìn)行通信,2、使用自定義消息進(jìn)行通訊。使用全局變量進(jìn)行通訊,對于傳遞數(shù)據(jù)量超大的圖像信息不太實(shí)用,為此,我們選用了第二種方法,在一個(gè)線程的執(zhí)行函數(shù)中向另一個(gè)線程發(fā)送自定義的消息來達(dá)到通信的目的。一個(gè)線程向另外一個(gè)線程發(fā)送消息是通過操作系統(tǒng)實(shí)現(xiàn)的。利用Windows操作系統(tǒng)的消息驅(qū)動(dòng)機(jī)制,當(dāng)一個(gè)線程發(fā)出一條消息時(shí),操作系統(tǒng)首先接收到該消息,然后把該消息轉(zhuǎn)發(fā)給目標(biāo)線程,但是接收消息的線程必須已經(jīng)建立了消息循環(huán),為此,我們在程序設(shè)計(jì)時(shí),為每個(gè)線程建立一個(gè)私有的消息循環(huán):while(PeekMessage(&message,NULL,0,0,PM_REMOVE)){if(message.message==WM_USER_QUIT){//quitreturn0;}TranslateMessage(&message);DispatchMessage(&message);}//...通過為每個(gè)線程添加消息循環(huán),線程間通信便變得非常簡單,僅僅需要pRecordThread->PostThreadMessageA(WM_USER_NEWPARAMETER,(int)param,NULL)便可發(fā)送向pRecordThread指針指向的線程發(fā)送一個(gè)WM_USER_NEWPARAMETER消息,該線程在接收到這個(gè)消息后,便進(jìn)行指定的操作,將參數(shù)param寫入緩存,完成一次線程間的通訊。當(dāng)系統(tǒng)中存在多個(gè)線程時(shí),就需要對線程進(jìn)行組織和管理,在該系統(tǒng)中,線程是通過消息來控制的,整個(gè)系統(tǒng)的UML時(shí)序圖如圖6-1:圖6-SEQ圖6-\*ARABIC1然而,由于線程間通訊使用的是指針傳遞,當(dāng)消息傳遞過去之后,便存在多個(gè)線程同時(shí)訪問一個(gè)內(nèi)存空間,造成訪問沖突,為了解決這個(gè)問題,當(dāng)線程接收到數(shù)據(jù)時(shí),便將圖像復(fù)制一份存入另一個(gè)地址中,并對該空間加鎖,防止其他線程的干擾,從而使系統(tǒng)能夠順利實(shí)現(xiàn)其功能。通過使用消息循環(huán)來管理線程,不僅可以使線程變得更為安全,還可以使線程的管理變得更為簡單,使系統(tǒng)的可擴(kuò)展性增強(qiáng)。結(jié)束語20結(jié)束語基于PERCLOS和圖像處理疲勞檢測系統(tǒng),可以實(shí)時(shí)的得到定位人眼并計(jì)算出人眼對面積,得到人的perclos值,判斷檢測駕駛員的疲勞狀態(tài),在駕駛員疲勞駕駛時(shí)進(jìn)行報(bào)警提醒,對于提高行車安全,降低交通事故發(fā)生率。本系統(tǒng)利用圖像處理技術(shù),從定位人臉,定位人眼,計(jì)算人眼面積,到計(jì)算perclos值,總體用時(shí)很少,約200ms,處理速度較快,識別率較高。但是該系統(tǒng)也有一定的不足,圖像處理的算法需要進(jìn)一步優(yōu)化,系統(tǒng)的線程管理尚需要進(jìn)一步完善。參考書目21參考書目Kaebler,學(xué)習(xí)OPENCV(中文版),清華大學(xué)出版社;Matlab中文論壇,Matlab神經(jīng)網(wǎng)絡(luò)30個(gè)案例分析,北京航空航天大學(xué)出版社;秦襄培,數(shù)字圖像處理(第二版),電子工業(yè)出版社;張宏林,VisualC++數(shù)字圖像模式識別技術(shù)及工程實(shí)踐,人民郵電出版社;附錄附錄22附錄//fatigueDetectionDlg.cpp:實(shí)現(xiàn)文件#include"stdafx.h"#include"fatigueDetection.h"#include"fatigueDetectionDlg.h"#include"WaveForm.h"#ifdef_DEBUG#definenewDEBUG_NEW#endif/*************************變量*********************************/HDChDC;//設(shè)備環(huán)境句柄CRectrect;staticCvMemStorage*storage=0;staticCvHaarClassifierCascade*cascade=0;staticCvHaarClassifierCascade*cascade_2=0;CStringcascade_name="";CStringcascade_name_2="";CvRectFaceColor_ROI;booldetect_flag=false;HWNDhWnd;CvCapture*capture;CWinThread*pReadImageThread;CWinThread*pDetectThread;CWinThread*pRecordThread;WaveForm*wf;intnArea2[300];intnArea4[300];intptr=0;intnArea_temp=0;intcount=0;doubledPerclos[5];intptrPerclos=0;boolisStop;/***********************變量END*******************************//***********************線程函數(shù)申明****************************/staticUINTCReadImage(LPVOIDlp);//線程2讀取圖像staticUINTCDetect(LPVOIDlp);//線程3識別人臉人眼計(jì)算參數(shù)staticUINTCRecord(LPVOIDlp);//線程4記錄面積和時(shí)間系列/*********************線程函數(shù)申明END*************************//************************功能函數(shù)******************************/CvRectFaceColor_detect(IplImage*image);voidDetect_draw(IplImage*dest,IplImage*image,IplImage*img_t);doubleperlogs_value(int*pArea,intnum);/*********************功能函數(shù)END*****************************///用于應(yīng)用程序“關(guān)于”菜單項(xiàng)的CAboutDlg對話框classCAboutDlg:publicCDialog{public: CAboutDlg();//對話框數(shù)據(jù) enum{IDD=IDD_ABOUTBOX}; protected: virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持//實(shí)現(xiàn)protected: DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){ CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)END_MESSAGE_MAP()//CfatigueDetectionDlg對話框CfatigueDetectionDlg::CfatigueDetectionDlg(CWnd*pParent/*=NULL*/) :CDialog(CfatigueDetectionDlg::IDD,pParent){ m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);}voidCfatigueDetectionDlg::DoDataExchange(CDataExchange*pDX){ CDialog::DoDataExchange(pDX); DDX_Control(pDX,IDC_SHOWWAVE,BtnShowWave); DDX_Control(pDX,IDC_LIST_PARAMETERS,listParameters);}BEGIN_MESSAGE_MAP(CfatigueDetectionDlg,CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_TIMER() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_SHOWWAVE,&CfatigueDetectionDlg::OnBnClickedShowwave) ON_MESSAGE(WM_USER_DRAW,&CfatigueDetectionDlg::OnUserDraw) ON_MESSAGE(WM_USER_PARA,&CfatigueDetectionDlg::OnUserPara) ON_WM_MOVE() ON_BN_CLICKED(IDC_btnBegin,&CfatigueDetectionDlg::OnBnClickedbtnbegin) ON_BN_CLICKED(IDC_btnPause,&CfatigueDetectionDlg::OnBnClickedbtnpause) ON_BN_CLICKED(IDC_btnEnd,&CfatigueDetectionDlg::OnBnClickedbtnend) ON_WM_CLOSE()END_MESSAGE_MAP()//CfatigueDetectionDlg消息處理程序BOOLCfatigueDetectionDlg::OnInitDialog(){ CDialog::OnInitDialog(); //將“關(guān)于...”菜單項(xiàng)添加到系統(tǒng)菜單中。 //IDM_ABOUTBOX必須在系統(tǒng)命令范圍內(nèi)。 ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX<0xF000); CMenu*pSysMenu=GetSystemMenu(FALSE); if(pSysMenu!=NULL) { CStringstrAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if(!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu); } } //設(shè)置此對話框的圖標(biāo)。當(dāng)應(yīng)用程序主窗口不是對話框時(shí),框架將自動(dòng) //執(zhí)行此操作 SetIcon(m_hIcon,TRUE); //設(shè)置大圖標(biāo) SetIcon(m_hIcon,FALSE); //設(shè)置小圖標(biāo) //TODO:在此添加額外的初始化代碼 GetDlgItem(IDC_btnPause)->EnableWindow(false); GetDlgItem(IDC_btnEnd)->EnableWindow(false); GetDlgItem(IDC_SHOWWAVE)->EnableWindow(false); wf=NULL; CStringszPath; if(!GetModuleFileName(NULL,szPath.GetBufferSetLength(201),200)) { MessageBox("Load*.dllerror!"); returnfalse; } szPath.ReleaseBuffer(); intnPos; nPos=szPath.ReverseFind('\\'); szPath=szPath.Left(nPos); cascade_name=szPath.GetString(); cascade_name.Append("\\face.dll"); cascade_name_2=szPath.GetString(); cascade_name_2.Append("\\eye.dll"); returnTRUE;//除非將焦點(diǎn)設(shè)置到控件,否則返回TRUE}voidCfatigueDetectionDlg::OnSysCommand(UINTnID,LPARAMlParam){ if((nID&0xFFF0)==IDM_ABOUTBOX) { CAboutDlgdlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID,lParam); }}//如果向?qū)υ捒蛱砑幼钚』粹o,則需要下面的代碼//來繪制該圖標(biāo)。對于使用文檔/視圖模型的MFC應(yīng)用程序,//這將由框架自動(dòng)完成。voidCfatigueDetectionDlg::OnPaint(){ if(IsIconic()) { CPaintDCdc(this);//用于繪制的設(shè)備上下文 SendMessage(WM_ICONERASEBKGND,reinterpret_cast<WPARAM>(dc.GetSafeHdc()),0); //使圖標(biāo)在工作區(qū)矩形中居中 intcxIcon=GetSystemMetrics(SM_CXICON); intcyIcon=GetSystemMetrics(SM_CYICON); CRectrect; GetClientRect(&rect); intx=(rect.Width()-cxIcon+1)/2; inty=(rect.Height()-cyIcon+1)/2; //繪制圖標(biāo) dc.DrawIcon(x,y,m_hIcon); } else { CDialog::OnPaint(); }}//當(dāng)用戶拖動(dòng)最小化窗口時(shí)系統(tǒng)調(diào)用此函數(shù)取得光標(biāo)//顯示。HCURSORCfatigueDetectionDlg::OnQueryDragIcon(){ returnstatic_cast<HCURSOR>(m_hIcon);}/*******************************************************************//*******************控件響應(yīng)*************************//*******************************************************************/voidCfatigueDetectionDlg::OnBnClickedShowwave(){ //顯示關(guān)閉波形 if(!wf||wf==0) { wf=newWaveForm(); wf->Create(IDD_WAVE); wf->ShowWindow(true); CRectcr; this->GetWindowRect(&cr); wf->move(cr.left+cr.Width(),cr.top,cr.Height()); wf->begin(); BtnShowWave.SetWindowTextA(_T("關(guān)閉波形")); }else { wf->DestroyWindow(); wf=NULL; BtnShowWave.SetWindowTextA(_T("顯示波形")); }}voidCfatigueDetectionDlg::OnBnClickedbtnbegin(){ isStop=false; //開始 hDC=GetDlgItem(IDC_PIC)->GetDC()->GetSafeHdc();GetDlgItem(IDC_PIC)->GetClientRect(&rect); capture=cvCaptureFromCAM(0); cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,320); cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,240); hWnd=GetSafeHwnd(); storage=cvCreateMemStorage(0); pReadImageThread=AfxBeginThread(CReadImage,hWnd); pDetectThread=AfxBeginThread(CDetect,hWnd); pRecordThread=AfxBeginThread(CRecord,hWnd); cascade=(CvHaarClassifierCascade*)cvLoad((char*)(LPTSTR)(LPCTSTR)cascade_name,0,0,0); cascade_2=(CvHaarClassifierCascade*)cvLoad((char*)(LPTSTR)(LPCTSTR)cascade_name_2,0,0,0); GetDlgItem(IDC_btnBegin)->EnableWindow(false); GetDlgItem(IDC_btnPause)->EnableWindow(true); GetDlgItem(IDC_btnEnd)->EnableWindow(true); GetDlgItem(IDC_SHOWWAVE)->EnableWindow(true); SetTimer(1,50,NULL);}voidCfatigueDetectionDlg::OnBnClickedbtnpause(){ //暫停 quit(); GetDlgItem(IDC_btnBegin)->EnableWindow(true); GetDlgItem(IDC_btnPause)->EnableWindow(false); GetDlgItem(IDC_btnEnd)->EnableWindow(false); GetDlgItem(IDC_SHOWWAVE)->EnableWindow(false);}voidCfatigueDetectionDlg::OnBnClickedbtnend(){ //結(jié)束 quit(); CDialog::OnOK();}/*********************************************************************//*******************控件響應(yīng)結(jié)束*********************//*********************************************************************//**********************************************************************//******************系統(tǒng)消息響應(yīng)********************//**********************************************************************/voidCfatigueDetectionDlg::OnMove(intx,inty){ //窗口移動(dòng)事件 CDialog::OnMove(x,y); if(wf) { CRectcr; this->GetWindowRect(&cr); wf->move(cr.Width()+x,cr.top,cr.Height()); }}voidCfatigueDetectionDlg::OnClose(){ //TODO:在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值 quit(); CDialog::OnClose();}//畫圖圖片指針-->wParam//hDC,rectLRESULTCfatigueDetectionDlg::OnUserDraw(WPARAMwParam,LPARAMlParam){ CvvImageimg; IplImage*Image2=(IplImage*)wParam; if(Image2){ img.CopyOf(Image2);//從IplImage拷貝圖像數(shù)據(jù)到CvvImage img.DrawToHDC(hDC,&rect);//在控件上繪制圖像 } return0;}//顯示參數(shù)//時(shí)間-->wParam面積-->lParamLRESULTCfatigueDetectionDlg::OnUserPara(WPARAMwParam,LPARAMlParam){ count++; doubleperclos=perlogs_value(nArea4,300); if(perclos<0.5) { dPerclos[ptrPerclos]=perclos; ptrPerclos++; CStringstr; str.Format(_T("id:%dperclos值:%4lf"),count,perclos); this->listParameters.InsertString(this->listParameters.GetCount(),str); this->listParameters.SendMessage(0x0115,1,0); if(ptrPerclos==5) { doubledsum=0; for(inti=0;i<5;i++) { dsum+=dPerclos[i]; } if(dsum/5>0.15) { Beep(1000,100); } ptrPerclos=0; } } return0;}voidCfatigueDetectionDlg::OnTimer(UINT_PTRnIDEvent){ if(nIDEvent==1) { nArea2[ptr]=nArea_temp; ptr++; if(ptr==300) { for(intm=0;m<300;m++) { nArea4[m]=nArea2[m]; } PostMessage(WM_USER_PARA,0,1); ptr=0; } CDialog::OnTimer(nIDEvent); }}/*********************************************************************//****************系統(tǒng)消息響應(yīng)結(jié)束*****************//*********************************************************************//**********************************************************************//******************線程函數(shù)************************//**********************************************************************/staticUINTCReadImage(LPVOIDlp){ IplImage*Image; MSGmessage; while(Image=cvQueryFrame(capture)) { if(isStop) break; while(PeekMessage(&message,NULL,0,0,PM_REMOVE)) { if(message.message==WM_USER_QUIT) { Sleep(500); if(capture) cvReleaseCapture(&capture); DWORDdwExitCode;GetExitCodeThread(pReadImageThread,&dwExitCode); AfxEndThread(dwExitCode); return0; } TranslateMessage(&message); DispatchMessage(&message); } //發(fā)送繪圖消息 PostMessage(hWnd,WM_USER_DRAW,(WPARAM)Image,NULL); //發(fā)送有新圖片 pDetectThread->PostThreadMessageA(WM_USER_NEWIMAGE,NULL,(LPARAM)Image); } return0;}//線程3識別人臉人眼計(jì)算面積staticUINTCDetect(LPVOIDlp){ IplImage*img_t; IplImage*img_temp; MSGmessage; while(true){ if(isStop) break; while(PeekMessage(&message,NULL,0,0,PM_REMOVE)) { if(message.message==WM_USER_QUIT) { Sleep(500); if(storage) cvReleaseMemStorage(&storage); if(cascade) cvReleaseHaarClassifierCascade(&cascade); if(cascade_2) cvReleaseHaarClassifierCascade(&cascade_2); DWORDdwExitCode; GetExitCodeThread(pReadImageThread,&dwExitCode); AfxEndThread(dwExitCode); return0; } elseif(message.message==WM_USER_NEWIMAGE) { LPARAMwP; //識別計(jì)算 if(!detect_flag) { wP=message.lParam; detect_flag=true; if(wP&&wP!=0&&wP!=NULL) { __try { CvRectcvrect; cvrect=FaceColor_detect((IplImage*)wP); img_t=cvCloneImage((IplImage*)wP); img_temp=cvCloneImage((IplImage*)wP); cvRectangle((IplImage*)wP,cvPoint(cvrect.x,cvrect.y),cvPoint(cvrect.x+cvrect.width,cvrect.y+cvrect.height),CV_RGB(0,255,0),1); if(message.wParam!=0&&cvrect.height!=0&&cvrect.width!=0){ cvSetImageROI(img_temp,cvrect); Detect_draw((IplImage*)wP,img_temp,img_t); cvResetImageROI(img_temp); } else { Detect_draw((IplImage*)wP,img_temp,img_t); } cvReleaseImage(&img_t); cvReleaseImage(&img_temp); } __except(EXCEPTION_EXECUTE_HANDLER) { } } detect_flag=false; } } TranslateMessage(&message); DispatchMessage(&message); } } return0;}//線程4記錄面積系列staticUINTCRecord(LPVOIDlp){ MSGmessage; while(true){ if(isStop) break; while(PeekMessage(&message,NULL,0,0,PM_REMOVE)) { if(message.message==WM_USER_QUIT) { Sleep(500); DWORDdwExitCode; GetExitCodeThread(pReadImageThread,&dwExitCode); AfxEndThread(dwExitCode); return0; } elseif(message.message==WM_USER_NEWPARAMETER) { if(wf!=0||wf) { wf->push(message.wParam); } nArea_temp=message.wParam; } TranslateMessage(&message); DispatchMessage(&message); } } return0;}/*******************************************************************//****************線程函數(shù)結(jié)束******************//******************************************************************//*******************************************************************//******************功能函數(shù)**********************//********************************************************************///膚色識別//IplImage*-->圖像指針CvRectFaceColor_detect(IplImage*image){ if(!image||isStop)returncvRect(0,0,0,0); IplImage*image_t=cvCreateImage(cvGetSize(image),8,image->nChannels); image_t=cvCloneImage(image); introw,col; doubleY,Cb,Cr; inttempmax_x=0,tempmax_y=0,tempmin_x=image_t->width,tempmin_y=image_t->height; IplImage*image_temp=cvCreateImage(cvSize(320,240),IPL_DEPTH_8U,1); uchar*imgrow_prt; uchar*imgtemprow_prt; for(row=0;row<image_t->height;row++) { imgrow_prt=(uchar*)(image_t->imageData+row*image_t->widthStep); imgtemprow_prt=(uchar*)(image_temp->imageData+row*image_temp->widthStep); for(col=0;col<image_t->width;col++) { Y=0.299*imgrow_prt[3*col+1]+0.587*imgrow_prt[3*col+2]+0.114*imgrow_prt[3*col+3]; Cb=(128+0.713*(imgtemprow_prt[3*col+1]-Y))/255; Cr=(128+0.564*(imgtemprow_prt[3*col+3]-Y))/255; Cb=Cb>0?Cb:0; Cr=Cr>0?Cr:0; if(Cb>0.43&&Cb<0.55&&Cr>0.53&&Cr<0.62) { imgtemprow_prt[col+1]=(uchar)Y; tempmin_y=tempmin_y<(row+1)?tempmin_y:(row+1); tempmin_x=tempmin_x<(col+1)?tempmin_x:(col+1); tempmax_x=tempmax_x<(col+1)?(col+1):tempmax_x; tempmax_y=tempmax_y<(row+1)?(row+1):tempmax_y; } else { imgtemprow_prt[col+1]=0; } } } imgrow_prt=NULL; imgtemprow_prt=NULL; cvReleaseImage(&image_temp); cvReleaseImage(&image_t); if(tempmin_x>tempmax_x&&tempmin_y>tempmax_y) { returncvRect(0,0,0,0); } returncvRect(tempmin_x,tempmin_y,tempmax_x-tempmin_x,tempmax_y-tempmin_y);}//計(jì)算眼睛面積voidContour_process(IplImage*image,doublex,doubley){ if(!image||isStop)return; intsum=0; intwidth_t=image->width; intheight_t=image->height; IplImage*image_temp=cvCreateImage(cvGetSize(image),8,1); IplImage*image_t=cvCreateImage(cvGetSize(image),8,image->nChannels); image_t=cvCloneImage(image); cvSetZero(image_temp); CvMemStorage*storage=cvCreateMemStorage(); CvSeq*first_contour=NULL; intnum_contour=cvFindContours(image_t,storage,&first_contour,sizeof(CvContour),CV_RETR_LIST); for(CvSeq*csq=first_contour;csq!=NULL;csq=csq->h_next) { cvDrawContours(image_temp,csq,cvScalar(255),cvScalar(255),2,2,8); } cvSetImageROI(image_temp,cvRect((int)(x-image_temp->width*0.45),(int)(y-image_temp->height*0.3),(int)(image_temp->width*0.9),(int)(image_temp->height*0.6))); cvDilate(image_temp,image_temp,NULL,2); cvResetImageROI(image_temp); for(introw=0;row<image_temp->height;row++){ uchar*imgrow_prt=(uchar*)(image_temp->imageData+row*image_temp->widthStep); for(intcol=0;col<image_temp->width;col++){ if(row<image_temp->height&&col<image_temp->width) { sum+=imgrow_prt[col+1]; } else { imgrow_prt[col+1]=0; } } } sum=sum/255; cvReleaseImage(&image_t); cvReleaseImage(&image_temp); if(width_t==0) { width_t=600; } sum=sum*360000/height_t/width_t; //WM_USER_NEWPARAMETER pRecordThread->PostThreadMessageA(WM_USER_NEWPARAMETER,(int)sum,NULL);}voidDetect_eye(IplImage*dest,IplImage*image,doublex,doubley,doublewidth,doubleheight){ if(!dest||!image||image==NULL||image==0||isStop)return; doublescale=1.3; inti=0; CvRect*a; IplImage*image_temp; __try{ image_temp=cvCreateImage(cvSize(cvGetSize(image).width*2,cvGetSize(image).height*2),8,1); cvPyrUp(image,image_temp,CV_GAUSSIAN_5x5); IplImage*small_image_2=cvCreateImage(cvSize(cvRound(cvGetSize(image_temp).width/scale),cvRound(cvGetSize(image_temp).height/scale)),8,1); cvResize(image_temp,small_image_2,CV_INTER_LINEAR); cvEqualizeHist(small_image_2,small_image_2); cvClearMemStorage(storage); if(cascade_2) { if(!storage||!small_image_2||!cascade_2)return; CvSeq*eyes=cvHaarDetectObjects(small_image_2,cascade_2,storage,1.1,2,CV_HAAR_FIND_BIGGEST_OBJECT,cvSize(10,10)); for(;i<(eyes?eyes->total:0);i++) { a=(CvRect*)cvGetSeqElem(eyes,i); CvMoments*moment=newCvMoments(); doubleM00; CvPoint2D32fcenter; cvSetImageROI(image_temp,cvRect((int)(a->x*scale),(int)(a->y*scale),(int)(a->width*scale),(int)(a->height*scale))); cvRectangle(dest,cvPoint((int)(a->x*scale/2+x),(int)(a->y*scale/2+y)),cvPoint((int)(x+(a->x+a->width)*scale/2),(int)(y+(a->y+a->height)*scale/2)),CV_RGB(255,255,0),1); cvMoments(image_temp,moment,0); M00=cvGetSpatialMoment(moment,0,0); center.x=(float)(cvGetSpatialMoment(moment,1,0)/M00); center.y=(float)(cvGetSpatialMoment(moment,0,1)/M00); cvCanny(image_temp,image_temp,50,150,3); cvCanny(image_temp,image_temp,50,150,3); Contour_process(image_temp,center.x,center.y); cvResetImageROI(image_temp); } } PostMessage(hWnd,WM_USER_DRAW,(WPARAM)dest,NULL); cvReleaseImage(&small_image_2); cvReleaseImage(&image_temp); } __except(EXCEPTION_EXECUTE_HANDLER) { }}voidDetect_draw(IplImage*dest,IplImage*image,IplImage*img_t){ if(!dest||!image||dest==0||image==0||isStop)return; doublescale=1.3; CvRectDetect_ROI; __try{ Detect_ROI=cvGetImageROI(image); IplImage*image_t=cvCreateImage(cvGetSize(img_t),8,1); inti=0; cvCvtColor(img_t,image_t,CV_BGR2GRAY); IplImage*gray=cvCreateImage(cvGetSize(image),8,1); IplImage*small_image=cvCreateImage(cvSize(cvRound(cvGetSize(image).width/scale),cvRound(cvGetSize(image).height/scale)),8,1); cvC
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 營養(yǎng)干預(yù)對亞健康人群免疫力提升的作用
- 英語飯桌情景對話閱讀帶翻譯
- 產(chǎn)業(yè)鏈整合型廠房出售與運(yùn)營管理合同
- 商業(yè)綜合體商業(yè)場地轉(zhuǎn)租租賃合同
- 辦公室花卉租賃與生態(tài)節(jié)能服務(wù)合同
- 采沙資源開發(fā)利用與生態(tài)補(bǔ)償協(xié)議
- 水鋼脫硫檢修方案
- 高端社區(qū)保潔方案
- 工地門禁定制方案
- 鎮(zhèn)江編制考試題及答案
- MOOC 集成電路設(shè)計(jì)基礎(chǔ)-華中科技大學(xué) 中國大學(xué)慕課答案
- 可持續(xù)發(fā)展的措施和目標(biāo)
- 成人疫苗接種知識講座
- OTA代運(yùn)營協(xié)議文檔
- 2024云南省福利彩票發(fā)行中心公開招聘編制外人員20人高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- 第五版急危重癥護(hù)理學(xué)實(shí)踐與學(xué)習(xí)指導(dǎo)試題題庫及答案
- 無人機(jī)技術(shù)助力船舶與港口管理
- 護(hù)理質(zhì)量指標(biāo)測試附有答案
- 學(xué)校工作亮點(diǎn)匯報(bào)課件
- JJG 443-2023燃油加油機(jī)(試行)
- 離心式壓縮機(jī)-新課件
評論
0/150
提交評論