📄 camera.cpp
字号:
/*
* Copyright (c) 2005-2006,华南理工大学机器人实验室
* All rights reserved.
*
* 文件名称:camera.cpp
* 文件标识:
* 摘 要:图像采集类的实现
*
* 当前版本:1.0
* 作 者:朱金辉
* 完成日期:
*
* 取代版本:
* 作 者:
* 完成日期:
*/
#include "StdAfx.h"
#include ".\camera.h"
Camera::Camera(void)
{
ready=false;
CoInitialize(NULL);
m_pCapture=NULL;
m_pGrab=NULL;
m_pGraph=NULL;
}
Camera::~Camera(void)
{
if(m_pCapture) {
m_pCapture->Release();
m_pCapture=NULL;
}
if(m_pGrab) {
m_pGrab->Release();
m_pGrab=NULL;
}
if(m_pGraph) {
m_pGraph->Release();
m_pGraph=NULL;
}
CoUninitialize();
}
// init
bool Camera::Init(int dev_num, char *pBuffer)
{
ready=false;
HRESULT hr;
/////////////////////////////////////////////////////////
//枚举视频设备
//创建一个系统枚举组件,并获得ICreateDevEnum接口
ICreateDevEnum* pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&pSysDevEnum);
if(FAILED(hr)) {
return false;
}
//指定枚举的类型目录,获得IEnumMoniker接口
IEnumMoniker* pClassEnum = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pClassEnum, 0);
if(FAILED(hr)) {
pSysDevEnum->Release();
pSysDevEnum=NULL;
return false;
}
pSysDevEnum->Release();
pSysDevEnum=NULL;
if(pClassEnum == NULL) {
return false;
}
pClassEnum->Reset();// Init pClassEnum.
//使用IEnumMoniker接口枚举所有的设备标识
IMoniker* pMoniker = NULL;
int num=0;
ULONG cFetched;
while (pClassEnum->Next(1, &pMoniker, &cFetched)== S_OK) {//Get camera device.
num++;
if(num == dev_num)
break;
}
pClassEnum->Release();
pClassEnum=NULL;
//创建Filter实例
IBaseFilter *m_pSrc=NULL;
// 给视频设备绑定source filter.(代表视频设备存在)
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter,(void **)&m_pSrc);
if(FAILED(hr)) {
return false;
}
// 绑定后pMoniker指针不再使用。
pMoniker->Release();
pMoniker = NULL;
///////////////////////////////////////////////////////////////////////
// 创造用于管理Filters 的IGraphBuilder。
// create a filter graph
m_pGraph = NULL;
hr = CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&m_pGraph);
if (FAILED(hr)) {
// Return an error.
cerr<<"create graphbuilder error!"<<endl;
m_pSrc->Release();
m_pSrc=NULL;
return false;
}
// add the capture filter to the graph
hr = m_pGraph->AddFilter(m_pSrc, L"Video Capture");
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
return false;
}
//创建Sample Grabber,并将之加入到Filter Graph中
// Create the Sample Grabber.
IBaseFilter *m_pF = NULL;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID *)&m_pF);
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
return false;
}
// Query the Sample Grabber for the ISampleGrabber interface
m_pGrab=NULL;
hr = m_pF->QueryInterface(IID_ISampleGrabber, (void **)&m_pGrab);
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
//Setting image type for image capture filter.
AM_MEDIA_TYPE amt;
memset(&amt, 0, sizeof(AM_MEDIA_TYPE));
amt.majortype = MEDIATYPE_Video;
amt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrab->SetMediaType(&amt);
if (FAILED(hr)) {
// Return an error.
cerr<<"set mediatype error!"<<endl;
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
MyFreeMediaType( amt );
// add the grabber to the graph
hr = m_pGraph->AddFilter(m_pF, L"Image Capture");
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
// build the graph for capture
m_pCapture=NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&m_pCapture);
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
//Initialize the Capture Graph Builder
hr = m_pCapture->SetFiltergraph(m_pGraph);
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
IBaseFilter* m_pNull=NULL;
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
reinterpret_cast<void **>(&m_pNull));
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
return false;
}
hr = m_pGraph->AddFilter(m_pNull, L"Null Renderer");
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
m_pNull->Release();
m_pNull=NULL;
return false;
}
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pSrc,m_pF,m_pNull);
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
m_pNull->Release();
m_pNull=NULL;
return false;
}
// ask for the connection media type so we know how big
// it is, so we can write out bitmaps
//
AM_MEDIA_TYPE mt;
hr = m_pGrab->GetConnectedMediaType( &mt );
if(FAILED(hr)) {
m_pSrc->Release();
m_pSrc=NULL;
m_pF->Release();
m_pF=NULL;
m_pNull->Release();
m_pNull=NULL;
return false;
}
MyFreeMediaType( mt );
m_pF->Release();
m_pF = NULL;
m_pSrc->Release();
m_pSrc = NULL;
m_pNull->Release();
m_pNull = NULL;
///////////////////////////////////////////////////////////
hr = m_pGrab->SetOneShot(TRUE);
if(FAILED(hr)) {
return false;
}
hr = m_pGrab->SetBufferSamples(TRUE);
if(FAILED(hr)) {
return false;
}
IMediaControl *m_pMc=NULL;
hr = m_pGraph->QueryInterface(IID_IMediaControl, (LPVOID *)&m_pMc);
if(FAILED(hr)) {
return false;
}
//Run the graph
hr = m_pMc ->Run();
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
return false;
}
IMediaEventEx *pEvent = NULL;
hr = m_pGraph->QueryInterface(IID_IMediaEventEx, (LPVOID *)&pEvent);
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
return false;
}
long evCode = 0;
//wait till it's done
pEvent->WaitForCompletion(INFINITE, &evCode);
hr = m_pGrab->GetCurrentBuffer(&m_BufferLength, NULL);
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
pEvent->Release();
pEvent=NULL;
return false;
}
hr = m_pMc ->Stop();
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
pEvent->Release();
pEvent=NULL;
return false;
}
//连续捕捉图像
hr = m_pGrab->SetOneShot(FALSE);
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
pEvent->Release();
pEvent=NULL;
return false;
}
hr = m_pMc ->Run();
if(FAILED(hr)) {
m_pMc->Release();
m_pMc=NULL;
pEvent->Release();
pEvent=NULL;
return false;
}
m_pMc ->Release();
m_pMc = NULL;
pBuffer = new char[m_BufferLength];
if(pBuffer==NULL) {
pEvent->Release();
pEvent=NULL;
return false;
}
//test
hr = m_pGrab->GetCurrentBuffer(&m_BufferLength, (long *)pBuffer);
if(FAILED(hr)) {
pEvent->Release();
pEvent=NULL;
return false;
}
pEvent->Release();
pEvent=NULL;
if(pBuffer!=NULL){
delete pBuffer;
pBuffer = NULL;
}
cout<<"Init camera success"<<endl;
ready=true;
return true;
}
//捕捉一帧图像
void Camera::CaptureImage(char *pBuffer)
{
m_pGrab->GetCurrentBuffer(&m_BufferLength, (long *)pBuffer);
}
void Camera::MyFreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0) {
CoTaskMemFree((PVOID)mt.pbFormat);
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL) {
// Unecessary because pUnk should not be used, but safest.
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -