PDA

View Full Version : Grab Images to IplImage*



northnorway
October 19, 2006, 13:23:33
I hava an exisiting program, that works on the IplImage* Format. So I need to create an interface, that grabs Images from the camera (Cam-Type: DFK 21F04) and "converts" it to an IplImage* object.

I tried to do that with the following code:



//Initialization:
DShowLib::Grabber* grabber;
DShowLib::tFrameHandlerSinkPtr pSink;

pSink = DShowLib::FrameHandlerSink::create( DShowLib::eRGB24, 1 );
pSink->setSnapMode(true);
grabber->setSinkType(pSink);
grabber->startLive(false); // Start the live video.
openCVImage = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U , 3);

...


//Grab one Image from Camera:
pSink->snapImages(1);
DShowLib::MemBufferCollection::tMemBufferPtr buffer = pSink->getLastAcqMemBuffer();

long bufferLength = buffer->getBufferSize(); // = 230400
long imageSize = frame->imageSize; // = 921600 (640*480*3*1Byte)

openCVImage->imageData =(char*) buffer->getPtr();


But my problem is, that the buffer that should contain the Image data is only 230400 Bytes long (concering to the return-value of getBufferSize()). But in my opinion it should be 921600 bytes long because this is the correct size of an RGB24-Image with 640 x 480 pixels.
Therefore I get a memory-access-violation-error if I try to access the IplImage.
Can anybody help me to access the complete Image Data which should be 921600 bytes long?

Thanks for your help!

Stefan Geissler
October 19, 2006, 15:18:37
Hello,

I think it is the line


openCVImage->imageData =(char*) buffer->getPtr()

that might cause the problem. I converted the image as follows:



smart_ptr<BITMAPINFOHEADER> pInf = pBuffer->getBitmapInfoHeader();
int iImageSize = pInf->biWidth * pInf->biHeight * pInf->biBitCount / 8 ;
m_pOpenCVImage = cvCreateImage( size, IPL_DEPTH_8U, pInf->biBitCount / 8 );

memcpy(m_pOpenCVImage->imageData, pBuffer->getPtr(), iImageSize );


This worked fine. You ma try the attached sample. The OpenCV Image is used in the "CListener" class.

northnorway
October 19, 2006, 16:43:48
Thanks a lot for your help! Now I see, the reason for my problem: I assumed, that the Image-Size is 640 x 480. But according to the information contained in pInf the snapped Image is only 320 x 240. Even though I inserted " grabber->showDevicePage();" in my initialization-section so that I can set the Video-Format to RGB24 640x480 in the "Device-Settings"-Dialog Box.
What else do I have to do, to get an Image with the size of 640x480?

Id be pleased if you could help me on more time!

Stefan Geissler
October 19, 2006, 17:19:14
Thanks a lot for your help! Now I see, the reason for my problem: I assumed, that the Image-Size is 640 x 480. But according to the information contained in pInf the snapped Image is only 320 x 240. Even though I inserted " grabber->showDevicePage();" in my initialization-section so that I can set the Video-Format to RGB24 640x480 in the "Device-Settings"-Dialog Box.
What else do I have to do, to get an Image with the size of 640x480?

Id be pleased if you could help me on more time!

You may set the video format "UYVY (640x480)" after you have selected a device. Or you may setup the device with the showDevicePage() and save the configuration to a file with SaveDeviceStateToFile(). Then you can load this configuration next time your application starts with "LoadDeviceStateFromFile()". If this fails, you can show the showDevicePage() dialog again. Everytime you change something on the device, you may save it to a file. This keeps your application compatible to each possible video capture devices and you do not have to take care if you would use a camera with other resolutions.

This part is copied from the sample, that I have sent to you. It is from InitDialog:

// Try to load the previously used video capture device.
if( m_cGrabber.loadDeviceStateFromFile( "device.xml"))
{
// Display the device's name in the caption bar of the application.
SetWindowText( "ICOpenCVSample " + CString(m_cGrabber.getDev().c_str()));
m_cGrabber.startLive(false); // The live video will be displayed by the CListener object.
}


And this part is the for setting up the device and saving its state to a file.

m_cGrabber.showDevicePage(this->m_hWnd);

// If we have selected a valid device, save it to the file "device.xml", so
// the application can load it automatically when it is started the next time.
if( m_cGrabber.isDevValid())
{
m_cGrabber.saveDeviceStateToFile("device.xml");
}

If you want to set the video format hard coded you may use the method Grabber::setVideoFormat()
Please refer to:
http://www.imagingcontrol.com/ic/docs/html/class/meth_descGrabber_setVideoFormat.htm

northnorway
October 20, 2006, 10:58:19
Im already doing exactly what you have described: I call grabber->showdevicePage() so that I can set the Image format of my camera to RGB24 640x480. But anyway, the picture I receive is only 320x240 pixels large.
Now I could try the hardcoded solution using grabber->setVideoFormat(). But unforunately I cant find any documentation about the necessary parameters used by this function.

northnorway
October 20, 2006, 14:33:10
Now I was able to solve the problem: I called the grabber->ShowDevicePage() before grabber->openDevice(). Obviously the call of openDevice() overwrites the camera settings, that were set before. So my assumption, that settings are stored persistently in the camera is obviously wrong.
Thanks for your help so far!