2015-07-20 79 views
1

我目前正在嘗試使用從Pleora SDK提供的示例派生的C++代碼從Basler acA1280彩色攝像機保存圖像(具體來說,圖像處理樣品)。 我想糾正我目前能保存圖像的一些問題:用Pleora SDK保存一個緩衝區給出藍色,加倍的BMP,灰色條在

  1. 它是藍色的
  2. 有兩個圖像
  3. 有圖像下一個大的灰色條

任何這些問題的建議,將不勝感激。迄今爲止,我主要關注顏色問題,因爲我曾希望正確的像素類型可以讓圖像承載更多顏色,但這並不成功。

我有具體問題是:

  1. 是像藍色,因爲我指定緩衝區有錯誤的像素類型,或者是因爲一些數據被丟棄?
  2. 是否有兩個圖像,因爲BMP文件中的對齊關閉?
  3. 由於ImagingBuffer規格與圖像尺寸無關(我試過其他尺寸值但沒有運氣,但這仍然是問題),是否由於圖像尺寸不正確而出現灰條?

EDIT 1 關於灰色條的下面,如果我劃分lHeight 2,所以

lBuffer->GetImage()->Alloc(lWidth, lHeight/2, PvPixelRGBa8); 

則灰色條被去除。所以分配的大小可能太多了。是否有可能雙圖像只是圖像的複製品,以便填充空間,或者由於對齊問題可能會使圖像翻倍?

使用Pleora代碼,我可以連接到相機並開始流式傳輸。 在這段代碼中,我嘗試將緩衝區寫入一個帶有混合結果的bmp文件。附加的圖像是我得到的輸出示例: enter image description here

我正在使用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的索引混合起來。這個藍色仍然太多,但問題不那麼明顯。

Somewhat improved Image

編輯3 繼@dkz的建議,我試圖改變像素類型RGB8。這導致下面的綠色圖像。使用他的代碼來獲得像素類型,我被認爲在寫入之前的像素類型實際上是UYVY。目前的圖像有一個好處,那就是隻有一個圖像,這似乎證實了@dkz的觀點,即一個16位圖像被當作32位圖像來處理,從而導致加倍。 enter image description here

回答

1

事實上,您在保存的文件中看到兩倍(或三倍)圖像,意味着您的實際數據中的像素類型錯誤。加倍的圖像意味着例如BMP閱讀器認爲圖像具有每像素32位,而實際數據是每像素16位。當您試圖以24位RGB訪問單聲道/拜爾8位像素時,通常會出現三重圖像。

該行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 Standard Features Naming Convention找到它們的含義。

+0

我看到你的觀點@dkz。該代碼最初嘗試將像素類型設置爲RGB8,但是當我簡單地使用它時,我獲得了像編輯3中那樣的綠色圖像。該圖片的一個好處是隻有一張圖片 - 所以我非常感謝您關於倍增的觀點是16位和32位之間的混淆。我已經打印出GetPixelType,並獲得34603039,互聯網搜索告訴我是UYVY。這是否意味着像素類型未在代碼中成功設置? – Deathkill14

+0

@dbz,請問另一個問題。應用轉換器是什麼意思?我看到有PvBufferConverter功能來改變像素類型。這相當於我已經在做的重新分配嗎? – Deathkill14

+0

感謝您的答案@dkz。它把我推向了正確的方向。 – Deathkill14

0

我發現問題的根源。 即使將此行應用於lImagingBuffer,也會過濾l緩衝區

lContrastFilter.Apply(lImagingBuffer); 

@dkz的評價是有幫助的,因爲它讓我從像素類型和過濾器,這最終導致了校正重新調整了。