Сохранение буфера с помощью Pleora SDK дает синий удвоенный BMP с серой полосой внизу

В настоящее время я пытаюсь сохранить изображение с цветной камеры Basler acA1280, используя код C ++, полученный из примеров, поставляемых с Pleora SDK (в частности, пример обработки изображений).
Я хотел бы исправить некоторые проблемы с изображением, которое я сейчас могу сохранить:

  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-битное, что приводит к удвоению.
введите описание изображения здесь

1

Решение

Тот факт, что вы видите удвоенные (или утроенные) изображения в сохраненном файле, означает, что в ваших реальных данных неверный тип пикселей. Двойное изображение означает, что, например, BMP-ридер считает, что изображение имеет 32 бита на пиксель, а фактические данные — 16 бит на пиксель. Тройное изображение обычно возникает, когда вы пытаетесь получить доступ к моно / байеровским 8-битным пикселям как 24-битному RGB.

Линия lBuffer->GetImage()->Alloc(lWidth, lHeight, PvPixelRGBa8) выглядит неправильно. После получения буфера вам больше не нужно выделять его (или ожидать, что он изменит свой пиксельный формат следующим образом). Вы должны быть в состоянии сохранить этот буфер как есть (или выполнить преобразование). Вы можете проверить текущий формат пикселя буфера с lBuffer->GetImage()->GetPixelType(),

Вы должны использовать GenICam PixelFormat Функция для запроса желаемого формата пикселей с камеры:

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 чтобы найти их смысл.

2

Другие решения

Я нашел источник проблемы.
Эта строка отфильтрована lBuffer хотя он применяется к lImagingBuffer.

lContrastFilter.Apply( lImagingBuffer );

Комментарий @dkz был полезен, потому что заставил меня переориентироваться с типов пикселей и на фильтры, что в конечном итоге привело к исправлению.

0

По вопросам рекламы [email protected]