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

137 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1"""Define the unit tests for the :mod:`colour.models.rgb.ictcp` module.""" 

2 

3from __future__ import annotations 

4 

5from itertools import product 

6 

7import numpy as np 

8 

9from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

10from colour.models.rgb import ICtCp_to_RGB, ICtCp_to_XYZ, RGB_to_ICtCp, XYZ_to_ICtCp 

11from colour.utilities import domain_range_scale, ignore_numpy_errors 

12 

13__author__ = "Colour Developers" 

14__copyright__ = "Copyright 2013 Colour Developers" 

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

16__maintainer__ = "Colour Developers" 

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

18__status__ = "Production" 

19 

20__all__ = [ 

21 "TestRGB_to_ICtCp", 

22 "TestICtCp_to_RGB", 

23 "TestXYZ_to_ICtCp", 

24 "TestICtCp_to_XYZ", 

25] 

26 

27 

28class TestRGB_to_ICtCp: 

29 """ 

30 Define :func:`colour.models.rgb.ictcp.TestRGB_to_ICtCp` definition unit 

31 tests methods. 

32 """ 

33 

34 def test_RGB_to_ICtCp(self) -> None: 

35 """Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition.""" 

36 

37 np.testing.assert_allclose( 

38 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952])), 

39 np.array([0.07351364, 0.00475253, 0.09351596]), 

40 atol=TOLERANCE_ABSOLUTE_TESTS, 

41 ) 

42 

43 np.testing.assert_allclose( 

44 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952]), L_p=4000), 

45 np.array([0.10516931, 0.00514031, 0.12318730]), 

46 atol=TOLERANCE_ABSOLUTE_TESTS, 

47 ) 

48 

49 np.testing.assert_allclose( 

50 RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952]), L_p=1000), 

51 np.array([0.17079612, 0.00485580, 0.17431356]), 

52 atol=TOLERANCE_ABSOLUTE_TESTS, 

53 ) 

54 

55 np.testing.assert_allclose( 

56 RGB_to_ICtCp( 

57 np.array([0.45620519, 0.03081071, 0.04091952]), 

58 method="ITU-R BT.2100-1 PQ", 

59 ), 

60 np.array([0.07351364, 0.00475253, 0.09351596]), 

61 atol=TOLERANCE_ABSOLUTE_TESTS, 

62 ) 

63 

64 np.testing.assert_allclose( 

65 RGB_to_ICtCp( 

66 np.array([0.45620519, 0.03081071, 0.04091952]), 

67 method="ITU-R BT.2100-2 PQ", 

68 ), 

69 np.array([0.07351364, 0.00475253, 0.09351596]), 

70 atol=TOLERANCE_ABSOLUTE_TESTS, 

71 ) 

72 

73 np.testing.assert_allclose( 

74 RGB_to_ICtCp( 

75 np.array([0.45620519, 0.03081071, 0.04091952]), 

76 method="ITU-R BT.2100-1 HLG", 

77 ), 

78 np.array([0.62567899, -0.03622422, 0.67786522]), 

79 atol=TOLERANCE_ABSOLUTE_TESTS, 

80 ) 

81 

82 np.testing.assert_allclose( 

83 RGB_to_ICtCp( 

84 np.array([0.45620519, 0.03081071, 0.04091952]), 

85 method="ITU-R BT.2100-2 HLG", 

86 ), 

87 np.array([0.62567899, -0.01984490, 0.35911259]), 

88 atol=TOLERANCE_ABSOLUTE_TESTS, 

89 ) 

90 

91 def test_n_dimensional_RGB_to_ICtCp(self) -> None: 

92 """ 

93 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition 

94 n-dimensional support. 

95 """ 

96 

97 RGB = np.array([0.45620519, 0.03081071, 0.04091952]) 

98 ICtCp = RGB_to_ICtCp(RGB) 

99 

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

101 ICtCp = np.tile(ICtCp, (6, 1)) 

102 np.testing.assert_allclose( 

103 RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS 

104 ) 

105 

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

107 ICtCp = np.reshape(ICtCp, (2, 3, 3)) 

108 np.testing.assert_allclose( 

109 RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS 

110 ) 

111 

112 def test_domain_range_scale_RGB_to_ICtCp(self) -> None: 

113 """ 

114 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition domain 

115 and range scale support. 

116 """ 

117 

118 RGB = np.array([0.45620519, 0.03081071, 0.04091952]) 

119 ICtCp = RGB_to_ICtCp(RGB) 

120 

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

122 for scale, factor in d_r: 

123 with domain_range_scale(scale): 

124 np.testing.assert_allclose( 

125 RGB_to_ICtCp(RGB * factor), 

126 ICtCp * factor, 

127 atol=TOLERANCE_ABSOLUTE_TESTS, 

128 ) 

129 

130 @ignore_numpy_errors 

131 def test_nan_RGB_to_ICtCp(self) -> None: 

132 """ 

133 Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition nan 

134 support. 

135 """ 

136 

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

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

139 RGB_to_ICtCp(cases) 

140 

141 

142class TestICtCp_to_RGB: 

143 """ 

144 Define :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition unit tests 

145 methods. 

146 """ 

147 

148 def test_ICtCp_to_RGB(self) -> None: 

149 """Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition.""" 

150 

151 np.testing.assert_allclose( 

152 ICtCp_to_RGB(np.array([0.07351364, 0.00475253, 0.09351596])), 

153 np.array([0.45620519, 0.03081071, 0.04091952]), 

154 atol=TOLERANCE_ABSOLUTE_TESTS, 

155 ) 

156 

157 np.testing.assert_allclose( 

158 ICtCp_to_RGB(np.array([0.10516931, 0.00514031, 0.12318730]), L_p=4000), 

159 np.array([0.45620519, 0.03081071, 0.04091952]), 

160 atol=TOLERANCE_ABSOLUTE_TESTS, 

161 ) 

162 

163 np.testing.assert_allclose( 

164 ICtCp_to_RGB(np.array([0.17079612, 0.00485580, 0.17431356]), L_p=1000), 

165 np.array([0.45620519, 0.03081071, 0.04091952]), 

166 atol=TOLERANCE_ABSOLUTE_TESTS, 

167 ) 

168 

169 np.testing.assert_allclose( 

170 ICtCp_to_RGB( 

171 np.array([0.07351364, 0.00475253, 0.09351596]), 

172 method="ITU-R BT.2100-1 PQ", 

173 ), 

174 np.array([0.45620519, 0.03081071, 0.04091952]), 

175 atol=TOLERANCE_ABSOLUTE_TESTS, 

176 ) 

177 

178 np.testing.assert_allclose( 

179 ICtCp_to_RGB( 

180 np.array([0.07351364, 0.00475253, 0.09351596]), 

181 method="ITU-R BT.2100-2 PQ", 

182 ), 

183 np.array([0.45620519, 0.03081071, 0.04091952]), 

184 atol=TOLERANCE_ABSOLUTE_TESTS, 

185 ) 

186 

187 np.testing.assert_allclose( 

188 ICtCp_to_RGB( 

189 np.array([0.62567899, -0.03622422, 0.67786522]), 

190 method="ITU-R BT.2100-1 HLG", 

191 ), 

192 np.array([0.45620519, 0.03081071, 0.04091952]), 

193 atol=TOLERANCE_ABSOLUTE_TESTS, 

194 ) 

195 

196 np.testing.assert_allclose( 

197 ICtCp_to_RGB( 

198 np.array([0.62567899, -0.01984490, 0.35911259]), 

199 method="ITU-R BT.2100-2 HLG", 

200 ), 

201 np.array([0.45620519, 0.03081071, 0.04091952]), 

202 atol=TOLERANCE_ABSOLUTE_TESTS, 

203 ) 

204 

205 def test_n_dimensional_ICtCp_to_RGB(self) -> None: 

206 """ 

207 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition 

208 n-dimensional support. 

209 """ 

210 

211 ICtCp = np.array([0.07351364, 0.00475253, 0.09351596]) 

212 RGB = ICtCp_to_RGB(ICtCp) 

213 

214 ICtCp = np.tile(ICtCp, (6, 1)) 

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

216 np.testing.assert_allclose( 

217 ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS 

218 ) 

219 

220 ICtCp = np.reshape(ICtCp, (2, 3, 3)) 

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

222 np.testing.assert_allclose( 

223 ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS 

224 ) 

225 

226 def test_domain_range_scale_ICtCp_to_RGB(self) -> None: 

227 """ 

228 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition domain 

229 and range scale support. 

230 """ 

231 

232 ICtCp = np.array([0.07351364, 0.00475253, 0.09351596]) 

233 RGB = ICtCp_to_RGB(ICtCp) 

234 

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

236 for scale, factor in d_r: 

237 with domain_range_scale(scale): 

238 np.testing.assert_allclose( 

239 ICtCp_to_RGB(ICtCp * factor), 

240 RGB * factor, 

241 atol=TOLERANCE_ABSOLUTE_TESTS, 

242 ) 

243 

244 @ignore_numpy_errors 

245 def test_nan_ICtCp_to_RGB(self) -> None: 

246 """ 

247 Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition nan 

248 support. 

249 """ 

250 

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

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

253 ICtCp_to_RGB(cases) 

254 

255 

256class TestXYZ_to_ICtCp: 

257 """ 

258 Define :func:`colour.models.rgb.ictcp.TestXYZ_to_ICtCp` definition unit 

259 tests methods. 

260 """ 

261 

262 def test_XYZ_to_ICtCp(self) -> None: 

263 """Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition.""" 

264 

265 np.testing.assert_allclose( 

266 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952])), 

267 np.array([0.06858097, -0.00283842, 0.06020983]), 

268 atol=TOLERANCE_ABSOLUTE_TESTS, 

269 ) 

270 

271 np.testing.assert_allclose( 

272 XYZ_to_ICtCp( 

273 np.array([0.20654008, 0.12197225, 0.05136952]), 

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

275 ), 

276 np.array([0.06792437, 0.00452089, 0.05514480]), 

277 atol=TOLERANCE_ABSOLUTE_TESTS, 

278 ) 

279 

280 np.testing.assert_allclose( 

281 XYZ_to_ICtCp( 

282 np.array([0.20654008, 0.12197225, 0.05136952]), 

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

284 chromatic_adaptation_transform="Bradford", 

285 ), 

286 np.array([0.06783951, 0.00476111, 0.05523093]), 

287 atol=TOLERANCE_ABSOLUTE_TESTS, 

288 ) 

289 

290 np.testing.assert_allclose( 

291 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952]), L_p=4000), 

292 np.array([0.09871102, -0.00447247, 0.07984812]), 

293 atol=TOLERANCE_ABSOLUTE_TESTS, 

294 ) 

295 

296 np.testing.assert_allclose( 

297 XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952]), L_p=1000), 

298 np.array([0.16173872, -0.00792543, 0.11409458]), 

299 atol=TOLERANCE_ABSOLUTE_TESTS, 

300 ) 

301 

302 np.testing.assert_allclose( 

303 XYZ_to_ICtCp( 

304 np.array([0.20654008, 0.12197225, 0.05136952]), 

305 method="ITU-R BT.2100-1 PQ", 

306 ), 

307 np.array([0.06858097, -0.00283842, 0.06020983]), 

308 atol=TOLERANCE_ABSOLUTE_TESTS, 

309 ) 

310 

311 np.testing.assert_allclose( 

312 XYZ_to_ICtCp( 

313 np.array([0.20654008, 0.12197225, 0.05136952]), 

314 method="ITU-R BT.2100-2 PQ", 

315 ), 

316 np.array([0.06858097, -0.00283842, 0.06020983]), 

317 atol=TOLERANCE_ABSOLUTE_TESTS, 

318 ) 

319 

320 np.testing.assert_allclose( 

321 XYZ_to_ICtCp( 

322 np.array([0.20654008, 0.12197225, 0.05136952]), 

323 method="ITU-R BT.2100-1 HLG", 

324 ), 

325 np.array([0.59242792, -0.06824263, 0.47421473]), 

326 atol=TOLERANCE_ABSOLUTE_TESTS, 

327 ) 

328 

329 np.testing.assert_allclose( 

330 XYZ_to_ICtCp( 

331 np.array([0.20654008, 0.12197225, 0.05136952]), 

332 method="ITU-R BT.2100-2 HLG", 

333 ), 

334 np.array([0.59242792, -0.03740730, 0.25122675]), 

335 atol=TOLERANCE_ABSOLUTE_TESTS, 

336 ) 

337 

338 def test_n_dimensional_XYZ_to_ICtCp(self) -> None: 

339 """ 

340 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition 

341 n-dimensional support. 

342 """ 

343 

344 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) 

345 ICtCp = XYZ_to_ICtCp(XYZ) 

346 

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

348 ICtCp = np.tile(ICtCp, (6, 1)) 

349 np.testing.assert_allclose( 

350 XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS 

351 ) 

352 

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

354 ICtCp = np.reshape(ICtCp, (2, 3, 3)) 

355 np.testing.assert_allclose( 

356 XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS 

357 ) 

358 

359 def test_domain_range_scale_XYZ_to_ICtCp(self) -> None: 

360 """ 

361 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition domain 

362 and range scale support. 

363 """ 

364 

365 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) 

366 ICtCp = XYZ_to_ICtCp(XYZ) 

367 

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

369 for scale, factor in d_r: 

370 with domain_range_scale(scale): 

371 np.testing.assert_allclose( 

372 XYZ_to_ICtCp(XYZ * factor), 

373 ICtCp * factor, 

374 atol=TOLERANCE_ABSOLUTE_TESTS, 

375 ) 

376 

377 @ignore_numpy_errors 

378 def test_nan_XYZ_to_ICtCp(self) -> None: 

379 """ 

380 Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition nan 

381 support. 

382 """ 

383 

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

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

386 XYZ_to_ICtCp(cases) 

387 

388 

389class TestICtCp_to_XYZ: 

390 """ 

391 Define :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition unit tests 

392 methods. 

393 """ 

394 

395 def test_ICtCp_to_XYZ(self) -> None: 

396 """Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition.""" 

397 

398 np.testing.assert_allclose( 

399 ICtCp_to_XYZ(np.array([0.06858097, -0.00283842, 0.06020983])), 

400 np.array([0.20654008, 0.12197225, 0.05136952]), 

401 atol=TOLERANCE_ABSOLUTE_TESTS, 

402 ) 

403 

404 np.testing.assert_allclose( 

405 ICtCp_to_XYZ( 

406 np.array([0.06792437, 0.00452089, 0.05514480]), 

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

408 ), 

409 np.array([0.20654008, 0.12197225, 0.05136952]), 

410 atol=TOLERANCE_ABSOLUTE_TESTS, 

411 ) 

412 

413 np.testing.assert_allclose( 

414 ICtCp_to_XYZ( 

415 np.array([0.06783951, 0.00476111, 0.05523093]), 

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

417 chromatic_adaptation_transform="Bradford", 

418 ), 

419 np.array([0.20654008, 0.12197225, 0.05136952]), 

420 atol=TOLERANCE_ABSOLUTE_TESTS, 

421 ) 

422 

423 np.testing.assert_allclose( 

424 ICtCp_to_XYZ(np.array([0.09871102, -0.00447247, 0.07984812]), L_p=4000), 

425 np.array([0.20654008, 0.12197225, 0.05136952]), 

426 atol=TOLERANCE_ABSOLUTE_TESTS, 

427 ) 

428 

429 np.testing.assert_allclose( 

430 ICtCp_to_XYZ(np.array([0.16173872, -0.00792543, 0.11409458]), L_p=1000), 

431 np.array([0.20654008, 0.12197225, 0.05136952]), 

432 atol=TOLERANCE_ABSOLUTE_TESTS, 

433 ) 

434 

435 np.testing.assert_allclose( 

436 ICtCp_to_XYZ( 

437 np.array([0.06858097, -0.00283842, 0.06020983]), 

438 method="ITU-R BT.2100-1 PQ", 

439 ), 

440 np.array([0.20654008, 0.12197225, 0.05136952]), 

441 atol=TOLERANCE_ABSOLUTE_TESTS, 

442 ) 

443 

444 np.testing.assert_allclose( 

445 ICtCp_to_XYZ( 

446 np.array([0.06858097, -0.00283842, 0.06020983]), 

447 method="ITU-R BT.2100-2 PQ", 

448 ), 

449 np.array([0.20654008, 0.12197225, 0.05136952]), 

450 atol=TOLERANCE_ABSOLUTE_TESTS, 

451 ) 

452 

453 np.testing.assert_allclose( 

454 ICtCp_to_XYZ( 

455 np.array([0.59242792, -0.06824263, 0.47421473]), 

456 method="ITU-R BT.2100-1 HLG", 

457 ), 

458 np.array([0.20654008, 0.12197225, 0.05136952]), 

459 atol=TOLERANCE_ABSOLUTE_TESTS, 

460 ) 

461 

462 np.testing.assert_allclose( 

463 ICtCp_to_XYZ( 

464 np.array([0.59242792, -0.03740730, 0.25122675]), 

465 method="ITU-R BT.2100-2 HLG", 

466 ), 

467 np.array([0.20654008, 0.12197225, 0.05136952]), 

468 atol=TOLERANCE_ABSOLUTE_TESTS, 

469 ) 

470 

471 def test_n_dimensional_ICtCp_to_XYZ(self) -> None: 

472 """ 

473 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition 

474 n-dimensional support. 

475 """ 

476 

477 ICtCp = np.array([0.06858097, -0.00283842, 0.06020983]) 

478 XYZ = ICtCp_to_XYZ(ICtCp) 

479 

480 ICtCp = np.tile(ICtCp, (6, 1)) 

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

482 np.testing.assert_allclose( 

483 ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

484 ) 

485 

486 ICtCp = np.reshape(ICtCp, (2, 3, 3)) 

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

488 np.testing.assert_allclose( 

489 ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

490 ) 

491 

492 def test_domain_range_scale_ICtCp_to_XYZ(self) -> None: 

493 """ 

494 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition domain 

495 and range scale support. 

496 """ 

497 

498 ICtCp = np.array([0.06858097, -0.00283842, 0.06020983]) 

499 XYZ = ICtCp_to_XYZ(ICtCp) 

500 

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

502 for scale, factor in d_r: 

503 with domain_range_scale(scale): 

504 np.testing.assert_allclose( 

505 ICtCp_to_XYZ(ICtCp * factor), 

506 XYZ * factor, 

507 atol=TOLERANCE_ABSOLUTE_TESTS, 

508 ) 

509 

510 @ignore_numpy_errors 

511 def test_nan_ICtCp_to_XYZ(self) -> None: 

512 """ 

513 Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition nan 

514 support. 

515 """ 

516 

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

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

519 ICtCp_to_XYZ(cases)