Donar $20 Donar $50 Donar $100 Donar mensualmente
 


Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Buscar en el tema
[Aporte] RGB24 to YUYV/YUV422
Autor Mensaje
sebasthian777 Sin conexión
Presidente del CEIT
mi propio camino NINGA
********

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 1.923
Agradecimientos dados: 44
Agradecimientos: 23 en 20 posts
Registro en: Nov 2011
Mensaje: #1
[Aporte] RGB24 to YUYV/YUV422
Quiero compartir con ustedes algo que me rompió las bolas mucho tiempo. Nunca lo pude encontrar de forma simple en internet y aunque hoy por hoy ya no se usa tanto, es algo copado para tener guardadito.

Este codigo convierte una imagen RGB de 24 en YUV422 o mas bien, YUYV...

http://en.wikipedia.org/wiki/YUV

Hay varios ejemplos dando vuelta de como convertir YUYV a RGB, pero realmente no hay casi nada de como ir pa el otro lado...

EL ejemplo que voy a poner a continuación, no es del todo correcto, porque no utiliza la formula "del todo correcta" sino mas bien una aproximación lograda por un promediado. Pero que resulta bastante eficiente. de una imagen de 500x500 pixeles le pifia a 50/100 pixeles, lo que es algo bastante aceptable, si luego le queremos aplicar algún filtro. Y el error se encuentra solo cuando el cambio de color en el borde, es muy brusco.



double matrix[3][3] = { 0.299, 0.587, 0.114, /* Y */
-0.169, 0.331, 0.499, /* U */
0.499, -0.418, -0.0813 }; /* V */
byte * newRGB24toYUYV(byte* buffer, int width, int height)
{
int MacroWidth = width / 2;
byte * buffYUYV = new byte[width*height*2];

int contadorYUYV = 0;
for( int fil = 0; fil < height; fil++ )
{
for( int mP = 0; mP < MacroWidth; mP++ )
{
//Tengo que procesar 6 bytes
//Que son 2 pixeles
//Y tengo que generar 4 bytes
//que es un macropixel
int pos = (fil*MacroWidth*6)//Cantidad de filas concretadas
+
(mP*6) //Columna actual
;

//Obtengo todos los bytes de los dos pixeles
byte R1 = buffer[pos];
byte G1 = buffer[pos+1];
byte B1 = buffer[pos+2];
byte R2 = buffer[pos+3];
byte G2 = buffer[pos+4];
byte B2 = buffer[pos+5];

//Convierto 6 Bytes RGB a macropixel de 4 Bytes YUYV
/*byte Y1 = matrix[0][0] * R1 + matrix[0][1] * G1 + matrix[0][2] * B1;

byte U = (
(matrix[1][0] * R1 - matrix[1][1] * G1 + matrix[1][2] * B1 + 128)
+
(matrix[1][0] * R2 - matrix[1][1] * G2 + matrix[1][2] * B2 + 128)
);
U -= U >> 1;

byte Y2 = matrix[0][0] * R2 + matrix[0][1] * G2 + matrix[0][2] * B2;

byte V = (
(matrix[2][0] * R1 + matrix[2][1] * G1 + matrix[2][2] * B1 + 128)
+
(matrix[2][0] * R2 + matrix[2][1] * G2 + matrix[2][2] * B2 + 128)
);
V -= V >> 1;*/

byte Y1 = (0.299 * R1) + ( 0.587 * G1 ) + (0.114 * B1);
byte Y2 = (0.299 * R2) + ( 0.587 * G2 ) + (0.114 * B2);
byte U = ( ( (-0.169*R1)-(0.331*G1)+(0.499*B1)+128 ) + ( (-0.169*R2)-(0.331*G2)+(0.499*B2)+128 ) ) ;
byte V = ( ((0.499*R1)-(0.418*G1)-(0.0813*B1)+128) + ((0.499*R2)-(0.418*G2)-(0.0813*B2)+128));
U -= U >> 1;
V -= V >> 1;

buffYUYV[contadorYUYV] = Y1; contadorYUYV++;

buffYUYV[contadorYUYV] = U; contadorYUYV++;

buffYUYV[contadorYUYV] = Y2; contadorYUYV++;

buffYUYV[contadorYUYV] = V; contadorYUYV++;

}
}
return buffYUYV;
}


Puede que tenga errores, no la testie del todo bien... (En los proximos dias la voy a tener que usar MUCHO, asi que si le encuentro algo, lo modifico)



De yapa les dejo la funcion de YUYVtoRGB24



#define LIMIT(x) ( (x) > 0xffff ? 0xff : ( (x) <= 0xff ? 0 : ( (x) >> 8 ) ) )
//SI X>65535 X=255 || SI 255=>X>65535 = 0 || SINO lo multiplico por 32

void YUYVtoRGB24(int width, int height, unsigned char *src, unsigned char *dst)
{
int line, col, linewidth;
int y, yy;
int u, v;
int vr, ug, vg, ub;
int r, g, b;
unsigned char *py, *pu, *pv;
linewidth = width - (width >> 1);
py = src+((height-1)*width*2);
pu = py + 1;
pv = py + 3;
y = *py;
yy = y << 8;
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;
for (line = height-20; line >= 0; line--)
{
py = src+(line*width*2);
pu = py + 1;
pv = py + 3;
for (col = 0; col < width; col++)
{
r = LIMIT(yy + vr);
g = LIMIT(yy - ug - vg);
b = LIMIT(yy + ub );
*dst++ = b;
*dst++ = g;
*dst++ = r;
py += 2;
y = *py;
yy = y << 8;
if ( (col & 1) == 1)
{
pu += 4;
pv += 4;
}
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = vr*+128;
vg = 183 * v;
vr = 359 * v;
}
}
}



Esta ultima si esta ultra perfeccionada =P, aunque como me dijeron una vez, todo codigo que no necesita ser mejorado, es sospechoso =P

ahi lo edite JAJAJA error grotesco en el contador de bytes "pos"

Nueva edición, otro error, pero en el promedio...

(19-11-2013 11:48).py escribió:  
(19-11-2013 11:46)sebasthian777 escribió:  
(19-11-2013 11:43).py escribió:  Terminemos Hurd.
Prefiero dejarle ese laburo a gente sin vida social y que no tenga sexo.
Cuando te casas? Asi voy armando el Gannt.
(Este mensaje fue modificado por última vez en: 16-09-2013 09:26 por sebasthian777.)
11-09-2013 09:27
Visita su sitio web Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] sebasthian777 recibio 1 Gracias por este post
brunodiaz (11-09-2013)
sebasthian777 Sin conexión
Presidente del CEIT
mi propio camino NINGA
********

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 1.923
Agradecimientos dados: 44
Agradecimientos: 23 en 20 posts
Registro en: Nov 2011
Mensaje: #2
RE: [Aporte] RGB24 to YUYV/YUV422
ATENCION!!!! LA MATRIZ estaba MAL!!! MUY MAL!
jaja

comente una parte del codigo y la sustitui como para que quede en evidencia cual fue el cambio!

salu2

(19-11-2013 11:48).py escribió:  
(19-11-2013 11:46)sebasthian777 escribió:  
(19-11-2013 11:43).py escribió:  Terminemos Hurd.
Prefiero dejarle ese laburo a gente sin vida social y que no tenga sexo.
Cuando te casas? Asi voy armando el Gannt.
16-09-2013 09:27
Visita su sitio web Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Buscar en el tema
Enviar respuesta 




Usuario(s) navegando en este tema: 1 invitado(s)



    This forum uses Lukasz Tkacz MyBB addons.