IplImage* YUV420_To_IplImage_Opencv(unsigned char* pYUV420, int width, int height)
{
if (!pYUV420)
{
return NULL;
}
IplImage *yuvimage,*rgbimg,*yimg,*uimg,*vimg,*uuimg,*vvimg;
int nWidth = width;
int nHeight = height;
rgbimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);
yuvimage = 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,pYUV420, nWidth);
cvSetData(uimg,pYUV420+nWidth*nHeight, nWidth/2);
cvSetData(vimg,pYUV420+long(nWidth*nHeight*1.25), nWidth/2);
cvResize(uimg,uuimg,CV_INTER_LINEAR);
cvResize(vimg,vvimg,CV_INTER_LINEAR);
cvMerge(yimg,uuimg,vvimg,NULL,yuvimage);
cvCvtColor(yuvimage,rgbimg,CV_YCrCb2RGB);
cvReleaseImage(&uuimg);
cvReleaseImage(&vvimg);
cvReleaseImageHeader(&yimg);
cvReleaseImageHeader(&uimg);
cvReleaseImageHeader(&vimg);
cvReleaseImage(&yuvimage);
if (!rgbimg)
{
return NULL;
}
return rgbimg;
}
void COpenCVDlg::OnBnClickedShowImage()
{
// TODO: 在此添加控件通知处理程序代码
BYTE * yuvbuf = new BYTE[(352*288*3)/2];
FILE * f = fopen("F:\\Video.yuv","r+b");
fread( yuvbuf,1,(352*288*3)/2,f);
fclose(f);
IplImage * iplimg = YUV420_To_IplImage_Opencv( yuvbuf, 352, 288);
CvvImage img;
img.CopyOf(iplimg);
img.DrawToHDC( CClientDC(this), CRect( 0,0,352,288) );
}
2、采用数学转换的方式,代码如下:
bool YUV420_To_BGR24(unsigned char *puc_y, unsigned char *puc_u, unsigned char *puc_v, unsigned char *puc_rgb, int width_y, int height_y)
{
if (!puc_y || !puc_u || !puc_v || !puc_rgb)
{
return false;
}
//初始化变量
int baseSize = width_y * height_y;
int rgbSize = baseSize * 3;
BYTE* rgbData = new BYTE[rgbSize];
memset(rgbData, 0, rgbSize);
/* 变量声明 */
int temp = 0;
BYTE* rData = rgbData; //r分量地址
BYTE* gData = rgbData + baseSize; //g分量地址
BYTE* bData = gData + baseSize; //b分量地址
int uvIndex =0, yIndex =0;
//YUV->RGB 的转换矩阵
//double Yuv2Rgb[3][3] = {1, 0, 1.4022,
// 1, -0.3456, -0.7145,
// 1, 1.771, 0};
for(int y=0; y < height_y; y++)
{
for(int x=0; x < width_y; x++)
{
uvIndex = (y>>1) * (width_y>>1) + (x>>1);
yIndex = y * width_y + x;
/* r分量 */
temp = (int)(puc_y[yIndex] + (puc_v[uvIndex] - 128) * 1.4022);
rData[yIndex] = temp<0 ? 0 : (temp > 255 ? 255 : temp);
/* g分量 */
temp = (int)(puc_y[yIndex] + (puc_u[uvIndex] - 128) * (-0.3456) +
(puc_v[uvIndex] - 128) * (-0.7145));
gData[yIndex] = temp < 0 ? 0 : (temp > 255 ? 255 : temp);
/* b分量 */
temp = (int)(puc_y[yIndex] + (puc_u[uvIndex] - 128) * 1.771);
bData[yIndex] = temp < 0 ? 0 : (temp > 255 ? 255 : temp);
}
}
//将R,G,B三个分量赋给img_data
int widthStep = width_y*3;
for (int y = 0; y < height_y; y++)
{
for (int x = 0; x < width_y; x++)
{
puc_rgb[y * widthStep + x * 3 + 2] = rData[y * width_y + x]; //R
puc_rgb[y * widthStep + x * 3 + 1] = gData[y * width_y + x]; //G
puc_rgb[y * widthStep + x * 3 + 0] = bData[y * width_y + x]; //B
}
}
if (!puc_rgb)
{
return false;
}
delete [] rgbData;
return true;
}
IplImage* YUV420_To_IplImage(unsigned char* pYUV420, int width, int height)
{
if (!pYUV420)
{
return NULL;
}
//初始化变量
int baseSize = width*height;
int imgSize = baseSize*3;
BYTE* pRGB24 = new BYTE[imgSize];
memset(pRGB24, 0, imgSize);
/* 变量声明 */
int temp = 0;
BYTE* yData = pYUV420; //y分量地址
BYTE* uData = pYUV420 + baseSize; //u分量地址
BYTE* vData = uData + (baseSize>>2); //v分量地址
if(YUV420_To_BGR24(yData, uData, vData, pRGB24, width, height) == false || !pRGB24)
{
return NULL;
}
IplImage *image = cvCreateImage(cvSize(width, height), 8,3);
memcpy(image->imageData, pRGB24, imgSize);
if (!image)
{
return NULL;
}
delete [] pRGB24;
return image;
}
yuv转rgb的函数:
-
- #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;
-
-
- tmp = MB(Y, U, V);
-
-
- B = (unsigned char)tmp;
-
- tmp = MG(Y, U, V);
-
-
- G = (unsigned char)tmp;
-
- tmp = MR(Y, U, V);
-
-
- R = (unsigned char)tmp;
-
-
- *pBGR = R;
- *(pBGR+1) = G;
- *(pBGR+2) = B;
-
-
- if ( i%2 == 0 && j%2 == 0)
- {
- *pU++;
-
- }
- else
- {
- if ( j%2 == 0 )
- {
- *pV++ ;
- }
- }
- }
-
- }
- }