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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。