예제 #1
0
 def test_judd_wyszecki(self, verbose=False):
     ''' Test computed chromaticities vs table in Judd and Wyszecki. '''
     if verbose:
         print('Test vs. Judd and Wyszecki:')
     table = Judd_Wyszeki_blackbody_chromaticity_table
     num_rows = table.shape[0]
     for i in range(0, num_rows):
         # Read temperature and expected chromaticity.
         T = table[i][0]
         x_expect = table[i][1]
         y_expect = table[i][2]
         # Calculate chromaticity for the temperature.
         xyz = blackbody.blackbody_color(T)
         colormodels.xyz_normalize(xyz)
         x_actual = xyz[0]
         y_actual = xyz[1]
         # Check against the tabulated result.
         x_error = math.fabs(x_actual - x_expect)
         y_error = math.fabs(y_actual - y_expect)
         # The tolerance used is larger than desired.
         # A tolerance of 5.0e-5 would match the precision in the book.
         tolerance = 15.0e-5
         self.assertAlmostEqual(x_actual, x_expect, delta=tolerance)
         self.assertAlmostEqual(y_actual, y_expect, delta=tolerance)
         # Print results.
         msg = 'T: %8.1f K    Calculated x,y: %.5f, %.5f    Expected x,y: %.5f, %.5f    Error: %.5e, %.5e' % (
             T, x_actual, y_actual, x_expect, y_expect, x_error, y_error)
         if verbose:
             print(msg)
예제 #2
0
 def test_judd_wyszecki(self, verbose=False):
     ''' Test computed chromaticities vs table in Judd and Wyszecki. '''
     if verbose:
         print ('Test vs. Judd and Wyszecki:')
     table = Judd_Wyszeki_blackbody_chromaticity_table
     num_rows = table.shape[0]
     for i in range (0, num_rows):
         # Read temperature and expected chromaticity.
         T        = table [i][0]
         x_expect = table [i][1]
         y_expect = table [i][2]
         # Calculate chromaticity for the temperature.
         xyz = blackbody.blackbody_color (T)
         colormodels.xyz_normalize (xyz)
         x_actual = xyz[0]
         y_actual = xyz[1]
         # Check against the tabulated result.
         x_error = math.fabs(x_actual - x_expect)
         y_error = math.fabs(y_actual - y_expect)
         # The tolerance used is larger than desired.
         # A tolerance of 5.0e-5 would match the precision in the book.
         tolerance = 15.0e-5
         self.assertAlmostEqual(x_actual, x_expect, delta=tolerance)
         self.assertAlmostEqual(y_actual, y_expect, delta=tolerance)
         # Print results.
         msg = 'T: %8.1f K    Calculated x,y: %.5f, %.5f    Expected x,y: %.5f, %.5f    Error: %.5e, %.5e' % (
             T, x_actual, y_actual, x_expect, y_expect, x_error, y_error)
         if verbose:
             print (msg)
예제 #3
0
def get_normalized_spectral_line_colors_annotated (
    brightness = 1.0,
    num_purples = 0,
    dwl_angstroms = 10):
    '''Get an array of xyz colors covering the visible spectrum.
    Optionally add a number of 'purples', which are colors interpolated between the color
    of the lowest wavelength (violet) and the highest (red).
    A text string describing the color is supplied for each color.

    brightness - Desired maximum rgb component of each color.  Default 1.0.  (Maxiumum displayable brightness)
    num_purples - Number of colors to interpolate in the 'purple' range.  Default 0.  (No purples)
    dwl_angstroms - Wavelength separation, in angstroms (0.1 nm).  Default 10 A. (1 nm spacing)
    '''
    # get range of wavelengths, in angstroms, so that we can have finer resolution than 1 nm
    wl_angstrom_range = range (10*start_wl_nm, 10*(end_wl_nm + 1), dwl_angstroms)
    # get total point count
    num_spectral = len (wl_angstrom_range)
    num_points   = num_spectral + num_purples
    xyzs = numpy.empty ((num_points, 3))
    names = []
    # build list of normalized color x,y values proceeding along each wavelength
    i = 0
    for wl_A in wl_angstrom_range:
        wl_nm = wl_A * 0.1
        xyz = xyz_from_wavelength (wl_nm)
        colormodels.xyz_normalize (xyz)
        xyzs [i] = xyz
        name = '%.1f nm' % wl_nm
        names.append (name)
        i += 1
    # interpolate from end point to start point (filling in the purples)
    first_xyz = xyzs [0]
    last_xyz  = xyzs [num_spectral - 1]
    for ipurple in range (0, num_purples):
        t = float (ipurple) / float (num_purples - 1)
        omt = 1.0 - t
        xyz = t * first_xyz + omt * last_xyz
        colormodels.xyz_normalize (xyz)
        xyzs [i] = xyz
        name = '%03d purple' % math.floor (1000.0 * t + 0.5)
        names.append (name)
        i += 1
    # scale each color to have the max rgb component equal to the desired brightness
    for i in range (0, num_points):
        rgb = colormodels.brightest_rgb_from_xyz (xyzs [i], brightness)
        xyzs [i] = colormodels.xyz_from_rgb (rgb)
    # done
    return (xyzs, names)
예제 #4
0
def xyzFromRGB(red, green=None, blue=None):
	"""
	RGB转成xyz
	"""
	if isinstance(red, basestring):
		# assume a hex string is passed
		if red[0] == "#":
			colorString = red[1:]
		else:
			colorString = red
		red = int(colorString[0:2], 16)
		green = int(colorString[2:4], 16)
		blue = int(colorString[4:], 16)

	# We need to convert the RGB value to Yxy.
	redScale = float(red) / 255.0
	greenScale = float(green) / 255.0
	blueScale = float(blue) / 255.0
	colormodels.init(
		phosphor_red=colormodels.xyz_color(0.64843, 0.33086),
		phosphor_green=colormodels.xyz_color(0.4091, 0.518),
		phosphor_blue=colormodels.xyz_color(0.167, 0.04))
	xyz = colormodels.irgb_color(red, green, blue)
	xyz = colormodels.xyz_from_rgb(xyz)
	xyz = colormodels.xyz_normalize(xyz)
	return xyz
예제 #5
0
def get_normalized_spectral_line_colors(brightness=1.0,
                                        num_purples=0,
                                        dwl_angstroms=10):
    '''Get an array of xyz colors covering the visible spectrum.
    Optionally add a number of 'purples', which are colors interpolated between the color
    of the lowest wavelength (violet) and the highest (red).

    brightness - Desired maximum rgb component of each color.  Default 1.0.  (Maxiumum displayable brightness)
    num_purples - Number of colors to interpolate in the 'purple' range.  Default 0.  (No purples)
    dwl_angstroms - Wavelength separation, in angstroms (0.1 nm).  Default 10 A. (1 nm spacing)
    '''
    # get range of wavelengths, in angstroms, so that we can have finer resolution than 1 nm
    wl_angstrom_range = xrange(10 * start_wl_nm, 10 * (end_wl_nm + 1),
                               dwl_angstroms)
    # get total point count
    num_spectral = len(wl_angstrom_range)
    num_points = num_spectral + num_purples
    xyzs = numpy.empty((num_points, 3))
    # build list of normalized color x,y values proceeding along each wavelength
    i = 0
    for wl_A in wl_angstrom_range:
        wl_nm = wl_A * 0.1
        xyz = xyz_from_wavelength(wl_nm)
        colormodels.xyz_normalize(xyz)
        xyzs[i] = xyz
        i += 1
    # interpolate from end point to start point (filling in the purples)
    first_xyz = xyzs[0]
    last_xyz = xyzs[num_spectral - 1]
    for ipurple in xrange(0, num_purples):
        t = float(ipurple) / float(num_purples - 1)
        omt = 1.0 - t
        xyz = t * first_xyz + omt * last_xyz
        colormodels.xyz_normalize(xyz)
        xyzs[i] = xyz
        i += 1
    # scale each color to have the max rgb component equal to the desired brightness
    for i in xrange(0, num_points):
        rgb = colormodels.rgb_from_xyz(xyzs[i])
        max_rgb = max(rgb)
        if max_rgb != 0.0:
            scale = brightness / max_rgb
            rgb *= scale
        xyzs[i] = colormodels.xyz_from_rgb(rgb)
    # done
    return xyzs
예제 #6
0
 def test_gold_point(self, verbose=False):
     ''' Test the chromaticity at the 'gold point'. '''
     # From Wyszecki & Stiles, p. 28.
     T = 1336.0  # 'Gold' point
     x_expect = 0.607
     y_expect = 0.381
     xyz = blackbody.blackbody_color(T)
     colormodels.xyz_normalize(xyz)
     x_actual = xyz[0]
     y_actual = xyz[1]
     # Check result. The tolerance is high, there is a discrepancy
     # in the last printed digit in the table in the book.
     # A tolerance of 5.0e-4 would match the precision in the book.
     tolerance = 6.0e-4
     self.assertAlmostEqual(x_actual, x_expect, delta=tolerance)
     self.assertAlmostEqual(y_actual, y_expect, delta=tolerance)
     # This source is supposed to be 0.11 cd/cm^2 = 1100 cd/m^2,
     # whereas monitors are c. 80 cd/m^2 to 300 cd/m^2.
     msg = 'Blackbody color at gold point: %s' % (str(xyz))
     if verbose:
         print(msg)
예제 #7
0
 def test_gold_point(self, verbose=False):
     ''' Test the chromaticity at the 'gold point'. '''
     # From Wyszecki & Stiles, p. 28.
     T        = 1336.0     # 'Gold' point
     x_expect = 0.607
     y_expect = 0.381
     xyz = blackbody.blackbody_color (T)
     colormodels.xyz_normalize (xyz)
     x_actual = xyz[0]
     y_actual = xyz[1]
     # Check result. The tolerance is high, there is a discrepancy
     # in the last printed digit in the table in the book.
     # A tolerance of 5.0e-4 would match the precision in the book.
     tolerance = 6.0e-4
     self.assertAlmostEqual(x_actual, x_expect, delta=tolerance)
     self.assertAlmostEqual(y_actual, y_expect, delta=tolerance)
     # This source is supposed to be 0.11 cd/cm^2 = 1100 cd/m^2,
     # whereas monitors are c. 80 cd/m^2 to 300 cd/m^2.
     msg = 'Blackbody color at gold point: %s' % (str (xyz))
     if verbose:
         print (msg)
예제 #8
0
def test_book (verbose=1):
    '''Test that the computed chromaticities match an existing table, from Judd and Wyszecki.'''
    num_passed = 0
    num_failed = 0
   
    (num_rows, num_cols) = book_chrom_table.shape
    for i in xrange (0, num_rows):
        T = book_chrom_table [i][0]
        book_x = book_chrom_table [i][1]
        book_y = book_chrom_table [i][2]
        # calculate color for T
        xyz = blackbody.blackbody_color (T)
        colormodels.xyz_normalize (xyz)
        dx = xyz [0] - book_x
        dy = xyz [1] - book_y
        # did we match the tablulated result?
        tolerance = 2.0e-4
        passed = (math.fabs (dx) <= tolerance) and (math.fabs (dy) <= tolerance)
        if passed:
            status = 'pass'
        else:
            status = 'FAILED'
        msg = 'test_book() : T = %g : calculated x,y = %g,%g : book values x,y = %g,%g : errors = %g,%g' % (
            T, xyz [0], xyz [1], book_x, book_y, dx, dy)
        if verbose >= 1:
            print msg
        if not passed:
            pass
            raise ValueError, msg
        if passed:
            num_passed += 1
        else:
            num_failed += 1

    msg = 'test_book() : %d tests passed, %d tests failed' % (
        num_passed, num_failed)
    print msg
예제 #9
0
def test_book (verbose=1):
    '''Test that the computed chromaticities match an existing table, from Judd and Wyszecki.'''
    num_passed = 0
    num_failed = 0
   
    (num_rows, num_cols) = book_chrom_table.shape
    for i in xrange (0, num_rows):
        T = book_chrom_table [i][0]
        book_x = book_chrom_table [i][1]
        book_y = book_chrom_table [i][2]
        # calculate color for T
        xyz = blackbody.blackbody_color (T)
        colormodels.xyz_normalize (xyz)
        dx = xyz [0] - book_x
        dy = xyz [1] - book_y
        # did we match the tablulated result?
        tolerance = 2.0e-4
        passed = (math.fabs (dx) <= tolerance) and (math.fabs (dy) <= tolerance)
        if passed:
            status = 'pass'
        else:
            status = 'FAILED'
        msg = 'test_book() : T = %g : calculated x,y = %g,%g : book values x,y = %g,%g : errors = %g,%g' % (
            T, xyz [0], xyz [1], book_x, book_y, dx, dy)
        if verbose >= 1:
            print msg
        if not passed:
            pass
            raise ValueError, msg
        if passed:
            num_passed += 1
        else:
            num_failed += 1

    msg = 'test_book() : %d tests passed, %d tests failed' % (
        num_passed, num_failed)
    print msg
예제 #10
0
파일: plots.py 프로젝트: Stanpol/ColorPy
def shark_fin_plot ():
    '''Draw the 'shark fin' CIE chromaticity diagram of the pure spectral lines (plus purples) in xy space.'''
    # get array of (approximate) colors for the boundary of the fin
    xyz_list = ciexyz.get_normalized_spectral_line_colors (brightness=1.0, num_purples=200, dwl_angstroms=2)
    # get normalized colors
    xy_list = xyz_list.copy()
    (num_colors, num_cols) = xy_list.shape
    for i in xrange (0, num_colors):
        colormodels.xyz_normalize (xy_list [i])
    # get phosphor colors and normalize
    red   = colormodels.PhosphorRed
    green = colormodels.PhosphorGreen
    blue  = colormodels.PhosphorBlue
    white = colormodels.PhosphorWhite
    colormodels.xyz_normalize (red)
    colormodels.xyz_normalize (green)
    colormodels.xyz_normalize (blue)
    colormodels.xyz_normalize (white)

    def get_direc_to_white (xyz):
        '''Get unit vector (xy plane) in direction of the white point.'''
        direc = white - xyz
        mag = math.hypot (direc [0], direc [1])
        if mag != 0.0:
            direc /= mag
        return (direc[0], direc[1])

    # plot
    pylab.clf ()
    # draw color patches for point in xy_list
    s = 0.025     # distance in xy plane towards white point
    for i in xrange (0, len (xy_list)-1):
        x0 = xy_list [i][0]
        y0 = xy_list [i][1]
        x1 = xy_list [i+1][0]
        y1 = xy_list [i+1][1]
        # get unit vectors in direction of white point
        (dir_x0, dir_y0) = get_direc_to_white (xy_list [i])
        (dir_x1, dir_y1) = get_direc_to_white (xy_list [i+1])
        # polygon vertices
        poly_x = [x0, x1, x1 + s*dir_x1, x0 + s*dir_x0]
        poly_y = [y0, y1, y1 + s*dir_y1, y0 + s*dir_y0]
        # draw (using full color, not normalized value)
        color_string = colormodels.irgb_string_from_rgb (
            colormodels.rgb_from_xyz (xyz_list [i]))
        pylab.fill (poly_x, poly_y, color_string, edgecolor=color_string)
    # draw the curve of the xy values of the spectral lines and purples
    pylab.plot (xy_list [:,0], xy_list [:,1], color='#808080', linewidth=3.0)
    # draw monitor gamut and white point
    pylab.plot ([red  [0], green[0]], [red  [1], green[1]], 'o-', color='k')
    pylab.plot ([green[0], blue [0]], [green[1], blue [1]], 'o-', color='k')
    pylab.plot ([blue [0], red  [0]], [blue [1], red  [1]], 'o-', color='k')
    pylab.plot ([white[0], white[0]], [white[1], white[1]], 'o-', color='k')
    # label phosphors
    dx = 0.01
    dy = 0.01
    pylab.text (red   [0] + dx, red   [1], 'Red',   ha='left',   va='center')
    pylab.text (green [0], green [1] + dy, 'Green', ha='center', va='bottom')
    pylab.text (blue  [0] - dx, blue  [1], 'Blue',  ha='right',  va='center')
    pylab.text (white [0], white [1] + dy, 'White', ha='center', va='bottom')
    # titles etc
    pylab.axis ([0.0, 0.85, 0.0, 0.85])
    pylab.xlabel (r'CIE $x$')
    pylab.ylabel (r'CIE $y$')
    pylab.title (r'CIE Chromaticity Diagram')
    filename = 'ChromaticityDiagram'
    print 'Saving plot %s' % (str (filename))
    pylab.savefig (filename)
예제 #11
0
def shark_fin_plot():
    '''Draw the 'shark fin' CIE chromaticity diagram of the pure spectral lines (plus purples) in xy space.'''
    # get array of (approximate) colors for the boundary of the fin
    xyz_list = ciexyz.get_normalized_spectral_line_colors(brightness=1.0,
                                                          num_purples=200,
                                                          dwl_angstroms=2)
    # get normalized colors
    xy_list = xyz_list.copy()
    (num_colors, num_cols) = xy_list.shape
    for i in xrange(0, num_colors):
        colormodels.xyz_normalize(xy_list[i])
    # get phosphor colors and normalize
    red = colormodels.PhosphorRed
    green = colormodels.PhosphorGreen
    blue = colormodels.PhosphorBlue
    white = colormodels.PhosphorWhite
    colormodels.xyz_normalize(red)
    colormodels.xyz_normalize(green)
    colormodels.xyz_normalize(blue)
    colormodels.xyz_normalize(white)

    def get_direc_to_white(xyz):
        '''Get unit vector (xy plane) in direction of the white point.'''
        direc = white - xyz
        mag = math.hypot(direc[0], direc[1])
        if mag != 0.0:
            direc /= mag
        return (direc[0], direc[1])

    # plot
    pylab.clf()
    # draw color patches for point in xy_list
    s = 0.025  # distance in xy plane towards white point
    for i in xrange(0, len(xy_list) - 1):
        x0 = xy_list[i][0]
        y0 = xy_list[i][1]
        x1 = xy_list[i + 1][0]
        y1 = xy_list[i + 1][1]
        # get unit vectors in direction of white point
        (dir_x0, dir_y0) = get_direc_to_white(xy_list[i])
        (dir_x1, dir_y1) = get_direc_to_white(xy_list[i + 1])
        # polygon vertices
        poly_x = [x0, x1, x1 + s * dir_x1, x0 + s * dir_x0]
        poly_y = [y0, y1, y1 + s * dir_y1, y0 + s * dir_y0]
        # draw (using full color, not normalized value)
        color_string = colormodels.irgb_string_from_rgb(
            colormodels.rgb_from_xyz(xyz_list[i]))
        pylab.fill(poly_x, poly_y, color_string, edgecolor=color_string)
    # draw the curve of the xy values of the spectral lines and purples
    pylab.plot(xy_list[:, 0], xy_list[:, 1], color='#808080', linewidth=3.0)
    # draw monitor gamut and white point
    pylab.plot([red[0], green[0]], [red[1], green[1]], 'o-', color='k')
    pylab.plot([green[0], blue[0]], [green[1], blue[1]], 'o-', color='k')
    pylab.plot([blue[0], red[0]], [blue[1], red[1]], 'o-', color='k')
    pylab.plot([white[0], white[0]], [white[1], white[1]], 'o-', color='k')
    # label phosphors
    dx = 0.01
    dy = 0.01
    pylab.text(red[0] + dx, red[1], 'Red', ha='left', va='center')
    pylab.text(green[0], green[1] + dy, 'Green', ha='center', va='bottom')
    pylab.text(blue[0] - dx, blue[1], 'Blue', ha='right', va='center')
    pylab.text(white[0], white[1] + dy, 'White', ha='center', va='bottom')
    # titles etc
    pylab.axis([0.0, 0.85, 0.0, 0.85])
    pylab.xlabel(r'CIE $x$')
    pylab.ylabel(r'CIE $y$')
    pylab.title(r'CIE Chromaticity Diagram')
    filename = 'ChromaticityDiagram'
    print 'Saving plot %s' % (str(filename))
    pylab.savefig(filename)
예제 #12
0
def shark_fin_plot():
    '''Draw the 'shark fin' CIE chromaticity diagram of the pure spectral lines (plus purples) in xy space.'''
    # get array of (approximate) colors for the boundary of the fin
    xyz_list = ciexyz.get_normalized_spectral_line_colors(brightness=1.0,
                                                          num_purples=200,
                                                          dwl_angstroms=2)
    # get normalized colors
    xy_list = xyz_list.copy()
    (num_colors, num_cols) = xy_list.shape
    for i in range(0, num_colors):
        colormodels.xyz_normalize(xy_list[i])
    # get phosphor colors and normalize
    red = colormodels.PhosphorRed
    green = colormodels.PhosphorGreen
    blue = colormodels.PhosphorBlue
    white = colormodels.PhosphorWhite
    colormodels.xyz_normalize(red)
    colormodels.xyz_normalize(green)
    colormodels.xyz_normalize(blue)
    colormodels.xyz_normalize(white)

    def get_direc_to_white(xyz):
        '''Get unit vector (xy plane) in direction of the white point.'''
        direc = white - xyz
        mag = math.hypot(direc[0], direc[1])
        if mag != 0.0:
            direc /= mag
        return (direc[0], direc[1])

    # plot
    pylab.clf()

    # draw best attempt at pure spectral colors on inner edge of shark fin
    s = 0.025  # distance in xy plane towards white point
    for i in range(0, len(xy_list) - 1):
        x0 = xy_list[i][0]
        y0 = xy_list[i][1]
        x1 = xy_list[i + 1][0]
        y1 = xy_list[i + 1][1]
        # get unit vectors in direction of white point
        (dir_x0, dir_y0) = get_direc_to_white(xy_list[i])
        (dir_x1, dir_y1) = get_direc_to_white(xy_list[i + 1])
        # polygon vertices
        poly_x = [x0, x1, x1 + s * dir_x1, x0 + s * dir_x0]
        poly_y = [y0, y1, y1 + s * dir_y1, y0 + s * dir_y0]
        # draw (using full color, not normalized value)
        color_string = colormodels.irgb_string_from_rgb(
            colormodels.rgb_from_xyz(xyz_list[i]))
        pylab.fill(poly_x, poly_y, color_string, edgecolor=color_string)

    # fill in the monitor gamut with true colors
    def get_brightest_irgb_string(xyz):
        '''Convert the xyz color to rgb, scale to maximum displayable brightness, and convert to a string.'''
        rgb = colormodels.brightest_rgb_from_xyz(xyz)
        color_string = colormodels.irgb_string_from_rgb(rgb)
        return color_string

    def fill_gamut_slice(v0, v1, v2):
        '''Fill in a slice of the monitor gamut with the correct colors.'''
        #num_s, num_t = 10, 10
        #num_s, num_t = 25, 25
        num_s, num_t = 50, 50
        dv10 = v1 - v0
        dv21 = v2 - v1
        for i_s in range(num_s):
            s_a = float(i_s) / float(num_s)
            s_b = float(i_s + 1) / float(num_s)
            for i_t in range(num_t):
                t_a = float(i_t) / float(num_t)
                t_b = float(i_t + 1) / float(num_t)
                # vertex coords
                v_aa = v0 + t_a * (dv10 + s_a * dv21)
                v_ab = v0 + t_b * (dv10 + s_a * dv21)
                v_ba = v0 + t_a * (dv10 + s_b * dv21)
                v_bb = v0 + t_b * (dv10 + s_b * dv21)
                # poly coords
                poly_x = [v_aa[0], v_ba[0], v_bb[0], v_ab[0]]
                poly_y = [v_aa[1], v_ba[1], v_bb[1], v_ab[1]]
                # average color
                avg = 0.25 * (v_aa + v_ab + v_ba + v_bb)
                # convert to rgb and scale to maximum displayable brightness
                color_string = get_brightest_irgb_string(avg)
                pylab.fill(poly_x,
                           poly_y,
                           color_string,
                           edgecolor=color_string)

    fill_gamut_slice(white, blue, green)
    fill_gamut_slice(white, green, red)
    fill_gamut_slice(white, red, blue)

    # draw the curve of the xy values of the spectral lines and purples
    pylab.plot(xy_list[:, 0], xy_list[:, 1], color='#808080', linewidth=3.0)
    # draw monitor gamut and white point
    pylab.plot([red[0], green[0]], [red[1], green[1]], 'o-', color='k')
    pylab.plot([green[0], blue[0]], [green[1], blue[1]], 'o-', color='k')
    pylab.plot([blue[0], red[0]], [blue[1], red[1]], 'o-', color='k')
    pylab.plot([white[0], white[0]], [white[1], white[1]], 'o-', color='k')
    # label phosphors
    dx = 0.01
    dy = 0.01
    pylab.text(red[0] + dx, red[1], 'Red', ha='left', va='center')
    pylab.text(green[0], green[1] + dy, 'Green', ha='center', va='bottom')
    pylab.text(blue[0] - dx, blue[1], 'Blue', ha='right', va='center')
    pylab.text(white[0], white[1] + dy, 'White', ha='center', va='bottom')
    # titles etc
    pylab.axis([0.0, 0.85, 0.0, 0.85])
    pylab.xlabel(r'CIE $x$')
    pylab.ylabel(r'CIE $y$')
    pylab.title(r'CIE Chromaticity Diagram')
    filename = 'ChromaticityDiagram'
    print('Saving plot %s' % (str(filename)))
    pylab.savefig(filename)
예제 #13
0
def shark_fin_plot ():
    '''Draw the 'shark fin' CIE chromaticity diagram of the pure spectral lines (plus purples) in xy space.'''
    # get array of (approximate) colors for the boundary of the fin
    xyz_list = ciexyz.get_normalized_spectral_line_colors (brightness=1.0, num_purples=200, dwl_angstroms=2)
    # get normalized colors
    xy_list = xyz_list.copy()
    (num_colors, num_cols) = xy_list.shape
    for i in range (0, num_colors):
        colormodels.xyz_normalize (xy_list [i])
    # get phosphor colors and normalize
    red   = colormodels.PhosphorRed
    green = colormodels.PhosphorGreen
    blue  = colormodels.PhosphorBlue
    white = colormodels.PhosphorWhite
    colormodels.xyz_normalize (red)
    colormodels.xyz_normalize (green)
    colormodels.xyz_normalize (blue)
    colormodels.xyz_normalize (white)

    def get_direc_to_white (xyz):
        '''Get unit vector (xy plane) in direction of the white point.'''
        direc = white - xyz
        mag = math.hypot (direc [0], direc [1])
        if mag != 0.0:
            direc /= mag
        return (direc[0], direc[1])

    # plot
    pylab.clf ()

    # draw best attempt at pure spectral colors on inner edge of shark fin
    s = 0.025     # distance in xy plane towards white point
    for i in range (0, len (xy_list)-1):
        x0 = xy_list [i][0]
        y0 = xy_list [i][1]
        x1 = xy_list [i+1][0]
        y1 = xy_list [i+1][1]
        # get unit vectors in direction of white point
        (dir_x0, dir_y0) = get_direc_to_white (xy_list [i])
        (dir_x1, dir_y1) = get_direc_to_white (xy_list [i+1])
        # polygon vertices
        poly_x = [x0, x1, x1 + s*dir_x1, x0 + s*dir_x0]
        poly_y = [y0, y1, y1 + s*dir_y1, y0 + s*dir_y0]
        # draw (using full color, not normalized value)
        color_string = colormodels.irgb_string_from_rgb (
            colormodels.rgb_from_xyz (xyz_list [i]))
        pylab.fill (poly_x, poly_y, color_string, edgecolor=color_string)

    # fill in the monitor gamut with true colors
    def get_brightest_irgb_string (xyz):
        '''Convert the xyz color to rgb, scale to maximum displayable brightness, and convert to a string.'''
        rgb = colormodels.brightest_rgb_from_xyz (xyz)
        color_string = colormodels.irgb_string_from_rgb (rgb)
        return color_string

    def fill_gamut_slice (v0, v1, v2):
        '''Fill in a slice of the monitor gamut with the correct colors.'''
        #num_s, num_t = 10, 10
        #num_s, num_t = 25, 25
        num_s, num_t = 50, 50
        dv10 = v1 - v0
        dv21 = v2 - v1
        for i_s in range (num_s):
            s_a = float (i_s)   / float (num_s)
            s_b = float (i_s+1) / float (num_s)
            for i_t in range (num_t):
                t_a = float (i_t)   / float (num_t)
                t_b = float (i_t+1) / float (num_t)
                # vertex coords
                v_aa = v0 + t_a * (dv10 + s_a * dv21)
                v_ab = v0 + t_b * (dv10 + s_a * dv21)
                v_ba = v0 + t_a * (dv10 + s_b * dv21)
                v_bb = v0 + t_b * (dv10 + s_b * dv21)
                # poly coords
                poly_x = [v_aa [0], v_ba [0], v_bb [0], v_ab [0]]
                poly_y = [v_aa [1], v_ba [1], v_bb [1], v_ab [1]]
                # average color
                avg = 0.25 * (v_aa + v_ab + v_ba + v_bb)
                # convert to rgb and scale to maximum displayable brightness
                color_string = get_brightest_irgb_string (avg)
                pylab.fill (poly_x, poly_y, color_string, edgecolor=color_string)
    fill_gamut_slice (white, blue,  green)
    fill_gamut_slice (white, green, red)
    fill_gamut_slice (white, red,   blue)

    # draw the curve of the xy values of the spectral lines and purples
    pylab.plot (xy_list [:,0], xy_list [:,1], color='#808080', linewidth=3.0)
    # draw monitor gamut and white point
    pylab.plot ([red  [0], green[0]], [red  [1], green[1]], 'o-', color='k')
    pylab.plot ([green[0], blue [0]], [green[1], blue [1]], 'o-', color='k')
    pylab.plot ([blue [0], red  [0]], [blue [1], red  [1]], 'o-', color='k')
    pylab.plot ([white[0], white[0]], [white[1], white[1]], 'o-', color='k')
    # label phosphors
    dx = 0.01
    dy = 0.01
    pylab.text (red   [0] + dx, red   [1], 'Red',   ha='left',   va='center')
    pylab.text (green [0], green [1] + dy, 'Green', ha='center', va='bottom')
    pylab.text (blue  [0] - dx, blue  [1], 'Blue',  ha='right',  va='center')
    pylab.text (white [0], white [1] + dy, 'White', ha='center', va='bottom')
    # titles etc
    pylab.axis ([0.0, 0.85, 0.0, 0.85])
    pylab.xlabel (r'CIE $x$')
    pylab.ylabel (r'CIE $y$')
    pylab.title (r'CIE Chromaticity Diagram')
    filename = 'ChromaticityDiagram'
    print ('Saving plot %s' % (str (filename)))
    pylab.savefig (filename)
예제 #14
0
import colormodels

# This script prints CIE xy coordinates for the monochromatic "rainbow" colors as a C++ array.

# Wavelenghts: begin, end and increment.
begin_wl = 360  # hardcoded in get_normalized_spectral_line_colors
end_wl = 830
delta_wl = 20

xyz_list = ciexyz.get_normalized_spectral_line_colors(brightness=1.0,
                                                      dwl_angstroms=delta_wl *
                                                      10)
xy_list = xyz_list.copy()
(num_colors, num_cols) = xy_list.shape
for i in xrange(0, num_colors):
    colormodels.xyz_normalize(xy_list[i])

entries = len(xy_list)

# print array
print "int begin_wl = {begin_wl};".format(begin_wl=begin_wl)
print "int end_wl = {end_wl};".format(end_wl=end_wl)
print "int delta_wl = {delta_wl};".format(delta_wl=delta_wl)
print "int entries = {entries};".format(entries=entries)
print "qreal monochromatic_xy[{entries}][2] = {{".format(entries=entries)
for xyz in xy_list:
    x = xyz[0]
    y = xyz[1]
    print("    {{ {x:.10f}, {y:.10f} }},").format(x=x, y=y)
print "};"