原创 OpenCV读取视频

2011-3-17 16:20 1420 5 5 分类: MCU/ 嵌入式

 

作者:王劲南,华清远见嵌入式学院讲师。

什么是OpenCV

OpenCV是Intel?开源计算机视觉库。它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法。

重要特性

OpenCV拥有包括300多个C函数的跨平台的中、高层API。它不依赖于其它的外部库——尽管也可以使用某些外部库。

OpenCV对非商业应用和商业应用和商业应用都是免费的。

OpenCV 为Intel? Integrated Performance Primitives (IPP) 提供了透明接口。 这意味着如果有为特定处理器优化的的 IPP 库, OpenCV 将在运行时自动加载这些库。

例程

include <stdio.h>

#include <cv.h>
        #include <cxcore.h>
        #include <highgui.h>

int main( int argc, char** argv )
        {
                //声明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])))
                        {
                                fprintf(stderr, "Can not open video file %s\n", argv[1]);
                                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);

                                //当前帧跟背景图相减
                                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);

                                //显示图像
                                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);

                return 0;
        }

注意:如果您无法使用cvCaptureFromFile函数打开视频,请安装必要的视频解码器。
嵌入式及3G相关资源及学习请点击:嵌入式开发视频 android开发视频 android培训 3G培训 QT培训 QT开发视频 物联网培训 物联网技术视频 嵌入式学习 

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条