Help needed handling image data
Hi
I'm trying to use code for an encoder from a project I found on CodeGuru, but I'm not sure how to use it. This is the first method I need to use:
Code:
//
// Convert from RGB24 to YUV420
//
int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned int *yuv)
{
unsigned int *u,*v,*y,*uu,*vv;
unsigned int *pu1,*pu2,*pu3,*pu4;
unsigned int *pv1,*pv2,*pv3,*pv4;
unsigned char *r,*g,*b;
int i,j;
uu=new unsigned int[w*h];
vv=new unsigned int[w*h];
if(uu==NULL || vv==NULL)
return 0;
y=yuv;
u=uu;
v=vv;
// Get r,g,b pointers from bmp image data....
r=bmp;
g=bmp+1;
b=bmp+2;
//Get YUV values for rgb values...
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
*y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;
*u++=(-RGB2YUV_UR[*r] -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16;
*v++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
r+=3;
g+=3;
b+=3;
}
}
// Now sample the U & V to obtain YUV 4:2:0 format
// Sampling mechanism...
/* @ -> Y
# -> U or V
@ @ @ @
# #
@ @ @ @
@ @ @ @
# #
@ @ @ @
*/
// Get the right pointers...
u=yuv+w*h;
v=u+(w*h)/4;
// For U
pu1=uu;
pu2=pu1+1;
pu3=pu1+w;
pu4=pu3+1;
// For V
pv1=vv;
pv2=pv1+1;
pv3=pv1+w;
pv4=pv3+1;
// Do sampling....
for(i=0;i<h;i+=2)
{
for(j=0;j<w;j+=2)
{
*u++=(*pu1+*pu2+*pu3+*pu4)>>2;
*v++=(*pv1+*pv2+*pv3+*pv4)>>2;
pu1+=2;
pu2+=2;
pu3+=2;
pu4+=2;
pv1+=2;
pv2+=2;
pv3+=2;
pv4+=2;
}
pu1+=w;
pu2+=w;
pu3+=w;
pu4+=w;
pv1+=w;
pv2+=w;
pv3+=w;
pv4+=w;
}
delete uu;
delete vv;
return 1;
}
------------------------------------------------------------------------------------------
Now, my input will be bmp, which is an unsigned char. The image I have is a IplImage, which has this structure:
Code:
// IPL image header
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* ignored by OpenCV */
int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */
char colorModel[4]; /* ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style) */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead */
int width; /* image width in pixels */
int height; /* image height in pixels */
struct _IplROI *roi;/* image ROI. when it is not NULL, this specifies image region to process */
struct _IplImage *maskROI; /* must be NULL in OpenCV */
void *imageId; /* ditto */
struct _IplTileInfo *tileInfo; /* ditto */
int imageSize; /* image data size in bytes
(=image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* pointer to aligned image data */
int widthStep; /* size of aligned image row in bytes */
int BorderMode[4]; /* border completion mode, ignored by OpenCV */
int BorderConst[4]; /* ditto */
char *imageDataOrigin; /* pointer to a very origin of image data
(not necessarily aligned) -
it is needed for correct image deallocation */
}
----------------------------------------------------------------------------------------
On the other side, I have an IplImage to DIB conversor, like this:
Code:
HBITMAP IplImageWidget::IplImage2DIB(const IplImage* Image){
int bpp = Image->nChannels * 8;
assert(Image->width >= 0 && Image->height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
CvMat dst;
void* dst_ptr = 0;
HBITMAP hbmp = NULL;
unsigned char buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
ZeroMemory(bmih, sizeof(BITMAPINFOHEADER));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = Image->width;
bmih->biHeight = Image->origin ? abs(Image->height) : -abs(Image->height);
bmih->biPlanes = 1;
bmih->biBitCount = bpp;
bmih->biCompression = BI_RGB;
if (bpp == 8) {
RGBQUAD* palette = bmi->bmiColors;
int i;
for (i = 0; i < 256; i++) {
palette[i].rgbRed = palette[i].rgbGreen = palette[i].rgbBlue = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
hbmp = CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, &dst_ptr, 0, 0);
cvInitMatHeader(&dst, Image->height, Image->width, CV_8UC3,
dst_ptr, (Image->width * Image->nChannels + 3) & -4);
cvConvertImage(Image, &dst, Image->origin ? CV_CVTIMG_FLIP : 0);
return hbmp;
}
------------------------------------------------------------------------------------
So, coming from the IplImage or the DIB, what can I use so that I get something that works with ConvertRGB2YUV?
Thanks
Re: Help needed handling image data
Please put your code in [code] tags so I can read it :).
The idea is that if you have access to pixel data then you can pass that to the function. It will return the RGB data converted to YUV, so you don't have to worry about too much things, because these two spaces have both 3 components.
You might wanna write your won conversion routine and understand what actually happens.
You can read this, if you like:
http://www.fourcc.org/fccyvrgb.php
Regards
Re: Help needed handling image data
Please attach large amounts of code instead of pasting it directly. And if you do paste code, embed it into [code] tags.