예제 #1
0
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
예제 #2
0
 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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
    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],
            ]))