I am currently trying to save an image from a Basler acA1280 color camera using C++ code derived from examples provided with the Pleora SDK (specifically, the image processing sample). I would like to correct some issues with the image I am currently able to save:
- It is blue
- There are two images
- There is a big grey bar under the images
Advice on any of these issues would be appreciated. I have primarily focused on the color issue so far since I had hoped that a correct pixel type would allow the image to carry more colors, but this was not successful.
Specific questions I have are:
- Is the image blue because the buffer I specify has the wrong pixel type, or because some data is being dropped?
- Are there two images because the alignment in the BMP file is off?
- Is the grey bar due to an incorrect sizing of the image, because the ImagingBuffer specs are not relevant to it (I have tried other size values without luck, but this could still be the issue)?
EDIT 1 Regarding the grey bar underneath, if I divide the lHeight by 2, so
lBuffer->GetImage()->Alloc(lWidth, lHeight/2, PvPixelRGBa8);
then the grey bar is removed. So perhaps the size allocated is too much. Is it possible that the double image is just a replicate of the image so that it fills the space, or could it be doubled due to an alignment issue?
Using the Pleora code, I am able to connect to the camera and start streaming.
Inside this section of the code, I attempt to write the buffer to a bmp file with mixed results. The attached image is an example of the output I get:
I am using a 32bit RGB pixel type to get this image. Reversing it to BGR works if I switch the output from the camera as well, but other pixel specifications just give constant grey images as output, or ghostly triple images in black and white with many lines.
The code that I think is relevant to understanding how the stream and buffer were created, and the image saved is below (please let me know if another section of the code is needed to understand the problem). I highlight the part where I save with the comment "Save original image":
// Acquire images until the user instructs us to stop.
cout << "<press a key to stop streaming>" << endl;
// allocate image
//AlignedImageBufferAllocator
PvFlushKb();
while ( !PvKbHit() )
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
PvBufferWriter lBufferWriter;
int lConvertedBufferIndex = 0;
PvBufferConverter lBufferConverter;
SimpleImagingLib::ImagingContrastFilter lContrastFilter;
// Retrieve next buffer
//PvResult lResult = lStream->RetrieveBuffer( &lBuffer, &lOperationResult, 1000 );
PvResult lResult = lStream->RetrieveBuffer(&lBuffer, &lOperationResult, 1000);
if ( lResult.IsOK() )
{
if (lOperationResult.IsOK())
{
//
// We now have a valid buffer. This is where you would typically process the buffer.
// -----------------------------------------------------------------------------------------
// ...
lBlockCount->GetValue( lBlockCountVal );
lFrameRate->GetValue( lFrameRateVal );
lBandwidth->GetValue( lBandwidthVal );
// Retrieve the imaging buffer based on the buffer's custom ID
SimpleImagingLib::ImagingBuffer *lImagingBuffer = gImagingBuffers + lBuffer->GetID();
// Retrieve our image based on buffer ID - which has been set to the index of the array
lContrastFilter.Apply( lImagingBuffer );
uint32_t lHeight = lImagingBuffer->GetHeight();
uint32_t lWidth = lImagingBuffer->GetWidth();
cout << fixed << setprecision( 1 );
cout << lDoodle[ lDoodleIndex ];
cout << " BlockID: " << uppercase << hex << setfill('0') << setw(16) << lBuffer->GetBlockID() << " W: " << dec << lWidth << " H: "
<< lHeight << " " << lFrameRateVal << " FPS " << ( lBandwidthVal / 1000000.0 ) << " Mb/s \r";
//Save original image
lBuffer->GetImage()->Alloc(lWidth, lHeight, PvPixelRGBa8);
lBufferWriter.Store(lBuffer, "C:\\Users\\Public\\Pictures\\ImageOriginal.bmp", PvBufferFormatBMP);
}
// Re-queue the buffer in the stream object.
lStream->QueueBuffer( lBuffer );
}
else
{
// Timeout
cout << lDoodle[ lDoodleIndex ] << " Timeout\r";
}
++lDoodleIndex %= 6;
}
EDIT 2 If I switch the pixel type from PvPixelRGBa8 to PvPixelBGRa8, and divide the lHeight in half, I obtain the image below, which could be an indication that the indexing for the RGB is mixed up. This one still has too much blue, but the problem is less pronounced.
Edit 3
Following the advice of @dkz, I attempted to change the pixel type to RGB8. This resulted in the green image below. Using his code to get the pixel type, I am led to believe that the pixel type at the time before writing is actually UYVY. The current picture has good point that there is only one image, which seems to confirm @dkz 's point that a 16 bit image was being mistreated as a 32 bit image, leading to doubling.
I have found the source of the problem. This line filtered lBuffer even though it is applied to lImagingBuffer.
The comment of @dkz was helpful because it made me refocus away from pixel types and to filters, which ultimately led to the correction.