我是Gem,今天做个简单的视频,我的耳机坏了,不好意思,没有声音,请原谅~~
  
    时间很仓促,我把作业全部做完了,完整的过程我演示你看看,有什么问题请你指出来~~

详细的代码说明和友好的界面(用MFC做),即将给出,如果你感兴趣,请时刻关注我的Blog: http://hexun.com/ctfysj

我们开始,在C++ 里面我建立了两个工程,一个是RGB2YUV,另一个是yuv2rgb的,我们先看看RGB2YUV

看我操作~~~

RGB2YUV420 演示:

用的图片是你给我的test.bmp,把test.bmp文件拷到工程目录下 E:\网站文件夹\YUV420和RGB相互转换\homework\RGB2YUV
   
    我转换成YUV420时候,存储在test.cif

看我生成这种文件啊~~

编译:  0 error(s), 0 warning(s)

这种效果可以吗? 应该还行吧~~

现在再看 RGB2YUV420 演示

RGB2YUV420 演示:

把上面生成的test.cif文件拷到工程目录下  E:\网站文件夹\YUV420和RGB相互转换\homework\yuv2rgb

还原成test.bmp文件
   
    编译:0 error(s), 0 warning(s)

还原后,差不多吧,反正我没有看出来有什么区别~~

完整的代码 : 在 RGBYUV420代码完整版.txt 记事本里面

慕容听雨
    个人主页:http://hexun.com/ctfysj
    QQ:308463776

说明:下面的代码用C\C++执行都可以,用C的时候请把#include<iostream> 删除。
       代码的详细说明视频即将推出,请时刻关注我的Blog: http://hexun.com/ctfysj

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>

//转换矩阵
#define MY(a,b,c) (( a*  0.2989  + b*  0.5866  + c*  0.1145))
#define MU(a,b,c) (( a*(-0.1688) + b*(-0.3312) + c*  0.5000 + 128))
#define MV(a,b,c) (( a*  0.5000  + b*(-0.4184) + c*(-0.0816) + 128))
//大小判断
#define DY(a,b,c) (MY(a,b,c) > 255 ? 255 : (MY(a,b,c) < 0 ? 0 : MY(a,b,c)))
#define DU(a,b,c) (MU(a,b,c) > 255 ? 255 : (MU(a,b,c) < 0 ? 0 : MU(a,b,c)))
#define DV(a,b,c) (MV(a,b,c) > 255 ? 255 : (MV(a,b,c) < 0 ? 0 : MV(a,b,c)))
//只处理352*288文件
#define WIDTH 352
#define HEIGHT 288

//读BMP
void ReadBmp(unsigned char *RGB,FILE *fp);

//转换函数
void Convert(unsigned char *RGB, unsigned char *YUV);

//入口
int main()
{
    int i=1;
    char file[255];
    FILE *fp;
    FILE *fp2;
    unsigned char *YUV = NULL;
    unsigned char *RGB = NULL;
    unsigned int imgSize = WIDTH*HEIGHT;

if((fp2 = fopen("test.cif", "wb")) == NULL)//生成文件名
    {
        return 0;
    }

RGB = (unsigned char*)malloc(imgSize*6);
    YUV = (unsigned char*)malloc(imgSize + (imgSize>>1));
  
    for(i=1; i<2; i++)
    {
        sprintf(file, "test.bmp", i);//读取文件
        if((fp = fopen(file, "rb")) == NULL)
    continue;

printf("打开文件%s\n", file);
        ReadBmp(RGB, fp);
        Convert(RGB, YUV);
        fwrite(YUV, 1, imgSize+(imgSize>>1), fp2);//写入文件
        fclose(fp);
    }

fclose(fp2);
    if(RGB)
        free(RGB);

if(YUV)
        free(YUV);

printf("完成\n");
    system("pause");
    return 1;
}

//读BMP
void ReadBmp(unsigned char *RGB,FILE *fp)
{
    int i,j;
    unsigned char temp;

fseek(fp,54, SEEK_SET);

fread(RGB+WIDTH*HEIGHT*3, 1, WIDTH*HEIGHT*3, fp);//读取
    for(i=HEIGHT-1,j=0; i>=0; i--,j++)//调整顺序
    {
        memcpy(RGB+j*WIDTH*3,RGB+WIDTH*HEIGHT*3+i*WIDTH*3,WIDTH*3);
    }
   
    //顺序调整
    for(i=0; (unsigned int)i < WIDTH*HEIGHT*3; i+=3)
    {
        temp = RGB[i];
        RGB[i] = RGB[i+2];
        RGB[i+2] = temp;
    }
}

void Convert(unsigned char *RGB, unsigned char *YUV)
{
    //变量声明
    unsigned int i,x,y,j;
    unsigned char *Y = NULL;
    unsigned char *U = NULL;
    unsigned char *V = NULL;
   
    Y = YUV;
    U = YUV + WIDTH*HEIGHT;
    V = U + ((WIDTH*HEIGHT)>>2);

for(y=0; y < HEIGHT; y++)
        for(x=0; x < WIDTH; x++)
        {
            j = y*WIDTH + x;
            i = j*3;
            Y[j] = (unsigned char)(DY(RGB[i], RGB[i+1], RGB[i+2]));

if(x%2 == 1 && y%2 == 1)
            {
                j = (WIDTH>>1) * (y>>1) + (x>>1);
                //上面i仍有效
                U[j] = (unsigned char)
                       ((DU(RGB[i  ], RGB[i+1], RGB[i+2]) +
                         DU(RGB[i-3], RGB[i-2], RGB[i-1]) +
                         DU(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +
                         DU(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);

V[j] = (unsigned char)
                       ((DV(RGB[i  ], RGB[i+1], RGB[i+2]) +
                         DV(RGB[i-3], RGB[i-2], RGB[i-1]) +
                         DV(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +
                         DV(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);
            }

}
}

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

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define WIDTH 352
#define HEIGHT 288
//转换矩阵
double YuvToRgb[3][3] = {1,       0,  1.4022,
                         1,    -0.3456, -0.7145,
                         1,   1.771,       0};

//根据RGB三分量写BMP,不必关注
int WriteBmp(int width, int height, unsigned char *R,unsigned char *G,unsigned char *B, char *BmpFileName);

//转换函数
int Convert(char *file, int width, int height, int n)
{
    //变量声明
    int i = 0;
    int temp = 0;
    int x = 0;
    int y = 0;
    int fReadSize = 0;
    int ImgSize = width*height;
    FILE *fp = NULL;
    unsigned char* yuv = NULL;
    unsigned char* rgb = NULL;
    unsigned char* cTemp[6];
    char BmpFileName[256];

//申请空间
    int FrameSize = ImgSize + (ImgSize >> 1);
    yuv = (unsigned char *)malloc(FrameSize);
    rgb = (unsigned char *)malloc(ImgSize*3);
    //读取指定文件中的指定帧
    if((fp = fopen(file, "rb")) == NULL)
        return 0;
    fseek(fp, FrameSize*(n-1), SEEK_CUR);
    fReadSize = fread(yuv, 1, FrameSize, fp);
    fclose(fp);
    if(fReadSize < FrameSize)
        return 0;
    //转换指定帧  如果你不是处理文件 主要看这里
    cTemp[0] = yuv;                        //y分量地址
    cTemp[1] = yuv + ImgSize;            //u分量地址
    cTemp[2] = cTemp[1] + (ImgSize>>2);    //v分量地址
    cTemp[3] = rgb;                        //r分量地址
    cTemp[4] = rgb + ImgSize;            //g分量地址
    cTemp[5] = cTemp[4] + ImgSize;        //b分量地址
    for(y=0; y < height; y++)
        for(x=0; x < width; x++)
        {
            //r分量
            temp = cTemp[0][y*width+x] + (cTemp[2][(y/2)*(width/2)+x/2]-128) * YuvToRgb[0][2];
            cTemp[3][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);
            //g分量
            temp = cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) * YuvToRgb[1][1]
                                       + (cTemp[2][(y/2)*(width/2)+x/2]-128) * YuvToRgb[1][2];
            cTemp[4][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);
            //b分量
            temp = cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) * YuvToRgb[2][1];
            cTemp[5][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 : temp);
        }

//写到BMP文件中
    sprintf(BmpFileName, "test.bmp", file, n);
    WriteBmp(width, height, cTemp[3], cTemp[4], cTemp[5], BmpFileName);

free(yuv);
    free(rgb);
    return n;
}
//入口 没啥东西
void main()
{
    int i=1;
//    for( i=0; i<260; i++)
        Convert("test.cif", WIDTH, HEIGHT, i);//调用上面的Convert,获取文件的第i帧
}

//写BMP  不必关注
int WriteBmp(int width, int height, unsigned char *R,unsigned char *G,unsigned char *B, char *BmpFileName)
{
    int x=0;
    int y=0;
    int i=0;
    int j=0;
    FILE *fp;
    unsigned char *WRGB;
    unsigned char *WRGB_Start;
    int yu = width*3%4;
    int BytePerLine = 0;

yu = yu!=0 ? 4-yu : yu;
    BytePerLine = width*3+yu;

if((fp = fopen(BmpFileName, "wb")) == NULL)
        return 0;
    WRGB = (unsigned char*)malloc(BytePerLine*height+54);
    memset(WRGB, 0, BytePerLine*height+54);
   
    //BMP头
    WRGB[0] = 'B';
    WRGB[1] = 'M';
    *((unsigned int*)(WRGB+2)) = BytePerLine*height+54;
    *((unsigned int*)(WRGB+10)) = 54;
    *((unsigned int*)(WRGB+14)) = 40;
    *((unsigned int*)(WRGB+18)) = width;
    *((unsigned int*)(WRGB+22)) = height;
    *((unsigned short*)(WRGB+26)) = 1;
    *((unsigned short*)(WRGB+28)) = 24;
    *((unsigned short*)(WRGB+34)) = BytePerLine*height;

WRGB_Start = WRGB + 54;

for(y=height-1,j=0; y >= 0; y--,j++)
    {
        for(x=0,i=0; x<width; x++)
        {
            WRGB_Start[y*BytePerLine+i++] = B[j*width+x];
            WRGB_Start[y*BytePerLine+i++] = G[j*width+x];
            WRGB_Start[y*BytePerLine+i++] = R[j*width+x];
        }
    }

fwrite(WRGB, 1, BytePerLine*height+54, fp);
    free(WRGB);
    fclose(fp);
    return 1;
}

视频和代码下载地址:

ftp://ctfysj.kongjian.in:***@ctfysj.kongjian.in/视频教学文件/homework.rar

***是密码,为了隐私,不能告诉别人,如你需要,请回复邮箱

密码:

**** 本内容跟帖回复才可浏览 *****

文件名: homework.rar

下载链接: http://cachefile5.fs2you.com/zh-cn/download/d643ef1aee1a19187dd0850c5259e48d/homework.rar

转载于:https://www.cnblogs.com/Gemgin/archive/2013/06/13/3136479.html

视频教程:YUV420和RGB相互转换--C++实现(二)相关推荐

  1. 图片格式之YUV420 转RGB格式(含代码)

    在数字图像处理种YUV格式也是我们经常遇到,与RGB一样也是一种编码格式,开始主要用于电视系统以及模拟视频领域.YUV,分为三个分量,"Y"表示明亮度(Luminance或Luma ...

  2. YUV RGB 相互转换矩阵

    YUV RGB 相互转换矩阵 不同色域下的转换矩阵 "BT2020 625 D65" RGB2XYZ Matrix: XYZ2RGB Matrix: RGB2YUV Matrix: ...

  3. bgr与rgb相互转换

    在opencv中的图像是以bgr形式存放的,但很多场景默认的是rgb形式的图像,这就导致实际应用中的颜色错乱,以下是bgr和rgb相互转换的函数: def rgb_bgr(r_color):r_col ...

  4. YUV420转YUV444 , YUV420转RGB

    我想大家应该知道了YUV的颜色表示原理即: Y = 0.299R + 0.587G + 0.114B  U = -0.147R - 0.289G + 0.436B  V = 0.615R - 0.51 ...

  5. Mixed Reality Martial Arts Training using Real-time 3D Human Pose Forecasting with a RGB Camera(翻译二)

    Implementation 本系统主要由两部分组成:单幅图像的三维姿态预测和虚拟现实中的模型拟合与碰撞检测.如图2所示,姿态预测由三个模块组成:二维姿态估计.二维姿态预测和三维姿态恢复.这三个模块在 ...

  6. 【视频教程】UG NX CAM 加工模块二次开发 视频教程

    教程简介: 本套 NX CAM 加工模块二次开发视频教程由胡君录制,教程详细的讲解了关于NX加工模块开发的各个知识点,以及同时使用UFun.NXOpen两种方式来对CAM模块开发的方法(详细请查看以下 ...

  7. 图像处理-HSV和RGB相互转换

    1.实现RGB到HSV的转换函数,函数声明:HSV RGB2HSV(COLORREF c) 函数功能:把COLORREF类对象c的颜色信息转换成一个HSV类对象返回. 代码: #include< ...

  8. php cms使用视频教程,PHPCMS v9视频模块使用教程二

    三.使用 1.本地上传.前面的步骤都完成后既可以使用视频模块了,可以直接在视频库管理中添加视频,也可以在视频模型的栏目添加内容是选择上传.视频文件是直接上传到酷6服务器的,需要一段上传和审核时间.完成 ...

  9. Lab图,RGB图,灰度图,二值图的联系

    https://blog.csdn.net/luxialan/article/details/39293069

最新文章

  1. QT制作窗口切换的小程序
  2. 【c语言】蓝桥杯算法提高 c++_ch02_02
  3. C++string类型与C语言字符数组的转换 std::string.c_str()函数
  4. 神策军丨优秀 Leader 养成记:多做简单又有效的事
  5. 【.NET架构】BIM软件架构02:Web管控平台后台架构
  6. 关于flink的setCommitOffsetsOnCheckpoints
  7. Markdown引用图片,且不使用网上链接的解决方法
  8. 矩阵快速幂(附模板)
  9. 微信登录接口报错:40163 code been used, hints: [ req_id: xXyYHa12345678 ]
  10. 图像频域增强:傅里叶变换
  11. 基于java宿舍管理系统的开题报告_基于Java的学生宿舍管理系统开题报告
  12. (附源码)ssmJavaEE无人机数据管理系统 毕业设计 111022
  13. PyTorch与PyTorch Geometric的安装
  14. 边缘计算的100个术语
  15. 软件构架实践-构架模式、参考模型、参考构架
  16. 2021年全球开关收入大约4944.1百万美元,预计2028年达到6146.3百万美元
  17. Js 代替eval的方法
  18. 物理学家眼中的世界:编程的未来
  19. html5背景图片铺满整个背景
  20. Matlab 常用语句

热门文章

  1. 数据库系统知识总结(一):数据库系统基础知识
  2. yy直播接口开发手册php,微信小程序 服务端接口·直播间接口
  3. nvm下载node版本缓慢问题
  4. Sketch在线版免费使用,Windows也能用的Sketch!
  5. 大数据分析案例-基于随机森林算法构建人口普查分析模型
  6. lesson2--html-css基础主要知识点
  7. java定时任务工具详解之Quartz
  8. TuShare Pro 股票期货数据提取神器(Python)
  9. Python numpy.atleast_3d函数方法的使用
  10. Nsight system(nsys)