欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RGB与YUV文件的互转

程序员文章站 2022-07-14 22:06:23
...

RGB转YUV公式
Y=0.2990R+0.5870G+0.1140B
U=-0.1684R-0.3316G+0.5B+128
V=0.5R-0.4187G-0.0813B+128
YUV转RGB公式
R=Y+1.13983*(V-128)
G=Y-0.39465*(U-128)-0.58260*(V-128)
B=Y+2.03211+(U-128)

原始的RGB文件(不知道为什么YUVViewer看rgb文件上下是颠倒的)
RGB与YUV文件的互转
代码如下

#include <iostream>
#include<stdio.h>
using namespace std;
int main(int argc,char* argv[])
{
    void Lookuptable();
    float aaa = RGBYUV00813[25];
    FILE* rgbFILE = NULL;
    FILE* yuvFILE = NULL;
    rgbFILE = fopen("down.rgb", "rb");
    yuvFILE = fopen("argv[2]", "wb");
    fseek(rgbFILE, 0L, SEEK_END);
    int size_rgb;
    size_rgb = ftell(rgbFILE);
    cout << size_rgb << endl;
    fseek(rgbFILE, 0L, SEEK_SET);//必须回到文件开始,不然读取不到需要的信息
    unsigned char* RGB_BUFFER = new unsigned char[size_rgb];
    unsigned char* Y_BUFFER = new unsigned char[size_rgb / 3];
    unsigned char* U_BUFFER = new unsigned char[size_rgb / 12];
    unsigned char* V_BUFFER = new unsigned char[size_rgb / 12];
    fread(RGB_BUFFER, sizeof(unsigned char), size_rgb, rgbFILE);
    for (int i = 0; i < size_rgb; i=i+3)
    {
        int b = RGB_BUFFER[i];
        int g = RGB_BUFFER[i + 1];
        int r = RGB_BUFFER[i + 2];
        int j = i / 3;
        Y_BUFFER[j] = 0.2990*r + 0.5870*g + 0.1140*b;
        cout << "deal Y" <<i<< endl;
    }
    for (int i = 0; i < size_rgb; i=i + 12)
    {
        int b = RGB_BUFFER[i];
        int g = RGB_BUFFER[i + 1];
        int r = RGB_BUFFER[i + 2];
        int j = i / 12;
        U_BUFFER[j] = -0.1684*r - 0.3316*g +0.5000*b+128;
        cout << "deal U" <<i<< endl;
    }
    for (int i = 0; i < size_rgb; i=i + 12)
    {
        int b = RGB_BUFFER[i];
        int g = RGB_BUFFER[i + 1];
        int r = RGB_BUFFER[i + 2];
        int j = i / 12;
        V_BUFFER[j] = 0.5000*r - 0.4187*g - 0.0813*b+128;
        cout << "deal V" <<i<< endl;
    }
    fwrite(Y_BUFFER, sizeof(unsigned char), 256 * 256, yuvFILE);
    fwrite(U_BUFFER, sizeof(unsigned char), 256 * 256/4, yuvFILE);
    fwrite(V_BUFFER, sizeof(unsigned char), 256 * 256/4, yuvFILE);
    fclose(rgbFILE);
    fclose(yuvFILE);
    free(RGB_BUFFER);
    free(Y_BUFFER);
    free(U_BUFFER);
    free(V_BUFFER);
}

转换之后的YUV文件
RGB与YUV文件的互转
YUV转RGB
代码如下

#include <iostream>
#include<stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
    FILE* rgbFILE = NULL;
    FILE* yuvFILE = NULL;
    rgbFILE = fopen("argv[4]", "wb");
    yuvFILE = fopen("argv[3].yuv", "rb");
    fseek(yuvFILE, 0L, SEEK_END);
    int size_yuv;
    size_yuv = ftell(yuvFILE);
    cout <<size_yuv << endl;
    fseek(yuvFILE, 0L, SEEK_SET);
    unsigned char* RGB_BUFFER = new unsigned char[size_yuv*2];
    unsigned char* Y_BUFFER = new unsigned char[size_yuv * 2 / 3];
    unsigned char* U_BUFFER = new unsigned char[size_yuv / 6];
    unsigned char* V_BUFFER = new unsigned char[size_yuv / 6];
    long ylength = size_yuv * 2 / 3;
    long ulength = size_yuv / 6;
    cout << ylength << "     " << ulength << endl;
    fread(Y_BUFFER, sizeof(unsigned char), size_yuv * 2 / 3, yuvFILE);
    fseek(yuvFILE, 65536L, SEEK_SET);//利用偏移量将一个文件读入不同数组
    fread(U_BUFFER, sizeof(unsigned char), size_yuv / 6, yuvFILE);
    fseek(yuvFILE, 81920L, SEEK_SET);
    fread(V_BUFFER, sizeof(unsigned char), size_yuv / 6, yuvFILE);
    for (int i = 0; i < size_yuv*2; i = i + 3)
    {
        RGB_BUFFER[i] = Y_BUFFER[i/3]+2.03211*(U_BUFFER[i/12]-128);
        RGB_BUFFER[i + 1] = Y_BUFFER[i/3]-0.39465*(U_BUFFER[i/12]-128)-0.58060*(V_BUFFER[i/12]-128);
        RGB_BUFFER[i + 2] = Y_BUFFER[i/3]+1.13983*(V_BUFFER[i/12]-128);
        //cout << i << endl;
    }
    fwrite(RGB_BUFFER, sizeof(unsigned char),size_yuv*2, rgbFILE);
    fclose(rgbFILE);
    fclose(yuvFILE);
    free(RGB_BUFFER);
    free(Y_BUFFER);
    free(U_BUFFER);
    free(V_BUFFER);
}

转换后的RGB文件
RGB与YUV文件的互转
部分区域出现了明显的色块
原因可能是由于YUV转RGB的过程中一组相邻的像素共用色度信息,就会导致同一色调的像素聚集产生色块。