我目前正在尝试使用派生自 Pleora SDK 提供的示例(特别是图像处理示例)的 C++ 代码从 Basler acA1280 彩色相机保存图像。我想更正我目前能够保存的图像的一些问题:
- 它是蓝色的
- 有两张图
- 图像下方有一个大的灰色条
对任何这些问题的建议将不胜感激。到目前为止,我主要关注颜色问题,因为我希望正确的像素类型可以让图像携带更多颜色,但这并不成功。
我的具体问题是:
- 图像是蓝色的,是因为我指定的缓冲区像素类型错误,还是因为某些数据被丢弃了?
- 是否因为 BMP 文件中的对齐关闭而出现两张图像?
- 灰色条是否是由于图像尺寸不正确,因为 ImagingBuffer 规格与它无关(我尝试了其他尺寸值但没有运气,但这仍然可能是问题)?
编辑 1 关于下面的灰色条,如果我将lHeight除以 2,那么
lBuffer->GetImage()->Alloc(lWidth, lHeight/2, PvPixelRGBa8);
然后删除灰色条。所以也许分配的大小太多了。双重图像是否可能只是图像的复制以填充空间,还是由于对齐问题而被加倍?
使用 Pleora 代码,我可以连接到相机并开始流式传输。在这部分代码中,我尝试将缓冲区写入 bmp 文件,但结果有好有坏。所附图像是我得到的输出示例:
我正在使用 32 位 RGB 像素类型来获取此图像。如果我也切换相机的输出,则将其反转为 BGR 也可以,但其他像素规格只会提供恒定的灰色图像作为输出,或者是带有许多线条的黑白三重图像。
我认为与理解流和缓冲区的创建方式相关的代码,保存的图像如下(如果需要另一部分代码来理解问题,请告诉我)。我用注释“保存原始图像”突出显示我保存的部分:
// 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;
}
编辑 2 如果我将像素类型从 PvPixelRGBa8 切换到 PvPixelBGRa8,并将lHeight分成两半,我得到下面的图像,这可能表明 RGB 的索引被混淆了。这一个仍然有太多的蓝色,但问题不那么明显。
编辑 3 按照@dkz 的建议,我尝试将像素类型更改为 RGB8。这导致了下面的绿色图像。使用他的代码获取像素类型,导致我认为写之前的像素类型实际上是UYVY。当前图片的优点是只有一张图像,这似乎证实了@dkz 的观点,即 16 位图像被误视为 32 位图像,导致翻倍。