当前位置:网站首页>Convert yv12 to rgb565 image conversion, with YUV to RGB test
Convert yv12 to rgb565 image conversion, with YUV to RGB test
2022-07-02 10:47:00 【Small waves-】
background :
Many years ago , I have made a long-term playback client , There's a problem , Some monitors cannot display YV12 Video images , Need to be converted to RGB Show , Is to use such a functional method , convert , Then insert the data into Frame Display , Here is the code used .
transformation YUV420P To RGB565, And write ddraw Surface memory pdst in , First create the conversion table , Then convert each pixel .
Code
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;
// Create conversion table
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;
}
// transformation YUV420P To RGB565, And write ddraw Surface memory pdst in
//y,u,v Three vector byte sequences
//src_ystride The source of y Line width
//src_uvstride The source of uv Line width
//dst_ystride Destination row width
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;// Half the width of the image
const int height2 = height/2;// Half the height of the image
unsigned char* yoff;
unsigned char* uoff;
unsigned char* voff;
for(j=0; j<height2; j++)// Line by line
{
yoff = y + j * 2 * src_ystride;
uoff = u + j * src_uvstride;
voff = v + j * src_uvstride;
for(i=0; i<width2; i++)// Column by column cycle
{
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);
}
}
}Conversion formula
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)
Reference resources
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.
Transform function test cases
#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;
}
边栏推荐
猜你喜欢

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

Introduction and Principle notes of UE4 material

Rapid prototyping

14. Code implementation of semaphore

Sum the two numbers to find the target value

Shapiro Wilk normal analysis by SPSS

集成学习概览

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

4. Random variables

VSCode工具使用
随机推荐
02-taildir source
长投学堂上面的账户安全吗?
2021-09-12
AttributeError: type object ‘Image‘ has no attribute ‘fromarray‘
Basic usage of mock server
JS reduce accumulator
2.hacking-lab脚本关[详细writeup]
12. Process synchronization and semaphore
js setTimeout()与面试题
互联网快讯:腾讯会议应用市场正式上线;Soul赴港递交上市申请书
高考的意义是什么
pytest--之测试报告allure配置
Excuse me, is it cost-effective to insure love life patron saint 2.0 increased lifelong life insurance? What are the advantages of this product?
Sus system availability scale
Operator-1初识Operator
AttributeError: type object ‘Image‘ has no attribute ‘fromarray‘
01安装虚拟机
PCL 点云转深度图像
记录 AttributeError: ‘NoneType‘ object has no attribute ‘nextcall‘
The nanny level tutorial of flutter environment configuration makes the doctor green to the end