yuv转opencv中的IplImage

来源:互联网 发布:长歌门成男脸型数据 编辑:程序博客网 时间:2024/05/16 11:05

一个小的程序,在网上找了很久没有发现

自己搞了一个大家看看

第一个是很笨的办法:

yuv三个分量分别写在3个矩阵下,然后合并之后转换为rgb分量的图片格式就可以了;

代码如下:

[html] view plaincopyprint?
  1. IplImage *image,*rgbimg,*yimg,*uimg,*vimg,*uuimg,*vvimg;
  2. rgbimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);
  3. image = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);
  4. yimg = cvCreateImageHeader(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
  5. uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
  6. vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
  7. uuimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
  8. vvimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
  9. cvSetData(yimg,pBuf, nWidth);
  10. cvSetData(uimg,pBuf+nWidth*nHeight, nWidth/2);
  11. cvSetData(vimg,pBuf+long(nWidth*nHeight*1.25), nWidth/2);
  12. cvResize(uimg,uuimg,CV_INTER_LINEAR);
  13. cvResize(vimg,vvimg,CV_INTER_LINEAR);
  14. cvMerge(yimg,uuimg,vvimg,NULL,image);
  15. cvCvtColor(image,rgbimg,CV_YCrCb2BGR);

还有一个方法就比较负载

首先自己根据原理转换为rgb格式

然后利用cvSetData()函数写入数据生成IplImage格式的图片

首先定义转换的公式:

[html] view plaincopyprint?
  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)))

yuv转rgb的函数:

[html] view plaincopyprint?
  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. unsigned char* pBGR = NULL;
  7. unsigned char R = 0;
  8. unsigned char G = 0;
  9. unsigned char B = 0;
  10. char Y = 0;
  11. char U = 0;
  12. char V = 0;
  13. double tmp = 0;
  14. for ( int i = 0; i<height; ++i )
  15. {
  16. for ( int j = 0; j<width; ++j )
  17. {
  18. pBGR = pRGB+ i*width*3+j*3;
  19. Y = *(pY+i*width+j);
  20. U = *pU;
  21. V = *pV;
  22. //B
  23. tmp = MB(Y, U, V);
  24. //B = (tmp > 255) ? 255 : (char)tmp;
  25. //B = (B<0) ? 0 : B;
  26. B = (unsigned char)tmp;
  27. //G
  28. tmp = MG(Y, U, V);
  29. //G = (tmp > 255) ? 255 : (char)tmp;
  30. // G = (G<0) ? 0 : G;
  31. G = (unsigned char)tmp;
  32. //R
  33. tmp = MR(Y, U, V);
  34. //R = (tmp > 255) ? 255 : (char)tmp;
  35. //R = (R<0) ? 0 : R;
  36. R = (unsigned char)tmp;
  37. *pBGR = R;
  38. *(pBGR+1) = G;
  39. *(pBGR+2) = B;
  40. if ( i%2 == 0 && j%2 == 0)
  41. {
  42. *pU++;
  43. //*pV++;
  44. }
  45. else
  46. {
  47. if ( j%2 == 0 )
  48. {
  49. *pV++ ;
  50. }
  51. }
  52. }
  53. }
  54. }

最后是写入IplImage的代码:

[html] view plaincopyprint?
  1. unsigned char* pRGB = NULL;
  2. pRGB = (unsigned char*)malloc(nSize*sizeof(unsigned char*)*2);
  3. YUV420_C_RGB(pBuf,pRGB,nWidth,nHeight);
  4. IplImage *image;
  5. image = cvCreateImageHeader(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);
  6. 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*************************************/
voidRGB_C_YUV420(char* pRGB, char* pYUV, intheight,intwidth)
{
char* pY = pYUV;
char* pU = pYUV+height*width;
char* pV = pU+(height*width/4);
char* pBGR = NULL;
charR = 0;
charG = 0;
charB = 0;
charY = 0;
charU = 0;
charV = 0;
doubletmp = 0;
for(inti = 0; i < height; ++i )
{
for(intj = 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;
}
}
}
}
}

0 0