⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.cpp

📁 比赛足球机器人系统中的DCT追球程序
💻 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 + -