Coverage for models/rgb/tests/test_rgb_colourspace.py: 100%

1"""

2 Define the unit tests for the :mod:`colour.models.rgb.rgb_colourspace` module.

3"""

4

5 from __future__ import annotations

6

7 import re

8 import textwrap

9 from itertools import product

10

11 import numpy as np

12

13 from colour.constants import TOLERANCE_ABSOLUTE_TESTS

14 from colour.models import (

15 RGB_COLOURSPACE_ACES2065_1,

16 RGB_COLOURSPACES,

17 RGB_Colourspace,

18 RGB_COLOURSPACE_sRGB,

19 RGB_to_RGB,

20 RGB_to_XYZ,

21 XYZ_to_RGB,

22 chromatically_adapted_primaries,

23 eotf_inverse_sRGB,

24 eotf_sRGB,

25 linear_function,

26 matrix_RGB_to_RGB,

27 normalised_primary_matrix,

28)

29 from colour.utilities import domain_range_scale, ignore_numpy_errors

30

31 __author__ = "Colour Developers"

32 __copyright__ = "Copyright 2013 Colour Developers"

33 __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"

34 __maintainer__ = "Colour Developers"

35 __email__ = "colour-developers@colour-science.org"

36 __status__ = "Production"

37

38 __all__ = [

39 "TestRGB_Colourspace",

40 "TestXYZ_to_RGB",

41 "TestRGB_to_XYZ",

42 "TestMatrix_RGB_to_RGB",

43 "TestRGB_to_RGB",

44]

45

46

47 class TestRGB_Colourspace:

48 """

49 Define :class:`colour.colour.models.RGB_Colourspace` class unit

50 tests methods.

51 """

52

53 def setup_method(self) -> None:

54 """Initialise the common tests attributes."""

55

56 p = np.array([0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700])

57 whitepoint = np.array([0.32168, 0.33767])

58 matrix_RGB_to_XYZ = np.identity(3)

59 matrix_XYZ_to_RGB = np.identity(3)

60 self._colourspace = RGB_Colourspace(

61 "RGB Colourspace",

62 p,

63 whitepoint,

64 "ACES",

65 matrix_RGB_to_XYZ,

66 matrix_XYZ_to_RGB,

67 linear_function,

68 linear_function,

69 )

70

71 def test_required_attributes(self) -> None:

72 """Test the presence of required attributes."""

73

74 required_attributes = (

75 "name",

76 "primaries",

77 "whitepoint",

78 "whitepoint_name",

79 "matrix_RGB_to_XYZ",

80 "matrix_XYZ_to_RGB",

81 "cctf_encoding",

82 "cctf_decoding",

83 "use_derived_matrix_RGB_to_XYZ",

84 "use_derived_matrix_XYZ_to_RGB",

85 )

86

87 for attribute in required_attributes:

88 assert attribute in dir(RGB_Colourspace)

89

90 def test_required_methods(self) -> None:

91 """Test the presence of required methods."""

92

93 required_methods = (

94 "__init__",

95 "__str__",

96 "__repr__",

97 "use_derived_transformation_matrices",

98 "chromatically_adapt",

99 "copy",

100 )

101

102 for method in required_methods:

103 assert method in dir(RGB_Colourspace)

104

105 def test__str__(self) -> None:

106 """

107 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.__str__`

108 method.

109 """

110

111 assert re.sub(" at 0x\\w+>", "", str(self._colourspace)) == (

112 textwrap.dedent(

113 """

114 RGB Colourspace

115 ---------------

116

117 Primaries : [[ 7.34700000e-01 2.65300000e-01]

118 [ 0.00000000e+00 1.00000000e+00]

119 [ 1.00000000e-04 -7.70000000e-02]]

120 Whitepoint : [ 0.32168 0.33767]

121 Whitepoint Name : ACES

122 Encoding CCTF : <function linear_function

123 Decoding CCTF : <function linear_function

124 NPM : [[ 1. 0. 0.]

125 [ 0. 1. 0.]

126 [ 0. 0. 1.]]

127 NPM -1 : [[ 1. 0. 0.]

128 [ 0. 1. 0.]

129 [ 0. 0. 1.]]

130 Derived NPM : [[ 9.52552396e-01 0.00000000e+00 9.36786317e-05]

131 [ 3.43966450e-01 7.28166097e-01 -7.21325464e-02]

132 [ 0.00000000e+00 0.00000000e+00 1.00882518e+00]]

133 Derived NPM -1 : [[ 1.04981102e+00 0.00000000e+00 -9.74845406e-05]

134 [ -4.95903023e-01 1.37331305e+00 9.82400361e-02]

135 [ 0.00000000e+00 0.00000000e+00 9.91252018e-01]]

136 Use Derived NPM : False

137 Use Derived NPM -1 : False

138 """

139 ).strip()

140 )

141

142 def test__repr__(self) -> None:

143 """

144 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\

145 __repr__` method.

146 """

147

148 assert re.sub(" at 0x\\w+>", "", repr(self._colourspace)) == (

149 textwrap.dedent(

150 """

151 RGB_Colourspace('RGB Colourspace',

152 [[ 7.34700000e-01, 2.65300000e-01],

153 [ 0.00000000e+00, 1.00000000e+00],

154 [ 1.00000000e-04, -7.70000000e-02]],

155 [ 0.32168, 0.33767],

156 'ACES',

157 [[ 1., 0., 0.],

158 [ 0., 1., 0.],

159 [ 0., 0., 1.]],

160 [[ 1., 0., 0.],

161 [ 0., 1., 0.],

162 [ 0., 0., 1.]],

163 linear_function,

164 linear_function,

165 False,

166 False)

167 """

168 ).strip()

169 )

170

171 def test_use_derived_transformation_matrices(self) -> None:

172 """

173 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\

174 use_derived_transformation_matrices` method.

175 """

176

177 np.testing.assert_array_equal(

178 self._colourspace.matrix_RGB_to_XYZ, np.identity(3)

179 )

180 np.testing.assert_array_equal(

181 self._colourspace.matrix_XYZ_to_RGB, np.identity(3)

182 )

183

184 self._colourspace.use_derived_transformation_matrices()

185

186 np.testing.assert_allclose(

187 self._colourspace.matrix_RGB_to_XYZ,

188 np.array(

189 [

190 [0.95255240, 0.00000000, 0.00009368],

191 [0.34396645, 0.72816610, -0.07213255],

192 [0.00000000, 0.00000000, 1.00882518],

193 ]

194 ),

195 atol=TOLERANCE_ABSOLUTE_TESTS,

196 )

197 np.testing.assert_allclose(

198 self._colourspace.matrix_XYZ_to_RGB,

199 np.array(

200 [

201 [1.04981102, 0.00000000, -0.00009748],

202 [-0.49590302, 1.37331305, 0.09824004],

203 [0.00000000, 0.00000000, 0.99125202],

204 ]

205 ),

206 atol=TOLERANCE_ABSOLUTE_TESTS,

207 )

208

209 self._colourspace.use_derived_matrix_RGB_to_XYZ = False

210 np.testing.assert_array_equal(

211 self._colourspace.matrix_RGB_to_XYZ, np.identity(3)

212 )

213 self._colourspace.use_derived_matrix_XYZ_to_RGB = False

214 np.testing.assert_array_equal(

215 self._colourspace.matrix_XYZ_to_RGB, np.identity(3)

216 )

217

218 def test_chromatically_adapt(self) -> None:

219 """

220 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\

221 chromatically_adapt` method.

222 """

223

224 whitepoint_t = np.array([0.31270, 0.32900])

225 colourspace = self._colourspace.chromatically_adapt(

226 whitepoint_t, "D50", "Bradford"

227 )

228

229 np.testing.assert_allclose(

230 colourspace.primaries,

231 np.array(

232 [

233 [0.73485524, 0.26422533],

234 [-0.00617091, 1.01131496],

235 [0.01596756, -0.06423550],

236 ]

237 ),

238 atol=TOLERANCE_ABSOLUTE_TESTS,

239 )

240 np.testing.assert_allclose(

241 colourspace.whitepoint, whitepoint_t, atol=TOLERANCE_ABSOLUTE_TESTS

242 )

243

244 assert colourspace.whitepoint_name == "D50"

245

246 np.testing.assert_allclose(

247 colourspace.primaries,

248 chromatically_adapted_primaries(

249 self._colourspace.primaries,

250 self._colourspace.whitepoint,

251 whitepoint_t,

252 "Bradford",

253 ),

254 atol=TOLERANCE_ABSOLUTE_TESTS,

255 )

256

257 np.testing.assert_allclose(

258 colourspace.matrix_RGB_to_XYZ,

259 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint),

260 atol=TOLERANCE_ABSOLUTE_TESTS,

261 )

262

263 np.testing.assert_allclose(

264 colourspace.matrix_XYZ_to_RGB,

265 np.linalg.inv(

266 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint)

267 ),

268 atol=TOLERANCE_ABSOLUTE_TESTS,

269 )

270

271 def test_copy(self) -> None:

272 """

273 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.copy`

274 method.

275 """

276

277 assert self._colourspace.copy() is not self

278

279

280 class TestXYZ_to_RGB:

281 """

282 Define :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition

283 unit tests methods.

284 """

285

286 def test_XYZ_to_RGB(self) -> None:

287 """

288 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB`

289 definition.

290 """

291

292 np.testing.assert_allclose(

293 XYZ_to_RGB(

294 np.array([0.21638819, 0.12570000, 0.03847493]),

295 RGB_COLOURSPACE_sRGB,

296 np.array([0.34570, 0.35850]),

297 "Bradford",

298 True,

299 ),

300 np.array([0.70556403, 0.19112904, 0.22341005]),

301 atol=TOLERANCE_ABSOLUTE_TESTS,

302 )

303

304 np.testing.assert_allclose(

305 XYZ_to_RGB(

306 np.array([0.21638819, 0.12570000, 0.03847493]),

307 RGB_COLOURSPACE_sRGB,

308 apply_cctf_encoding=True,

309 ),

310 np.array([0.72794351, 0.18184112, 0.17951801]),

311 atol=TOLERANCE_ABSOLUTE_TESTS,

312 )

313

314 np.testing.assert_allclose(

315 XYZ_to_RGB(

316 np.array([0.21638819, 0.12570000, 0.03847493]),

317 RGB_COLOURSPACE_ACES2065_1,

318 np.array([0.34570, 0.35850]),

319 ),

320 np.array([0.21959099, 0.06985815, 0.04703704]),

321 atol=TOLERANCE_ABSOLUTE_TESTS,

322 )

323

324 np.testing.assert_allclose(

325 XYZ_to_RGB(

326 np.array([0.21638819, 0.12570000, 0.03847493]),

327 "sRGB",

328 np.array([0.34570, 0.35850]),

329 "Bradford",

330 True,

331 ),

332 XYZ_to_RGB(

333 np.array([0.21638819, 0.12570000, 0.03847493]),

334 RGB_COLOURSPACE_sRGB,

335 np.array([0.34570, 0.35850]),

336 "Bradford",

337 True,

338 ),

339 atol=TOLERANCE_ABSOLUTE_TESTS,

340 )

341

342 # TODO: Remove tests when dropping deprecated signature support.

343 np.testing.assert_allclose(

344 XYZ_to_RGB(

345 np.array([0.21638819, 0.12570000, 0.03847493]),

346 np.array([0.34570, 0.35850]), # pyright: ignore

347 np.array([0.31270, 0.32900]),

348 np.array( # pyright: ignore

349 [

350 [3.24062548, -1.53720797, -0.49862860],

351 [-0.96893071, 1.87575606, 0.04151752],

352 [0.05571012, -0.20402105, 1.05699594],

353 ]

354 ),

355 "Bradford", # pyright: ignore

356 eotf_inverse_sRGB,

357 ),

358 np.array([0.70556599, 0.19109268, 0.22340812]),

359 atol=TOLERANCE_ABSOLUTE_TESTS,

360 )

361

362 np.testing.assert_allclose(

363 XYZ_to_RGB(

364 np.array([0.21638819, 0.12570000, 0.03847493]),

365 np.array([0.34570, 0.35850]), # pyright: ignore

366 np.array([0.31270, 0.32900]),

367 np.array( # pyright: ignore

368 [

369 [3.24062548, -1.53720797, -0.49862860],

370 [-0.96893071, 1.87575606, 0.04151752],

371 [0.05571012, -0.20402105, 1.05699594],

372 ]

373 ),

374 None, # pyright: ignore

375 eotf_inverse_sRGB,

376 ),

377 np.array([0.72794579, 0.18180021, 0.17951580]),

378 atol=TOLERANCE_ABSOLUTE_TESTS,

379 )

380

381 np.testing.assert_allclose(

382 XYZ_to_RGB(

383 np.array([0.21638819, 0.12570000, 0.03847493]),

384 np.array([0.34570, 0.35850]), # pyright: ignore

385 np.array([0.32168, 0.33767]),

386 np.array( # pyright: ignore

387 [

388 [1.04981102, 0.00000000, -0.00009748],

389 [-0.49590302, 1.37331305, 0.09824004],

390 [0.00000000, 0.00000000, 0.99125202],

391 ]

392 ),

393 ),

394 np.array([0.21959099, 0.06985815, 0.04703704]),

395 atol=TOLERANCE_ABSOLUTE_TESTS,

396 )

397

398 np.testing.assert_allclose(

399 XYZ_to_RGB(

400 np.array([0.21638819, 0.12570000, 0.03847493]),

401 np.array([0.34570, 0.35850]), # pyright: ignore

402 np.array([0.31270, 0.32900, 1.00000]),

403 np.array( # pyright: ignore

404 [

405 [3.24062548, -1.53720797, -0.49862860],

406 [-0.96893071, 1.87575606, 0.04151752],

407 [0.05571012, -0.20402105, 1.05699594],

408 ]

409 ),

410 ),

411 np.array([0.45620801, 0.03079991, 0.04091883]),

412 atol=TOLERANCE_ABSOLUTE_TESTS,

413 )

414

415 def test_n_dimensional_XYZ_to_RGB(self) -> None:

416 """

417 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition

418 n-dimensional support.

419 """

420

421 XYZ = np.array([0.21638819, 0.12570000, 0.03847493])

422 W_R = np.array([0.34570, 0.35850])

423 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True)

424

425 XYZ = np.tile(XYZ, (6, 1))

426 RGB = np.tile(RGB, (6, 1))

427 np.testing.assert_allclose(

428 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),

429 RGB,

430 atol=TOLERANCE_ABSOLUTE_TESTS,

431 )

432

433 W_R = np.tile(W_R, (6, 1))

434 np.testing.assert_allclose(

435 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),

436 RGB,

437 atol=TOLERANCE_ABSOLUTE_TESTS,

438 )

439

440 XYZ = np.reshape(XYZ, (2, 3, 3))

441 W_R = np.reshape(W_R, (2, 3, 2))

442 RGB = np.reshape(RGB, (2, 3, 3))

443 np.testing.assert_allclose(

444 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True),

445 RGB,

446 atol=TOLERANCE_ABSOLUTE_TESTS,

447 )

448

449 def test_domain_range_scale_XYZ_to_RGB(self) -> None:

450 """

451 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition

452 domain and range scale support.

453 """

454

455 XYZ = np.array([0.21638819, 0.12570000, 0.03847493])

456 W_R = np.array([0.34570, 0.35850])

457 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R)

458

459 d_r = (("reference", 1), ("1", 1), ("100", 100))

460 for scale, factor in d_r:

461 with domain_range_scale(scale):

462 np.testing.assert_allclose(

463 XYZ_to_RGB(XYZ * factor, "sRGB", W_R),

464 RGB * factor,

465 atol=TOLERANCE_ABSOLUTE_TESTS,

466 )

467

468 @ignore_numpy_errors

469 def test_nan_XYZ_to_RGB(self) -> None:

470 """

471 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition

472 nan support.

473 """

474

475 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]

476 cases = np.array(list(set(product(cases, repeat=3))))

477 XYZ_to_RGB(cases, "sRGB", cases[..., 0:2])

478

479

480 class TestRGB_to_XYZ:

481 """

482 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition

483 unit tests methods.

484 """

485

486 def test_RGB_to_XYZ(self) -> None:

487 """

488 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ`

489 definition.

490 """

491

492 np.testing.assert_allclose(

493 RGB_to_XYZ(

494 np.array([0.70556403, 0.19112904, 0.22341005]),

495 RGB_COLOURSPACE_sRGB,

496 np.array([0.34570, 0.35850]),

497 "Bradford",

498 True,

499 ),

500 np.array([0.21639121, 0.12570714, 0.03847642]),

501 atol=TOLERANCE_ABSOLUTE_TESTS,

502 )

503

504 np.testing.assert_allclose(

505 RGB_to_XYZ(

506 np.array([0.72794351, 0.18184112, 0.17951801]),

507 RGB_COLOURSPACE_sRGB,

508 apply_cctf_decoding=True,

509 ),

510 np.array([0.21639100, 0.12570754, 0.03847682]),

511 atol=TOLERANCE_ABSOLUTE_TESTS,

512 )

513

514 np.testing.assert_allclose(

515 RGB_to_XYZ(

516 np.array([0.21959099, 0.06985815, 0.04703704]),

517 RGB_COLOURSPACE_ACES2065_1,

518 np.array([0.34570, 0.35850]),

519 ),

520 np.array([0.21638819, 0.12570000, 0.03847493]),

521 atol=TOLERANCE_ABSOLUTE_TESTS,

522 )

523

524 np.testing.assert_allclose(

525 RGB_to_XYZ(

526 np.array([0.21638819, 0.12570000, 0.03847493]),

527 "sRGB",

528 np.array([0.34570, 0.35850]),

529 "Bradford",

530 True,

531 ),

532 RGB_to_XYZ(

533 np.array([0.21638819, 0.12570000, 0.03847493]),

534 RGB_COLOURSPACE_sRGB,

535 np.array([0.34570, 0.35850]),

536 "Bradford",

537 True,

538 ),

539 atol=TOLERANCE_ABSOLUTE_TESTS,

540 )

541

542 # TODO: Remove tests when dropping deprecated signature support.

543 np.testing.assert_allclose(

544 RGB_to_XYZ(

545 np.array([0.70556599, 0.19109268, 0.22340812]),

546 np.array([0.31270, 0.32900]), # pyright: ignore

547 np.array([0.34570, 0.35850]),

548 np.array( # pyright: ignore

549 [

550 [0.41240000, 0.35760000, 0.18050000],

551 [0.21260000, 0.71520000, 0.07220000],

552 [0.01930000, 0.11920000, 0.95050000],

553 ]

554 ),

555 "Bradford", # pyright: ignore

556 eotf_sRGB,

557 ),

558 np.array([0.21638819, 0.12570000, 0.03847493]),

559 atol=TOLERANCE_ABSOLUTE_TESTS,

560 )

561

562 np.testing.assert_allclose(

563 RGB_to_XYZ(

564 np.array([0.72794579, 0.18180021, 0.17951580]),

565 np.array([0.31270, 0.32900]), # pyright: ignore

566 np.array([0.34570, 0.35850]),

567 np.array( # pyright: ignore

568 [

569 [0.41240000, 0.35760000, 0.18050000],

570 [0.21260000, 0.71520000, 0.07220000],

571 [0.01930000, 0.11920000, 0.95050000],

572 ]

573 ),

574 None, # pyright: ignore

575 eotf_sRGB,

576 ),

577 np.array([0.21638819, 0.12570000, 0.03847493]),

578 atol=TOLERANCE_ABSOLUTE_TESTS,

579 )

580

581 np.testing.assert_allclose(

582 RGB_to_XYZ(

583 np.array([0.21959099, 0.06985815, 0.04703704]),

584 np.array([0.32168, 0.33767]), # pyright: ignore

585 np.array([0.34570, 0.35850]),

586 np.array( # pyright: ignore

587 [

588 [0.95255240, 0.00000000, 0.00009368],

589 [0.34396645, 0.72816610, -0.07213255],

590 [0.00000000, 0.00000000, 1.00882518],

591 ]

592 ),

593 ),

594 np.array([0.21638819, 0.12570000, 0.03847493]),

595 atol=TOLERANCE_ABSOLUTE_TESTS,

596 )

597

598 np.testing.assert_allclose(

599 RGB_to_XYZ(

600 np.array([0.45620801, 0.03079991, 0.04091883]),

601 np.array([0.31270, 0.32900, 1.00000]), # pyright: ignore

602 np.array([0.34570, 0.35850]),

603 np.array( # pyright: ignore

604 [

605 [0.41240000, 0.35760000, 0.18050000],

606 [0.21260000, 0.71520000, 0.07220000],

607 [0.01930000, 0.11920000, 0.95050000],

608 ]

609 ),

610 ),

611 np.array([0.21638819, 0.12570000, 0.03847493]),

612 atol=TOLERANCE_ABSOLUTE_TESTS,

613 )

614

615 def test_n_dimensional_RGB_to_XYZ(self) -> None:

616 """

617 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition

618 n-dimensional support.

619 """

620

621 RGB = np.array([0.70556599, 0.19109268, 0.22340812])

622 W_R = np.array([0.31270, 0.32900])

623 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True)

624

625 RGB = np.tile(RGB, (6, 1))

626 XYZ = np.tile(XYZ, (6, 1))

627 np.testing.assert_allclose(

628 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),

629 XYZ,

630 atol=TOLERANCE_ABSOLUTE_TESTS,

631 )

632

633 W_R = np.tile(W_R, (6, 1))

634 np.testing.assert_allclose(

635 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),

636 XYZ,

637 atol=TOLERANCE_ABSOLUTE_TESTS,

638 )

639

640 RGB = np.reshape(RGB, (2, 3, 3))

641 W_R = np.reshape(W_R, (2, 3, 2))

642 XYZ = np.reshape(XYZ, (2, 3, 3))

643 np.testing.assert_allclose(

644 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True),

645 XYZ,

646 atol=TOLERANCE_ABSOLUTE_TESTS,

647 )

648

649 def test_domain_range_scale_XYZ_to_RGB(self) -> None:

650 """

651 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition

652 domain and range scale support.

653 """

654

655 RGB = np.array([0.45620801, 0.03079991, 0.04091883])

656 W_R = np.array([0.31270, 0.32900])

657 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R)

658

659 d_r = (("reference", 1), ("1", 1), ("100", 100))

660 for scale, factor in d_r:

661 with domain_range_scale(scale):

662 np.testing.assert_allclose(

663 RGB_to_XYZ(RGB * factor, "sRGB", W_R),

664 XYZ * factor,

665 atol=TOLERANCE_ABSOLUTE_TESTS,

666 )

667

668 @ignore_numpy_errors

669 def test_nan_RGB_to_XYZ(self) -> None:

670 """

671 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition

672 nan support.

673 """

674

675 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]

676 cases = np.array(list(set(product(cases, repeat=3))))

677 RGB_to_XYZ(cases, "sRGB", cases[..., 0:2])

678

679

680 class TestMatrix_RGB_to_RGB:

681 """

682 Define :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB`

683 definition unit tests methods.

684 """

685

686 def test_matrix_RGB_to_RGB(self) -> None:

687 """

688 Test :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB`

689 definition.

690 """

691

692 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]

693 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"]

694 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]

695

696 np.testing.assert_allclose(

697 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace),

698 np.array(

699 [

700 [2.52164943, -1.13688855, -0.38491759],

701 [-0.27521355, 1.36970515, -0.09439245],

702 [-0.01592501, -0.14780637, 1.16380582],

703 ]

704 ),

705 atol=TOLERANCE_ABSOLUTE_TESTS,

706 )

707

708 np.testing.assert_allclose(

709 matrix_RGB_to_RGB(sRGB_colourspace, aces_2065_1_colourspace),

710 np.array(

711 [

712 [0.43958564, 0.38392940, 0.17653274],

713 [0.08953957, 0.81474984, 0.09568361],

714 [0.01738718, 0.10873911, 0.87382059],

715 ]

716 ),

717 atol=TOLERANCE_ABSOLUTE_TESTS,

718 )

719

720 np.testing.assert_allclose(

721 matrix_RGB_to_RGB(aces_2065_1_colourspace, aces_cg_colourspace, "Bradford"),

722 np.array(

723 [

724 [1.45143932, -0.23651075, -0.21492857],

725 [-0.07655377, 1.17622970, -0.09967593],

726 [0.00831615, -0.00603245, 0.99771630],

727 ]

728 ),

729 atol=TOLERANCE_ABSOLUTE_TESTS,

730 )

731

732 np.testing.assert_allclose(

733 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, "Bradford"),

734 np.array(

735 [

736 [2.52140089, -1.13399575, -0.38756186],

737 [-0.27621406, 1.37259557, -0.09628236],

738 [-0.01532020, -0.15299256, 1.16838720],

739 ]

740 ),

741 atol=TOLERANCE_ABSOLUTE_TESTS,

742 )

743

744 np.testing.assert_allclose(

745 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, None),

746 np.array(

747 [

748 [2.55809607, -1.11933692, -0.39181451],

749 [-0.27771575, 1.36589396, -0.09353075],

750 [-0.01711199, -0.14854588, 1.08104848],

751 ]

752 ),

753 atol=TOLERANCE_ABSOLUTE_TESTS,

754 )

755

756 np.testing.assert_allclose(

757 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace),

758 matrix_RGB_to_RGB("ACES2065-1", "sRGB"),

759 atol=TOLERANCE_ABSOLUTE_TESTS,

760 )

761

762

763 class TestRGB_to_RGB:

764 """

765 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition

766 unit tests methods.

767 """

768

769 def test_RGB_to_RGB(self) -> None:

770 """Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition."""

771

772 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]

773 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]

774

775 np.testing.assert_allclose(

776 RGB_to_RGB(

777 np.array([0.21931722, 0.06950287, 0.04694832]),

778 aces_2065_1_colourspace,

779 sRGB_colourspace,

780 ),

781 np.array([0.45595289, 0.03040780, 0.04087313]),

782 atol=TOLERANCE_ABSOLUTE_TESTS,

783 )

784

785 np.testing.assert_allclose(

786 RGB_to_RGB(

787 np.array([0.45595571, 0.03039702, 0.04087245]),

788 sRGB_colourspace,

789 aces_2065_1_colourspace,

790 ),

791 np.array([0.21931722, 0.06950287, 0.04694832]),

792 atol=TOLERANCE_ABSOLUTE_TESTS,

793 )

794

795 np.testing.assert_allclose(

796 RGB_to_RGB(

797 np.array([0.21931722, 0.06950287, 0.04694832]),

798 aces_2065_1_colourspace,

799 sRGB_colourspace,

800 "Bradford",

801 ),

802 np.array([0.45597530, 0.03030054, 0.04086041]),

803 atol=TOLERANCE_ABSOLUTE_TESTS,

804 )

805

806 np.testing.assert_allclose(

807 RGB_to_RGB(

808 np.array([0.21931722, 0.06950287, 0.04694832]),

809 aces_2065_1_colourspace,

810 sRGB_colourspace,

811 None,

812 ),

813 np.array([0.46484236, 0.02963459, 0.03667609]),

814 atol=TOLERANCE_ABSOLUTE_TESTS,

815 )

816

817 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"]

818 aces_cc_colourspace = RGB_COLOURSPACES["ACEScc"]

819

820 np.testing.assert_allclose(

821 RGB_to_RGB(

822 np.array([0.21931722, 0.06950287, 0.04694832]),

823 aces_cg_colourspace,

824 aces_cc_colourspace,

825 apply_cctf_decoding=True,

826 apply_cctf_encoding=True,

827 ),

828 np.array([0.42985679, 0.33522924, 0.30292336]),

829 atol=TOLERANCE_ABSOLUTE_TESTS,

830 )

831

832 np.testing.assert_allclose(

833 RGB_to_RGB(

834 np.array([0.46956438, 0.48137533, 0.43788601]),

835 aces_cc_colourspace,

836 sRGB_colourspace,

837 apply_cctf_decoding=True,

838 apply_cctf_encoding=True,

839 ),

840 np.array([0.60983062, 0.67896356, 0.50435764]),

841 atol=TOLERANCE_ABSOLUTE_TESTS,

842 )

843

844 np.testing.assert_equal(

845 RGB_to_RGB(

846 np.array([0.21931722, 0.06950287, 0.04694832]),

847 aces_2065_1_colourspace,

848 RGB_COLOURSPACES["ProPhoto RGB"],

849 apply_cctf_encoding=True,

850 out_int=True,

851 ),

852 np.array([120, 59, 46]),

853 )

854

855 np.testing.assert_allclose(

856 RGB_to_RGB(

857 np.array([0.21931722, 0.06950287, 0.04694832]),

858 aces_2065_1_colourspace,

859 sRGB_colourspace,

860 ),

861 RGB_to_RGB(

862 np.array([0.21931722, 0.06950287, 0.04694832]),

863 "ACES2065-1",

864 "sRGB",

865 ),

866 atol=TOLERANCE_ABSOLUTE_TESTS,

867 )

868

869 def test_n_dimensional_RGB_to_RGB(self) -> None:

870 """

871 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition

872 n-dimensional support.

873 """

874

875 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]

876 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]

877 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832])

878 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace)

879

880 RGB_i = np.tile(RGB_i, (6, 1))

881 RGB_o = np.tile(RGB_o, (6, 1))

882 np.testing.assert_allclose(

883 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace),

884 RGB_o,

885 atol=TOLERANCE_ABSOLUTE_TESTS,

886 )

887

888 RGB_i = np.reshape(RGB_i, (2, 3, 3))

889 RGB_o = np.reshape(RGB_o, (2, 3, 3))

890 np.testing.assert_allclose(

891 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace),

892 RGB_o,

893 atol=TOLERANCE_ABSOLUTE_TESTS,

894 )

895

896 def test_domain_range_scale_XYZ_to_RGB(self) -> None:

897 """

898 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition

899 domain and range scale support.

900 """

901

902 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]

903 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]

904 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832])

905 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace)

906

907 d_r = (("reference", 1), ("1", 1), ("100", 100))

908 for scale, factor in d_r:

909 with domain_range_scale(scale):

910 np.testing.assert_allclose(

911 RGB_to_RGB(

912 RGB_i * factor,

913 aces_2065_1_colourspace,

914 sRGB_colourspace,

915 ),

916 RGB_o * factor,

917 atol=TOLERANCE_ABSOLUTE_TESTS,

918 )

919

920 @ignore_numpy_errors

921 def test_nan_RGB_to_RGB(self) -> None:

922 """

923 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition

924 nan support.

925 """

926

927 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"]

928 sRGB_colourspace = RGB_COLOURSPACES["sRGB"]

929

930 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]

931 cases = np.array(list(set(product(cases, repeat=3))))

932 RGB_to_RGB(cases, aces_2065_1_colourspace, sRGB_colourspace)