В настоящее время я пытаюсь сохранить изображение с цветной камеры Basler acA1280, используя код C ++, полученный из примеров, поставляемых с Pleora SDK (в частности, пример обработки изображений).
Я хотел бы исправить некоторые проблемы с изображением, которое я сейчас могу сохранить:
Консультации по любому из этих вопросов будут оценены. До сих пор я уделял основное внимание проблеме цвета, так как надеялся, что правильный тип пикселя позволит изображению передавать больше цветов, но это не удалось.
У меня есть конкретные вопросы:
РЕДАКТИРОВАТЬ 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-битное, что приводит к удвоению.
Тот факт, что вы видите удвоенные (или утроенные) изображения в сохраненном файле, означает, что в ваших реальных данных неверный тип пикселей. Двойное изображение означает, что, например, 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 чтобы найти их смысл.
Я нашел источник проблемы.
Эта строка отфильтрована lBuffer хотя он применяется к lImagingBuffer.
lContrastFilter.Apply( lImagingBuffer );
Комментарий @dkz был полезен, потому что заставил меня переориентироваться с типов пикселей и на фильтры, что в конечном итоге привело к исправлению.