Il existe de nombreuses conversions de couleurs différentes pour YUV, mais elles ont toutes des résultats différents! Lequel est officiellement correct?Conversion vers l'espace colorimétrique YUV/YCbCr - nombreuses versions
Ceci est la sortie de mon programme de test. J'ai l'entrée R = 128 G = 50 B = 50 (la valeur maximum est 255). Le tableau affiche les valeurs YUV converties et les valeurs RVB reconverties (qui ne correspondent pas à l'original).
./ColourConversion.exe 128 50 50
Y U V R G B Name
===============================================================================
0 0 0 128 50 50 a) Original RGB Values
79 116 162 128 50 49 b) Microsoft MSDN integer maths
78 116 162 126 49 47 c) ITU-R BT.601
73 120 162 127 49 49 d) HDTV ITU-R BT.709
73 114 202 176 25 48 e) RGB to full-range YCbCr
78 116 162 126 49 47 f) Book 'Video Demystified'
Voici mon code (en C#):
using System;
namespace ColourConversion
{
class MainClass
{
//Turn on debug to enter RGB values in 'red, geen & blue'
public static bool debug = true;
public static int red = 128;
public static int green = 50;
public static int blue = 50;
//for printTidy()
public static string alphabet = "abcdefghijklmnopqrstuvwxyz";
public static int testCount = 0;
public static void Main (string[] args)
{
//init variables
int r, g, b, R, G, B, Y, U, V, C, D, E;
r = g = b = R = G = B = Y = U = V = C = D = E = 0;
//read user input if not in debug mode
if (!debug) {
if (args.Length < 3) {
//Print CLI usage
Console.WriteLine ("Enter RGB values in the format:");
Console.WriteLine ("ColourConversion.exe 255 255 255");
return;
} else {
r = clip(int.Parse (args[0]));
g = clip(int.Parse (args[1]));
b = clip(int.Parse (args[2]));
}
}else{
r = clip(red);
g = clip(green);
b = clip(blue);
}
//write table header
Console.Write("Y".PadLeft(10));
Console.Write("U".PadLeft(10));
Console.Write("V".PadLeft(10));
Console.Write("R".PadLeft(10));
Console.Write("G".PadLeft(10));
Console.Write("B".PadLeft(10));
Console.WriteLine(" Name");
Console.WriteLine("===============================================================================");
printTidy(Y,U,V,r,g,b, "Original RGB Values");
//---------------------------------------------------------------
//Microsoft MSDN integer maths
//http://msdn.microsoft.com/en-us/library/ms893078
R = r;
G = g;
B = b;
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
C = Y - 16;
D = U - 128;
E = V - 128;
R = clip ((298 * C + 409 * E + 128) >> 8);
G = clip ((298 * C - 100 * D - 208 * E + 128) >> 8);
B = clip ((298 * C + 516 * D + 128) >> 8);
printTidy(Y,U,V,R,G,B, "Microsoft MSDN integer maths");
//---------------------------------------------------------------
//ITU-R BT.601
//http://www.equasys.de/colorconversion.html
R = r;
G = g;
B = b;
//http://www.equasys.de/equasysRGB_YCbCrColorConversionSDTV.png
Y = clip(16 + (0.257 * R + 0.504 * G + 0.098 * B));
U = clip(128 + (-0.148 * R + -0.291 * G + 0.439 * B));
V = clip(128 + (0.439 * R + -0.368 * G + -0.071 * B));
//http://www.equasys.de/equasysYCbCr_RGBColorConversionSDTV.png
R = clip(1.164 * (Y - 16) + 0.0 * (U - 128) + 1.596 * (V - 128));
G = clip(1.164 * (Y - 16) + -0.392 * (U - 128) + -0.813 * (V - 128));
B = clip(1.164 * (Y - 16) + 2.017 * (U - 128) + 0.0 * (V - 128));
printTidy(Y,U,V,R,G,B, "ITU-R BT.601");
//---------------------------------------------------------------
//HTDV ITU-R BT.709
//http://www.equasys.de/colorconversion.html
R = r;
G = g;
B = b;
//http://www.equasys.de/equasysRGB_YCbCrColorConversionHDTV.png
Y = clip(16 + ((0.183 * R) + (0.614 * G) + (0.062 * B)));
U = clip(128 + ((-0.101 * R) + (-0.339 * G) + (0.439 * B)));
V = clip(128 + ((0.439 * R) + (-0.399 * G) + (-0.040 * B)));
//http://www.equasys.de/equasysYCbCr_RGBColorConversionHDTV.png
R = clip((1.164 * (Y-16)) + (0.0 * (U-128)) + (1.793 * (V-128)));
G = clip((1.164 * (Y-16)) + (-0.213 * (U-128)) + (-0.533 * (V-128)));
B = clip((1.164 * (Y-16)) + (2.112 * (U-128)) + (0.0 * (V-128)));
printTidy(Y,U,V,R,G,B, "HDTV ITU-R BT.709");
//---------------------------------------------------------------
//RGB to full-range YCbCr
//http://www.equasys.de/colorconversion.html
R = r;
G = g;
B = b;
//http://www.equasys.de/equasysRGB_FullRangeYCbCrColorConversion.png
Y = clip(0.0 + ((0.299 * R) + (0.587 * G) + (0.114 * B)));
U = clip(128.0 + ((-0.169 * R) + (-0.331 * G) + (0.500 * B)));
V = clip(128.0 + ((0.500 * R) + (0.419 * G) + (-0.081 * R)));
//http://www.equasys.de/equasysFullRangeYCbCr_RGBColorConversion.png
R = clip((1.0 * Y) + (0.0 * (U - 128)) + (1.4 * (V - 128)));
G = clip((1.0 * Y) + (-0.343 * (U - 128)) + (-0.711 * (V - 128)));
B = clip((1.0 * Y) + (1.765 * (U - 128)) + (0.0 * (V - 128)));
printTidy(Y,U,V,R,G,B, "RGB to full-range YCbCr");
//---------------------------------------------------------------
//Book 'Video Demystified' ISBN 1-878707-09-4
//http://www.fourcc.org/fccyvrgb.php
R = r;
G = g;
B = b;
Y = clip((0.257 * R) + (0.504 * G) + (0.098 * B) + 16);
V = clip((0.439 * R) - (0.368 * G) - (0.071 * B) + 128);
U = clip(-(0.148 * R) - (0.291 * G) + (0.439 * B) + 128);
B = clip(1.164*(Y - 16) + 2.018*(U - 128));
G = clip(1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128));
R = clip(1.164*(Y - 16) + 1.596*(V - 128));
printTidy(Y,U,V,R,G,B, "Book 'Video Demystified'");
}
//Print output in a nice form
public static void printTidy(int Y,int U,int V,int R,int G,int B, string methodName)
{
Console.Write(Y.ToString().PadLeft(10));
Console.Write(U.ToString().PadLeft(10));
Console.Write(V.ToString().PadLeft(10));
Console.Write(R.ToString().PadLeft(10));
Console.Write(G.ToString().PadLeft(10));
Console.Write(B.ToString().PadLeft(10));
Console.WriteLine(" " + alphabet[testCount++] + ") " + methodName);
return;
}
//overload for clip() - converts double to int
public static int clip (double d)
{
return clip((int)d);
}
//clips int to between 0 and 255
public static int clip (int i)
{
if (i < 0)
return 0;
if (i > 255)
return 255;
return i;
}
}
}
La source que j'espère utiliser est une image PNG qui est de couleur 24 bits 8 bits par pixel. Je dois le convertir en YUV afin d'exécuter des tests de comparaison de qualité tels que PSNR et SSIM etc. Idéalement, je suppose que je voudrais utiliser la même conversion que ffmpeg ... – ross
Vous auriez besoin de rechercher la norme utilisée pour la conversion en/de png alors. Trouver un document de normes pour le type de fichier sera un bon point de départ. – Dave