c++ - How do I get a bitmap image from raw Bayer image data (byte array)? -
i have image data gets acquired so:
unsigned char* imagedata = null; getimage(imagedata);
the imagedata
returns raw bayergr8 format: say:
g r g r g r g r ... b g b g b g b g ... g r g r g r g r ... ...
where each of pixels occupies 8 bits.
the images being grabbed 2752x2200 (pixels).
whenever set bitmap , create bitmap using image data, bitmap comes out blank. here bitmap setup:
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;
so far have tried following:
hdc hdc = ::getdc(null); hbitmap hbit = createdibitmap(hdc, globalinfoheader, cbm_init, imagedata, pbmi, dib_rgb_colors);
but said bitmap ends being blank light-gray image. have been looking on wikipedia article on bitmaps , feel may have biclrused value, have no idea value should , have far been playing numbers.
i have tried converting image data directly cimage (which later convert hbitmap) so:
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) { ( int y=0; y<nheight; ++y ) { ( int x=0; x<nwidth; ++x ) { *pcursor = *pinbuffer; ++pcursor; ++pinbuffer; } // consider stride pcursor += nstride; } } else { memcpy( poutimage->getbits(), pinbuffer, nwidth * nheight ); } } }
my question is: how take raw bayer image data , rgb color bitmap out of it?
edit:
got it. here's function created got working (interpolation method):
///////////////////////////////////////////////////////////// // convertbayer8tobgr() // converts raw bayergr8 pixels // 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 = 0; < 2752; i++) //g r g r g... { if(currenttempindex % 2 == 0 /* even, green */) { //avg blue if(j == 0) //if in first row, 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, 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 left-down blue pixel { nearestbluesavg = *(bayerimgdat+currenttempindex-1+2752); } else // else take both left-down , 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 = 0; < 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 right-up pixel { nearestredsavg = *(bayerimgdat+currenttempindex+1-2752); } else //else take both left-up , 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, take previous blue (next blue doesnt exist) { nearestbluesavg = *(bayerimgdat + currenttempindex - 1); } else //else take both next , 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, 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; }
you have interpolate components of bayer image. here's helpful link:
http://www.siliconimaging.com/rgb%20bayer.htm
look halfway down interpolation section.
as far target image goes, create stock-standard rgb 24-bit or 32-bit bitmap , set bits interpolate components bayer image.
it seems half of question colour conversion , half why bitmap code not working. there countless examples out there rgb bitmap creation in windows, won't go it.
Comments
Post a Comment