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文件上下是颠倒的)
代码如下
#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文件
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文件
部分区域出现了明显的色块
原因可能是由于YUV转RGB的过程中一组相邻的像素共用色度信息,就会导致同一色调的像素聚集产生色块。
上一篇: 实现RGB文件与YUV文件相互转化