rgb to yuv 互相转化

说明:下面的代码用C\C++执行都可以,用C的时候请把#include<iostream> 删除。

RGB to YUV420 原代码:  RGB2YUV.CPP文件

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include<iostream>  
  5.   
  6. //转换矩阵  
  7. #define MY(a,b,c) (( a*  0.2989  + b*  0.5866  + c*  0.1145))  
  8. #define MU(a,b,c) (( a*(-0.1688) + b*(-0.3312) + c*  0.5000 + 128))  
  9. #define MV(a,b,c) (( a*  0.5000  + b*(-0.4184) + c*(-0.0816) + 128))  
  10. //大小判断  
  11. #define DY(a,b,c) (MY(a,b,c) > 255 ? 255 : (MY(a,b,c) < 0 ? 0 : MY(a,b,c)))  
  12. #define DU(a,b,c) (MU(a,b,c) > 255 ? 255 : (MU(a,b,c) < 0 ? 0 : MU(a,b,c)))  
  13. #define DV(a,b,c) (MV(a,b,c) > 255 ? 255 : (MV(a,b,c) < 0 ? 0 : MV(a,b,c)))  
  14. //只处理352*288文件  
  15. #define WIDTH 352  
  16. #define HEIGHT 288  
  17.   
  18. //读BMP  
  19. void ReadBmp(unsigned char *RGB,FILE *fp);  
  20.   
  21. //转换函数  
  22. void Convert(unsigned char *RGB, unsigned char *YUV);  
  23.   
  24. //入口  
  25. int main()  
  26. {  
  27.     int i="1";  
  28.     char file[255];  
  29.     FILE *fp;  
  30.     FILE *fp2;  
  31.     unsigned char *YUV = NULL;  
  32.     unsigned char *RGB = NULL;  
  33.     unsigned int imgSize = WIDTH*HEIGHT;  
  34.   
  35.     if((fp2 = fopen("test.cif""wb")) == NULL)//生成文件名  
  36.     {  
  37.         return 0;  
  38.     }  
  39.   
  40.     RGB = (unsigned char*)malloc(imgSize*6);  
  41.     YUV = (unsigned char*)malloc(imgSize + (imgSize>>1));  
  42.     
  43.     for(i=1; i<2; i++)  
  44.     {  
  45.         sprintf(file, "test.bmp", i);//读取文件  
  46.         if((fp = fopen(file, "rb")) == NULL)  
  47.     continue;  
  48.   
  49.         printf("打开文件%s\n", file);  
  50.         ReadBmp(RGB, fp);  
  51.         Convert(RGB, YUV);  
  52.         fwrite(YUV, 1, imgSize+(imgSize>>1), fp2);//写入文件  
  53.         fclose(fp);  
  54.     }  
  55.   
  56.     fclose(fp2);  
  57.     if(RGB)  
  58.         free(RGB);  
  59.   
  60.     if(YUV)  
  61.         free(YUV);  
  62.   
  63.     printf("完成\n");  
  64.     system("pause");  
  65.     return 1;  
  66. }  
  67.   
  68. //读BMP  
  69. void ReadBmp(unsigned char *RGB,FILE *fp)  
  70. {  
  71.     int i,j;  
  72.     unsigned char temp;  
  73.   
  74.     fseek(fp,54, SEEK_SET);  
  75.   
  76.     fread(RGB+WIDTH*HEIGHT*3, 1, WIDTH*HEIGHT*3, fp);//读取  
  77.     for(i=HEIGHT-1,j=0; i>=0; i--,j++)//调整顺序  
  78.     {  
  79.         memcpy(RGB+j*WIDTH*3,RGB+WIDTH*HEIGHT*3+i*WIDTH*3,WIDTH*3);  
  80.     }  
  81.      
  82.     //顺序调整  
  83.     for(i=0; (unsigned int)i < WIDTH*HEIGHT*3; i+=3)  
  84.     {  
  85.         temp = RGB;  
  86.         RGB = RGB[i+2];  
  87.         RGB[i+2] = temp;  
  88.     }  
  89. }  
  90.   
  91. void Convert(unsigned char *RGB, unsigned char *YUV)  
  92. {  
  93.     //变量声明  
  94.     unsigned int i,x,y,j;  
  95.     unsigned char *Y = NULL;  
  96.     unsigned char *U = NULL;  
  97.     unsigned char *V = NULL;  
  98.      
  99.     Y = YUV;  
  100.     U = YUV + WIDTH*HEIGHT;  
  101.     V = U + ((WIDTH*HEIGHT)>>2);  
  102.   
  103.     for(y=0; y < HEIGHT; y++)  
  104.         for(x=0; x < WIDTH; x++)  
  105.         {  
  106.             j = y*WIDTH + x;  
  107.             i = j*3;  
  108.             Y[j] = (unsigned char)(DY(RGB, RGB[i+1], RGB[i+2]));  
  109.   
  110.             if(x%2 == 1 && y%2 == 1)  
  111.             {  
  112.                 j = (WIDTH>>1) * (y>>1) + (x>>1);  
  113.                 //上面i仍有效  
  114.                 U[j] = (unsigned char)  
  115.                        ((DU(RGB[i  ], RGB[i+1], RGB[i+2]) +  
  116.                          DU(RGB[i-3], RGB[i-2], RGB[i-1]) +  
  117.                          DU(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +  
  118.                          DU(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);  
  119.   
  120.                 V[j] = (unsigned char)  
  121.                        ((DV(RGB[i  ], RGB[i+1], RGB[i+2]) +  
  122.                          DV(RGB[i-3], RGB[i-2], RGB[i-1]) +  
  123.                          DV(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +  
  124.                          DV(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);  
  125.             }  
  126.   
  127.         }  
  128. }  


YUV420 to RGB 原代码: yuv2rgb.cpp文件


  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <iostream>  
  4. #define WIDTH 352  
  5. #define HEIGHT 288  
  6. //转换矩阵  
  7. double YuvToRgb[3][3] = {1,       0,  1.4022,  
  8.                          1,    -0.3456, -0.7145,  
  9.                          1,   1.771,       0};  
  10.   
  11. //根据RGB三分量写BMP,不必关注  
  12. int WriteBmp(int width, int height, unsigned char *R,unsigned char *G,unsigned char *B, char *BmpFileName);  
  13.   
  14. //转换函数  
  15. int Convert(char *file, int width, int height, int n)  
  16. {  
  17.     //变量声明  
  18.     int i = 0;  
  19.     int temp = 0;  
  20.     int x = 0;  
  21.     int y = 0;  
  22.     int fReadSize = 0;  
  23.     int ImgSize = width*height;  
  24.     FILE *fp = NULL;  
  25.     unsigned char* yuv = NULL;  
  26.     unsigned char* rgb = NULL;  
  27.     unsigned char* cTemp[6];  
  28.     char BmpFileName[256];  
  29.   
  30.     //申请空间  
  31.     int FrameSize = ImgSize + (ImgSize >> 1);  
  32.     yuv = (unsigned char *)malloc(FrameSize);  
  33.     rgb = (unsigned char *)malloc(ImgSize*3);  
  34.     //读取指定文件中的指定帧  
  35.     if((fp = fopen(file, "rb")) == NULL)  
  36.         return 0;  
  37.     fseek(fp, FrameSize*(n-1), SEEK_CUR);  
  38.     fReadSize = fread(yuv, 1, FrameSize, fp);  
  39.     fclose(fp);  
  40.     if(fReadSize < FrameSize)  
  41.         return 0;  
  42.     //转换指定帧  如果你不是处理文件 主要看这里  
  43.     cTemp[0] = yuv;                        //y分量地址  
  44.     cTemp[1] = yuv + ImgSize;            //u分量地址  
  45.     cTemp[2] = cTemp[1] + (ImgSize>>2);    //v分量地址  
  46.     cTemp[3] = rgb;                        //r分量地址  
  47.     cTemp[4] = rgb + ImgSize;            //g分量地址  
  48.     cTemp[5] = cTemp[4] + ImgSize;        //b分量地址  
  49.     for(y=0; y < height; y++)  
  50.         for(x=0; x < width; x++)  
  51.         {  
  52.             //r分量  
  53.             temp = cTemp[0][y*width+x] + (cTemp[2][(y/2)*(width/2)+x/2]-128) * YuvToRgb[0][2];  
  54.             cTemp[3][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);  
  55.             //g分量  
  56.             temp = cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) * YuvToRgb[1][1]  
  57.                                        + (cTemp[2][(y/2)*(width/2)+x/2]-128) * YuvToRgb[1][2];  
  58.             cTemp[4][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);  
  59.             //b分量  
  60.             temp = cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) * YuvToRgb[2][1];  
  61.             cTemp[5][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);  
  62.         }  
  63.   
  64.     //写到BMP文件中  
  65.     sprintf(BmpFileName, "test.bmp", file, n);  
  66.     WriteBmp(width, height, cTemp[3], cTemp[4], cTemp[5], BmpFileName);  
  67.   
  68.     free(yuv);  
  69.     free(rgb);  
  70.     return n;  
  71. }  
  72. //入口 没啥东西  
  73. void main()  
  74. {  
  75.     int i="1";  
  76. //    for( i="0"; i<260; i++)  
  77.         Convert("test.cif", WIDTH, HEIGHT, i);//调用上面的Convert,获取文件的第i帧  
  78. }  
  79.   
  80. //写BMP  不必关注  
  81. int WriteBmp(int width, int height, unsigned char *R,unsigned char *G,unsigned char *B, char *BmpFileName)  
  82. {  
  83.     int x="0";  
  84.     int y="0";  
  85.     int i="0";  
  86.     int j="0";  
  87.     FILE *fp;  
  88.     unsigned char *WRGB;  
  89.     unsigned char *WRGB_Start;  
  90.     int yu = width*3%4;  
  91.     int BytePerLine = 0;  
  92.   
  93.     yu = yu!=0 ? 4-yu : yu;  
  94.     BytePerLine = width*3+yu;  
  95.   
  96.     if((fp = fopen(BmpFileName, "wb")) == NULL)  
  97.         return 0;  
  98.     WRGB = (unsigned char*)malloc(BytePerLine*height+54);  
  99.     memset(WRGB, 0, BytePerLine*height+54);  
  100.      
  101.     //BMP头  
  102.     WRGB[0] = 'B';  
  103.     WRGB[1] = 'M';  
  104.     *((unsigned int*)(WRGB+2)) = BytePerLine*height+54;  
  105.     *((unsigned int*)(WRGB+10)) = 54;  
  106.     *((unsigned int*)(WRGB+14)) = 40;  
  107.     *((unsigned int*)(WRGB+18)) = width;  
  108.     *((unsigned int*)(WRGB+22)) = height;  
  109.     *((unsigned short*)(WRGB+26)) = 1;  
  110.     *((unsigned short*)(WRGB+28)) = 24;  
  111.     *((unsigned short*)(WRGB+34)) = BytePerLine*height;  
  112.   
  113.     WRGB_Start = WRGB + 54;  
  114.   
  115.     for(y=height-1,j=0; y >= 0; y--,j++)  
  116.     {  
  117.         for(x=0,i=0; x<width; x++)  
  118.         {  
  119.             WRGB_Start[y*BytePerLine+i++] = B[j*width+x];  
  120.             WRGB_Start[y*BytePerLine+i++] = G[j*width+x];  
  121.             WRGB_Start[y*BytePerLine+i++] = R[j*width+x];  
  122.         }  
  123.     }  
  124.   
  125.     fwrite(WRGB, 1, BytePerLine*height+54, fp);  
  126.     free(WRGB);  
  127.     fclose(fp);  
  128.     return 1;  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值