- #include <cv.h>
- #include <highgui.h>
- int main()
- {
- IplImage *pFrame = NULL;
- IplImage *pGrayImg = NULL;
- IplImage *pFGImg = NULL;
- IplImage *pBGImg_8U = NULL;
- IplImage *pBGImg_32F = NULL;
- IplConvKernel * pKernel = NULL;
- CvCapture *pCapture = cvCreateCameraCapture(1);
- cvNamedWindow("webcam", 1);
- cvNamedWindow("background", 1);
- cvNamedWindow("foreground", 1);
- pKernel = cvCreateStructuringElementEx( 5, 3, 0,0
- , CV_SHAPE_ELLIPSE, NULL);
- if(!(pFrame = cvQueryFrame(pCapture)))
- {
- fprintf(stderr, "Can not open");
- return -1;
- }
- else
- {
- pGrayImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
- pFGImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
- pBGImg_8U = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
- pBGImg_32F = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_32F, 1);
- cvCvtColor(pFrame, pGrayImg, CV_BGR2GRAY);
- /* 建立背景 */
- cvConvertScale(pGrayImg, pBGImg_32F);
- cvConvertScale(pBGImg_32F, pBGImg_8U);
- }
- while(pFrame = cvQueryFrame(pCapture))
- {
- cvCvtColor(pFrame, pGrayImg, CV_BGR2GRAY);
- cvAbsDiff(pGrayImg, pBGImg_8U, pFGImg);
- /* 前景二值化做形態學處理 */
- cvThreshold(pFGImg, pFGImg, 30.0, 255, CV_THRESH_BINARY);
- cvMorphologyEx(pFGImg, pFGImg, 0, pKernel, CV_MOP_OPEN,1);
- cvMorphologyEx(pFGImg, pFGImg, 0, pKernel, CV_MOP_CLOSE,1);
- double t = (double)cvGetTickCount();
- /* 背景更新 */
- cvRunningAvg(pGrayImg, pBGImg_32F, 0.05, 0);
- t = (double)cvGetTickCount()-t;
- printf("%.lf\n", t / (cvGetTickFrequency()*1000));
- cvScale(pBGImg_32F, pBGImg_8U);
- cvShowImage("webcam", pFrame);
- cvShowImage("background", pBGImg_8U);
- cvShowImage("foreground", pFGImg);
- if(cvWaitKey(1) > 0)
- break;
- }
- cvDestroyWindow("webcam");
- cvDestroyWindow("background");
- cvDestroyWindow("foreground");
- cvReleaseImage(&pFrame);
- cvReleaseImage(&pGrayImg);
- cvReleaseImage(&pBGImg_8U);
- cvReleaseImage(&pBGImg_32F);
- return 0;
- }
將所需使用資料型態先初始化,並藉由if判斷是否偵測到webcam進行記憶體宣告,使用兩個存放背景的資料的變數pBGImg_8U、pBGImg_32F,因為若要顯示背景影像則只能用8-bit 無號數資料顯示,若要進行之後的cvRunningAvg()背景更新則僅能使用32-bit 浮點數資料運算。迴圈中不斷進行影像相減在做二值化及形態學處理得到前景,最後使用cvRunningAvg()進行背景更新。
函示說明
cvConvertScale
cvConvertScale(來源影像, 輸出影像);
cvAbsDiff()
cvAbsDiff(目前影像, 背景影像, 前景影像);
將當前的frame當作目前影像,而把已建置好的背景影像作為參數,兩個影像作相減並取絕對值得到前景。cvMorphologyEx()
void cvMorphologyEx(const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, int iteration = 1)
Parameters: |
|
---|
Opening operation:
Closing operation:
Morphological gradient:
“Top hat”:
“Black hat”:
cvRunningAvg()
void cvRunningAvg(const CvArr* src, CvArr* dst, double alpha, const
CvArr* mask=NULL )
Parameters: |
|
---|
該函數計算輸入圖像src和dst的累加器的加權總合,使dst成為一個偵序列的連續平均值
也就是說,參數α用來調節更新速度多快(速度有多快累加器“忘記”前面的圖像)。該功能支持多通道圖像。每個通道獨立處理。
沒有留言:
張貼留言