2013-05-13 203 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位图,所以我不会进入它。