您好,登錄后才能下訂單哦!
這篇文章主要介紹OpenCV如何實(shí)現(xiàn)幀間差分法,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
具體內(nèi)容如下
一.基本概念
基于視頻的車輛檢測(cè)算法種類很多:光流法檢測(cè),幀差法,背景消除法(其中包括:直方圖法,平均值法,單分布和混合高斯分布背景模型,Kalman濾波等),邊緣檢測(cè)法,運(yùn)動(dòng)矢量檢測(cè)法...下面分享的是運(yùn)動(dòng)目標(biāo)檢測(cè)算法中最基本的方法—幀間差分法。
相鄰幀間圖像差分思想:檢測(cè)出了相鄰兩幀圖像中發(fā)生變化的區(qū)域。該方法是用圖像序列中的連續(xù)兩幀圖像進(jìn)行差分,然后二值化該灰度差分圖像來提取運(yùn)動(dòng)信息。由幀間變化區(qū)域檢測(cè)分割得到的圖像,區(qū)分出背景區(qū)域和運(yùn)動(dòng)車輛區(qū)域,進(jìn)而提取要檢測(cè)的車輛目標(biāo)。
它是通過比較圖像序列中前后兩幀圖像對(duì)應(yīng)像素點(diǎn)灰度值的不同,通過兩幀相減,如果灰度值很小,可以認(rèn)為該點(diǎn)無運(yùn)動(dòng)物體經(jīng)過;反之灰度變化很大,則認(rèn)為有物體經(jīng)過。第k幀和k+1幀圖像fk(x,y),fk+l(x,y)之間的變化用一個(gè)二值差分圖像D(x,y)表示,如式:
二值圖中0對(duì)應(yīng)前后未變化的地方,1對(duì)應(yīng)變化的地方。流程圖如下圖所示:
幀差法的特點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,運(yùn)算速度快,對(duì)于動(dòng)態(tài)環(huán)境自適應(yīng)性是很強(qiáng)的,對(duì)光線的變化不是十分的敏感。但是在運(yùn)動(dòng)體內(nèi)易產(chǎn)生空洞.特別是目標(biāo)運(yùn)動(dòng)速度較快時(shí),影響目標(biāo)區(qū)域準(zhǔn)確提取。我們以年輛檢測(cè)為例,車輛檢測(cè)除了要檢測(cè)出運(yùn)動(dòng)車輛.同時(shí)還要檢測(cè)出暫時(shí)停止的車輛,在這個(gè)方面,此類方法無能為力。而且如果車輛的體積較大,那么車輛在前后幀中根容易產(chǎn)生重疊部分,尤其是大貨車,這使得幀問差分的結(jié)果主要為車頭和車尾。車輛中間部分的差分值相對(duì)報(bào)?。纬煽斩?,不利于檢測(cè)。
二.程序源代碼
#include "stdafx.h" #include "highgui.h" #include "cxcore.h" #include "ml.h" #include "cv.h" void main() { CvCapture* capture; capture=cvCaptureFromFile("video.avi");//獲取視頻 cvNamedWindow("camera",CV_WINDOW_AUTOSIZE); cvNamedWindow("moving area",CV_WINDOW_AUTOSIZE); IplImage* tempFrame;//用于遍歷capture中的幀,通道數(shù)為3,需要轉(zhuǎn)化為單通道才可以處理 IplImage* currentFrame;//當(dāng)前幀 IplImage* previousFrame;//上一幀 /* CvMat結(jié)構(gòu),本質(zhì)上和IplImage差不多,但是因?yàn)镮plImage里的數(shù)據(jù)只能用uchar的形式存放,當(dāng)需要這些圖像數(shù)據(jù)看作數(shù)據(jù)矩陣來運(yùn)算時(shí),0~255的精度顯然滿足不了要求; 然而CvMat里卻可以存放任意通道數(shù)、任意格式的數(shù)據(jù) */ CvMat* tempFrameMat; CvMat* currentFrameMat; //IplImage要轉(zhuǎn)成CvMat進(jìn)行處理 CvMat* previousFrameMat; int frameNum=0; while(tempFrame=cvQueryFrame(capture)) { //tempFrame=cvQueryFrame(capture); frameNum++; if(frameNum==1) { //第一幀先初始化各個(gè)結(jié)構(gòu),為它們分配空間 previousFrame=cvCreateImage(cvSize(tempFrame->width,tempFrame->height),IPL_DEPTH_8U,1); currentFrame=cvCreateImage(cvSize(tempFrame->width,tempFrame->height),IPL_DEPTH_8U,1); currentFrameMat=cvCreateMat(tempFrame->height, tempFrame->width, CV_32FC1); previousFrameMat=cvCreateMat(tempFrame->height, tempFrame->width, CV_32FC1); tempFrameMat=cvCreateMat(tempFrame->height, tempFrame->width, CV_32FC1); //此時(shí)這些IplImage和CvMat都是空的,沒有存有數(shù)據(jù) } if(frameNum>=2) { cvCvtColor(tempFrame, currentFrame, CV_BGR2GRAY);//轉(zhuǎn)化為單通道灰度圖,此時(shí)currentFrame已經(jīng)存了tempFrame的內(nèi)容 /* 用cvConvert將IplImage轉(zhuǎn)為CvMat,接下來用cvAbsDiff對(duì)它們處理 經(jīng)過轉(zhuǎn)換后,currentFrame沒有改變,但是tempFrameMat已經(jīng)存了currentFrame的內(nèi)容 */ cvConvert(currentFrame,tempFrameMat); cvConvert(previousFrame,previousFrameMat); cvAbsDiff(tempFrameMat,previousFrameMat,currentFrameMat);//做差求絕對(duì)值 /* 在currentFrameMat中找大于20(閾值)的像素點(diǎn),把currentFrame中對(duì)應(yīng)的點(diǎn)設(shè)為255 此處閾值可以幫助把車輛的陰影消除掉 */ cvThreshold(currentFrameMat,currentFrame,20,255.0,CV_THRESH_BINARY); //cvConvert(currentFrameMat,currentFrame); //觀察不二值化的情況 cvDilate(currentFrame,currentFrame); //膨脹 cvErode(currentFrame,currentFrame); //腐蝕 cvFlip(currentFrame, NULL, 0); //垂直翻轉(zhuǎn) //顯示圖像 cvShowImage("camera",tempFrame); cvShowImage("moving area",currentFrame); } //把當(dāng)前幀保存作為下一次處理的前一幀 cvCvtColor(tempFrame, previousFrame, CV_BGR2GRAY); cvWaitKey(33); }//end while //釋放資源 cvReleaseImage(&tempFrame); cvReleaseImage(&previousFrame); cvReleaseImage(¤tFrame); cvReleaseCapture(&capture); cvReleaseMat(&previousFrameMat); cvReleaseMat(¤tFrameMat); cvDestroyWindow("camera"); cvDestroyWindow("moving area"); }
以上是“OpenCV如何實(shí)現(xiàn)幀間差分法”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。