View Full Version : Simple External Trigger with Opencv

July 29, 2010, 19:55:01
Hi I am having some trouble getting the camera to work with an external trigger and to use the captured buffer in an IplImage for opencv.

I know the hardware trigger works because I have verified this with IC Capture. The issue seems to be when I run my code I am not getting the image off of the buffer in the camera. The viewer window I have setup in opencv just remains blank I guess my problem is in extracting the image off the buffer or maybe setting up the trigger?

I saw in some previous posts that Stefan said you should use the callback function instead of snapImages because snapImages is a blocking call.

Here is what I believe to be the relevant portions of my code, the callback function and main code.


void CListener::frameReady( Grabber& caller, smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
memcpy(input->imageData, pBuffer->getPtr(), 640*480);
cvShowImage("Input", input); //show image
key = cvWaitKey(10);


(From main)

Grabber grabber;
CListener *pListener = new CListener();

// Disable overlay. If it was in the graph, we could not get UYVY images.
grabber.setOverlayBitmapPathPosition( ePP_NONE );
grabber.addListener(pListener, GrabberListener::eFRAMEREADY);

if( !setupDeviceFromFile( grabber ) )
return -1;


tFrameHandlerSinkPtr pSink = FrameHandlerSink::create( eY800, 1 );

// We use snap mode.
pSink->setSnapMode( true );

grabber.setSinkType( pSink );

// Prepare the live mode, to get the output size if the sink.
if( !grabber.prepareLive( false ) )
printf("Could not render the VideoFormat into the sink. \n");

FrameTypeInfo info;
pSink->getOutputFrameType( info );
BYTE** pBuf = (BYTE **)malloc(nPics*sizeof(BYTE *));
BYTE* buffer = new BYTE[640*480*NPICS];

for( int i = 0; i < nPics; ++i )
pBuf[i] = new BYTE[info.buffersize];

tMemBufferCollectionPtr pCollection = MemBufferCollection::create( info, nPics, pBuf );
if( pCollection == 0 || !pSink->setMemBufferCollection( pCollection ) )
std::cerr << "Could not set the new MemBufferCollection, because types do not match.";

// Start live mode for fast snapping. The live video will not be displayed,
// because false is passed to startLive().


Stefan Geissler
July 30, 2010, 09:05:43

grabber.setExternalTrigger(true); works only if the live video has been stopped. Thus call this before you call startLive().

If you used VCD properties instead of setExternalTrigger, then the call works, because the VCD properties use a different approach.

However, call


and all should be fine.

You may have a look on http://www.imagingcontrol.com/en_US/support/documentation/class/meth_descGrabber_setExternalTrigger.htm

It is also a good idea to check return values of these functions.

July 30, 2010, 16:08:23
Thanks Stefan,

I tried what you said and I still have problems. Tracing the program it seems the callback function is not executing. Am I registering it correctly?

This is the call back function.

void CListener::frameReady( Grabber& caller, smart_ptr<MemBuffer> pBuffer, DWORD currFrame)

//input->imageData = (char*)pSink->getLastAcqMemBuffer()->getPtr();

memcpy(input->imageData, pBuffer->getPtr(), 640*480);
cvShowImage("Depth Edge", input); //show image
key = cvWaitKey(5);
printf("\nFrame is ready");


This is where I overwrite the listening functions in Listener.h

class CListener : public DShowLib::GrabberListener
// 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
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.

And this is how I register it in the program.

grabber.addListener(pListener, GrabberListener::eFRAMEREADY);

I am not sure what I'm doing wrong. I'm not that good at programming I'm more of a hardware guy.

I did switch the order of the startlive and the external trigger statements but the opencv window remains blank. Thanks for your help so far.

Stefan Geissler
July 30, 2010, 16:45:56

you must set the snapmode to false:

pSink->setSnapMode( false );

The the images will automatically be copied into the sink and the grabberr listener is called.

July 30, 2010, 16:55:00
Thanks Stefan works perfectly now. :-)