12-12-2011 10:33 PM
I'm attempting to capture and write Bayer-decoded frames to disk using NI IMAQ in MSVC++, using these basic steps:
- capture a frame with 'imgSnap'
- decode Bayer codor with 'imgBayerColorDecode'
- write the result to disk via 'imgSessionSaveBufferEx'
While the below code does write the raw file to disk, the call to write a Bayer-decoded buffer fails. It's likely my error is in understanding how to correctly initialize my RGB image buffer so that it is a 'member' to the same session ID that I use to capture a raw frame. Or perhaps 'imgSessionSaveBufferEx' is not the right function to write a Bayer-decoded image to disk.
The line that fails is: imgSessionSaveBufferEx(sid,RGBBuffer,"snapshot_decoded.jpg");
Thanks in advance for any comments on errors in the brief toy program below,
-Kevin
#include "stdafx.h"
#include "niimaq.h" // Include the NIIMAQ.H header file in all C source files that use NI-IMAQ functions.
#include <windows.h>
int main(int argc, char* argv[])
{
// Low-level image capture
INTERFACE_ID iid;
SESSION_ID sid;
BUFLIST_ID bid;
BUFLIST_ID rgb_buf;
void * IMAQBuffer = NULL; //NI-IMAQ image
void *RGBBuffer = NULL; // Bayer decoded RGB
static uInt8 bayerPattern;
bayerPattern = 1; // Use first Bayer Pattern
static uInt32 acqWinWidth;
static uInt32 acqWinHeight;
static uInt32 bufSize;
uInt32 redLUT[65536];
uInt32 greenLUT[65536];
uInt32 blueLUT[65536];
unsigned int bytesPerPixel, bitsPerPixel;
//Initialize interface and session
imgInterfaceOpen ("img0", &iid);
imgSessionOpen (iid, &sid);
imgGetAttribute (sid, IMG_ATTR_ROI_WIDTH, &acqWinWidth);
imgGetAttribute (sid, IMG_ATTR_ROI_HEIGHT, &acqWinHeight);
imgGetAttribute (sid, IMG_ATTR_BYTESPERPIXEL, &bytesPerPixel);
imgGetAttribute (sid, IMG_ATTR_BITSPERPIXEL, &bitsPerPixel);
imgCreateBufList(1, &bid); //Creates a buffer list with one buffer
imgCreateBufList(1, &rgb_buf); //Creates a buffer list with one buffer
bufSize = acqWinWidth * acqWinHeight * bytesPerPixel;
// Configure buffer for IMAQBuffer
imgCreateBuffer(sid, FALSE, bufSize, &IMAQBuffer);
imgSetBufferElement(bid, 0, IMG_BUFF_ADDRESS, (uInt32)IMAQBuffer);
imgSetBufferElement(bid, 0, IMG_BUFF_SIZE, bufSize);
imgSetBufferElement(bid, 0, IMG_BUFF_COMMAND, IMG_CMD_STOP);
// Capture an image into the buffer created above
imgSnap (sid, (void **)&IMAQBuffer); //NI-IMAQ function
Sleep(20); // Wait to ensure buffer write is complete before decoding
// GBGB-RGRG Bayer decoding assumed
// See: C:\Users\Public\Documents\National Instruments\NI-IMAQ\Examples\MSVC\Color\BayerDecode
// TO DO: Add error checking
if(imgBayerColorDecode(RGBBuffer, IMAQBuffer, acqWinHeight, acqWinWidth,
acqWinWidth, acqWinWidth, redLUT, greenLUT, blueLUT, bayerPattern, bitsPerPixel, 0))
{
// Save contents of the image buffer IMAQBuffer
imgSessionSaveBufferEx(sid,IMAQBuffer,"snapshot_raw.jpg");
// <<<--- Fails on next line
imgSessionSaveBufferEx(sid,RGBBuffer,"snapshot_decoded.jpg");
}
else
{
// Catch Bayer decoding exception
}
// Close the session, free resources
imgClose(iid, 0);
return 0;
}
12-14-2011 10:32 AM
Hello Kevin,
What exactly happens when that line "fails"? Do you receive an error message? Does the code freeze? What exactly occurs?
12-14-2011 11:12 AM
Thanks for following up, Michael,
The noted line fails to write an image to disk, but does not display an error message in the console or hang execution. It just silently exits the write task for the color image [(b) below], after successfully completing the write task for the raw Bayer image (a):
(a) imgSessionSaveBufferEx(sid,IMAQBuffer,"snapshot_raw.jpg"); // writes a "snapshot_raw.jpg" to disk, as expect
(b) imgSessionSaveBufferEx(sid,RGBBuffer,"snapshot_decoded.jpg"); // fails to write "snapshot_decoded.jpg" to disk, but produces no error
I suspect that' RGBBuffer' has no context for 'sid', creating a NULL parameter for imgSessionSaveBufferEx, but I don't know if this is actually a problem or how to declare 'RGBBuffer' as member to the 'sid' session in the above referenced code.
Thanks again,
-Kevin
12-15-2011 07:51 PM
Hi Kevin,
I think there might be a problem with the line: if(imgBayerColorDecode(RGBBuffer, IMAQBuffer, acqWinHeight, acqWinWidth, acqWinWidth, acqWinWidth, redLUT, greenLUT, blueLUT, bayerPattern, bitsPerPixel, 0)). It may not be returning what we expect. I'll look in to this more...
12-16-2011 01:38 PM
Hi Kevin,
I have two suggestions. First, I think you might have a problem with the line "if(imgBayerColorDecode(RGBBuffer, IMAQBuffer, acqWinHeight, acqWinWidth, acqWinWidth, acqWinWidth, redLUT, greenLUT, blueLUT, bayerPattern, bitsPerPixel, 0))". I believe that when imgBayerColorDecode succeeds that the if statement will return 0 and proceed to the else case. Conversely, if there is an error with imgBayerColorDecode, then I think the if statement will run the true case and try to save the image. I think you might need to switch the cases or put a 'not' in the logic. Second, I suggest that you look over the Bayer Decoding shipping example. You should find it at Documents\National Instruments\NI-IMAQ\Examples\MSVC\Color\BayerDecode. This example should help to shed some light on the error.
12-16-2011 03:11 PM
Thanks for your help, Michael,
I do realize that the '"if(imgBayerColorDecode(...))" construction is not well formed, and will try for better error checking. I'll also have a look at the file you reference, in case the problem is elsewhere.
Thanks again,
-Kevin