2010-10-15 29 views
4

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; 
     } 
    } 
} 

Répondre

2

Aucun sont 'officiellement correct' par exemple, BT.601 applique à .DV vidéo, tandis que d'autres Appliquons à d'autres normes ...

Quelle est la source des couleurs YUV/YCbCr? Cela vous dira comment le convertir.

+0

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

+0

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