我目前正在嘗試使用從Pleora SDK提供的示例派生的C++代碼從Basler acA1280彩色攝像機保存圖像(具體來說,圖像處理樣品)。 我想糾正我目前能保存圖像的一些問題:用Pleora SDK保存一個緩衝區給出藍色,加倍的BMP,灰色條在
- 它是藍色的
- 有兩個圖像
- 有圖像下一個大的灰色條
任何這些問題的建議,將不勝感激。迄今爲止,我主要關注顏色問題,因爲我曾希望正確的像素類型可以讓圖像承載更多顏色,但這並不成功。
我有具體問題是:
- 是像藍色,因爲我指定緩衝區有錯誤的像素類型,或者是因爲一些數據被丟棄?
- 是否有兩個圖像,因爲BMP文件中的對齊關閉?
- 由於ImagingBuffer規格與圖像尺寸無關(我試過其他尺寸值但沒有運氣,但這仍然是問題),是否由於圖像尺寸不正確而出現灰條?
EDIT 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;
}
EDIT 2 如果我從PvPixelRGBa8切換像素類型PvPixelBGRa8,並劃分lHeight一半,我得到下面的圖像,這可能表示RGB的索引混合起來。這個藍色仍然太多,但問題不那麼明顯。
編輯3 繼@dkz的建議,我試圖改變像素類型RGB8。這導致下面的綠色圖像。使用他的代碼來獲得像素類型,我被認爲在寫入之前的像素類型實際上是UYVY。目前的圖像有一個好處,那就是隻有一個圖像,這似乎證實了@dkz的觀點,即一個16位圖像被當作32位圖像來處理,從而導致加倍。
我看到你的觀點@dkz。該代碼最初嘗試將像素類型設置爲RGB8,但是當我簡單地使用它時,我獲得了像編輯3中那樣的綠色圖像。該圖片的一個好處是隻有一張圖片 - 所以我非常感謝您關於倍增的觀點是16位和32位之間的混淆。我已經打印出GetPixelType,並獲得34603039,互聯網搜索告訴我是UYVY。這是否意味着像素類型未在代碼中成功設置? – Deathkill14
@dbz,請問另一個問題。應用轉換器是什麼意思?我看到有PvBufferConverter功能來改變像素類型。這相當於我已經在做的重新分配嗎? – Deathkill14
感謝您的答案@dkz。它把我推向了正確的方向。 – Deathkill14