@@ -502,6 +502,29 @@ def _f(value):
502502 % (src_format , dst_format ))
503503
504504
505+ class Matrix (object ):
506+ """Simple matrix calculus
507+
508+ >>> Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])([1, 2, 3])
509+ (1, 2, 3)
510+
511+ >>> Matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]]) * [1, 1, 1]
512+ (1, 2, 3)
513+
514+ """
515+
516+ def __init__ (self , m ):
517+ self ._m = m
518+
519+ def __call__ (self , v ):
520+ return tuple (
521+ sum (x1 * x2 for x1 , x2 in zip (u , v ))
522+ for u in self ._m )
523+
524+ def __mul__ (self , v ):
525+ return self .__call__ (v )
526+
527+
505528def register_converter (registry , src , dst , ** kwargs ):
506529
507530 def decorator (f ):
@@ -1309,6 +1332,18 @@ class CMYK(Tuple("cyan", "magenta", "yellow", "key")):
13091332
13101333 """
13111334
1335+ @register_format (Formats )
1336+ class YUV (Tuple ("luma" , "u" , "v" )):
1337+ """3-uple of Luma, U, V.
1338+
1339+ Luma is between 0.0 and 1.0, U and V are coordinate
1340+ with values between -1.0 and 1.0.
1341+
1342+ >>> YUV.blue
1343+ YUV(luma=0.114, u=0.436, v=-0.10001)
1344+
1345+ """
1346+
13121347
13131348
13141349@register_format (Formats )
@@ -1888,6 +1923,54 @@ def cmyk2cmy(cmyk):
18881923 return tuple ((float (x ) * (1 - float (k ))) + k for x in (c , m , y ))
18891924
18901925
1926+ RGB_TO_YUV = Matrix ([
1927+ [0.299 , 0.587 , 0.114 ],
1928+ [- 0.14713 , - 0.28886 , 0.436 ],
1929+ [0.615 , - 0.51499 , - 0.10001 ],
1930+ ])
1931+
1932+
1933+ @register_converter (Converters , RGB , YUV )
1934+ def rgb2yuv (rgb ):
1935+ """Converting from RGB to YUV using BT.709 conversion
1936+
1937+ cf. https://en.wikipedia.org/wiki/YUV
1938+
1939+ >>> rgb2yuv((1., 0., 0.))
1940+ (0.299, -0.14713, 0.615)
1941+
1942+ """
1943+ return RGB_TO_YUV (rgb )
1944+
1945+
1946+ ## Use:
1947+ ##
1948+ ## >>> import colour
1949+ ## >>> from numpy import matrix, linalg
1950+ ## >>> print (linalg.inv(RGB_TO_YUV))
1951+ ##
1952+ ## To get the reverse matrix.
1953+ YUV_TO_RGB = Matrix ([
1954+ [1. , - 0.0000117983844 , 1.13983458 ],
1955+ [1.00000395 , - 0.394646053 , - 0.580594234 ],
1956+ [0.999979679 , 2.03211194 , - 0.0000151129807 ],
1957+ ])
1958+
1959+
1960+ @register_converter (Converters , YUV , RGB )
1961+ def yuv2rgb (yuv ):
1962+ """Converting from YUV to RGB using BT.709 conversion
1963+
1964+ cf. https://en.wikipedia.org/wiki/YUV
1965+
1966+ >>> yuv2rgb((1., 0., 0.)) # doctest: +ELLIPSIS
1967+ (1.0, 1.0..., 0.99...)
1968+
1969+ """
1970+
1971+ return YUV_TO_RGB (yuv )
1972+
1973+
18911974class Color (mkDataSpace (formats = Formats , converters = Converters ,
18921975 picker = RGB_color_picker )):
18931976 """Abstraction of a color object
@@ -1941,6 +2024,8 @@ class Color(mkDataSpace(formats=Formats, converters=Converters,
19412024 '#0000ff'
19422025 >>> b.web
19432026 'blue'
2027+ >>> b.yuv # doctest: +ELLIPSIS
2028+ YUV(luma=0.114, u=0.436, v=-0.10001)
19442029
19452030 Change values
19462031 -------------
@@ -2053,8 +2138,6 @@ class Color(mkDataSpace(formats=Formats, converters=Converters,
20532138 >>> c.hsl_saturation # doctest: +ELLIPSIS
20542139 0.778...
20552140
2056- TODO: could add YUV conversion.
2057-
20582141 Recursive init
20592142 --------------
20602143
0 commit comments