一个小的程序,在网上找了很久没有发现
自己搞了一个大家看看
第一个是很笨的办法:
yuv三个分量分别写在3个矩阵下,然后合并之后转换为rgb分量的图片格式就可以了;
代码如下:
IplImage *image,*rgbimg,*yimg,*uimg,*vimg,*uuimg,*vvimg; rgbimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3); image = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3); yimg = cvCreateImageHeader(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1); uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1); vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1); uuimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1); vvimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1); cvSetData(yimg,pBuf, nWidth); cvSetData(uimg,pBuf+nWidth*nHeight, nWidth/2); cvSetData(vimg,pBuf+long(nWidth*nHeight*1.25), nWidth/2); cvResize(uimg,uuimg,CV_INTER_LINEAR); cvResize(vimg,vvimg,CV_INTER_LINEAR); cvMerge(yimg,uuimg,vvimg,NULL,image); cvCvtColor(image,rgbimg,CV_YCrCb2BGR);
首先自己根据原理转换为rgb格式
然后利用cvSetData()函数写入数据生成IplImage格式的图片
首先定义转换的公式:
#define MR(Y,U,V) (Y + (1.403)*(V-128)) #define MG(Y,U,V) (Y - (0.344) * (U-128) - (0.714) * (V-128) ) #define MB(Y,U,V) (Y + ((1.773) * (U-128)))
void YUV420_C_RGB( char* pYUV, unsigned char* pRGB, int height, int width) { char* pY = pYUV; char* pU = pYUV+height*width; char* pV = pU+(height*width/4); unsigned char* pBGR = NULL; unsigned char R = 0; unsigned char G = 0; unsigned char B = 0; char Y = 0; char U = 0; char V = 0; double tmp = 0; for ( int i = 0; i < height; ++i ) { for ( int j = 0; j < width; ++j ) { pBGR = pRGB+ i*width*3+j*3; Y = *(pY+i*width+j); U = *pU; V = *pV; //B tmp = MB(Y, U, V); //B = (tmp > 255) ? 255 : (char)tmp; //B = (B<0) ? 0 : B; B = (unsigned char)tmp; //G tmp = MG(Y, U, V); //G = (tmp > 255) ? 255 : (char)tmp; // G = (G<0) ? 0 : G; G = (unsigned char)tmp; //R tmp = MR(Y, U, V); //R = (tmp > 255) ? 255 : (char)tmp; //R = (R<0) ? 0 : R; R = (unsigned char)tmp; *pBGR = R; *(pBGR+1) = G; *(pBGR+2) = B; if ( i%2 == 0 && j%2 == 0) { *pU++; //*pV++; } else { if ( j%2 == 0 ) { *pV++ ; } } } } }
unsigned char* pRGB = NULL; pRGB = (unsigned char*)malloc(nSize*sizeof(unsigned char*)*2); YUV420_C_RGB(pBuf,pRGB,nWidth,nHeight); IplImage *image; image = cvCreateImageHeader(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3); cvSetData(image,pRGB,nWidth*3);程序都运行过
编译环境为vs2008
opencv2.0版本
另外,附上RGB转YUV420格式的代码:
#define MY(R,G,B) ((0.299)*R + (0.587)*G + (0.114)*B)
#define MU(R,G,B) (-(0.169)*R - (0.332)*G+ (0.501)*B)
#define MV(R,G,B) ( (0.450)*R - (0.419)*G - (0.081)*B )
#define MR(Y,U,V) (Y + (1.403)*V)
#define MG(Y,U,V) (Y - ( (0.3455) * U - ( (0.7169) * V ) ) )
#define MB(Y,U,V) (Y + ((1.7790) * U))
/**************************rgb->yuv420*************************************/
void
RGB_C_YUV420(
char
* pRGB,
char
* pYUV,
int
height,
int
width)
{
char
* pY = pYUV;
char
* pU = pYUV+height*width;
char
* pV = pU+(height*width/4);
char
* pBGR = NULL;
char
R = 0;
char
G = 0;
char
B = 0;
char
Y = 0;
char
U = 0;
char
V = 0;
double
tmp = 0;
for
(
int
i = 0; i < height; ++i )
{
for
(
int
j = 0; j < width; ++j )
{
pBGR = pRGB+ i*width*3+j*3;
B = *pBGR;
G = *(pBGR+1);
R = *(pBGR+2);
//Y
Y = MY(R,G,B);
//U
U = MU(R,G,B);
//V
V = MV(R,G,B);
*(pY+i*width+j) = Y;
if
( i%2 == 0 && j%2 == 0)
{
*pU = U;
pU++;
}
else
{
if
( j%2 == 0 )
{
*pV++ = V;
}
}
}
}
}