1

我目前正在尝试使用派生自 Pleora SDK 提供的示例(特别是图像处理示例)的 C++ 代码从 Basler acA1280 彩色相机保存图像。我想更正我目前能够保存的图像的一些问题:

  1. 它是蓝色的
  2. 有两张图
  3. 图像下方有一个大的灰色条

对任何这些问题的建议将不胜感激。到目前为止,我主要关注颜色问题,因为我希望正确的像素类型可以让图像携带更多颜色,但这并不成功。

我的具体问题是:

  1. 图像是蓝色的,是因为我指定的缓冲区像素类型错误,还是因为某些数据被丢弃了?
  2. 是否因为 BMP 文件中的对齐关闭而出现两张图像?
  3. 灰色条是否是由于图像尺寸不正确,因为 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 位图像,导致翻倍。 在此处输入图像描述

4

2 回答 2

2

您在保存的文件中看到两倍(或三倍)图像的事实意味着您的实际数据中有错误的像素类型。双重图像意味着例如 BMP 阅读器认为图像具有每像素 32 位,而实际数据是每像素 16 位。当您尝试将单声道/拜耳 8 位像素作为 24 位 RGB 访问时,通常会出现三重图像。

这条线lBuffer->GetImage()->Alloc(lWidth, lHeight, PvPixelRGBa8)看起来不对。获取缓冲区后,您不必再分配它(或期望像这样更改其像素格式)。您应该能够按原样保存此缓冲区(或执行转换)。您可以使用 . 检查当前缓冲区像素格式lBuffer->GetImage()->GetPixelType()

您应该使用 GenICamPixelFormat功能从相机请求所需的像素格式:

PvDevice* lDevice = Connect( aConnectionID );
PvGenParameterArray* lParameters = lDevice->GetParameters();
PvGenParameter *lParameter = lParameters->Get( "PixelFormat" );
PvGenEnum *lPixelFormatParameter = dynamic_cast<PvGenEnum *>( lParameter );
lPixelFormatParameter->SetValue( "RGB8" ); // if camera supports RGB8 pixels

请参阅 Pleora 的 GenICamParameters 示例,从相机中转储所有可用功能并参阅GenICam 标准功能命名约定以查找它们的含义。

于 2015-07-20T22:21:28.113 回答
0

我找到了问题的根源。此行过滤lBuffer即使它应用于lImagingBuffer

lContrastFilter.Apply( lImagingBuffer );

@dkz 的评论很有帮助,因为它让我重新关注像素类型和过滤器,这最终导致了更正。

于 2015-07-21T13:55:04.300 回答