PDA

View Full Version : Grabbing 1 frame through command prompt



padu
October 1, 2007, 20:02:25
Hello,

I'm trying to learn how to operate the classlib and for that I'm writing a very simple test application.

The application runs from the command prompt and shall initialize the device, grab a frame and pass it along to a image processing function that I will write latter on.

Here's the source code:


// PromptCapture.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "PromptCapture.h"
#include "PersonTracker.h"
#include "tisudshl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
_tprintf(_T("\nPrompt Capture is a stepstone for the PersonFollowing Project\n"));
_tprintf(_T("SDSU - IMSL: for SPAWAR\n"));
_tprintf(_T("================================================== ===========\n\n"));

LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER tick1, tick2; // A point in time
double totalTime;

// get the high resolution counter's accuracy
QueryPerformanceFrequency(&ticksPerSecond);


//initialize camera
printf("CAMERA INITIALIZATION\n");
QueryPerformanceCounter(&tick1);
if( ! DShowLib::InitLibrary( "------------" ) )
{
return FALSE;
}
DShowLib::Grabber grabber;

QueryPerformanceCounter(&tick2);
totalTime = (double(tick2.QuadPart - tick1.QuadPart) / ticksPerSecond.QuadPart);

if( !grabber.showDevicePage() || !grabber.isDevValid() )
{
return -1;
}

QueryPerformanceCounter(&tick1);
grabber.startLive(false);
if (grabber.isLive())
printf("Camera is live\n");
else
printf("Camera is not live\n");
QueryPerformanceCounter(&tick2);
totalTime += (double(tick2.QuadPart - tick1.QuadPart) / ticksPerSecond.QuadPart);
printf("Camera initialized in %f milliseconds\n\n", totalTime*1000);


//capture a frame
printf("FRAME GRABBING\n");
QueryPerformanceCounter(&tick1);
//capture frame here
// Snap one image and copy it into the MemBufferCollection.
grabber.snapImages(1);
DShowLib::Error e = grabber.getLastError();
if (e.isError())
{
// Display the error.
cout << "error\n";
printf(e.c_str());
return -1;
}
DShowLib::Grabber::tMemBufferPtr pBuff = grabber.getActiveMemBuffer();
pBuff->save("test.jpg");


QueryPerformanceCounter(&tick2);
totalTime = (double(tick2.QuadPart - tick1.QuadPart) / ticksPerSecond.QuadPart);
// Display real numbers
printf("Frame captured in %f milliseconds\n\n", totalTime*1000);

//calculate person position from captured frame
printf("PERSON TRACKING\n");
QueryPerformanceCounter(&tick1);
CPersonTracker* personTracker = new CPersonTracker();
int pos = personTracker->GetLastKnownPersonPosition(0);
QueryPerformanceCounter(&tick2);
totalTime = (double(tick2.QuadPart - tick1.QuadPart) / ticksPerSecond.QuadPart);

printf("Person centroid is %d,%d.\n", 0,0);
printf("Person bounding box is (%d,%d)-(%d,%d).\n", 0,0,0,0);
printf("Person tracked in %f milliseconds\n", totalTime*1000);

grabber.stopLive();
delete personTracker;
}

return nRetCode;

}



and here's the output of it:



Prompt Capture is a stepstone for the PersonFollowing Project
SDSU - IMSL: for SPAWAR
================================================== ======

CAMERA INITIALIZATION
Camera is live
Camera initialized in 74.672840 milliseconds

FRAME GRABBING
error
Unknown error


The error happens when I try to use "grabber.snapImages(1)".
Is there a precondition to it? At that point, the camera is initialized and live.


Thanks

Padu

Stefan Geissler
October 2, 2007, 10:59:52
Hi Padu,

As far as I can see, you did not create the Membuffer collection assign it to the grabber.
Please add following lines before you call startlive():


// Create the frame handler sink
smart_ptr<FrameHandlerSink> pSink = FrameHandlerSink::create( DShowLib::eRGB24, 5);

// enable snap mode (formerly tFrameGrabberMode::eSNAP).
pSink->setSnapMode( true );

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


You may refer to the "callback" sample in your IC Imaging Control installation path in the "samples" directory.

padu
October 3, 2007, 22:09:05
Hi Padu,
You may refer to the "callback" sample in your IC Imaging Control installation path in the "samples" directory.

Thanks, I did. I tried to adapt the concepts there into my program but I'm still having problems.

I decided to run the callback sample and then go back to my app later, but I also run into a series of problems trying to run the callback program.

Here are they:

1) When it gets to the inline function setupDeviceFromFile, it does show the device dialog successfull, but when it tries to save the configuration to a file
(cmdhelper.h line 179: gr.saveDeviceStateToFile( devStateFilename, true, true, false );), it gives me an access violation

First-chance exception at 0x00303c7a in Callback.exe: 0xC0000005: Access violation reading location 0xcccccccc.
Unhandled exception at 0x00303c7a in Callback.exe: 0xC0000005: Access violation reading location 0xcccccccc.

2) If I change the Callback.cpp file to call the grabber.showDevicePage() instead of setupDeviceFromFile, then it gives me a very weird error when trying to execute the following line:
grabber.getOverlay()->setEnable( true );

and here's the error as reported in the output window:
HEAP[Callback.exe]: Invalid Address specified to RtlValidateHeap( 01680000, 01118140 )
Windows has triggered a breakpoint in Callback.exe.

This may be due to a corruption of the heap, and indicates a bug in Callback.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information



So I gave up and tried to make my simple 1 frame grabber to work, and here's where I'm stuck:



int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{



//initialize camera
if( ! DShowLib::InitLibrary( "REMOVED" ) )
{
return FALSE;
}

DShowLib::Grabber grabber;

//set grabber device
if( !grabber.showDevicePage() || !grabber.isDevValid() )
{
return -1;
}

//create the sink
smart_ptr<FrameHandlerSink> pSink = FrameHandlerSink::create( DShowLib::eRGB24, 1 );

//set snap mode
pSink->setSnapMode( true );

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


int retval = grabber.startLive(false);
if (!retval)
{
cout << "Could not start video stream";
return -1;
}

// give the device time to adjust automatic settings i.e. auto exposure
Sleep( 250 );

if (grabber.isLive())
cout << "Camera is live\n";
else
{
cout << "Camera is not live\n";
return -1;
}

Error err;

//capture a frame
pSink->snapImages( 1,5000 );
if (err.isError())
{
cout << "Error: " << err.c_str();
return -1;
}


grabber.stopLive();

// get pointer to the image data
MemBufferCollection::tMemBufferPtr pActiveBuf = pSink->getLastAcqMemBuffer();

if (pActiveBuf==0)
{
cout << "Could not retrieve active buffer.\n";
return -1;
}

cout << "bits per pixel " << pActiveBuf->getBitsPerPixel();
cout << "frame count = " << pSink->getFrameCount();

err = DShowLib::saveToFileJPEG(*(pActiveBuf),"Testimage.jpg",90);
if (err.isError())
{
cout << "Error: " << err.c_str();
return -1;
}

pActiveBuf = pSink->getMemBufferCollection()->getBuffer(0);
err = DShowLib::saveToFileJPEG(*(pActiveBuf),"Testimage.jpg",90);
if (err.isError())
{
cout << "Error: " << err.c_str();
return -1;
}

}

return nRetCode;
}




The first problem is with pSink->snapImages( 1,5000 );
It doesn't matter how long I set the time out, it times out and returns the following error:
Error: the timeout passed to snapImages( ... ) did elapse before all images could be snaped


Any hope for me? I know it is probably something I'm doing wrong, but I'm getting very frustrated.

Thanks for your help

Stefan Geissler
October 4, 2007, 10:18:06
Hi,

which version of C++ do you use?

Stefan Geissler
October 4, 2007, 13:53:10
Hello,

We have checked the "callback" again with VC 7.1 and found no problems. If you use VC 7.0, then may some memory errors can occur.

padu
October 4, 2007, 18:00:59
Hi,

which version of C++ do you use?


Microsoft Visual Studio 2005
Version 8.0.50727.42 (RTM.050727-4200)
Microsoft .NET Framework
Version 2.0.50727

Installed Edition: Standard

Microsoft Visual Basic 2005 77633-233-0040764-41463
Microsoft Visual Basic 2005

Microsoft Visual C# 2005 77633-233-0040764-41463
Microsoft Visual C# 2005

Microsoft Visual C++ 2005 77633-233-0040764-41463
Microsoft Visual C++ 2005

Microsoft Visual J# 2005 77633-233-0040764-41463
Microsoft Visual J# 2005

Microsoft Visual Web Developer 2005 77633-233-0040764-41463
Microsoft Visual Web Developer 2005



Running under Windows Vista Business Edition

Stefan Geissler
October 5, 2007, 09:25:25
Hello Padu,

We have checked this in Windows Vista too. But I will do this again.

padu
October 9, 2007, 18:56:45
Hello Padu,

We have checked this in Windows Vista too. But I will do this again.

Hi Stefan,

I'm still stuck. Is there any way that you could write a very simple command prompt app (like the one I wrote above) that will capture one frame and write it to a jpeg file?

Sascha Schmidt
October 10, 2007, 16:06:10
Hallo Padu,

Please refer to the Imaging Control VC8 samples.
There is an simple command prompt sample called "MembufferCollection" (...\The Imaging Source Europe GmbH\IC Imaging Control 3.0\samples\vc8\MembufferCollection), which grabs some images and saves them to .jpg files.

I have tested the sample with Visual Studio 8 on Win Vista 64. I think it is exactly what you need.