C++ DirectShow读取摄像头后然后保存图像数据

#include <stdio.h>

#include "camerads.h"

#include <highgui.h>

const char *g_szTitle = "Camera";

int main()
{
        // 1、考虑到已经存在了显示图像的窗口,那就不必再次驱动摄像头了,即便往下驱动那也是摄像头已被占用。
        if(IsWindowVisible(FindWindow(NULL, g_szTitle)))
        {
                return (-1);
        }

        //仅仅获取摄像头数目
        int m_iCamCount = CCameraDS::CameraCount();
        printf("There are %d cameras.\n", m_iCamCount);

        if(m_iCamCount == 0)
        {
                return (-1);
        }

        CCameraDS m_CamDS;

        //获取所有摄像头的名称
        for(int i = 0; i < m_iCamCount; i++)
        {
                char szCamName[1024];

                int retval = m_CamDS.CameraName(i, szCamName, sizeof(szCamName));

                if(retval >0)
                {
                        printf("Camera #%d's Name is '%s'.\n", i, szCamName);
                }
                else
                {
                        printf("Can not get Camera #%d's name.\n", i);
                }
        }

        // 2、考虑到如果有多个摄像头,或者又有其中某个或某几个正在被其它程序占有,故需要逐个遍历,
        // 直到找到可用的为止。
        int m_iCamNum = 0; // 摄像头编号

        IplImage *pFrame = NULL;

        while(m_iCamNum < m_iCamCount)
        {
                if((! m_CamDS.OpenCamera(m_iCamNum, false, 640, 480)) || ((pFrame = m_CamDS.QueryFrame()) == NULL))
                {
                        m_iCamNum++;
                }
                else
                { // 找到合适的摄像头,退出循环。
                        break;
                }

                // 关闭摄像头,必须要关闭,因为即将要进行下一次的检测,检测前要清空当前的占用空间。
                m_CamDS.CloseCamera();
        }

        if(m_iCamNum == m_iCamCount)
        {
                fprintf(stderr, "Can not open camera or is used by another app.\n");

                return (-1);
        }

        cvNamedWindow(g_szTitle);
        //显示
        cvShowImage(g_szTitle, pFrame);

        printf("%d %d\n", m_CamDS.GetHeight(), m_CamDS.GetWidth());
        CvVideoWriter *vw = cvCreateVideoWriter("e:\\123.avi", CV_FOURCC('X', 'V', 'I', 'D'), 25, 
                CvSize(m_CamDS.GetWidth(), m_CamDS.GetHeight()));//视频的长宽应该和摄像头的长宽一致,否则总是生产不了AVI
        if (vw == NULL){
                printf("cvCreateVideoWriter failed\n");
                return 0;
        }

        DWORD dwTime1 = GetTickCount();
        int nWrite = 0;
        while(GetTickCount() - dwTime1 < 5000)
        {
                //获取一帧
                pFrame = m_CamDS.QueryFrame();
                if (pFrame == NULL){
                        printf("QueryFrame Failed\n");
                        break;
                }
                nWrite = cvWriteFrame(vw, pFrame);
                if (nWrite != 1){
                        printf("WriteVideo Failed\n");
                        break;
                }
                //显示
                cvShowImage(g_szTitle, pFrame);

                if (cvWaitKey(20) == 'q'){
                        break;
                }
        }
        
        m_CamDS.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头
        cvReleaseVideoWriter(&vw);
        cvDestroyWindow(g_szTitle);

        return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。