在使用opencv编程的过程中,发现使用cvCapture读取视频时,我用的维视相机只能读出黑白色的图像,但是用usb接口的摄像头还是能够正常读出彩色的图像。让人相当的郁闷哈!!!
经过各方面的查找,发现在使用opencv的项目中增加DirectShow能够让维视相机采集到彩色的视频。下面是在VS2008+Opencv中配置DirectShow的步骤:
1.将CameraDS.h 和CameraDS.cpp文件复制到你的项目中。
注意:1.将文件中#include "DirectShow/Include/qedit.h"和#include "DirectShow/Include/dshow.h"修改为#include “qedit.h”和#include “dshow.h”,保存;
2.将#include "CameraDS.h"修改为#include “camerads.h,”
CameraDS.h源文件:
#ifndef CCAMERA_H
#define CCAMERA_H
#define WIN32_LEAN_AND_MEAN
#include <atlbase.h>
//#include "DirectShow/Include/qedit.h"
//#include "DirectShow/Include/dshow.h"
#include "qedit.h"
#include "dshow.h"
#include <windows.h>
#include <opencv/cxcore.h>
#define MYFREEMEDIATYPE(mt) {if ((mt).cbFormat != 0) \
{CoTaskMemFree((PVOID)(mt).pbFormat); \
(mt).cbFormat = 0; \
(mt).pbFormat = NULL; \
} \
if ((mt).pUnk != NULL) \
{ \
(mt).pUnk->Release(); \
(mt).pUnk = NULL; \
}}
class CCameraDS
{
private:
IplImage * m_pFrame;
bool m_bConnected;
int m_nWidth;
int m_nHeight;
bool m_bLock;
bool m_bChanged;
long m_nBufferSize;
CComPtr<IGraphBuilder> m_pGraph;
CComPtr<IBaseFilter> m_pDeviceFilter;
CComPtr<IMediaControl> m_pMediaControl;
CComPtr<IBaseFilter> m_pSampleGrabberFilter;
CComPtr<ISampleGrabber> m_pSampleGrabber;
CComPtr<IPin> m_pGrabberInput;
CComPtr<IPin> m_pGrabberOutput;
CComPtr<IPin> m_pCameraOutput;
CComPtr<IMediaEvent> m_pMediaEvent;
CComPtr<IBaseFilter> m_pNullFilter;
CComPtr<IPin> m_pNullInputPin;
private:
bool BindFilter(int nCamIDX, IBaseFilter **pFilter);
void SetCrossBar();
public:
CCameraDS();
virtual ~CCameraDS();
//打开摄像头,nCamID指定打开哪个摄像头,取值可以为0,1,2,...
//bDisplayProperties指示是否自动弹出摄像头属性页
//nWidth和nHeight设置的摄像头的宽和高,
//如果摄像头不支持所设定的宽度和高度,则返回false
bool CCameraDS::OpenCamera(int nCamID,
bool bDisplayProperties=true,
int nWidth=320,
int nHeight=240
);
//关闭摄像头,析构函数会自动调用这个函数
void CloseCamera();
//返回摄像头的数目
//可以不用创建CCameraDS实例,
//采用int c=CCameraDS::CameraCount();得到结果。
static int CameraCount();
//根据摄像头的编号返回摄像头的名字
//nCamID: 摄像头编号
//sName: 用于存放摄像头名字的数组
//nBufferSize: sName的大小
//可以不用创建CCameraDS实例,
//采用CCameraDS::CameraName();得到结果。
static int CCameraDS::CameraName(
int nCamID,
char* sName,
int nBufferSize);
//返回图像宽度
int GetWidth(){return m_nWidth;}
//返回图像高度
int GetHeight(){return m_nHeight;}
//抓取一帧,返回的IplImage不可手动释放!
//返回图像数据的为RGB模式的Top-down(第一个字节为左上角像素),
//即IplImage::origin=0(IPL_ORIGIN_TL)
IplImage * QueryFrame();
};
#endif
2.将DirectShow文件夹复制到你的opencv根目录下,其他目录也可以。只是管理方便。我的DirectShow文件放在D:\Program Files\OpenCV2.3.1目录下,然后分别把DirectShow文件夹中的Include和Lib<