2013-05-13 163 views
2

我有被收購,像這樣的圖像數據:如何從原始Bayer圖像數據(字節數組)獲取位圖圖像?

unsigned char* imageData = NULL; 
GetImage(imageData); 

imageData返回爲原料BayerGR8格式:即:

G R G R G R G R ... 
B G B G B G B G ... 
G R G R G R G R ... 
     ... 

其中每個那些像素佔據8位。

正在抓取的圖像是2752x2200(像素)。

每當我設置一個位圖,然後使用這個圖像數據創建一個位圖,位圖總是空白。這裏是我的位圖設置:

BITMAPFILEHEADER* bf = new BITMAPFILEHEADER; 
    bf->bfType = 0x4d42; 
    bf->bfSize = 6054400 + 54 + sizeof(BITMAPINFO); 
    bf->bfOffBits = 54; 

    BITMAPINFOHEADER* bih = new BITMAPINFOHEADER; 
    bih->biSize = 40; 
    bih->biWidth = 2752; 
    bih->biHeight = 2200; 
    bih->biPlanes = 1; 
    bih->biBitCount = 8; 
    bih->biCompression = 0; 
    bih->biXPelsPerMeter = 2835; 
    bih->biYPelsPerMeter = 2835; 
    bih->biClrUsed = 0; 
    bih->biClrImportant = 0; 

到目前爲止,我已經試過如下:

HDC hdc = ::GetDC(NULL); 
HBITMAP hbit = CreateDIBitmap(hdc, globalinfoheader, CBM_INIT, imageData, pbmi, DIB_RGB_COLORS); 

但正如我所說的位圖最終是一個空白淺灰色圖像。我一直在尋找維基百科關於位圖的文章,我覺得它可能與biClrUsed值有關,但我不知道它應該是什麼樣的價值,並且迄今爲止一直在玩這些數字。

我也曾嘗試將圖像數據直接轉換成的CImage(我後來轉換爲HBITMAP),像這樣:

void ConvertImageBufferToCImage(unsigned char *pInBuffer, CImage *pOutImage) 
{ 
    if (NULL != *pOutImage) 
    { 
     unsigned char *pCursor = (unsigned char*)pOutImage->GetBits(); 
     int nHeight = 2200; 
     int nWidth = 2752; 
     int nStride = 0; 

     if (0 < nStride) 
     { 
      for (int y=0; y<nHeight; ++y) 
      { 
       for (int x=0; x<nWidth; ++x) 
       { 
        *pCursor = *pInBuffer; 
        ++pCursor; 
        ++pInBuffer; 
       } 
       // Consider stride 
       pCursor += nStride; 
      } 
     } 
     else 
     { 
      memcpy(pOutImage->GetBits(), pInBuffer, nWidth * nHeight); 
     } 
    } 
} 

我的問題是:我怎麼把我的原始拜耳圖像數據並從中獲得一個RGB顏色位圖?

編輯:

明白了。這裏是我創建的函數(插值方法):

///////////////////////////////////////////////////////////// 
// ConvertBayer8ToBgr() 
// Converts raw BayerGR8 pixels into 
//  BGR pixels. 
// 
// G | R | G | R    B G R | B G R | B G R | B G R 
// --- --- --- ---   ------- ------- ------- ------- 
// B | G | B | G  |\ B G R | B G R | B G R | B G R 
// --- --- --- --- ----- \ ------- ------- ------- ------- 
// G | R | G | R -----/ B G R | B G R | B G R | B G R 
// --- --- --- ---  |/ ------- ------- ------- ------- 
// B | G | B | G    B G R | B G R | B G R | B G R 
// 
///////////////////////////////////////////////////////////// 
void ConvertBayer8ToBGR(VmbUchar_t* bayerImgDat, VmbUchar_t* bgrOutputDat) 
{ 
    VmbUchar_t* newimagedata_start = bgrOutputDat; 

    int currentTempIndex = 0; 
    int nearestBluesAvg = 0; 
    int nearestRedsAvg = 0; 
    int nearestGreensAvg = 0; 

    for(int j = 0; j < 1100; j++) 
    { 
     for(int i = 0; i < 2752; i++) //G R G R G... 
     { 
      if(currentTempIndex % 2 == 0 /* even, green */) 
      { 
       //avg blue 
       if(j == 0) //if in the first row, only take next blue 
       { 
        nearestBluesAvg = *(bayerImgDat+currentTempIndex+2752); 
       } 
       else 
       { 
        nearestBluesAvg = (*(bayerImgDat + currentTempIndex + 2752) + *(bayerImgDat+currentTempIndex-2752))/2; 
       } 
       *bgrOutputDat = nearestBluesAvg; //b 
       bgrOutputDat++; 
       *bgrOutputDat = *(bayerImgDat + currentTempIndex); //g 
       bgrOutputDat++; 
       //avg red 
       if(i == 0) //if in first column, only take next red 
       { 
        nearestRedsAvg = *(bayerImgDat+currentTempIndex+1); 
       } 
       else 
       { 
        nearestRedsAvg = ((*(bayerImgDat+currentTempIndex+1)) + (*(bayerImgDat+currentTempIndex-1)))/2; 
       } 
       *bgrOutputDat = nearestRedsAvg; //r 
       bgrOutputDat++; 

       currentTempIndex++; 
      } 
      else /* odd, red*/ 
      { 
       //avg blue 
       if(i == 1099) //if in last column, take just left-down blue pixel 
       { 
        nearestBluesAvg = *(bayerImgDat+currentTempIndex-1+2752); 
       } 
       else // else take both left-down and right-down 
       { 
        nearestBluesAvg = (*(bayerImgDat+currentTempIndex+1+2752) + *(bayerImgDat+currentTempIndex-1+2752))/2; 
       } 
       *bgrOutputDat = nearestBluesAvg; //b 
       bgrOutputDat++; 
       //avg green 
       nearestGreensAvg = (*(bayerImgDat+currentTempIndex-1) + *(bayerImgDat+currentTempIndex+2752))/2; 
       *bgrOutputDat = nearestGreensAvg; //g 
       bgrOutputDat++; 
       *bgrOutputDat = *(bayerImgDat + currentTempIndex); //r 
       bgrOutputDat++; 

       currentTempIndex++; 
      } 
     } 
     for(int i = 0; i < 2752; i++)//B G B G B G B.... 
     { 
      if(currentTempIndex % 2 == 0 /* even, blue */) 
      { 

       *bgrOutputDat = *(bayerImgDat + currentTempIndex); //b 
       bgrOutputDat++; 
       //avg green 
       nearestGreensAvg = (*(bayerImgDat + currentTempIndex + 1) + *(bayerImgDat + currentTempIndex -2752))/2; 
       *bgrOutputDat = nearestGreensAvg; //g 
       bgrOutputDat++; 
       //avg red 
       if(i == 0) //if first column, take only right-up pixel 
       { 
        nearestRedsAvg = *(bayerImgDat+currentTempIndex+1-2752); 
       } 
       else //else take both left-up and right-up pixels 
       { 
        nearestRedsAvg = (*(bayerImgDat+currentTempIndex-1-2752) + *(bayerImgDat+currentTempIndex+1-2752))/2; 
       } 
       *bgrOutputDat = nearestRedsAvg; //r 
       bgrOutputDat++; 

       currentTempIndex++; 

      } 
      else /* odd, green*/ 
      { 
       //avg blue 
       if(i == 2751) //if in last column, only take previous blue (next blue doesnt exist) 
       { 
        nearestBluesAvg = *(bayerImgDat + currentTempIndex - 1); 
       } 
       else //else take both next and previous 
       { 
        nearestBluesAvg = (*(bayerImgDat+currentTempIndex+1) + *(bayerImgDat+currentTempIndex-1))/2; 
       } 
       *bgrOutputDat = nearestBluesAvg; //b 
       bgrOutputDat++; 
       *bgrOutputDat = *(bayerImgDat + currentTempIndex); //g 
       bgrOutputDat++; 
       //avg red 
       if(j == 1099) //if in last row, only take previous red (next red doesn't exist) 
       { 
        nearestRedsAvg = *(bayerImgDat+currentTempIndex-2752); 
       } 
       else //else take both 
       { 
        nearestRedsAvg = (*(bayerImgDat+currentTempIndex+2752) + *(bayerImgDat+currentTempIndex-2752))/2; 
       } 
       *bgrOutputDat = nearestRedsAvg; //r 
       bgrOutputDat++; 

       currentTempIndex++; 
      } 
     } 
    } 


    bgrOutputDat = newimagedata_start; 
} 

回答

2

您必須插入拜耳圖像的組件。下面是一個有用的鏈接:

http://www.siliconimaging.com/RGB%20Bayer.htm

看一半,即可進行插值段。

就目標圖像而言,只需創建一個庫存標準RGB 24位或32位位圖,並在插入拜耳圖像中的組件時設置位。

你的問題似乎有一半是關於顏色轉換的,一半是關於你的位圖代碼不工作的原因。在那裏有無數的例子可以在Windows中創建RGB位圖,所以我不會進入它。