回调函数处理图像(待整理)

本文介绍了一种使用回调函数在C++环境下实现相机设备的数据采集与处理的方法,具体包括初始化相机控件、设置缓冲区大小、创建监听器对象、注册回调事件以及保存处理后的图像数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

回调函数是将就是通过函数指针调用函数,即将该参数传递给其他函数,在调用该参数时候也自动调用该参数。

#include <iostream>
#include <conio.h>

#include <tisudshl.h>

#include "CmdHelper.h"
#include "Listener.h"

using namespace _DSHOWLIB_NAMESPACE;

// Specify the number of buffers to be used.
////宏定义
#define NUM_BUFFERS 10

int main(int argc, char* argv[])
{
     ///初始化相机控件的类库
	DShowLib::InitLibrary();
    ///注册程序正常退出时候需要的调用的函数
	atexit( ExitLibrary );
    ///创建采集对象
	Grabber grabber;

	// Create the GrabberListener object.
	// CListener is derived from GrabberListener.
	
	///new CListener()被赋值给指针,在后面调用该函数的时候就会调用该指针
	CListener *pListener = new CListener();
												
	if( !setupDeviceFromFile( grabber ) )
	{
		return -1;
	}
	
	// Assign the number of buffers to the cListener object.
	pListener->setBufferSize( NUM_BUFFERS );

	// Enable the overlay bitmap to display the frame counter in the live video.
       /////创建帧数窗口
	grabber.getOverlay()->setEnable( true );

	// Register the pListener object for the frame ready and 
	// the overlay callback event.
	//创建一个listener 对象
	grabber.addListener( pListener, GrabberListener::eFRAMEREADY|
										GrabberListener::eOVERLAYCALLBACK );


	// Create a FrameTypeInfoArray data structure describing the allowed color formats.
	///创建一个数据结构用来表示图像的格式
	FrameTypeInfoArray acceptedTypes = FrameTypeInfoArray::createRGBArray();

	// Create the frame handler sink
      // 创建帧存储
	smart_ptr<FrameHandlerSink> pSink = FrameHandlerSink::create( acceptedTypes, NUM_BUFFERS );

	// enable snap mode (formerly tFrameGrabberMode::eSNAP).

	pSink->setSnapMode( true );

	// Apply the sink to the grabber.
	grabber.setSinkType( pSink );

	grabber.startLive();				// Start the grabber.

	pSink->snapImages( NUM_BUFFERS );	// Grab NUM_BUFFERS images.

	grabber.stopLive();					// Stop the grabber.
	
	// Save the buffers for which CListener::frameReady() has not been called.
	// Since CListener::frameReady() calls Sleep(250), it cannot be called for
	// every buffer. Nevertheless, all buffers are copied to the MemBufferCollection.
	for( size_t i = 0; i < pListener->m_BufferWritten.size(); i++ )
	{
		if( !pListener->m_BufferWritten[i] )
		{
			std::cout << "Buffer " << i << " processed in main()." << std::endl;
			pListener->saveImage( pSink->getMemBufferCollection()->getBuffer( i ), i);
		}
	}
	// The CListener object must be unregistered for all events
	// before it may be destroyed.
	grabber.removeListener( pListener );

	// Now, it must be checked whether the CListener object has been unregistered
	// for all events.
	while( grabber.isListenerRegistered( pListener ) )
	{
		Sleep( 0 ); // Wait and give pending callbacks a chance to complete.
	}

	// Now, the application can be sure that no callback methods of pListener
	// will be called anymore. It is now safe to delete pListener.
	delete pListener;

	std::cout << "Press any key to continue!" << std::endl;
	std::cin.get();
	return 0;
}

listener.h

#include <tisudshl.h>

class CListener : public DShowLib::GrabberListener  
{
public:
	// Overwrite the GrabberListener methods we need
	////在子类中重载父类方法
	virtual void overlayCallback( DShowLib::Grabber& caller, smart_ptr<DShowLib::OverlayBitmap> pBitmap, const DShowLib::tsMediaSampleDesc& MediaSampleDesc ); 
	////
	virtual void frameReady( DShowLib::Grabber& caller, smart_ptr<DShowLib::MemBuffer> pBuffer, DWORD FrameNumber ); 

	// Save one image and mark it as saved
///c存储一副图像,同时标记这福图像已经存储
	void		saveImage( smart_ptr<DShowLib::MemBuffer> pBuffer, DWORD currFrame );
	// Setup the buffersize. 
	///计数
	void		setBufferSize( unsigned long NumBuffers );

	std::vector<bool>	m_BufferWritten;	// array of flags which buffers have been saved.
};



listener.cpp



#include <iostream>

#include "Listener.h"

using namespace DShowLib;

//////////////////////////////////////////////////////////////////////////
/*! The overlayCallback() method draws the number of the current frame. The
	frame count is a member of the tsMediaSampleDesc structure that is passed
	to overlayCallback() by the Grabber.
*/
void	CListener::overlayCallback( Grabber& caller, smart_ptr<OverlayBitmap> pBitmap, 
								   const tsMediaSampleDesc& MediaSampleDesc)
{
	char szText[25];
	if( pBitmap->getEnable() == true ) // Draw only, if the overlay bitmap is enabled.
	{
		sprintf( szText,"%04d ", MediaSampleDesc.FrameNumber);
		pBitmap->drawText( RGB(255,0,0), 0, 0, szText );
	}
}

//////////////////////////////////////////////////////////////////////////
/*! The frameReady() method calls the saveImage method to save the image buffer to disk.
*/
void	CListener::frameReady( Grabber& caller, smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
{
	std::cout << "Buffer " << currFrame << " processed in CListener::frameReady()." << std::endl;

	saveImage( pBuffer, currFrame ); // Do the buffer processing.


	::Sleep(250); // Simulate a time expensive processing.
}

//////////////////////////////////////////////////////////////////////////
/*! Initialize the array of bools that is used to memorize, which buffers were processed in 
	the frameReady() method. The size of the array is specified by the parameter NumBuffers.
	It should be equal to the number of buffers in the FrameHandlerSink.
	All members of m_BufferWritten are initialized to false.
	This means that no buffers have been processed.
*/
void	CListener::setBufferSize( unsigned long NumBuffers )
{
	m_BufferWritten.resize( NumBuffers, false );
}

//////////////////////////////////////////////////////////////////////////
/*! The image passed by the MemBuffer pointer is saved to a BMP file.
*/
void	CListener::saveImage( smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
{
	char filename[MAX_PATH];
	if( currFrame < m_BufferWritten.size() )
	{
		sprintf( filename, "image%02i.bmp", currFrame );

		saveToFileBMP( *pBuffer, filename );

		m_BufferWritten.at( currFrame ) = true;
	}
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值