使用OpenCV实现运动背景的重建
生活随笔
收集整理的這篇文章主要介紹了
使用OpenCV实现运动背景的重建
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
聲明:本文轉載 曾青松的專欄,為便于學習轉帖至此,如有需要請查看原始出處。
void?CObjectDetectDlg::OnButtonOpenfile()? ?? ?? { ?? ?? ????//?TODO:?Add?your?control?notification?handler?code?here ?? ?? ????//?文件打開對話框 ?? ?? ????CFileDialog?dlg(true,"*.avi",NULL,NULL,"*.avi|*.avi||"); ?? ?? ????if?(dlg.DoModal()==IDOK) ?? ?? ????{ ?? ?? ????????strAviFilePath?=?dlg.GetPathName(); ?? ?? ????}else?? ?? ????{ ?? ?? ????????return; ?? ?? ????} ?? ?? ???? ?? ?? } ?? ?? ?? ?? void?CObjectDetectDlg::OnButtonProcess()? ?? ?? { ?? ?? ????//?TODO:?Add?your?control?notification?handler?code?here ?? ?? ????//聲明IplImage指針 ?? ?? ????IplImage*?pFrame?=?NULL; ?? ?? ????IplImage*?pFrImg?=?NULL; ?? ?? ????IplImage*?pBkImg?=?NULL; ?? ?? ???? ?? ?? ????CvMat*?pFrameMat?=?NULL; ?? ?? ????CvMat*?pFrMat?=?NULL; ?? ?? ????CvMat*?pBkMat?=?NULL; ?? ?? ???? ?? ?? ????CvCapture*?pCapture?=?NULL; ?? ?? ???? ?? ?? ????int?nFrmNum?=?0; ?? ?? ???? ?? ?? ????//打開AVI視頻文件 ?? ?? ????if(strAviFilePath=="")??//判斷文件路徑是否為空 ?? ?? ????{ ?? ?? ????????MessageBox("請先選擇AVI視頻文件!"); ?? ?? ????????return; ?? ?? ????}else?? ?? ????{ ?? ?? ????????if(!(pCapture?=?cvCaptureFromFile(strAviFilePath))) ?? ?? ????????{ ?? ?? ????????????MessageBox("打開AVI視頻文件失敗!"); ?? ?? ????????????return; ?? ?? ????????} ?? ?? ????} ?? ?? ???? ?? ?? ????//創建窗口 ?? ?? ????cvNamedWindow("Video",?1); ?? ?? ????cvNamedWindow("Background",1); ?? ?? ????cvNamedWindow("Foreground",1); ?? ?? ???? ?? ?? ????//使窗口有序排列,窗口寬330 ?? ?? ????cvMoveWindow("Video",?30,?0); ?? ?? ????cvMoveWindow("Background",?360,?0); ?? ?? ????cvMoveWindow("Foreground",?690,?0); ?? ?? ???? ?? ?? ????//逐幀讀取視頻 ?? ?? ????while(pFrame?=?cvQueryFrame(?pCapture?)) ?? ?? ????{ ?? ?? ????????nFrmNum++; ?? ?? ???????? ?? ?? ????????//如果是第一幀,需要申請內存,并初始化 ?? ?? ????????if(nFrmNum?==?1) ?? ?? ????????{ ?? ?? ????????????pBkImg?=?cvCreateImage(cvSize(pFrame->width,?pFrame->height),?IPL_DEPTH_8U,1);?//?存放背景圖像(灰度) ?? ?? ????????????pFrImg?=?cvCreateImage(cvSize(pFrame->width,?pFrame->height),?IPL_DEPTH_8U,1);?//?存放中間圖像(灰度) ?? ?? ???????????? ?? ?? ????????????pBkMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ????????????pFrMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ????????????pFrameMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ???????????? ?? ?? ????????????//轉化成單通道圖像再處理(灰度) ?? ?? ????????????cvCvtColor(pFrame,?pBkImg,?CV_BGR2GRAY); ?? ?? ????????????cvCvtColor(pFrame,?pFrImg,?CV_BGR2GRAY); ?? ?? ???????????? ?? ?? ????????????cvConvert(pFrImg,?pFrameMat); ?? ?? ????????????cvConvert(pFrImg,?pFrMat); ?? ?? ????????????cvConvert(pFrImg,?pBkMat); ?? ?? ????????} ?? ?? ????????else?? ?? ????????{ ?? ?? ????????????cvCvtColor(pFrame,?pFrImg,?CV_BGR2GRAY);?//轉化成單通道圖像再處理(灰度) ?? ?? ????????????cvConvert(pFrImg,?pFrameMat); ?? ?? ???????????? ?? ?? ????????????//高斯濾波先,以平滑圖像 ?? ?? ????????????//cvSmooth(pFrameMat,?pFrameMat,?CV_GAUSSIAN,?3,?0,?0); ?? ?? ???????????? ?? ?? ????????????//當前幀跟背景圖相減(求背景差并取絕對值) ?? ?? ???????????cvAbsDiff(pFrameMat,?pBkMat,?pFrMat); ?? ?? ???????????? ?? ?? ????????????//二值化前景圖(這里采用特定閾值進行二值化) ?? ?? ????????????cvThreshold(pFrMat,?pFrImg,?60,?255.0,?CV_THRESH_BINARY); ?? ?? ???????????? ?? ?? ????????????//進行形態學濾波,去掉噪音 ?? ?? ????????????cvErode(pFrImg,?pFrImg,?0,?1); ?? ?? ????????????cvDilate(pFrImg,?pFrImg,?0,?1); ?? ?? ???????????? ?? ?? ????????????//滑動平均更新背景(求平均) ?? ?? ????????????cvRunningAvg(pFrameMat,?pBkMat,?0.003,?0); ?? ?? ????????????//將背景轉化為圖像格式,用以顯示 ?? ?? ????????????cvConvert(pBkMat,?pBkImg); ?? ?? ???????????? ?? ?? ????????????//?保持原圖像的旋轉方向 ?? ?? ????????????pBkImg->origin?=?pFrImg->origin?=?pFrame->origin; ?? ?? ???????????? ?? ?? ????????????//顯示圖像 ?? ?? ????????????//?cvFlip(pFrame,?pFrame,?0); ?? ?? ????????????//cvFlip(pBkImg,?pBkImg,?0);?//轉置一下,否則圖像是顛倒的 ?? ?? ????????????cvFlip(pFrImg,?pFrImg,?0); ?? ?? ???????????? ?? ?? ????????????//顯示圖像 ?? ?? ????????????cvShowImage("Video",?pFrame); ?? ?? ????????????cvShowImage("Background",?pBkImg); ?? ?? ????????????cvShowImage("Foreground",?pFrImg); ?? ?? ???????????? ?? ?? ????????????//如果有按鍵事件,則跳出循環 ?? ?? ????????????//此等待也為cvShowImage函數提供時間完成顯示 ?? ?? ????????????//等待時間可以根據CPU速度調整 ?? ?? ????????????if(?cvWaitKey(2)?>=?0?) ?? ?? ????????????????break; ?? ?? ????????} ?? ?? ????} ?? ?? ???? ?? ?? ????//銷毀窗口 ?? ?? ????cvDestroyWindow("Video"); ?? ?? ????cvDestroyWindow("Background"); ?? ?? ????cvDestroyWindow("Foreground"); ?? ?? ???? ?? ?? ????//釋放圖像和矩陣 ?? ?? ????cvReleaseImage(&pFrImg); ?? ?? ????cvReleaseImage(&pBkImg); ?? ?? ???? ?? ?? ????cvReleaseMat(&pFrameMat); ?? ?? ????cvReleaseMat(&pFrMat); ?? ?? ????cvReleaseMat(&pBkMat); ?? ?? ???? ?? ?? ????cvReleaseCapture(&pCapture); ?? ?? ???? ?? ?? ???? ?? ?? } ?? ?? ?? ?? ?? ?? //運動目標檢測,直接從攝像機獲取圖像 ?? ?? void?CObjectDetectDlg::OnButtonCamer()? ?? ?? { ?? ?? ???? ?? ?? ????//聲明IplImage指針 ?? ?? ????IplImage*?pFrame?=?NULL; ?? ?? ????IplImage*?pFrImg?=?NULL; ?? ?? ????IplImage*?pBkImg?=?NULL; ?? ?? ???? ?? ?? ????CvMat*?pFrameMat?=?NULL; ?? ?? ????CvMat*?pFrMat?=?NULL; ?? ?? ????CvMat*?pBkMat?=?NULL; ?? ?? ???? ?? ?? ????CvCapture*?pCapture?=?NULL; ?? ?? ???? ?? ?? ????int?nFrmNum?=?0; ?? ?? ???? ?? ?? ????//創建窗口 ?? ?? ????cvNamedWindow("video",?1); ?? ?? ????cvNamedWindow("background",1); ?? ?? ????cvNamedWindow("foreground",1); ?? ?? ????//使窗口有序排列 ?? ?? ????cvMoveWindow("video",?30,?0); ?? ?? ????cvMoveWindow("background",?360,?0); ?? ?? ????cvMoveWindow("foreground",?690,?0); ?? ?? ????//if(?argc?>?2?) ?? ?? ????//{ ?? ?? ????//?fprintf(stderr,?"Usage:?bkgrd?[video_file_name]/n"); ?? ?? ????//?return?-1; ?? ?? ????//} ?? ?? ???? ?? ?? ????打開攝像頭 ?? ?? ????//if?(argc?==1) ?? ?? ????//?if(?!(pCapture?=?cvCaptureFromCAM(-1))) ?? ?? ????//?{ ?? ?? ????//??fprintf(stderr,?"Can?not?open?camera./n"); ?? ?? ????//??return?-2; ?? ?? ????//?} ?? ?? ???? ?? ?? ????//打開視頻文件 ?? ?? ????//if(argc?==?2) ?? ?? ????//if(?!(pCapture?=?cvCaptureFromFile(argv[1]))) ?? ?? ????//if(?!(pCapture?=?cvCaptureFromFile(this->strAviFilePath))) ?? ?? ????if(?!(pCapture?=?cvCaptureFromCAM(-1)))? ?? ?? ????{ ?? ?? ???????????MessageBox("打開攝像機視頻失敗!"); ?? ?? ????????????return; ?? ?? ????????//fprintf(stderr,?"Can?not?open?video?file?%s/n",?this->strAviFilePath); ?? ?? ????????//??return?-2; ?? ?? ????} ?? ?? ???? ?? ?? ????//逐幀讀取視頻 ?? ?? ????while(pFrame?=?cvQueryFrame(?pCapture?)) ?? ?? ????{ ?? ?? ????????nFrmNum++; ?? ?? ???????? ?? ?? ????????//如果是第一幀,需要申請內存,并初始化 ?? ?? ????????if(nFrmNum?==?1) ?? ?? ????????{ ?? ?? ????????????pBkImg?=?cvCreateImage(cvSize(pFrame->width,?pFrame->height),??IPL_DEPTH_8U,1); ?? ?? ????????????pFrImg?=?cvCreateImage(cvSize(pFrame->width,?pFrame->height),??IPL_DEPTH_8U,1); ?? ?? ???????????? ?? ?? ????????????pBkMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ????????????pFrMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ????????????pFrameMat?=?cvCreateMat(pFrame->height,?pFrame->width,?CV_32FC1); ?? ?? ???????????? ?? ?? ????????????//轉化成單通道圖像再處理 ?? ?? ????????????cvCvtColor(pFrame,?pBkImg,?CV_BGR2GRAY); ?? ?? ????????????cvCvtColor(pFrame,?pFrImg,?CV_BGR2GRAY); ?? ?? ???????????? ?? ?? ????????????cvConvert(pFrImg,?pFrameMat); ?? ?? ????????????cvConvert(pFrImg,?pFrMat); ?? ?? ????????????cvConvert(pFrImg,?pBkMat); ?? ?? ????????} ?? ?? ????????else?? ?? ????????{ ?? ?? ????????????cvCvtColor(pFrame,?pFrImg,?CV_BGR2GRAY); ?? ?? ????????????cvConvert(pFrImg,?pFrameMat); ?? ?? ????????????//高斯濾波先,以平滑圖像 ?? ?? ????????????//cvSmooth(pFrameMat,?pFrameMat,?CV_GAUSSIAN,?3,?0,?0); ?? ?? ???????????? ?? ?? ????????????//當前幀跟背景圖相減 ?? ?? ????????????<FONT?style="BACKGROUND-COLOR:?#00ffff">cvAbsDiff</FONT>(pFrameMat,?pBkMat,?pFrMat); ?? ?? ???????????? ?? ?? ????????????//二值化前景圖 ?? ?? ????????????cvThreshold(pFrMat,?pFrImg,?60,?255.0,?CV_THRESH_BINARY); ?? ?? ???????????? ?? ?? ????????????//進行形態學濾波,去掉噪音? ?? ?? ????????????//cvErode(pFrImg,?pFrImg,?0,?1); ?? ?? ????????????//cvDilate(pFrImg,?pFrImg,?0,?1); ?? ?? ???????????? ?? ?? ????????????//更新背景 ?? ?? ????????????cvRunningAvg(pFrameMat,?pBkMat,?0.003,?0); ?? ?? ????????????//將背景轉化為圖像格式,用以顯示 ?? ?? ????????????cvConvert(pBkMat,?pBkImg); ?? ?? ???????????? ?? ?? ????????????//?保持原圖像的旋轉方向 ?? ?? ????????????pBkImg->origin?=?pFrImg->origin?=?pFrame->origin; ?? ?? ???????????? ?? ?? ????????????//顯示圖像 ?? ?? ????????????//?cvFlip(pFrame,?pFrame,?0); ?? ?? ????????????//cvFlip(pBkImg,?pBkImg,?0);?//轉置一下,否則圖像是顛倒的 ?? ?? ????????????//cvFlip(pFrImg,?pFrImg,?0); ?? ?? ???????????? ?? ?? ????????????cvShowImage("video",?pFrame); ?? ?? ????????????cvShowImage("background",?pBkImg); ?? ?? ????????????cvShowImage("foreground",?pFrImg); ?? ?? ???????????? ?? ?? ????????????//如果有按鍵事件,則跳出循環 ?? ?? ????????????//此等待也為cvShowImage函數提供時間完成顯示 ?? ?? ????????????//等待時間可以根據CPU速度調整 ?? ?? ????????????if(?cvWaitKey(2)?>=?0?) ?? ?? ????????????????break; ?? ?? ????????} ?? ?? ???????? ?? ?? ????} ?? ?? ???? ?? ?? ????//銷毀窗口 ?? ?? ????cvDestroyWindow("video"); ?? ?? ????cvDestroyWindow("background"); ?? ?? ????cvDestroyWindow("foreground"); ?? ?? ???? ?? ?? ????//釋放圖像和矩陣 ?? ?? ????cvReleaseImage(&pFrImg); ?? ?? ????cvReleaseImage(&pBkImg); ?? ?? ???? ?? ?? ????cvReleaseMat(&pFrameMat); ?? ?? ????cvReleaseMat(&pFrMat); ?? ?? ????cvReleaseMat(&pBkMat); ?? ?? ???? ?? ?? ????cvReleaseCapture(&pCapture); ?? ?? }??
總結
以上是生活随笔為你收集整理的使用OpenCV实现运动背景的重建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如今,我们为什么很难看到高质量的文章?
- 下一篇: 3.6 总结