YUV转IPLImage(RGB)
原帖地址:http://blog.csdn.net/dreamd1987/article/details/7259479
一个小的程序,在网上找了很久没有发现
自己搞了一个大家看看
第一个是很笨的办法:
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);
- 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)))
- #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)))
yuv转rgb的函数:
- 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++ ;
- }
- }
- }
- }
- }
- 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++ ;
- }
- }
- }
- }
- }
最后是写入IplImage的代码:
- 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);
- 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版本