YUV420数据转为IplImage格式



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的函数:

[cpp]  view plain copy
    1. #define MR(Y,U,V) (Y + (1.403)*(V-128))  
    2. #define MG(Y,U,V) (Y - (0.344) * (U-128) - (0.714) * (V-128) )   
    3. #define MB(Y,U,V) (Y + ((1.773) * (U-128)))  

  1. void YUV420_C_RGB( char* pYUV, unsigned char* pRGB, int height, int width)  
  2. {  
  3.     char* pY = pYUV;  
  4.     char* pU = pYUV+height*width;  
  5.     char* pV = pU+(height*width/4);  
  6.   
  7.   
  8.     unsigned char* pBGR = NULL;  
  9.     unsigned char R = 0;  
  10.     unsigned char G = 0;  
  11.     unsigned char B = 0;  
  12.     char Y = 0;  
  13.     char U = 0;  
  14.     char V = 0;  
  15.     double tmp = 0;  
  16.     for ( int i = 0; i < height; ++i )  
  17.     {  
  18.         for ( int j = 0; j < width; ++j )  
  19.         {  
  20.             pBGR = pRGB+ i*width*3+j*3;  
  21.   
  22.             Y = *(pY+i*width+j);  
  23.             U = *pU;  
  24.             V = *pV;  
  25.   
  26.             //B  
  27.             tmp = MB(Y, U, V);  
  28.             //B = (tmp > 255) ? 255 : (char)tmp;  
  29.             //B = (B<0) ? 0 : B;  
  30.             B = (unsigned char)tmp;  
  31.             //G  
  32.             tmp = MG(Y, U, V);  
  33.             //G = (tmp > 255) ? 255 : (char)tmp;  
  34.            // G = (G<0) ? 0 : G;  
  35.             G = (unsigned char)tmp;  
  36.             //R  
  37.             tmp = MR(Y, U, V);  
  38.             //R = (tmp > 255) ? 255 : (char)tmp;  
  39.             //R = (R<0) ? 0 : R;  
  40.             R = (unsigned char)tmp;  
  41.   
  42.   
  43.             *pBGR     = R;              
  44.             *(pBGR+1) = G;          
  45.             *(pBGR+2) = B;  
  46.           
  47.   
  48.             if ( i%2 == 0 && j%2 == 0)  
  49.             {  
  50.                 *pU++;  
  51.                 //*pV++;  
  52.             }  
  53.             else  
  54.             {  
  55.                 if ( j%2 == 0 )  
  56.                 {  
  57.                     *pV++ ;  
  58.                 }  
  59.             }  
  60.         }  
  61.       
  62.     }  
  63. }  

你可能感兴趣的:(YUV420数据转为IplImage格式)