|
| 1 | +""" Display RGB colorspaces to XYZ conversion matrices and their inverses |
| 2 | +
|
| 3 | +.. moduleauthor:: `Marie FETIVEAU <github.com/mfe>`_ |
| 4 | +
|
| 5 | +""" |
| 6 | +from utils.colors_helper import xy_to_XYZ |
| 7 | +from utils.colorspaces import COLORSPACES |
| 8 | +from utils.private_colorspaces import PRIVATE_COLORSPACES |
| 9 | +import numpy |
| 10 | +import argparse |
| 11 | + |
| 12 | + |
| 13 | +class RGBToXYZMatrixException(Exception): |
| 14 | + pass |
| 15 | + |
| 16 | + |
| 17 | +def get_primaries_matrix(xy_red, xy_green, xy_blue): |
| 18 | + """Return primaries XYZ matrix form xy coords |
| 19 | +
|
| 20 | + Args: |
| 21 | + xy_red (float, float): red primary coords |
| 22 | +
|
| 23 | + xy_green (float, float): green primary coords |
| 24 | +
|
| 25 | + xy_blue (float, float): blue primary coords |
| 26 | +
|
| 27 | + Returns: |
| 28 | + .numpy.matrix (3x3) |
| 29 | +
|
| 30 | + """ |
| 31 | + XYZ_red = xy_to_XYZ(xy_red) |
| 32 | + XYZ_green = xy_to_XYZ(xy_green) |
| 33 | + XYZ_blue = xy_to_XYZ(xy_blue) |
| 34 | + primaries_matrix = numpy.matrix( |
| 35 | + [ |
| 36 | + [XYZ_red[0], XYZ_green[0], XYZ_blue[0]], |
| 37 | + [XYZ_red[1], XYZ_green[1], XYZ_blue[1]], |
| 38 | + [XYZ_red[2], XYZ_green[2], XYZ_blue[2]], |
| 39 | + ]) |
| 40 | + return primaries_matrix |
| 41 | + |
| 42 | + |
| 43 | +def get_white_matrix(xy_white): |
| 44 | + """Return white point XYZ matrix form xy coords |
| 45 | +
|
| 46 | + Args: |
| 47 | + xy_white (float, float): white point coords |
| 48 | +
|
| 49 | + Returns: |
| 50 | + .numpy.matrix (3x1) |
| 51 | +
|
| 52 | + """ |
| 53 | + XYZ_white = xy_to_XYZ(xy_white) |
| 54 | + white_matrix = numpy.matrix( |
| 55 | + [ |
| 56 | + [XYZ_white[0]], |
| 57 | + [XYZ_white[1]], |
| 58 | + [XYZ_white[2]], |
| 59 | + ]) |
| 60 | + return white_matrix |
| 61 | + |
| 62 | + |
| 63 | +def get_RGB_to_XYZ_matrix(xy_red, xy_green, xy_blue, xy_white): |
| 64 | + """Compute RGB to XYZ matrix |
| 65 | + See Bruce Lindbloom page : |
| 66 | + http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html |
| 67 | +
|
| 68 | + Args: |
| 69 | + xy_red (float, float): red primary coords |
| 70 | +
|
| 71 | + xy_green (float, float): green primary coords |
| 72 | +
|
| 73 | + xy_blue (float, float): blue primary coords |
| 74 | +
|
| 75 | + xy_white (float, float): white point coords |
| 76 | +
|
| 77 | + Returns: |
| 78 | + .numpy.matrix (3x3) |
| 79 | +
|
| 80 | + """ |
| 81 | + primaries_matrix = get_primaries_matrix(xy_red, xy_green, xy_blue) |
| 82 | + white_matrix = get_white_matrix(xy_white) |
| 83 | + s = primaries_matrix ** -1 * white_matrix |
| 84 | + s_r, s_g, s_b = s.item(0, 0), s.item(1, 0), s.item(2, 0) |
| 85 | + RGB_to_XYZ = numpy.matrix([ |
| 86 | + [s_r * primaries_matrix.item(0, 0), s_g * primaries_matrix.item(0, 1), |
| 87 | + s_b * primaries_matrix.item(0, 2)], |
| 88 | + [s_r * primaries_matrix.item(1, 0), s_g * primaries_matrix.item(1, 1), |
| 89 | + s_b * primaries_matrix.item(1, 2)], |
| 90 | + [s_r * primaries_matrix.item(2, 0), s_g * primaries_matrix.item(2, 1), |
| 91 | + s_b * primaries_matrix.item(2, 2)]]) |
| 92 | + return RGB_to_XYZ |
| 93 | + |
| 94 | + |
| 95 | +def matrix_to_string(matrix, extra=""): |
| 96 | + return ("{0:.10f} {1:.10f} {2:.10f} {9}\n" |
| 97 | + "{3:.10f} {4:.10f} {5:.10f} {10}\n" |
| 98 | + "{6:.10f} {7:.10f} {8:.10f} {11} \n").format(matrix.item(0, 0), |
| 99 | + matrix.item(0, 1), |
| 100 | + matrix.item(0, 2), |
| 101 | + matrix.item(1, 0), |
| 102 | + matrix.item(1, 1), |
| 103 | + matrix.item(1, 2), |
| 104 | + matrix.item(2, 0), |
| 105 | + matrix.item(2, 1), |
| 106 | + matrix.item(2, 2), |
| 107 | + extra, |
| 108 | + extra, |
| 109 | + extra) |
| 110 | + |
| 111 | + |
| 112 | +def display_matrix(colorspace, format): |
| 113 | + """Display RGB to XYZ matrix corresponding to colorspace and formatting |
| 114 | + as format |
| 115 | +
|
| 116 | + Args: |
| 117 | + colorspace (str): input colorspace. For now, REC709 is the only option. |
| 118 | +
|
| 119 | + format (str): output format. simple, matrix, spimtx. |
| 120 | +
|
| 121 | + """ |
| 122 | + try: |
| 123 | + colorspace_obj = COLORSPACES[colorspace] |
| 124 | + except KeyError: |
| 125 | + colorspace_obj = PRIVATE_COLORSPACES[colorspace] |
| 126 | + matrix = get_RGB_to_XYZ_matrix(colorspace_obj.get_red_primaries(), |
| 127 | + colorspace_obj.get_green_primaries(), |
| 128 | + colorspace_obj.get_blue_primaries(), |
| 129 | + colorspace_obj.get_white_point()) |
| 130 | + if format == 'simple': |
| 131 | + matrix_dump = matrix_to_string(matrix) |
| 132 | + inv_matrix_dump = matrix_to_string(matrix.I) |
| 133 | + elif format == 'spimtx': |
| 134 | + matrix_dump = matrix_to_string(matrix, "0") |
| 135 | + inv_matrix_dump = matrix_to_string(matrix.I, "0") |
| 136 | + else: |
| 137 | + matrix_dump = "{0}".format(matrix) |
| 138 | + inv_matrix_dump = "{0}".format(matrix.I) |
| 139 | + print "{0} to XYZ matrix ({1} output):\n".format(colorspace, format) |
| 140 | + print matrix_dump |
| 141 | + print "XYZ to {0} matrix ({1} output):\n".format(colorspace, format) |
| 142 | + print inv_matrix_dump |
| 143 | + |
| 144 | + |
| 145 | +def __get_options(): |
| 146 | + """ Return rgb_to_xyz option parser |
| 147 | +
|
| 148 | + Returns: |
| 149 | + .argparse.ArgumentParser.args |
| 150 | +
|
| 151 | + """ |
| 152 | + ## Define parser |
| 153 | + description = 'Print RGB -> XYZ matrix' |
| 154 | + parser = argparse.ArgumentParser(description=description) |
| 155 | + # RGB colorspace |
| 156 | + parser.add_argument("-c", "--colorspace", |
| 157 | + help=("Input RGB Colorspace."), |
| 158 | + type=str, |
| 159 | + choices= sorted(COLORSPACES.keys() + |
| 160 | + PRIVATE_COLORSPACES.keys()), |
| 161 | + default='REC709') |
| 162 | + # Output format |
| 163 | + parser.add_argument("-f", "--format", |
| 164 | + help=("Output formatting."), |
| 165 | + type=str, |
| 166 | + choices=['matrix', 'spimtx', 'simple'], |
| 167 | + default='matrix') |
| 168 | + return parser.parse_args() |
| 169 | + |
| 170 | + |
| 171 | +if __name__ == '__main__': |
| 172 | + """ Command line interface |
| 173 | + """ |
| 174 | + args = __get_options() |
| 175 | + display_matrix(args.colorspace, args.format) |
0 commit comments