PDA

View Full Version : Display a membuffercollection



jthomas
June 3, 2014, 04:46:17
Hello,

I am writing a standalone application exe. with Visual studio 2010, using command line arguments.
First step, a number of frames from the grabber are saved in membuffercollection.
At the end of a code, I have been requested to display the buffer.
Should I use : GrabberListener and a callback function ?
If I need to create a callback function to display membuffercollection, Have you a idea on the source code of this function ?


Here my source code C++ :

int main (int argc, char **argv)
{

unsigned int numexp = 100; // number of exposures 100 by default
string outfile = "out"; // name
unsigned short thresholding = 0;
int index;
int c;
bool looping = false;
unsigned int start, end, tot;
opterr = 0;

// CImgDisplay *w;
// CImg<unsigned short> outframe ;


while ((c =getopt(argc,argv,"ln:o:t:")) != -1) {
switch (c) {
case 'l':
looping = true;
break;
case 'n':
numexp = atoi(optarg);
break;
case 'o':
outfile = optarg;
break;
case 't':
thresholding = atoi(optarg);
break;
default:
usage();
// NOTREACHED
}
}


for(index = optind; index < argc; index++){
cout<<"Non-option argument: "<<argv[index]<<endl;}



//Declaration des variables
int e=1;
bool loop = true;

double s;
HWND xhwnd=NULL;
int iOffsUpperLeft = 0;
BYTE* pbImgData1 ;
BYTE* pbImgData2 ;
BYTE* pbTresh;

int temp;
DWORD pos;
DWORD th;
int i=0;

//Initiate libraries from the device
if( ! DShowLib::InitLibrary() ){return FALSE;}
atexit( DShowLib::ExitLibrary );

//Create a frame grabbe
DShowLib::Grabber* m_pGrabber;
DShowLib::Grabber::tVidCapDevListPtr m_pVidCapDevList;

DShowLib::tFrameHandlerSinkPtr m_pSink;
DShowLib::tMemBufferCollectionPtr m_pCollection;

FrameTypeInfo info;
MemBufferCollection::tMemBufferPtr pActiveBuf;
MemBufferCollection::tMemBufferPtr pThresh;

m_pGrabber = new DShowLib::Grabber();
m_pVidCapDevList = m_pGrabber->getAvailableVideoCaptureDevices();


//Menu
m_pGrabber->showDevicePage();
m_pGrabber->openDev(m_pVidCapDevList->at(0));

xhwnd = m_pGrabber->getHWND();
m_pGrabber->setHWND(xhwnd);

if(looping){
m_pGrabber->startLive();
Sleep(2000);
}

s =((double)numexp)/( m_pGrabber->getFPS());


m_pSink = FrameHandlerSink::create(eY800, 1);
// We use snap mode.
m_pSink->setSnapMode( true );

// Set the sink.
m_pGrabber->setSinkType( m_pSink );

// Prepare the live mode, to get the output size if the sink.
if( !m_pGrabber->prepareLive( false ) )
{
std::cerr << "Could not render the VideoFormat into a eY800 sink.";
return -1;
}
m_pSink->getOutputFrameType( info );
BYTE* pBuf[1000];

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

m_pCollection = MemBufferCollection::create( info, numexp, pBuf );
if( m_pCollection == 0 || !m_pSink->setMemBufferCollection( m_pCollection ) )
{
std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
return -1;
}
// Start live mode for fast snapping. The live video will not be displayed,
// because false is passed to startLive().
m_pGrabber->startLive( false );

// Snap 5 images. The images are copied to the MemBufferCollection the
// application created above.

m_pSink->snapImages( numexp );
m_pGrabber->stopLive();

start = clock();

//Processed Buffer
temp =(int)floor((float)(info.buffersize));

for(pos = 0; pos <(DWORD)(numexp-1) ;pos++){

pbImgData1 = m_pCollection->getBuffer(pos)->getPtr();
pbImgData2 = m_pCollection->getBuffer(pos+1)->getPtr();

for(int pos_pixel=0 ; pos_pixel<temp; pos_pixel++){

pbImgData2[iOffsUpperLeft + pos_pixel ]= (BYTE)floor((float)(pbImgData1[iOffsUpperLeft + pos_pixel ] + pbImgData2[iOffsUpperLeft + pos_pixel ] )/2) ;

}

pActiveBuf = m_pCollection->getBuffer(pos+1);
}
//THRESHOLDING
if(thresholding != 0){

for(th = 0; th <(DWORD)(numexp-1) ;th++){

pbTresh = m_pCollection->getBuffer(th)->getPtr();

for(int pos_th=0 ; pos_th<temp; pos_th++){

if( pbTresh[iOffsUpperLeft + pos_th] >= thresholding){
pbTresh[iOffsUpperLeft + pos_th ] = 255;
}
else{
pbTresh[iOffsUpperLeft + pos_th ] = 0;
}
}
pThresh = m_pCollection->getBuffer(th + 1 );
}
}


end = clock();
tot = (unsigned int)s + ((end - start)/CLOCKS_PER_SEC);

//mkdir("Accumulated images");
//m_pCollection->save( "Accumulated images/result*.bmp" );
m_pCollection->save( "result*.bmp" );


//Display buffer


/**********************************
??????????????????????????????????
***********************************/

return 0;

}


With Thanks,

Julia

Stefan Geissler
June 4, 2014, 09:08:57
Hello Julia

Sorry for the delay of my answer.

Displaying an image buffer in C++ is not as simple. However, you save the images to BMP files, therefore, why do no use the Windows Image display program for this?

jthomas
June 5, 2014, 06:32:54
Hello Stefan,

Thank you for you response. My supervisor requests me to display the buffer without saving data.
I am wondering if it is possible to do a frame filter in c++ (accumulated a number of exposures and do a thresholding) then apply it on the grabber (setDeviceFrameFilter) ?

With thanks,

Julia

Stefan Geissler
June 5, 2014, 08:12:36
Hello Julia,

I suppose, your application has a Window handle, it is not a command line application.

Please have a look in the "DemoApp" sample, in the "childview.cpp". In its "onpaint" is shown, how to display a membuffer using SetDIBits() function.

The "Callback" samples how to handle the buffers :



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

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

grabber.stopLive(); // Stop the grabber.

for( size_t i = 0; i < NUM_BUFFERS ; i++ )
{
DrawImage( pSink->getMemBufferCollection()->getBuffer( i ) ) ;
}


You only need to implement the "DrawImage()" as shown in Childview.cpp from the "DemoApp" sample.

I think, this solves your problem.