当前位置:网站首页>转换YV12到RGB565图像转换,附YUV转RGB测试
转换YV12到RGB565图像转换,附YUV转RGB测试
2022-07-02 06:50:00 【微澜-】
背景:
许多年前,自己做了很久的播放客户端,遇到了一个问题,有些显示器无法显示YV12视频图像,需要转换为RGB显示,就是用了这么个函数方法,进行转换,然后把数据塞给Frame进行显示,下面是使用的代码。
转换YUV420P到RGB565,并写入ddraw表面显存pdst中,先创建转换表,然后把每一个像素进行转换。
代码
int* colortab;
int* u_b_tab;
int* u_g_tab;
int* v_g_tab;
int* v_r_tab;
unsigned int * r_2_pix;
unsigned int * g_2_pix;
unsigned int * b_2_pix;
//创建转换表
void CreateYUVTab()
{
int i;
int u, v;
colortab = (int *)malloc(4*256*sizeof(int));
u_b_tab = &colortab[0*256];
u_g_tab = &colortab[1*256];
v_g_tab = &colortab[2*256];
v_r_tab = &colortab[3*256];
for (i=0; i<256; i++)
{
u = v = (i-128);
u_b_tab[i] = (int) ( 1.772 * u);
u_g_tab[i] = (int) ( 0.34414 * u);
v_g_tab[i] = (int) ( 0.71414 * v);
v_r_tab[i] = (int) ( 1.402 * v);
}
rgb_2_pix = (unsigned int *)malloc(3*768*sizeof(unsigned int));
r_2_pix = &rgb_2_pix[0*768];
g_2_pix = &rgb_2_pix[1*768];
b_2_pix = &rgb_2_pix[2*768];
for(i=0; i<256; i++)
{
r_2_pix[i] = 0;
g_2_pix[i] = 0;
b_2_pix[i] = 0;
}
for(i=0; i<256; i++)
{
r_2_pix[i+256] = (i & 0xF8) << 8;
g_2_pix[i+256] = (i & 0xFC) << 3;
b_2_pix[i+256] = (i ) >> 3;
}
for(i=0; i<256; i++)
{
r_2_pix[i+512] = 0xF8 << 8;
g_2_pix[i+512] = 0xFC << 3;
b_2_pix[i+512] = 0x1F;
}
r_2_pix += 256;
g_2_pix += 256;
b_2_pix += 256;
}
//转换YUV420P到RGB565,并写入ddraw表面显存pdst中
//y,u,v 三个向量字节序列
//src_ystride 源的y行宽
//src_uvstride 源的uv行宽
//dst_ystride 目的行宽
void DisplayYUV(unsigned int *pdst, unsigned char *y, unsigned char *u, unsigned char *v, int width, int height, int src_ystride, int src_uvstride, int dst_ystride)
{
int i, j;
int r, g, b, rgb;
int yy, ub, ug, vg, vr;
const int width2 = width/2;//图像宽的一半
const int height2 = height/2;//图像高的一半
unsigned char* yoff;
unsigned char* uoff;
unsigned char* voff;
for(j=0; j<height2; j++)//逐行循环
{
yoff = y + j * 2 * src_ystride;
uoff = u + j * src_uvstride;
voff = v + j * src_uvstride;
for(i=0; i<width2; i++)//逐列循环
{
yy = *(yoff+(i<<1));
ub = u_b_tab[*(uoff+i)];
ug = u_g_tab[*(uoff+i)];
vg = v_g_tab[*(voff+i)];
vr = v_r_tab[*(voff+i)];
b = yy + ub;
g = yy - ug - vg;
r = yy + vr;
rgb = r_2_pix[r] + g_2_pix[g] + b_2_pix[b];
yy = *(yoff+(i<<1)+1);
b = yy + ub;
g = yy - ug - vg;
r = yy + vr;
pdst[(j*dst_ystride+i)] = (rgb)+((r_2_pix[r] + g_2_pix[g] + b_2_pix[b])<<16);
yy = *(yoff+(i<<1)+src_ystride);
b = yy + ub;
g = yy - ug - vg;
r = yy + vr;
rgb = r_2_pix[r] + g_2_pix[g] + b_2_pix[b];
yy = *(yoff+(i<<1)+src_ystride+1);
b = yy + ub;
g = yy - ug - vg;
r = yy + vr;
pdst [((2*j+1)*dst_ystride+i*2)>>1] = (rgb)+((r_2_pix[r] + g_2_pix[g] + b_2_pix[b])<<16);
}
}
}转换公式
RGB to YUV Conversion
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
YUV to RGB Conversion
B = 1.164(Y - 16) + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)
参考
http://forum.videohelp.com/topic290086.html
I played a little with the code, and I found the right conversion formulas:
#define GETR(y,u,v) ((1.164 * (y - 16)) + (1.596 * ((v) - 128)))
#define GETG(y,u,v) ((1.164 * (y - 16)) - (0.813 * ((v) - 128)) - (0.391 * ((u) - 128)))
#define GETB(y,u,v) ((1.164 * (y - 16)) + (2.018 * ((u) - 128)))
Images seems to be in the right color using these formulas.
转换函数测试用例
#include <TIME.H>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
void YUV2RGB(unsigned char Y, unsigned char U, unsigned char V, unsigned char* pRGB)
{
int R, G, B;
B = (int)(1.164*(Y - 16) + 2.018*(U - 128));
G = (int)(1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128));
R = (int)(1.164*(Y - 16) + 1.596*(V - 128));
// #define GETR(y,u,v) ((1.164 * (y - 16)) + (1.596 * ((v) - 128)))
// #define GETG(y,u,v) ((1.164 * (y - 16)) - (0.813 * ((v) - 128)) - (0.391 * ((u) - 128)))
// #define GETB(y,u,v) ((1.164 * (y - 16)) + (2.018 * ((u) - 128)))
//cout << "RGB("<<GETR(y,u,v)<<","<<GETG(y,u,v)<<","<<GETB(y,u,v)<<","<<")"<<endl;
//cout << "("<<(int)Y<<","<<(int)U<<","<<(int)V<<")->RGB("<<R<<","<<G<<","<<B<<","<<")"<<endl;
R= min(255,max(0,R));
G= min(255,max(0,G));
B= min(255,max(0,B));
pRGB[0] = R ;
pRGB[1] = G;
pRGB[2] = B;
return;
}
void RGB2YUV(unsigned char R, unsigned char G, unsigned char B, unsigned char* pYUV)
{
int Y, U, V;
Y = 16 + 0.257*R + 0.504*G + 0.098*B;
U = 128 - 0.148*R - 0.291*G + 0.439*B;
V = 128 + 0.439*R - 0.368*G - 0.071*B;
Y= min(255,max(0,Y));
U= min(255,max(0,U));
V= min(255,max(0,V));
pYUV[0] = Y;
pYUV[1] = U;
pYUV[2] = V;
return;
}
int __cdecl main (int argc, CHAR **argv)
{
unsigned char RGB[3];
unsigned char YUV[3];
int r=255,g=0,b=0;
RGB2YUV(r, g, b, YUV);
cout << "("<<(unsigned int)(YUV[0])<<","<<(unsigned int)(YUV[1])<<","<<(unsigned int)(YUV[2])<<")->RGB("<<r<<","<<g<<","<<b<<","<<")"<<endl;
int y=(unsigned int)(YUV[0]),u=(unsigned int)(YUV[1]),v=(unsigned int)(YUV[2]);
YUV2RGB(y, u, v, RGB);
cout << "("<<(int)y<<","<<(int)u<<","<<(int)v<<")->RGB("<<(unsigned int)(RGB[0])<<","<<(unsigned int)(RGB[1])<<","<<(unsigned int)(RGB[2])<<","<<")"<<endl;
system( "PAUSE" );
return 0;
}
边栏推荐
- Importing tables from sqoop
- Blender海洋制作
- Mongodb quickly get started with some simple operations of mongodb command line
- 高考的意义是什么
- Deep understanding of redis cache avalanche / cache breakdown / cache penetration
- 虚幻材质编辑器基础——如何连接一个最基本的材质
- 使用Windbg静态分析dump文件(实战经验总结)
- Basic usage of mock server
- Use WinDbg to statically analyze dump files (summary of practical experience)
- KS009基于SSH实现宠物管理系统
猜你喜欢

ue4材质的入门和原理笔记

MYSQL环境配置

VLAN experiment

stm32和電機開發(上比特系統)

Beautiful and intelligent, Haval H6 supreme+ makes Yuanxiao travel safer

Allure -- common configuration items

Use WinDbg to statically analyze dump files (summary of practical experience)

The primary market project galaxy will conduct public offering on coinlist on February 17

pytest框架实现前后置

2021-10-02
随机推荐
【虚幻4】UMG组件的简介与使用(更新中...)
Blender volume fog
【Unity3D】制作进度条——让Image同时具有Filled和Sliced的功能
SQOOP 1.4.6 INSTALL
STM32 and motor development (upper system)
2.14 is it Valentine's day or Valentine's day when the mainstream market continues to fluctuate and wait for changes?
Pytest-- test report allure configuration
"Talking about podcasts" vol.352 the age of children: breaking the inner scroll, what can we do before high school?
Blender海洋制作
VLAN experiment
Blender camera surround motion, animation rendering, video synthesis
Aiphacode is not a substitute for programmers, but a tool for developers
02-taildir source
MYSQL关键字
数据库字典Navicat自动生成版本
What is the significance of the college entrance examination
[Fantasy 4] introduction and use of UMG components (under update...)
AI技术产业热点分析
Applet development summary
Test -- Summary of interview questions