def shape_cube_lg2( function, min_exposure=-6.5, max_exposure=6.5, middle_grey=0.18, shaper_size=2**14 - 1, cube_size=33, name=None, ): # 1D shaper domain = middle_grey * 2**np.array([min_exposure, max_exposure]) shaper_lut = LUT1D(domain=domain, size=shaper_size) shaper_lut.name = "{0} - Shaper".format(name) if name else "Shaper" shaper_lut.table = log_encoding_Log2( shaper_lut.table, middle_grey=middle_grey, min_exposure=min_exposure, max_exposure=max_exposure, ) # 3D cube shaped_cube = LUT3D(size=cube_size, name=name) shaped_cube.table = log_decoding_Log2( shaped_cube.table, middle_grey=middle_grey, min_exposure=min_exposure, max_exposure=max_exposure, ) shaped_cube.table = function(shaped_cube.table) # Concatenate 1D shaper + 3D lut lut1d3d = LUTSequence(shaper_lut, shaped_cube) return lut1d3d
def generate_lut1d3d(self, size=33, shaper_size=2**14): shaper_to_lin = partial( log_decoding_Log2, middle_grey=self.middle_grey_in, min_exposure=self.ev_below_middle_grey, max_exposure=self.ev_above_middle_grey, ) lin_to_shaper = partial( log_encoding_Log2, middle_grey=self.middle_grey_in, min_exposure=self.ev_below_middle_grey, max_exposure=self.ev_above_middle_grey, ) shaper = LUT1D( size=shaper_size, name=f"{self.name} -- Shaper", domain=shaper_to_lin([0.0, 1.0]), comments=[ f"{'Min Exposure:':<20}{self.ev_below_middle_grey}", f"{'Max Exposure:':<20}{self.ev_above_middle_grey}", f"{'Middle Grey:':<20}{self.middle_grey_in}", ], ) shaper.table = lin_to_shaper(shaper.table) cube = LUT3D( size=size, name=self.name, comments=self.comments, ) cube.table = self._apply_shaped(cube.table) return LUTSequence(shaper, cube)
def test_write_LUT_IridasCube(self): """ Tests :func:`colour.io.luts.iridas_cube.write_LUT_IridasCube` definition. """ LUT_1_r = read_LUT_IridasCube( os.path.join(LUTS_DIRECTORY, 'ACES_Proxy_10_to_ACES.cube')) write_LUT_IridasCube( LUT_1_r, os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.cube')) LUT_1_t = read_LUT_IridasCube( os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.cube')) self.assertEqual(LUT_1_r, LUT_1_t) write_LUT_IridasCube( LUTSequence(LUT_1_r), os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.cube')) self.assertEqual(LUT_1_r, LUT_1_t) LUT_2_r = read_LUT_IridasCube(os.path.join(LUTS_DIRECTORY, 'Demo.cube')) write_LUT_IridasCube( LUT_2_r, os.path.join(self._temporary_directory, 'Demo.cube')) LUT_2_t = read_LUT_IridasCube( os.path.join(self._temporary_directory, 'Demo.cube')) self.assertEqual(LUT_2_r, LUT_2_t) self.assertListEqual(LUT_2_r.comments, LUT_2_t.comments) LUT_3_r = read_LUT_IridasCube( os.path.join(LUTS_DIRECTORY, 'Three_Dimensional_Table.cube')) write_LUT_IridasCube( LUT_3_r, os.path.join(self._temporary_directory, 'Three_Dimensional_Table.cube')) LUT_3_t = read_LUT_IridasCube( os.path.join(self._temporary_directory, 'Three_Dimensional_Table.cube')) self.assertEqual(LUT_3_r, LUT_3_t) LUT_4_r = read_LUT_IridasCube( os.path.join(LUTS_DIRECTORY, 'ACES_Proxy_10_to_ACES.cube')) write_LUT_IridasCube( LUT_4_r.as_LUT(LUT1D, force_conversion=True), os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.cube')) LUT_4_t = read_LUT_IridasCube( os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.cube')) self.assertEqual(LUT_4_r, LUT_4_t)
def test_write_LUT(self): """Test :func:`colour.io.luts.__init__.write_LUT` definition.""" LUT_1_r = read_LUT( os.path.join(LUTS_DIRECTORY, "sony_spi1d", "eotf_sRGB_1D.spi1d")) write_LUT( LUT_1_r, os.path.join(self._temporary_directory, "eotf_sRGB_1D.spi1d"), ) LUT_1_t = read_LUT( os.path.join(self._temporary_directory, "eotf_sRGB_1D.spi1d")) self.assertEqual(LUT_1_r, LUT_1_t) write_LUT( LUTSequence(LUT_1_r), os.path.join(self._temporary_directory, "eotf_sRGB_1D.spi1d"), ) self.assertEqual(LUT_1_r, LUT_1_t) LUT_2_r = read_LUT( os.path.join( LUTS_DIRECTORY, "resolve_cube", "Three_Dimensional_Table_With_Shaper.cube", )) write_LUT( LUT_2_r, os.path.join( self._temporary_directory, "Three_Dimensional_Table_With_Shaper.cube", ), ) LUT_2_t = read_LUT( os.path.join( self._temporary_directory, "Three_Dimensional_Table_With_Shaper.cube", )) self.assertEqual(LUT_2_r, LUT_2_t)
def test_write_LUT_SonySPI3D(self): """ Tests :func:`colour.io.luts.sony_spi3d.write_LUT_SonySPI3D` definition. """ LUT_r = read_LUT_SonySPI3D( os.path.join(LUTS_DIRECTORY, 'Colour_Correct.spi3d')) write_LUT_SonySPI3D( LUT_r, os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) LUT_t = read_LUT_SonySPI3D( os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) self.assertEqual(LUT_r, LUT_t) write_LUT_SonySPI3D( LUTSequence(LUT_r), os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) self.assertEqual(LUT_r, LUT_t)
def test_write_LUT_SonySPI1D(self): """ Tests :func:`colour.io.luts.sony_spi1d.write_LUT_SonySPI1D` definition. """ LUT_1_r = read_LUT_SonySPI1D( os.path.join(LUTS_DIRECTORY, 'oetf_reverse_sRGB_1D.spi1d')) write_LUT_SonySPI1D( LUT_1_r, os.path.join(self._temporary_directory, 'oetf_reverse_sRGB_1D.spi1d')) LUT_1_t = read_LUT_SonySPI1D( os.path.join(self._temporary_directory, 'oetf_reverse_sRGB_1D.spi1d')) self.assertEqual(LUT_1_r, LUT_1_t) write_LUT_SonySPI1D( LUTSequence(LUT_1_r), os.path.join(self._temporary_directory, 'oetf_reverse_sRGB_1D.spi1d')) self.assertEqual(LUT_1_r, LUT_1_t) LUT_2_r = read_LUT_SonySPI1D( os.path.join(LUTS_DIRECTORY, 'oetf_reverse_sRGB_2D.spi1d')) write_LUT_SonySPI1D( LUT_2_r, os.path.join(self._temporary_directory, 'oetf_reverse_sRGB_2D.spi1d')) LUT_2_t = read_LUT_SonySPI1D( os.path.join(self._temporary_directory, 'oetf_reverse_sRGB_2D.spi1d')) self.assertEqual(LUT_2_r, LUT_2_t) self.assertListEqual(LUT_2_r.comments, LUT_2_t.comments)
def generate_clf(self, size=33): cube = LUT3D(size=size, name=self.name, comments=self.comments) radiometric_minimum = 0.18 * spow(2, self.ev_below_middle_grey) shaper = Range( min_in_value=radiometric_minimum, max_in_value=self.radiometric_maximum, min_out_value=0, max_out_value=1, no_clamp=not self.gamut_clip, name=f"{self.name} -- shaper", ) inv_shaper = Range( min_in_value=0, max_in_value=1, min_out_value=radiometric_minimum, max_out_value=self.radiometric_maximum, no_clamp=not self.gamut_clip, ) cube.table = inv_shaper.apply(cube.table) cube.table = self.apply(cube.table) return LUTSequence(shaper, cube)
def test_write_LUT_Cinespace(self): """ Tests :func:`colour.io.luts.cinespace_csp.write_LUT_Cinespace` definition. """ LUT_1_r = read_LUT_Cinespace( os.path.join(LUTS_DIRECTORY, 'ACES_Proxy_10_to_ACES.csp')) write_LUT_Cinespace( LUT_1_r, os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.csp')) LUT_1_t = read_LUT_Cinespace( os.path.join(self._temporary_directory, 'ACES_Proxy_10_to_ACES.csp')) self.assertEqual(LUT_1_r, LUT_1_t) self.assertEqual(LUT_1_r, LUT_1_t) LUT_2_r = read_LUT_Cinespace(os.path.join(LUTS_DIRECTORY, 'Demo.csp')) write_LUT_Cinespace( LUT_2_r, os.path.join(self._temporary_directory, 'Demo.csp')) LUT_2_t = read_LUT_Cinespace( os.path.join(self._temporary_directory, 'Demo.csp')) self.assertEqual(LUT_2_r, LUT_2_t) self.assertListEqual(LUT_2_r.comments, LUT_2_t.comments) LUT_3_r = read_LUT_Cinespace( os.path.join(LUTS_DIRECTORY, 'ThreeDimensionalTable.csp')) write_LUT_Cinespace( LUT_3_r, os.path.join(self._temporary_directory, 'ThreeDimensionalTable.csp')) LUT_3_t = read_LUT_Cinespace( os.path.join(self._temporary_directory, 'ThreeDimensionalTable.csp')) self.assertEqual(LUT_3_r, LUT_3_t) write_LUT_Cinespace( LUTSequence(LUT_1_r, LUT_3_r), os.path.join(self._temporary_directory, 'test_sequence.csp')) r = np.array([0.0, 0.1, 0.2, 0.4, 0.8, 1.2]) g = np.array([-0.1, 0.5, 1.0, np.nan, np.nan, np.nan]) b = np.array([-1.0, -0.5, 0.0, 0.5, 1.0, np.nan]) domain = tstack((r, g, b)) LUT_4_t = LUT3x1D(domain=domain, table=domain * 2) write_LUT_Cinespace( LUT_4_t, os.path.join(self._temporary_directory, 'ragged_domain.csp')) LUT_4_r = read_LUT_Cinespace( os.path.join(self._temporary_directory, 'ragged_domain.csp')) np.testing.assert_almost_equal(LUT_4_t.domain, LUT_4_r.domain) np.testing.assert_almost_equal(LUT_4_t.table, LUT_4_r.table, decimal=6)
def test_write_LUT_SonySPI3D(self): """ Tests :func:`colour.io.luts.sony_spi3d.write_LUT_SonySPI3D` definition. """ LUT_r = read_LUT_SonySPI3D( os.path.join(LUTS_DIRECTORY, 'Colour_Correct.spi3d')) write_LUT_SonySPI3D( LUT_r, os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) LUT_t = read_LUT_SonySPI3D( os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) self.assertEqual(LUT_r, LUT_t) write_LUT_SonySPI3D( LUTSequence(LUT_r), os.path.join(self._temporary_directory, 'Colour_Correct.spi3d')) self.assertEqual(LUT_r, LUT_t) # Test for proper indexes sequentiality. path = os.path.join(self._temporary_directory, 'Size_10_Indexes.spi3d') write_LUT_SonySPI3D(LUT3D(size=10), path) indexes = [] with open(path) as spi3d_file: lines = filter(None, (line.strip() for line in spi3d_file.readlines())) for line in lines: if line.startswith('#'): continue tokens = line.split() if len(tokens) == 6: indexes.append(parse_array(tokens[:3], DEFAULT_INT_DTYPE)) np.testing.assert_array_equal( as_int_array(indexes)[:200, ...], np.array([ [0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [0, 0, 5], [0, 0, 6], [0, 0, 7], [0, 0, 8], [0, 0, 9], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 1, 5], [0, 1, 6], [0, 1, 7], [0, 1, 8], [0, 1, 9], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4], [0, 2, 5], [0, 2, 6], [0, 2, 7], [0, 2, 8], [0, 2, 9], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [0, 3, 4], [0, 3, 5], [0, 3, 6], [0, 3, 7], [0, 3, 8], [0, 3, 9], [0, 4, 0], [0, 4, 1], [0, 4, 2], [0, 4, 3], [0, 4, 4], [0, 4, 5], [0, 4, 6], [0, 4, 7], [0, 4, 8], [0, 4, 9], [0, 5, 0], [0, 5, 1], [0, 5, 2], [0, 5, 3], [0, 5, 4], [0, 5, 5], [0, 5, 6], [0, 5, 7], [0, 5, 8], [0, 5, 9], [0, 6, 0], [0, 6, 1], [0, 6, 2], [0, 6, 3], [0, 6, 4], [0, 6, 5], [0, 6, 6], [0, 6, 7], [0, 6, 8], [0, 6, 9], [0, 7, 0], [0, 7, 1], [0, 7, 2], [0, 7, 3], [0, 7, 4], [0, 7, 5], [0, 7, 6], [0, 7, 7], [0, 7, 8], [0, 7, 9], [0, 8, 0], [0, 8, 1], [0, 8, 2], [0, 8, 3], [0, 8, 4], [0, 8, 5], [0, 8, 6], [0, 8, 7], [0, 8, 8], [0, 8, 9], [0, 9, 0], [0, 9, 1], [0, 9, 2], [0, 9, 3], [0, 9, 4], [0, 9, 5], [0, 9, 6], [0, 9, 7], [0, 9, 8], [0, 9, 9], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4], [1, 0, 5], [1, 0, 6], [1, 0, 7], [1, 0, 8], [1, 0, 9], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 1, 5], [1, 1, 6], [1, 1, 7], [1, 1, 8], [1, 1, 9], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 2, 6], [1, 2, 7], [1, 2, 8], [1, 2, 9], [1, 3, 0], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 3, 5], [1, 3, 6], [1, 3, 7], [1, 3, 8], [1, 3, 9], [1, 4, 0], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [1, 4, 5], [1, 4, 6], [1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 5, 0], [1, 5, 1], [1, 5, 2], [1, 5, 3], [1, 5, 4], [1, 5, 5], [1, 5, 6], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 6, 0], [1, 6, 1], [1, 6, 2], [1, 6, 3], [1, 6, 4], [1, 6, 5], [1, 6, 6], [1, 6, 7], [1, 6, 8], [1, 6, 9], [1, 7, 0], [1, 7, 1], [1, 7, 2], [1, 7, 3], [1, 7, 4], [1, 7, 5], [1, 7, 6], [1, 7, 7], [1, 7, 8], [1, 7, 9], [1, 8, 0], [1, 8, 1], [1, 8, 2], [1, 8, 3], [1, 8, 4], [1, 8, 5], [1, 8, 6], [1, 8, 7], [1, 8, 8], [1, 8, 9], [1, 9, 0], [1, 9, 1], [1, 9, 2], [1, 9, 3], [1, 9, 4], [1, 9, 5], [1, 9, 6], [1, 9, 7], [1, 9, 8], [1, 9, 9], ]))