一个去除视频前景,保留背景的 opencv 小程序 (附注释)

来源:互联网 发布:ajax返回json为null 编辑:程序博客网 时间:2024/06/04 19:01
/**  这是从网络上的一个获取背景的小程序.*  程序运行后,从视频或者摄像头不断的获取图片,*  并从动态图片中去除动态部分, 只保留背景(静态部分).*  原程序只处理单色灰度图. 本人改为处理RGB彩色图.*/#include <stdio.h>#include <opencv/cv.h>#include <opencv/cxcore.h>#include <opencv/highgui.h>int main( int argc, char** argv ){//声明IplImage图像指针IplImage* pFrame = NULL; IplImage* pFrameBK = NULL; IplImage* pFrameFG = NULL; IplImage* pFrImgR = NULL;IplImage* pFrImgG = NULL;IplImage* pFrImgB = NULL;IplImage* pBkImgR = NULL;IplImage* pBkImgG = NULL;IplImage* pBkImgB = NULL;//声明CvMat矩阵指针。用于处理RGB三个通道数据.CvMat* pFrameMatR = NULL;CvMat* pFrameMatG = NULL;CvMat* pFrameMatB = NULL;CvMat* pFrMatR = NULL;CvMat* pFrMatG = NULL;CvMat* pFrMatB = NULL;CvMat* pBkMatR = NULL;CvMat* pBkMatG = NULL;CvMat* pBkMatB = NULL;//"black box" capture structure 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");fprintf(stderr, "Usage: bkgrd\n");return -1;}//打开摄像头,原型:IplImage* cvQueryFrame( CvCapture* capture )\函数cvQueryFrame从摄像头或者文件中抓取一帧,\然后解压并返回这一帧。\这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。\返回的图像不可以被用户释放或者修改。if (argc ==1)if( !(pCapture = cvCaptureFromCAM(-1))){fprintf(stderr, "Can not open camera.\n");return -2;}//打开视频文件if(argc == 2)if( !(pCapture = cvCaptureFromFile(argv[1]))){fprintf(stderr, "Can not open video file %s\n", argv[1]);return -2;}try{//逐帧读取视频while(pFrame = cvQueryFrame( pCapture )){nFrmNum++;//如果是第一帧,需要申请内存,并初始化,初始化需要的是(cvSize(宽高),颜色深度,通道数)if(nFrmNum == 1){pFrameBK = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,pFrame->nChannels);pFrameFG = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,pFrame->nChannels);pBkImgR = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pBkImgG = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pBkImgB = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pFrImgR = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pFrImgG = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pFrImgB = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);        //初始化矩阵pBkMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pBkMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pBkMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrameMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrameMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrameMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//RGB图像分离成单通道图像再处理cvSplit(pFrame, pBkImgR, pBkImgG, pBkImgB, 0);cvSplit(pFrame, pFrImgR, pFrImgG, pFrImgB, 0);cvConvert(pFrImgR, pFrameMatR);cvConvert(pFrImgG, pFrameMatG);cvConvert(pFrImgB, pFrameMatB);cvConvert(pFrImgR, pFrMatR);cvConvert(pFrImgG, pFrMatG);cvConvert(pFrImgB, pFrMatB);cvConvert(pFrImgR, pBkMatR);cvConvert(pFrImgG, pBkMatG);cvConvert(pFrImgB, pBkMatB);}else{cvSplit(pFrame, pFrImgR, pFrImgG, pFrImgB, 0);cvConvert(pFrImgR, pFrameMatR);cvConvert(pFrImgG, pFrameMatG);cvConvert(pFrImgB, pFrameMatB);//当前帧跟背景图相减cvAbsDiff(pFrameMatR, pBkMatR, pFrMatR);cvAbsDiff(pFrameMatG, pBkMatG, pFrMatG);cvAbsDiff(pFrameMatB, pBkMatB, pFrMatB);//二值化前景图cvThreshold(pFrMatR, pFrImgR, 60, 255.0, CV_THRESH_BINARY);cvThreshold(pFrMatG, pFrImgG, 60, 255.0, CV_THRESH_BINARY);cvThreshold(pFrMatB, pFrImgB, 60, 255.0, CV_THRESH_BINARY);//更新背景cvRunningAvg(pFrameMatR, pBkMatR, 0.003, 0);cvRunningAvg(pFrameMatG, pBkMatG, 0.003, 0);cvRunningAvg(pFrameMatB, pBkMatB, 0.003, 0);//将背景转化为图像格式,用以显示cvConvert(pBkMatR, pBkImgR);cvConvert(pBkMatG, pBkImgG);cvConvert(pBkMatB, pBkImgB);cvMerge(pBkImgR, pBkImgG, pBkImgB, 0, pFrameBK);cvMerge(pFrImgR, pFrImgG, pFrImgB, 0, pFrameFG);//显示图像cvShowImage("video", pFrame);cvShowImage("background", pFrameBK);cvShowImage("foreground", pFrameFG);//如果有按键事件,则跳出循环if( cvWaitKey(2) >= 0 )break;}}}catch(cv::Exception& e){std::cout<<e.what()<<std::endl;}//销毁窗口cvDestroyWindow("video");cvDestroyWindow("background");cvDestroyWindow("foreground");//释放图像和矩阵cvReleaseImage(&pFrameBK);cvReleaseImage(&pFrameFG);cvReleaseImage(&pFrImgR);cvReleaseImage(&pFrImgG);cvReleaseImage(&pFrImgB);cvReleaseImage(&pBkImgR);cvReleaseImage(&pBkImgG);cvReleaseImage(&pBkImgB);cvReleaseMat(&pFrameMatR);cvReleaseMat(&pFrameMatG);cvReleaseMat(&pFrameMatB);cvReleaseMat(&pFrMatR);cvReleaseMat(&pFrMatG);cvReleaseMat(&pFrMatB);cvReleaseMat(&pBkMatR);cvReleaseMat(&pBkMatG);cvReleaseMat(&pBkMatB);cvReleaseCapture(&pCapture);cvWaitKey(0);return 0;}

0 0
原创粉丝点击