Coverage for colour/models/rgb/tests/test_cylindrical.py: 100%

175 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-15 19:01 +1300

1"""Define the unit tests for the :mod:`colour.models.rgb.cylindrical` 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.cylindrical import ( 

11 HCL_to_RGB, 

12 HSL_to_RGB, 

13 HSV_to_RGB, 

14 RGB_to_HCL, 

15 RGB_to_HSL, 

16 RGB_to_HSV, 

17) 

18from colour.utilities import domain_range_scale, ignore_numpy_errors 

19 

20__author__ = "Colour Developers" 

21__copyright__ = "Copyright 2013 Colour Developers" 

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

23__maintainer__ = "Colour Developers" 

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

25__status__ = "Production" 

26 

27__all__ = [ 

28 "TestRGB_to_HSV", 

29 "TestHSV_to_RGB", 

30 "TestRGB_to_HSL", 

31 "TestHSL_to_RGB", 

32 "TestRGB_to_HCL", 

33 "TestHCL_to_RGB", 

34] 

35 

36 

37class TestRGB_to_HSV: 

38 """ 

39 Define :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition unit 

40 tests methods. 

41 """ 

42 

43 def test_RGB_to_HSV(self) -> None: 

44 """Test :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition.""" 

45 

46 np.testing.assert_allclose( 

47 RGB_to_HSV(np.array([0.45620519, 0.03081071, 0.04091952])), 

48 np.array([0.99603944, 0.93246304, 0.45620519]), 

49 atol=TOLERANCE_ABSOLUTE_TESTS, 

50 ) 

51 

52 np.testing.assert_allclose( 

53 RGB_to_HSV(np.array([0.00000000, 0.00000000, 0.00000000])), 

54 np.array([0.00000000, 0.00000000, 0.00000000]), 

55 atol=TOLERANCE_ABSOLUTE_TESTS, 

56 ) 

57 

58 np.testing.assert_allclose( 

59 RGB_to_HSV(np.array([1.00000000, 1.00000000, 1.00000000])), 

60 np.array([0.00000000, 0.00000000, 1.00000000]), 

61 atol=TOLERANCE_ABSOLUTE_TESTS, 

62 ) 

63 

64 np.testing.assert_allclose( 

65 RGB_to_HSV(np.array([0.00000000, 1.00000000, 1.00000000])), 

66 np.array([0.50000000, 1.00000000, 1.00000000]), 

67 atol=TOLERANCE_ABSOLUTE_TESTS, 

68 ) 

69 

70 def test_n_dimensional_RGB_to_HSV(self) -> None: 

71 """ 

72 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition 

73 n-dimensional arrays support. 

74 """ 

75 

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

77 HSV = RGB_to_HSV(RGB) 

78 

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

80 HSV = np.tile(HSV, (6, 1)) 

81 np.testing.assert_allclose(RGB_to_HSV(RGB), HSV, atol=TOLERANCE_ABSOLUTE_TESTS) 

82 

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

84 HSV = np.reshape(HSV, (2, 3, 3)) 

85 np.testing.assert_allclose(RGB_to_HSV(RGB), HSV, atol=TOLERANCE_ABSOLUTE_TESTS) 

86 

87 def test_domain_range_scale_RGB_to_HSV(self) -> None: 

88 """ 

89 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition 

90 domain and range scale support. 

91 """ 

92 

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

94 HSV = RGB_to_HSV(RGB) 

95 

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

97 for scale, factor in d_r: 

98 with domain_range_scale(scale): 

99 np.testing.assert_allclose( 

100 RGB_to_HSV(RGB * factor), 

101 HSV * factor, 

102 atol=TOLERANCE_ABSOLUTE_TESTS, 

103 ) 

104 

105 @ignore_numpy_errors 

106 def test_nan_RGB_to_HSV(self) -> None: 

107 """ 

108 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition nan 

109 support. 

110 """ 

111 

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

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

114 RGB_to_HSV(cases) 

115 

116 

117class TestHSV_to_RGB: 

118 """ 

119 Define :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition unit 

120 tests methods. 

121 """ 

122 

123 def test_HSV_to_RGB(self) -> None: 

124 """Test :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition.""" 

125 

126 np.testing.assert_allclose( 

127 HSV_to_RGB(np.array([0.99603944, 0.93246304, 0.45620519])), 

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

129 atol=TOLERANCE_ABSOLUTE_TESTS, 

130 ) 

131 

132 np.testing.assert_allclose( 

133 HSV_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), 

134 np.array([0.00000000, 0.00000000, 0.00000000]), 

135 atol=TOLERANCE_ABSOLUTE_TESTS, 

136 ) 

137 

138 np.testing.assert_allclose( 

139 HSV_to_RGB(np.array([0.00000000, 0.00000000, 1.00000000])), 

140 np.array([1.00000000, 1.00000000, 1.00000000]), 

141 atol=TOLERANCE_ABSOLUTE_TESTS, 

142 ) 

143 

144 np.testing.assert_allclose( 

145 HSV_to_RGB(np.array([0.50000000, 1.00000000, 1.00000000])), 

146 np.array([0.00000000, 1.00000000, 1.00000000]), 

147 atol=TOLERANCE_ABSOLUTE_TESTS, 

148 ) 

149 

150 def test_n_dimensional_HSV_to_RGB(self) -> None: 

151 """ 

152 Test :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition 

153 n-dimensional arrays support. 

154 """ 

155 

156 HSV = np.array([0.99603944, 0.93246304, 0.45620519]) 

157 RGB = HSV_to_RGB(HSV) 

158 

159 HSV = np.tile(HSV, (6, 1)) 

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

161 np.testing.assert_allclose(HSV_to_RGB(HSV), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

162 

163 HSV = np.reshape(HSV, (2, 3, 3)) 

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

165 np.testing.assert_allclose(HSV_to_RGB(HSV), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

166 

167 def test_domain_range_scale_HSV_to_RGB(self) -> None: 

168 """ 

169 Test :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition 

170 domain and range scale support. 

171 """ 

172 

173 HSV = np.array([0.99603944, 0.93246304, 0.45620519]) 

174 RGB = HSV_to_RGB(HSV) 

175 

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

177 for scale, factor in d_r: 

178 with domain_range_scale(scale): 

179 np.testing.assert_allclose( 

180 HSV_to_RGB(HSV * factor), 

181 RGB * factor, 

182 atol=TOLERANCE_ABSOLUTE_TESTS, 

183 ) 

184 

185 @ignore_numpy_errors 

186 def test_nan_HSV_to_RGB(self) -> None: 

187 """ 

188 Test :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition nan 

189 support. 

190 """ 

191 

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

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

194 HSV_to_RGB(cases) 

195 

196 

197class TestRGB_to_HSL: 

198 """ 

199 Define :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition unit 

200 tests methods. 

201 """ 

202 

203 def test_RGB_to_HSL(self) -> None: 

204 """Test :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition.""" 

205 

206 np.testing.assert_allclose( 

207 RGB_to_HSL(np.array([0.45620519, 0.03081071, 0.04091952])), 

208 np.array([0.99603944, 0.87347144, 0.24350795]), 

209 atol=TOLERANCE_ABSOLUTE_TESTS, 

210 ) 

211 

212 np.testing.assert_allclose( 

213 RGB_to_HSL(np.array([0.00000000, 0.00000000, 0.00000000])), 

214 np.array([0.00000000, 0.00000000, 0.00000000]), 

215 atol=TOLERANCE_ABSOLUTE_TESTS, 

216 ) 

217 

218 np.testing.assert_allclose( 

219 RGB_to_HSL(np.array([1.00000000, 1.00000000, 1.00000000])), 

220 np.array([0.00000000, 0.00000000, 1.00000000]), 

221 atol=TOLERANCE_ABSOLUTE_TESTS, 

222 ) 

223 

224 np.testing.assert_allclose( 

225 RGB_to_HSL(np.array([1.00000000, 0.00000000, 0.00000000])), 

226 np.array([0.00000000, 1.00000000, 0.50000000]), 

227 atol=TOLERANCE_ABSOLUTE_TESTS, 

228 ) 

229 

230 def test_n_dimensional_RGB_to_HSL(self) -> None: 

231 """ 

232 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition 

233 n-dimensional arrays support. 

234 """ 

235 

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

237 HSL = RGB_to_HSL(RGB) 

238 

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

240 HSL = np.tile(HSL, (6, 1)) 

241 np.testing.assert_allclose(RGB_to_HSL(RGB), HSL, atol=TOLERANCE_ABSOLUTE_TESTS) 

242 

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

244 HSL = np.reshape(HSL, (2, 3, 3)) 

245 np.testing.assert_allclose(RGB_to_HSL(RGB), HSL, atol=TOLERANCE_ABSOLUTE_TESTS) 

246 

247 def test_domain_range_scale_RGB_to_HSL(self) -> None: 

248 """ 

249 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition 

250 domain and range scale support. 

251 """ 

252 

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

254 HSL = RGB_to_HSL(RGB) 

255 

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

257 for scale, factor in d_r: 

258 with domain_range_scale(scale): 

259 np.testing.assert_allclose( 

260 RGB_to_HSL(RGB * factor), 

261 HSL * factor, 

262 atol=TOLERANCE_ABSOLUTE_TESTS, 

263 ) 

264 

265 @ignore_numpy_errors 

266 def test_nan_RGB_to_HSL(self) -> None: 

267 """ 

268 Test :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition nan 

269 support. 

270 """ 

271 

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

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

274 RGB_to_HSL(cases) 

275 

276 

277class TestHSL_to_RGB: 

278 """ 

279 Define :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition unit 

280 tests methods. 

281 """ 

282 

283 def test_HSL_to_RGB(self) -> None: 

284 """Test :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition.""" 

285 

286 np.testing.assert_allclose( 

287 HSL_to_RGB(np.array([0.99603944, 0.87347144, 0.24350795])), 

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

289 atol=TOLERANCE_ABSOLUTE_TESTS, 

290 ) 

291 

292 np.testing.assert_allclose( 

293 HSL_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), 

294 np.array([0.00000000, 0.00000000, 0.00000000]), 

295 atol=TOLERANCE_ABSOLUTE_TESTS, 

296 ) 

297 

298 np.testing.assert_allclose( 

299 HSL_to_RGB(np.array([0.00000000, 0.00000000, 1.00000000])), 

300 np.array([1.00000000, 1.00000000, 1.00000000]), 

301 atol=TOLERANCE_ABSOLUTE_TESTS, 

302 ) 

303 

304 np.testing.assert_allclose( 

305 HSL_to_RGB(np.array([0.00000000, 1.00000000, 0.50000000])), 

306 np.array([1.00000000, 0.00000000, 0.00000000]), 

307 atol=TOLERANCE_ABSOLUTE_TESTS, 

308 ) 

309 

310 def test_n_dimensional_HSL_to_RGB(self) -> None: 

311 """ 

312 Test :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition 

313 n-dimensional arrays support. 

314 """ 

315 

316 HSL = np.array([0.99603944, 0.87347144, 0.24350795]) 

317 RGB = HSL_to_RGB(HSL) 

318 

319 HSL = np.tile(HSL, (6, 1)) 

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

321 np.testing.assert_allclose(HSL_to_RGB(HSL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

322 

323 HSL = np.reshape(HSL, (2, 3, 3)) 

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

325 np.testing.assert_allclose(HSL_to_RGB(HSL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

326 

327 def test_domain_range_scale_HSL_to_RGB(self) -> None: 

328 """ 

329 Test :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition 

330 domain and range scale support. 

331 """ 

332 

333 HSL = np.array([0.99603944, 0.87347144, 0.24350795]) 

334 RGB = HSL_to_RGB(HSL) 

335 

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

337 for scale, factor in d_r: 

338 with domain_range_scale(scale): 

339 np.testing.assert_allclose( 

340 HSL_to_RGB(HSL * factor), 

341 RGB * factor, 

342 atol=TOLERANCE_ABSOLUTE_TESTS, 

343 ) 

344 

345 @ignore_numpy_errors 

346 def test_nan_HSL_to_RGB(self) -> None: 

347 """ 

348 Test :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition nan 

349 support. 

350 """ 

351 

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

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

354 HSL_to_RGB(cases) 

355 

356 

357class TestRGB_to_HCL: 

358 """ 

359 Define :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition unit 

360 tests methods. 

361 """ 

362 

363 def test_RGB_to_HCL(self) -> None: 

364 """Test :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition.""" 

365 

366 np.testing.assert_allclose( 

367 RGB_to_HCL(np.array([0.45620519, 0.03081071, 0.04091952])), 

368 np.array([-0.03167854, 0.2841715, 0.22859647]), 

369 atol=TOLERANCE_ABSOLUTE_TESTS, 

370 ) 

371 

372 np.testing.assert_allclose( 

373 RGB_to_HCL(np.array([1.00000000, 2.00000000, 0.50000000])), 

374 np.array([1.83120102, 1.0075282, 1.00941024]), 

375 atol=TOLERANCE_ABSOLUTE_TESTS, 

376 ) 

377 

378 np.testing.assert_allclose( 

379 RGB_to_HCL(np.array([2.00000000, 1.00000000, 0.50000000])), 

380 np.array([0.30909841, 1.0075282, 1.00941024]), 

381 atol=TOLERANCE_ABSOLUTE_TESTS, 

382 ) 

383 

384 np.testing.assert_allclose( 

385 RGB_to_HCL(np.array([0.50000000, 1.00000000, 2.00000000])), 

386 np.array([-2.40349351, 1.0075282, 1.00941024]), 

387 atol=TOLERANCE_ABSOLUTE_TESTS, 

388 ) 

389 

390 def test_n_dimensional_RGB_to_HCL(self) -> None: 

391 """ 

392 Test :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition 

393 n-dimensional arrays support. 

394 """ 

395 

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

397 HCL = RGB_to_HCL(RGB) 

398 

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

400 HCL = np.tile(HCL, (6, 1)) 

401 np.testing.assert_allclose(RGB_to_HCL(RGB), HCL, atol=TOLERANCE_ABSOLUTE_TESTS) 

402 

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

404 HCL = np.reshape(HCL, (2, 3, 3)) 

405 np.testing.assert_allclose(RGB_to_HCL(RGB), HCL, atol=TOLERANCE_ABSOLUTE_TESTS) 

406 

407 def test_domain_range_scale_RGB_to_HCL(self) -> None: 

408 """ 

409 Test :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition 

410 domain and range scale support. 

411 """ 

412 

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

414 HCL = RGB_to_HCL(RGB) 

415 

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

417 for scale, factor in d_r: 

418 with domain_range_scale(scale): 

419 np.testing.assert_allclose( 

420 RGB_to_HCL(RGB * factor), 

421 HCL * factor, 

422 atol=TOLERANCE_ABSOLUTE_TESTS, 

423 ) 

424 

425 @ignore_numpy_errors 

426 def test_nan_RGB_to_HCL(self) -> None: 

427 """ 

428 Test :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition nan 

429 support. 

430 """ 

431 

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

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

434 RGB_to_HCL(cases) 

435 

436 

437class TestHCL_to_RGB: 

438 """ 

439 Define :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition unit 

440 tests methods. 

441 """ 

442 

443 def test_HCL_to_RGB(self) -> None: 

444 """Test :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition.""" 

445 

446 np.testing.assert_allclose( 

447 HCL_to_RGB(np.array([-0.03167854, 0.28417150, 0.22859647])), 

448 np.array([0.45620333, 0.03081048, 0.04091925]), 

449 atol=TOLERANCE_ABSOLUTE_TESTS, 

450 ) 

451 

452 np.testing.assert_allclose( 

453 HCL_to_RGB(np.array([1.00000000, 2.00000000, 0.50000000])), 

454 np.array([0.92186029, 0.71091922, -2.26364935]), 

455 atol=TOLERANCE_ABSOLUTE_TESTS, 

456 ) 

457 

458 np.testing.assert_allclose( 

459 HCL_to_RGB(np.array([2.00000000, 1.00000000, 0.50000000])), 

460 np.array([-0.31368585, 1.00732462, -0.51534497]), 

461 atol=TOLERANCE_ABSOLUTE_TESTS, 

462 ) 

463 

464 np.testing.assert_allclose( 

465 HCL_to_RGB(np.array([0.50000000, 1.00000000, 2.00000000])), 

466 np.array([3.88095422, 3.11881934, 2.40881719]), 

467 atol=TOLERANCE_ABSOLUTE_TESTS, 

468 ) 

469 

470 def test_n_dimensional_HCL_to_RGB(self) -> None: 

471 """ 

472 Test :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition 

473 n-dimensional arrays support. 

474 """ 

475 

476 HCL = np.array([0.99603944, 0.87347144, 0.24350795]) 

477 RGB = HCL_to_RGB(HCL) 

478 

479 HCL = np.tile(HCL, (6, 1)) 

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

481 np.testing.assert_allclose(HCL_to_RGB(HCL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

482 

483 HCL = np.reshape(HCL, (2, 3, 3)) 

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

485 np.testing.assert_allclose(HCL_to_RGB(HCL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS) 

486 

487 def test_domain_range_scale_HCL_to_RGB(self) -> None: 

488 """ 

489 Test :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition 

490 domain and range scale support. 

491 """ 

492 

493 HCL = np.array([0.99603944, 0.87347144, 0.24350795]) 

494 RGB = HCL_to_RGB(HCL) 

495 

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

497 for scale, factor in d_r: 

498 with domain_range_scale(scale): 

499 np.testing.assert_allclose( 

500 HCL_to_RGB(HCL * factor), 

501 RGB * factor, 

502 atol=TOLERANCE_ABSOLUTE_TESTS, 

503 ) 

504 

505 @ignore_numpy_errors 

506 def test_nan_HCL_to_RGB(self) -> None: 

507 """ 

508 Test :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition nan 

509 support. 

510 """ 

511 

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

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

514 HCL_to_RGB(cases)