当前位置:网站首页>转换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;
}
边栏推荐
- How to judge the quality of primary market projects when the market is depressed?
- 2021-09-12
- Network real-time video streaming based on OpenCV
- 2.14 is it Valentine's day or Valentine's day when the mainstream market continues to fluctuate and wait for changes?
- [leetcode] sword finger offer 53 - I. find the number I in the sorted array
- webUI自动化学习
- MYSQL环境配置
- [Lua] summary of common knowledge points (including common interview sites)
- Remember the use of add method once
- Delivery mode design of Spartacus UI of SAP e-commerce cloud
猜你喜欢
虛幻AI藍圖基礎筆記(萬字整理)
Pytest-- test report allure configuration
2021-10-02
Blender stone carving
stm32和電機開發(上比特系統)
AutoCAD - layer Linetype
JS reduce accumulator
[pit avoidance guide] pit encountered using ugui: the text component cannot indent the first line by two spaces
2021-10-02
[MySQL] an exception occurs when connecting to MySQL: connection must be valid and open
随机推荐
pytest学习--base
Beautiful and intelligent, Haval H6 supreme+ makes Yuanxiao travel safer
[unity3d] cannot correctly obtain the attribute value of recttransform, resulting in calculation error
Translation d30 (with AC code POJ 28:sum number)
Pytest framework implements pre post
【教程】如何让VisualStudio的HelpViewer帮助文档独立运行
12.进程同步与信号量
Determine whether there are duplicate elements in the array
Delivery mode design of Spartacus UI of SAP e-commerce cloud
lunix重新分配root 和 home 空间内存
[unity3d] production progress bar - make image have the functions of filled and sliced at the same time
4.随机变量
Blender摄像机环绕运动、动画渲染、视频合成
Edge computing accelerates live video scenes: clearer, smoother, and more real-time
【Unity3D】嵌套使用Layout Group制作拥有动态子物体高度的Scroll View
[unity3d] nested use layout group to make scroll view with dynamic sub object height
【Lua】常见知识点汇总(包含常见面试考点)
Introduction and Principle notes of UE4 material
ue4材质的入门和原理笔记
《MySQL 8 DBA基础教程》简介