[Python-checkins] cpython: Issue #14323: Expanded the number of digits in the coefficients for the

serhiy.storchaka python-checkins at python.org
Tue Aug 6 10:52:03 CEST 2013


http://hg.python.org/cpython/rev/80e9cb6163b4
changeset:   85050:80e9cb6163b4
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Aug 06 11:51:23 2013 +0300
summary:
  Issue #14323: Expanded the number of digits in the coefficients for the
RGB -- YIQ conversions so that they match the FCC NTSC versions.

files:
  Doc/whatsnew/3.4.rst      |   7 +++++
  Lib/colorsys.py           |  18 ++++++++++----
  Lib/test/test_colorsys.py |  32 +++++++++++++++++++++++---
  Misc/NEWS                 |   3 ++
  4 files changed, 51 insertions(+), 9 deletions(-)


diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -251,6 +251,13 @@
 
 The module supports new file types: door, event port and whiteout.
 
+colorsys
+--------
+
+The number of digits in the coefficients for the RGB --- YIQ conversions have
+been expanded so that they match the FCC NTSC versions.  The change in
+results should be less than 1% and may better match results found elsewhere.
+
 
 Optimizations
 =============
diff --git a/Lib/colorsys.py b/Lib/colorsys.py
--- a/Lib/colorsys.py
+++ b/Lib/colorsys.py
@@ -33,17 +33,25 @@
 # YIQ: used by composite video signals (linear combinations of RGB)
 # Y: perceived grey level (0.0 == black, 1.0 == white)
 # I, Q: color components
+#
+# There are a great many versions of the constants used in these formulae.
+# The ones in this library uses constants from the FCC version of NTSC.
 
 def rgb_to_yiq(r, g, b):
     y = 0.30*r + 0.59*g + 0.11*b
-    i = 0.60*r - 0.28*g - 0.32*b
-    q = 0.21*r - 0.52*g + 0.31*b
+    i = 0.74*(r-y) - 0.27*(b-y)
+    q = 0.48*(r-y) + 0.41*(b-y)
     return (y, i, q)
 
 def yiq_to_rgb(y, i, q):
-    r = y + 0.948262*i + 0.624013*q
-    g = y - 0.276066*i - 0.639810*q
-    b = y - 1.105450*i + 1.729860*q
+    # r = y + (0.27*q + 0.41*i) / (0.74*0.41 + 0.27*0.48)
+    # b = y + (0.74*q - 0.48*i) / (0.74*0.41 + 0.27*0.48)
+    # g = y - (0.30*(r-y) + 0.11*(b-y)) / 0.59
+
+    r = y + 0.9468822170900693*i + 0.6235565819861433*q
+    g = y - 0.27478764629897834*i - 0.6356910791873801*q
+    b = y - 1.1085450346420322*i + 1.7090069284064666*q
+
     if r < 0.0:
         r = 0.0
     if g < 0.0:
diff --git a/Lib/test/test_colorsys.py b/Lib/test/test_colorsys.py
--- a/Lib/test/test_colorsys.py
+++ b/Lib/test/test_colorsys.py
@@ -1,4 +1,4 @@
-import unittest, test.support
+import unittest
 import colorsys
 
 def frange(start, stop, step):
@@ -69,8 +69,32 @@
             self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb))
             self.assertTripleEqual(rgb, colorsys.hls_to_rgb(*hls))
 
-def test_main():
-    test.support.run_unittest(ColorsysTest)
+    def test_yiq_roundtrip(self):
+        for r in frange(0.0, 1.0, 0.2):
+            for g in frange(0.0, 1.0, 0.2):
+                for b in frange(0.0, 1.0, 0.2):
+                    rgb = (r, g, b)
+                    self.assertTripleEqual(
+                        rgb,
+                        colorsys.yiq_to_rgb(*colorsys.rgb_to_yiq(*rgb))
+                    )
+
+    def test_yiq_values(self):
+        values = [
+            # rgb, yiq
+            ((0.0, 0.0, 0.0), (0.0, 0.0, 0.0)), # black
+            ((0.0, 0.0, 1.0), (0.11, -0.3217, 0.3121)), # blue
+            ((0.0, 1.0, 0.0), (0.59, -0.2773, -0.5251)), # green
+            ((0.0, 1.0, 1.0), (0.7, -0.599, -0.213)), # cyan
+            ((1.0, 0.0, 0.0), (0.3, 0.599, 0.213)), # red
+            ((1.0, 0.0, 1.0), (0.41, 0.2773, 0.5251)), # purple
+            ((1.0, 1.0, 0.0), (0.89, 0.3217, -0.3121)), # yellow
+            ((1.0, 1.0, 1.0), (1.0, 0.0, 0.0)), # white
+            ((0.5, 0.5, 0.5), (0.5, 0.0, 0.0)), # grey
+        ]
+        for (rgb, yiq) in values:
+            self.assertTripleEqual(yiq, colorsys.rgb_to_yiq(*rgb))
+            self.assertTripleEqual(rgb, colorsys.yiq_to_rgb(*yiq))
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -202,6 +202,9 @@
 Library
 -------
 
+- Issue #14323: Expanded the number of digits in the coefficients for the
+  RGB -- YIQ conversions so that they match the FCC NTSC versions.
+
 - Issue #17998: Fix an internal error in regular expression engine.
 
 - Issue #17557: Fix os.getgroups() to work with the modified behavior of

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list