├── LICENSE.txt ├── README.md ├── matlab ├── D65.m ├── code_examples.m ├── color-data-master │ ├── rit-dupont │ │ ├── alman1989.mat │ │ └── berns.mat │ └── witt │ │ ├── table_a1.mat │ │ └── table_a2.mat ├── data │ ├── Canon5DMarkIII_spectralSensitivity.m │ ├── get_D65_spectrum.m │ ├── get_XYZ_spectrum.m │ ├── get_datasets.m │ └── testing_on_datasets.m ├── images │ └── README.md ├── proLab_color_conversions │ ├── XYZ2proLab.m │ ├── XYZ2proLab_model.m │ ├── proLab2XYZ.m │ ├── proLab2XYZ_model.m │ ├── proLab_param.m │ └── projTrans3D.m ├── proLab_reference_values.m ├── reference_illuminant.m ├── research │ ├── estim_gain_by_discret.m │ ├── estim_gain_by_noise.m │ ├── noise_model_verification.m │ ├── statistical_test.m │ ├── test_Canon5DMarkIII_spectralSensitivity.m │ ├── test_central_linearity.m │ └── view_raw.m ├── search_optimal_proLab_param.m ├── search_optimal_proLab_param │ ├── CritDataBase.m │ ├── cache │ │ └── README.md │ ├── color_dist.m │ ├── color_spaces_collection.m │ ├── criterion_report.m │ ├── culc_P.m │ ├── delete_duplicate_rows.m │ ├── deltaE2000.m │ ├── find_optimal_m.m │ ├── get_CIEDE2000.m │ ├── get_Eucl_distance.m │ ├── get_STRESS.m │ ├── get_XYZ_sRGB_planes.m │ ├── get_color_body_boundary_mesh.m │ ├── get_color_body_constraints.m │ ├── get_covariance.m │ ├── get_quantum_noise.m │ ├── get_sample.m │ ├── get_sample_temp.m │ ├── get_sigma.m │ ├── get_sigma_linearization.m │ ├── is_camera_sane.m │ ├── is_color_body.m │ ├── is_color_cone.m │ ├── m2M.m │ ├── m2Q.m │ ├── penalty.m │ ├── proLab_Jacobian.m │ ├── reverse_permutation.m │ ├── sensor_noize_param.m │ ├── simulate_camera_noise.m │ └── vertex.m ├── standard_color_conversions │ ├── LMS2XYZ.m │ ├── LMS_matrix.m │ ├── Lab2XYZ.m │ ├── XYZ2CAM16UCS.m │ ├── XYZ2LMS.m │ ├── XYZ2Lab.m │ ├── XYZ2XYZ.m │ ├── XYZ2deviceRGB.m │ ├── XYZ2linRGB.m │ ├── XYZ2sRGB.m │ ├── XYZ2xyY.m │ ├── deviceRGB2XYZ.m │ ├── deviceRGB2linRGB_matrix.m │ ├── deviceRGB_matrix.m │ ├── linRGB2XYZ.m │ ├── linRGB2sRGB.m │ ├── linRGB_matrix.m │ ├── sRGB2XYZ.m │ ├── sRGB2linRGB.m │ └── xyY2XYZ.m ├── test │ ├── check_conditions.m │ ├── check_mQ_compliance.m │ ├── compare_data.m │ ├── executbity_test.m │ ├── test_CIEDE2000_symmetry.m │ ├── test_CIEDE2000_tria_ineq.m │ ├── test_LMS.m │ ├── test_Lab.m │ ├── test_any.m │ ├── test_color_body.m │ ├── test_completeness.m │ ├── test_decomposition.m │ ├── test_deviceRGB.m │ ├── test_get_D65_spectrum.m │ ├── test_get_STRESS.m │ ├── test_get_XYZ_sRGB_planes.m │ ├── test_get_XYZ_spectrum.m │ ├── test_get_quantum_noise.m │ ├── test_get_sample.m │ ├── test_is_camera_sane.m │ ├── test_is_color_cone.m │ ├── test_linRGB_Y_const.m │ ├── test_proLab_model.m │ ├── test_sRGB.m │ ├── test_spectral_math.m │ └── test_xyY.m └── visualization │ ├── for_introduction.m │ ├── generate_all_images.m │ ├── noise_verification.m │ ├── plot_MacAd_Ell.m │ ├── plot_any_spectrum.m │ ├── plot_chromaticity.m │ ├── plot_chromaticity_frame.m │ ├── plot_color_body.m │ ├── plot_color_body_cut.m │ ├── plot_color_body_projection.m │ ├── plot_cube.m │ ├── plot_heteroscedasticity.m │ ├── plot_image_color_distribution.m │ ├── plot_lazer_triangle.m │ ├── plot_sRGB_gamut.m │ ├── plot_sample.m │ ├── plot_sigma.m │ ├── plot_simulate_camera_noise.m │ └── save_plot.m └── python └── XYZ_to_CAM16UCS.py /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ivan Konovalenko 4 | Copyright (c) 2021 Anna Smagina 5 | Copyright (c) 2021 Vladislav Kokhan 6 | Copyright (c) 2021 Smart Engines Service LLC 7 | Copyright (c) 2021 Institute for Information Transmission Problems of the Russian Academy of Sciences (Kharkevich Institute) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProLab: perceptually uniform projective colour coordinate system 2 | 3 | This is the MatLab-implementation of convertions function from and to perceptually uniform colour space proLab 4 | described in the following paper 5 | 6 | @article{konovalenko2020prolab, 7 | title={ProLab: perceptually uniform projective colour coordinate system}, 8 | author={Konovalenko, Ivan A and Smagina, Anna A and Nikolaev, Dmitry P and Nikolaev, Petr P}, 9 | journal={arXiv preprint arXiv:2012.07653}, 10 | year={2020} 11 | } 12 | 13 | ## The main files are listed below 14 | 15 | \matlab\proLab_color_conversions\XYZ2proLab.m — function that implements transformation form CIE XYZ color space to proLab color space. 16 | 17 | \matlab\proLab_color_conversions\proLab2XYZ.m — function that implements transformation form proLab color space to CIE XYZ color space. 18 | 19 | \matlab\code_examples.m — script which contains examples of using XYZ2proLab and proLab2XYZ. 20 | 21 | \matlab\proLab_reference_values.m — script which contains reference values for proLab testing. 22 | 23 | \matlab\proLab_color_conversions\proLab_param.m — function that stores and returns proLab parameters. 24 | 25 | \matlab\search_optimal_proLab_param.m — script that implements the search optimal proLab parameters. 26 | 27 | \matlab\reference_illuminant.m — function that returns CIE XYZ color coordinates of reference illuminant. 28 | 29 | \matlab\D65.m — function that returns CIE XYZ color coordinates of D65 standard illuminant. 30 | -------------------------------------------------------------------------------- /matlab/D65.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = D65 3 | % XYZ = [0.950469988842714, 1.000000013046456, 1.088830006023924]; 4 | XYZ = [0.95047, 1, 1.08883]; 5 | end 6 | 7 | -------------------------------------------------------------------------------- /matlab/code_examples.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath(pwd)); 6 | 7 | %% Examples of using XYZ2proLab and proLab2XYZ 8 | 9 | sizes = {... 10 | [1, 3], ... % one color 11 | [5, 3], ... % vector of colors 12 | [5, 5, 3] ... % matrix of colors (image) 13 | } 14 | for i = 1:size(sizes, 2) 15 | for j = 1:2 16 | if j == 1 17 | XYZ = rand(sizes{i}); 18 | elseif j == 2 19 | XYZ = {rand(sizes{i}), rand(sizes{i})}; 20 | end 21 | XYZ 22 | ref_illum = rand(1,3) 23 | param.Q = rand(4,4) 24 | 25 | proLab = XYZ2proLab(XYZ) 26 | proLab = XYZ2proLab(XYZ, ref_illum) 27 | 28 | XYZ = proLab2XYZ(proLab) 29 | XYZ = proLab2XYZ(proLab, ref_illum) 30 | end 31 | end -------------------------------------------------------------------------------- /matlab/color-data-master/rit-dupont/alman1989.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konovalenko-iitp/proLab/74000f79551ed79c995b15e966f36aa5e21f263e/matlab/color-data-master/rit-dupont/alman1989.mat -------------------------------------------------------------------------------- /matlab/color-data-master/rit-dupont/berns.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konovalenko-iitp/proLab/74000f79551ed79c995b15e966f36aa5e21f263e/matlab/color-data-master/rit-dupont/berns.mat -------------------------------------------------------------------------------- /matlab/color-data-master/witt/table_a1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konovalenko-iitp/proLab/74000f79551ed79c995b15e966f36aa5e21f263e/matlab/color-data-master/witt/table_a1.mat -------------------------------------------------------------------------------- /matlab/color-data-master/witt/table_a2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konovalenko-iitp/proLab/74000f79551ed79c995b15e966f36aa5e21f263e/matlab/color-data-master/witt/table_a2.mat -------------------------------------------------------------------------------- /matlab/data/Canon5DMarkIII_spectralSensitivity.m: -------------------------------------------------------------------------------- 1 | 2 | function RGB = Canon5DMarkIII_spectralSensitivity(lambda) 3 | 4 | [fullLambda, R, G, B] = get_data; 5 | 6 | fullLambda = [-Inf; fullLambda; Inf]; 7 | 8 | R = [R(1); R; R(end)]; 9 | G = [G(1); G; G(end)]; 10 | B = [B(1); B; B(end)]; 11 | 12 | idx = knnsearch(fullLambda,lambda); 13 | idx(lambda <= fullLambda(idx)) = idx(lambda <= fullLambda(idx)) - 1; 14 | t = (lambda - fullLambda(idx))./(fullLambda(idx+1) - fullLambda(idx)); 15 | RGB = [(1-t).*R(idx) + t.*R(idx+1), (1-t).*G(idx) + t.*G(idx+1), (1-t).*B(idx) + t.*B(idx+1)]; 16 | 17 | RGB(isnan(RGB))=0; 18 | 19 | end 20 | 21 | function [fullLambda, R, G, B] = get_data 22 | 23 | data = [380.0,0.00010782834,0.02183312,0.0 24 | 380.6678,0.00010782834,0.02183312,0.0 25 | 381.33557,0.00010782834,0.02183312,0.0 26 | 382.00333,0.00010782834,0.02183312,0.0 27 | 382.6711,0.00010782834,0.02183312,0.0 28 | 383.3389,0.00010782834,0.02183312,0.0 29 | 384.00668,0.00010782834,0.02183312,0.0 30 | 384.67447,0.00010782834,0.02183312,0.0 31 | 385.34222,0.00010782834,0.02183312,0.0 32 | 386.01,0.00010782834,0.02183312,0.0 33 | 386.6778,0.00010782834,0.02183312,0.0 34 | 387.34558,0.00010782834,0.02183312,0.0 35 | 388.01337,0.00010782834,0.02183312,0.0 36 | 388.68112,0.00010782834,0.02183312,0.0 37 | 389.3489,0.00010782834,0.02183312,0.0 38 | 390.0167,0.00010782834,0.02183312,0.0 39 | 390.68448,0.00010782834,0.02183312,0.0 40 | 391.35226,0.00010782834,0.02183312,0.0 41 | 392.02002,0.00010782834,0.02183312,0.0 42 | 392.6878,0.00010782834,0.02183312,0.0 43 | 393.3556,0.00010782834,0.02183312,0.0 44 | 394.02338,0.00010782834,0.02183312,0.0 45 | 394.69116,0.00010782834,0.02183312,0.0 46 | 395.35892,0.00010782834,0.02183312,0.0 47 | 396.0267,0.00010782834,0.02183312,0.0 48 | 396.6945,0.00010782834,0.02183312,0.0 49 | 397.36227,0.00010782834,0.02183312,0.0 50 | 398.03006,0.00010782834,0.02183312,0.0 51 | 398.6978,0.00010782834,0.02183312,0.0 52 | 399.3656,0.00010782834,0.02183312,0.0 53 | 400.0334,0.00010782834,0.02183312,0.00016224377 54 | 400.70117,0.00010782834,0.02183312,0.003407119 55 | 401.36896,0.00010782834,0.02183312,0.0066519943 56 | 402.0367,0.00010782834,0.02183312,0.0075825374 57 | 402.7045,0.00010782834,0.02183312,0.008237106 58 | 403.37228,0.00010782834,0.02183312,0.008891675 59 | 404.04007,-0.000126325,0.021842051,0.009546244 60 | 404.70786,-0.00037346422,0.021884052,0.0102008125 61 | 405.37564,-0.00062060344,0.021926051,0.01085538 62 | 406.0434,-0.00086774264,0.02196805,0.011509949 63 | 406.71118,-0.0011148818,0.022010049,0.012164518 64 | 407.37897,-0.0013620211,0.022052048,0.013695605 65 | 408.04675,-0.0016091602,0.022094049,0.017378163 66 | 408.71454,-0.0018562995,0.022136047,0.02106072 67 | 409.3823,-0.0021034386,0.022263361,0.024743278 68 | 410.05008,-0.0023505779,0.02268664,0.028425833 69 | 410.71786,-0.002597717,0.02310992,0.032108393 70 | 411.38565,-0.0028448564,0.0235332,0.035790946 71 | 412.05344,-0.0030919956,0.02395648,0.039473504 72 | 412.7212,-0.0033391346,0.02437976,0.04315606 73 | 413.38898,-0.0035862739,0.024803039,0.049012855 74 | 414.05676,-0.0038334131,0.02522632,0.057324503 75 | 414.72455,-0.004080552,0.0256496,0.06563615 76 | 415.39233,-0.0043276916,0.026711615,0.073947795 77 | 416.0601,-0.0045748306,0.02823613,0.08225945 78 | 416.72787,-0.00482197,0.029760646,0.09057109 79 | 417.39566,-0.005069109,0.031285163,0.09888274 80 | 418.06345,-0.005316248,0.03280968,0.10762313 81 | 418.73123,-0.0055633876,0.034334194,0.11817072 82 | 419.399,-0.0058105267,0.035858713,0.12871832 83 | 420.06677,-0.006057666,0.03738323,0.13926591 84 | 420.73456,-0.005880511,0.038907744,0.1498135 85 | 421.40234,-0.005589844,0.038823806,0.1603611 86 | 422.07013,-0.005299177,0.038630392,0.17059216 87 | 422.73788,-0.00500851,0.03843698,0.17895192 88 | 423.40567,-0.0047178427,0.03824357,0.1873117 89 | 424.07346,-0.0044271755,0.038050156,0.19567145 90 | 424.74124,-0.004136509,0.037856743,0.20403121 91 | 425.40903,-0.0038458416,0.03766333,0.21239099 92 | 426.07678,-0.0035681692,0.037469916,0.22075075 93 | 426.74457,-0.0033457843,0.037637312,0.23102538 94 | 427.41235,-0.003123399,0.038677286,0.24149124 95 | 428.08014,-0.0029010142,0.039717257,0.2519571 96 | 428.74792,-0.0026786292,0.04075723,0.26242295 97 | 429.41568,-0.002456244,0.041797202,0.2728888 98 | 430.08347,-0.0022338592,0.042837173,0.2885247 99 | 430.75125,-0.0020114742,0.043877147,0.3043901 100 | 431.41904,-0.0017890892,0.044917118,0.32025555 101 | 432.08682,-0.0012432083,0.045957092,0.33529633 102 | 432.75458,-0.00047501345,0.048483174,0.3464645 103 | 433.42236,0.00029318142,0.051813718,0.3576327 104 | 434.09015,0.0010613763,0.05514426,0.36880088 105 | 434.75793,0.0018295712,0.058474805,0.37996906 106 | 435.42572,0.002597766,0.06180535,0.39589697 107 | 436.09348,0.003365961,0.065135896,0.41610152 108 | 436.76126,0.004134156,0.06846644,0.43630603 109 | 437.42905,0.0049023507,0.07179698,0.45587048 110 | 438.09683,0.0052441345,0.07511673,0.47519052 111 | 438.76462,0.005580314,0.07631087,0.49514958 112 | 439.43237,0.0059164935,0.07750502,0.51739055 113 | 440.10016,0.0062526735,0.078699164,0.5396315 114 | 440.76794,0.006588853,0.079893306,0.55458605 115 | 441.43573,0.0069250325,0.081087455,0.56911296 116 | 442.10352,0.007261212,0.0822816,0.5836399 117 | 442.77127,0.0075973915,0.083475746,0.5926862 118 | 443.43906,0.007801154,0.08466989,0.5979862 119 | 444.10684,0.0077958168,0.085338816,0.6032863 120 | 444.77463,0.00779048,0.085079335,0.6085864 121 | 445.4424,0.0077851424,0.084819846,0.6138865 122 | 446.11017,0.007779805,0.08456036,0.6191866 123 | 446.77795,0.007774468,0.084300876,0.6244866 124 | 447.44574,0.0077691306,0.08404139,0.62831193 125 | 448.11353,0.007763793,0.0837819,0.6313121 126 | 448.7813,0.0077584563,0.08352241,0.6343122 127 | 449.4491,0.007644638,0.08326293,0.63731235 128 | 450.11685,0.007502582,0.08450485,0.64031255 129 | 450.78464,0.007360526,0.086337715,0.6433127 130 | 451.45242,0.0072184703,0.08817057,0.64631283 131 | 452.1202,0.0070764143,0.09000344,0.64931303 132 | 452.788,0.0069343587,0.0918363,0.6523132 133 | 453.45575,0.0067923027,0.09366916,0.6575085 134 | 454.12354,0.006650247,0.09550203,0.6650917 135 | 454.79132,0.0066089923,0.09733489,0.67267483 136 | 455.4591,0.0069679255,0.0993864,0.680258 137 | 456.1269,0.0073268586,0.10418074,0.6878412 138 | 456.79465,0.0076857917,0.108975075,0.6954243 139 | 457.46243,0.008044725,0.11376941,0.7030075 140 | 458.13022,0.008403658,0.11856375,0.7116498 141 | 458.798,0.0087625915,0.123358086,0.7213096 142 | 459.4658,0.009121524,0.12815242,0.7309694 143 | 460.13354,0.009480458,0.13294676,0.7406293 144 | 460.80133,0.009538009,0.13787398,0.75028914 145 | 461.46912,0.009395953,0.14493103,0.75994897 146 | 462.1369,0.009253898,0.1519881,0.764384 147 | 462.8047,0.009111841,0.15904516,0.76525587 148 | 463.47244,0.008969786,0.16610222,0.7661277 149 | 464.14023,0.00882773,0.17315929,0.7669996 150 | 464.808,0.008685674,0.18021634,0.76787144 151 | 465.4758,0.008543618,0.1872734,0.76874334 152 | 466.1436,0.008408136,0.19577241,0.76961523 153 | 466.81134,0.008971771,0.20826063,0.77048707 154 | 467.47913,0.009535407,0.22074886,0.77135897 155 | 468.1469,0.010099043,0.23323709,0.76825225 156 | 468.8147,0.010662679,0.24601363,0.7648096 157 | 469.48248,0.011226314,0.26649538,0.761367 158 | 470.15024,0.011789951,0.2869771,0.75792444 159 | 470.81802,0.012353586,0.30086133,0.7544818 160 | 471.4858,0.0129172215,0.30183378,0.7510392 161 | 472.1536,0.013554805,0.30280623,0.7475966 162 | 472.82138,0.014300278,0.3037787,0.744154 163 | 473.48914,0.015045752,0.30475116,0.7392376 164 | 474.15692,0.015791224,0.33855018,0.7318976 165 | 474.8247,0.016536698,0.37053123,0.72455764 166 | 475.4925,0.017282171,0.39000484,0.7172176 167 | 476.16028,0.018027645,0.4094785,0.7098776 168 | 476.82803,0.018773118,0.42895213,0.7025376 169 | 477.49582,0.01951859,0.44717124,0.6951976 170 | 478.1636,0.020245854,0.46491522,0.68694425 171 | 478.8314,0.020968605,0.4826592,0.67797977 172 | 479.49918,0.021691354,0.49850976,0.66901535 173 | 480.16693,0.022414103,0.51359844,0.6600509 174 | 480.83472,0.023136852,0.5286872,0.6510865 175 | 481.5025,0.023859603,0.5381352,0.6421913 176 | 482.1703,0.024582352,0.5420412,0.6333116 177 | 482.83807,0.025305102,0.54594713,0.62443197 178 | 483.50583,0.025955115,0.54985315,0.6155523 179 | 484.1736,0.026307415,0.55375916,0.60667264 180 | 484.8414,0.026659714,0.55766517,0.59748006 181 | 485.5092,0.027012015,0.5615712,0.58796036 182 | 486.17697,0.027364315,0.56547713,0.57844067 183 | 486.84473,0.027716616,0.56938314,0.56892097 184 | 487.5125,0.028068915,0.5733857,0.5593804 185 | 488.1803,0.028421216,0.5795831,0.54948294 186 | 488.84808,0.028773516,0.58578056,0.5395855 187 | 489.51587,0.029182106,0.591978,0.529688 188 | 490.18362,0.03005461,0.5981754,0.51979053 189 | 490.8514,0.030927114,0.60503954,0.50989306 190 | 491.5192,0.03179962,0.6149403,0.5035702 191 | 492.18698,0.032672122,0.62484103,0.4995921 192 | 492.85477,0.033544622,0.6347418,0.49561402 193 | 493.52255,0.034417126,0.6446425,0.49163592 194 | 494.1903,0.03528963,0.6545432,0.48765785 195 | 494.8581,0.036162134,0.6656813,0.48367977 196 | 495.52588,0.037550475,0.679268,0.47970167 197 | 496.19366,0.038944,0.6928547,0.4757236 198 | 496.86145,0.04033752,0.70644146,0.4717455 199 | 497.5292,0.04173105,0.72004515,0.4668818 200 | 498.197,0.04312457,0.73486,0.4619212 201 | 498.86478,0.044518095,0.74967486,0.45696056 202 | 499.53256,0.045911618,0.7644897,0.45199993 203 | 500.20035,0.047305144,0.7762023,0.44703934 204 | 500.8681,0.048306905,0.7769698,0.4420787 205 | 501.5359,0.049247336,0.77773726,0.43711808 206 | 502.20367,0.050187767,0.7785047,0.4309524 207 | 502.87146,0.051128197,0.7792722,0.42062443 208 | 503.53925,0.05206863,0.78003967,0.41029644 209 | 504.207,0.05300906,0.78080714,0.39996845 210 | 504.8748,0.053949494,0.7815746,0.38964045 211 | 505.54257,0.054889925,0.7823421,0.37908068 212 | 506.21036,0.055830356,0.7839582,0.36850405 213 | 506.87814,0.057176422,0.78605676,0.3579274 214 | 507.5459,0.058645483,0.7881553,0.3473508 215 | 508.21368,0.06011454,0.7902539,0.3372075 216 | 508.88147,0.0615836,0.79235244,0.32795316 217 | 509.54926,0.06305266,0.794451,0.31869885 218 | 510.21704,0.064521715,0.7965496,0.30944455 219 | 510.8848,0.065990776,0.7986482,0.3001902 220 | 511.55258,0.06745984,0.80435973,0.29130125 221 | 512.22034,0.069352,0.8148535,0.28619602 222 | 512.8881,0.07144928,0.82534724,0.2810908 223 | 513.5559,0.07354655,0.83584106,0.2759856 224 | 514.2237,0.07564383,0.8463348,0.27088037 225 | 514.8915,0.0777411,0.85682863,0.26577514 226 | 515.55927,0.07983838,0.8682588,0.26066995 227 | 516.22705,0.08193565,0.87980926,0.25556472 228 | 516.89484,0.08403292,0.89135975,0.2504595 229 | 517.5626,0.0861302,0.90291023,0.24529095 230 | 518.2304,0.08822747,0.91450083,0.24010757 231 | 518.8982,0.09001737,0.9261838,0.23492418 232 | 519.5659,0.09172733,0.9378668,0.2297408 233 | 520.2337,0.09343729,0.9495498,0.2245574 234 | 520.9015,0.09514725,0.9612328,0.21937402 235 | 521.5693,0.09685721,0.9646435,0.21419063 236 | 522.23706,0.09856717,0.9665888,0.20923187 237 | 522.90485,0.100277126,0.96853405,0.2047418 238 | 523.57263,0.101902634,0.9704793,0.20025174 239 | 524.2404,0.103248395,0.97242457,0.19576167 240 | 524.9082,0.10459415,0.9743699,0.1912716 241 | 525.576,0.10593991,0.97631514,0.18678154 242 | 526.2437,0.10728567,0.9782604,0.18229148 243 | 526.9115,0.10863143,0.98020566,0.1778014 244 | 527.5793,0.10997719,0.9814668,0.17331134 245 | 528.2471,0.111322954,0.98237824,0.16934636 246 | 528.91486,0.11266871,0.9832897,0.1658346 247 | 529.58264,0.11398856,0.98420113,0.16232283 248 | 530.2504,0.11524542,0.98511255,0.15881108 249 | 530.9182,0.11650226,0.986024,0.1552993 250 | 531.586,0.117759116,0.98693544,0.15178755 251 | 532.2538,0.11901597,0.9878469,0.1482758 252 | 532.9215,0.120272815,0.98826116,0.14476402 253 | 533.5893,0.12152967,0.988288,0.14125226 254 | 534.2571,0.12278652,0.9883148,0.13943098 255 | 534.92487,0.12493028,0.9883417,0.13762039 256 | 535.59265,0.12810881,0.9883685,0.13580978 257 | 536.26044,0.13128734,0.98839533,0.13399918 258 | 536.9282,0.13446587,0.98842216,0.13218857 259 | 537.596,0.1376444,0.988449,0.13037796 260 | 538.2638,0.14082293,0.98847586,0.12856737 261 | 538.9316,0.14400145,0.984579,0.12675676 262 | 539.5993,0.14717999,0.9803331,0.12478007 263 | 540.2671,0.15038587,0.9760871,0.12257953 264 | 540.9349,0.1537202,0.97184116,0.12037899 265 | 541.60266,0.15705453,0.96759516,0.11817845 266 | 542.27045,0.16038886,0.9633492,0.11597791 267 | 542.93823,0.16372319,0.9591032,0.11377737 268 | 543.606,0.16705751,0.9548573,0.11157683 269 | 544.2738,0.17039183,0.95030296,0.1093763 270 | 544.9416,0.17372616,0.9449337,0.10717575 271 | 545.6094,0.17706048,0.93956447,0.10552976 272 | 546.2771,0.18049626,0.9341953,0.1039712 273 | 546.9449,0.18440565,0.92882603,0.102412626 274 | 547.6127,0.18831503,0.92345685,0.100854054 275 | 548.28046,0.19222443,0.9180876,0.09929548 276 | 548.94824,0.19613382,0.91271836,0.09773692 277 | 549.616,0.2000432,0.90734917,0.096178345 278 | 550.2838,0.2039526,0.90343875,0.09461977 279 | 550.9516,0.20786199,0.9003821,0.09295915 280 | 551.6194,0.21177137,0.89732546,0.09105149 281 | 552.2872,0.21631147,0.8942689,0.08914382 282 | 552.9549,0.2214241,0.8912122,0.08723616 283 | 553.6227,0.22653674,0.8881556,0.0853285 284 | 554.29047,0.23164938,0.88509893,0.083420835 285 | 554.95825,0.23676202,0.88204235,0.08151317 286 | 555.62604,0.24187465,0.8789857,0.079605505 287 | 556.2938,0.24698728,0.8759641,0.07769784 288 | 556.9616,0.25209993,0.87294304,0.07609418 289 | 557.6294,0.25721255,0.8699219,0.07494373 290 | 558.2972,0.26306564,0.8669008,0.07379327 291 | 558.96497,0.2697884,0.8638797,0.07264282 292 | 559.63275,0.2765112,0.86085856,0.07149236 293 | 560.3005,0.28323397,0.85783744,0.0703419 294 | 560.96826,0.28995672,0.8548163,0.06919145 295 | 561.63605,0.2966795,0.8504613,0.06804099 296 | 562.30383,0.30340227,0.844969,0.067420706 297 | 562.9716,0.31012505,0.8394766,0.06703999 298 | 563.6394,0.31707644,0.83398426,0.06665927 299 | 564.3072,0.32414103,0.82849187,0.066278554 300 | 564.975,0.33120564,0.82299954,0.06589784 301 | 565.64276,0.33827022,0.81750715,0.06551712 302 | 566.31055,0.3453348,0.8120148,0.0651364 303 | 566.9783,0.3523994,0.8046978,0.064755686 304 | 567.64606,0.36058617,0.79544634,0.06437497 305 | 568.31384,0.36950412,0.7861948,0.063591346 306 | 568.9816,0.37842208,0.77694327,0.062490467 307 | 569.6494,0.38734004,0.7676918,0.061389584 308 | 570.3172,0.39625797,0.7583633,0.060288705 309 | 570.985,0.4052071,0.7489663,0.059187826 310 | 571.6528,0.4141698,0.7395693,0.058086943 311 | 572.32056,0.42313245,0.7301723,0.056986064 312 | 572.98834,0.43209514,0.72077525,0.055885185 313 | 573.65607,0.44105783,0.71021307,0.0547843 314 | 574.32385,0.4500205,0.69905853,0.05453482 315 | 574.99164,0.45931745,0.68790394,0.054301582 316 | 575.6594,0.4720428,0.6767494,0.054068346 317 | 576.3272,0.48476815,0.66583306,0.05383511 318 | 576.995,0.4974935,0.65556186,0.053601872 319 | 577.6628,0.51021886,0.64529073,0.053368635 320 | 578.33057,0.52187,0.6350196,0.0531354 321 | 578.99835,0.5329531,0.62474847,0.05290216 322 | 579.66614,0.54403615,0.61500764,0.052588798 323 | 580.33386,0.5551192,0.60637295,0.052150298 324 | 581.00165,0.5662023,0.59773827,0.051711798 325 | 581.66943,0.5766303,0.5891036,0.0512733 326 | 582.3372,0.5870224,0.5804689,0.0508348 327 | 583.005,0.5974146,0.5721366,0.0503963 328 | 583.6728,0.60780674,0.5659068,0.049957804 329 | 584.3406,0.6181989,0.55967706,0.049519304 330 | 585.00836,0.628591,0.5534473,0.049080804 331 | 585.67615,0.63898313,0.54721755,0.049044736 332 | 586.34393,0.64937526,0.5409878,0.049107734 333 | 587.01166,0.65778095,0.53475803,0.04917073 334 | 587.67944,0.6652696,0.5285283,0.049233727 335 | 588.3472,0.67275834,0.52020586,0.049296726 336 | 589.015,0.680247,0.50963545,0.049359724 337 | 589.6828,0.68773574,0.49906507,0.049422722 338 | 590.3506,0.6952244,0.4884947,0.04948572 339 | 591.0184,0.70271313,0.4776833,0.04934074 340 | 591.68616,0.70422775,0.46676663,0.04839988 341 | 592.35394,0.7018439,0.45584998,0.047459025 342 | 593.0217,0.6994601,0.4449333,0.046518166 343 | 593.68945,0.69707626,0.43328846,0.04557731 344 | 594.35724,0.69469243,0.42059514,0.04463645 345 | 595.025,0.6923086,0.40790182,0.04369559 346 | 595.6928,0.6899248,0.39520848,0.042754736 347 | 596.3606,0.68754095,0.38233575,0.041813876 348 | 597.0284,0.6851572,0.3692693,0.041059103 349 | 597.69617,0.6814117,0.3562029,0.040415198 350 | 598.36395,0.6764439,0.34313646,0.039771292 351 | 599.03174,0.671476,0.33062896,0.039127387 352 | 599.6995,0.66650814,0.31857523,0.03848348 353 | 600.36725,0.6615403,0.3065215,0.037839577 354 | 601.03503,0.65657246,0.29446778,0.03719567 355 | 601.7028,0.6516046,0.2831938,0.036551766 356 | 602.3706,0.6466368,0.2723918,0.035933577 357 | 603.0384,0.6416653,0.26158983,0.035905458 358 | 603.7062,0.63597834,0.25078782,0.03587734 359 | 604.37396,0.63029134,0.24033844,0.03584922 360 | 605.04175,0.62460434,0.23070768,0.035821103 361 | 605.70953,0.61891735,0.2210769,0.03579298 362 | 606.3773,0.61323035,0.21144614,0.03576486 363 | 607.0451,0.6075434,0.20181538,0.035736743 364 | 607.7128,0.6018564,0.19262555,0.035708625 365 | 608.3806,0.5961694,0.18473184,0.035271756 366 | 609.0484,0.5907344,0.17683814,0.034330897 367 | 609.7162,0.58555794,0.16894443,0.03339004 368 | 610.384,0.5803815,0.16105074,0.032449182 369 | 611.05176,0.5752051,0.1548924,0.031508323 370 | 611.71954,0.5700286,0.15062442,0.030567467 371 | 612.3873,0.5648522,0.14635643,0.029626608 372 | 613.0551,0.5596757,0.14208844,0.02868575 373 | 613.7229,0.55449927,0.13782045,0.027744893 374 | 614.3906,0.54932284,0.13355246,0.02765906 375 | 615.0584,0.54415435,0.12928449,0.027704056 376 | 615.7262,0.5389861,0.1250165,0.02774905 377 | 616.394,0.53381777,0.120748505,0.027794046 378 | 617.06177,0.5286495,0.11699539,0.027839042 379 | 617.72955,0.52348125,0.113344096,0.027884036 380 | 618.39734,0.51831293,0.1096928,0.027929032 381 | 619.0651,0.5131447,0.106041506,0.027974026 382 | 619.7329,0.5079764,0.10239021,0.028022626 383 | 620.4007,0.501219,0.098738916,0.028089067 384 | 621.0684,0.4941653,0.09508762,0.028155508 385 | 621.7362,0.48711166,0.09143633,0.028221946 386 | 622.404,0.480058,0.08805026,0.028288387 387 | 623.0718,0.47300437,0.08578652,0.028354827 388 | 623.73956,0.46595073,0.08352279,0.028421266 389 | 624.40735,0.46005914,0.08125905,0.028487707 390 | 625.07513,0.4544202,0.07899531,0.028554147 391 | 625.7429,0.44878125,0.07673158,0.028517215 392 | 626.4107,0.44314232,0.07446784,0.028135095 393 | 627.0785,0.43750337,0.0722041,0.027752975 394 | 627.7462,0.43186444,0.069940366,0.027370855 395 | 628.414,0.42622548,0.067833364,0.026988735 396 | 629.0818,0.42058656,0.06585594,0.026606616 397 | 629.7496,0.41530332,0.06387853,0.026224496 398 | 630.41736,0.4100476,0.061901115,0.025842376 399 | 631.08514,0.40479186,0.059923697,0.025460256 400 | 631.7529,0.39953613,0.057946283,0.025729157 401 | 632.4207,0.3942804,0.05596887,0.026054224 402 | 633.0885,0.38902467,0.05399145,0.026379293 403 | 633.7563,0.38376895,0.052014038,0.02670436 404 | 634.424,0.37851322,0.051190995,0.027029427 405 | 635.0918,0.3736588,0.050491016,0.027354496 406 | 635.7596,0.3689062,0.049791034,0.027679563 407 | 636.42737,0.3641536,0.049091052,0.02800463 408 | 637.09515,0.359401,0.04839107,0.02836802 409 | 637.76294,0.35464838,0.04769109,0.028771466 410 | 638.4307,0.34989575,0.04699111,0.02917491 411 | 639.0985,0.34514314,0.046291128,0.029578354 412 | 639.7663,0.34039053,0.04549955,0.0299818 413 | 640.4341,0.33559096,0.044447172,0.030385243 414 | 641.1018,0.33073434,0.043394797,0.030788688 415 | 641.7696,0.3258777,0.042342417,0.031192131 416 | 642.4374,0.32102108,0.04129004,0.031353448 417 | 643.10516,0.31616446,0.040237665,0.031166194 418 | 643.77295,0.31130785,0.039185286,0.030978942 419 | 644.44073,0.30645123,0.03813291,0.03079169 420 | 645.1085,0.30159461,0.037080534,0.030604439 421 | 645.7763,0.29673797,0.03625887,0.030417185 422 | 646.4441,0.29190215,0.03558091,0.030229934 423 | 647.1119,0.28707328,0.034902956,0.030042682 424 | 647.77966,0.28224444,0.034225,0.02985543 425 | 648.4474,0.27741557,0.033547044,0.029668177 426 | 649.1152,0.2725867,0.032869086,0.02931709 427 | 649.78296,0.26775786,0.032191128,0.028840054 428 | 650.45074,0.262929,0.031513173,0.028363017 429 | 651.1185,0.25810012,0.030835217,0.027885979 430 | 651.7863,0.25342762,0.030564198,0.027408943 431 | 652.4541,0.24929272,0.030304711,0.026931906 432 | 653.1219,0.24515781,0.030045224,0.02645487 433 | 653.7897,0.24102288,0.029785737,0.025977833 434 | 654.45746,0.23688798,0.029526252,0.025837475 435 | 655.1252,0.23275305,0.029266765,0.026257448 436 | 655.79297,0.22861814,0.029007278,0.026677419 437 | 656.46075,0.22448322,0.028747791,0.02709739 438 | 657.12854,0.2203483,0.028401429,0.02751736 439 | 657.7963,0.21574397,0.027877646,0.02793733 440 | 658.4641,0.21093012,0.027353862,0.0283573 441 | 659.1319,0.20611626,0.026830079,0.028777272 442 | 659.7997,0.2013024,0.026306296,0.029055474 443 | 660.46747,0.19648853,0.025782513,0.029156853 444 | 661.13525,0.19167466,0.025258727,0.029258229 445 | 661.803,0.1868608,0.024734944,0.029359605 446 | 662.47076,0.18367323,0.02421116,0.029460983 447 | 663.13855,0.1806449,0.024200307,0.02956236 448 | 663.80634,0.17761657,0.024425363,0.029663736 449 | 664.4741,0.17458822,0.024650421,0.029765114 450 | 665.1419,0.17155989,0.024875479,0.02986649 451 | 665.8097,0.16853154,0.025100535,0.029967824 452 | 666.4775,0.1655032,0.025325593,0.030068738 453 | 667.14526,0.16247486,0.02555065,0.03016965 454 | 667.81305,0.15917376,0.025775708,0.030270563 455 | 668.4808,0.15450697,0.025959,0.030371478 456 | 669.14856,0.14984018,0.02517092,0.03047239 457 | 669.81635,0.14517339,0.024382839,0.030573305 458 | 670.48413,0.14050658,0.02359476,0.030674217 459 | 671.1519,0.13583979,0.02280668,0.030775132 460 | 671.8197,0.131173,0.022018598,0.030912487 461 | 672.4875,0.1265062,0.021230519,0.031053081 462 | 673.1553,0.121839404,0.02044244,0.031193675 463 | 673.82306,0.117083676,0.019654358,0.03133427 464 | 674.49084,0.11227798,0.019207701,0.031474862 465 | 675.15857,0.10747227,0.019278586,0.03161546 466 | 675.82635,0.10266657,0.019349469,0.03175605 467 | 676.49414,0.097860865,0.019420354,0.031896647 468 | 677.1619,0.09305516,0.019491239,0.03182627 469 | 677.8297,0.08824946,0.019562121,0.03131165 470 | 678.4975,0.08344375,0.019633006,0.030797033 471 | 679.1653,0.078886926,0.019703891,0.030282414 472 | 679.83307,0.07622697,0.019774774,0.029767795 473 | 680.50085,0.073567025,0.018851262,0.029253175 474 | 681.16864,0.07090707,0.017602865,0.028738556 475 | 681.83636,0.068247125,0.016354468,0.028223937 476 | 682.50415,0.06558717,0.015106071,0.027709318 477 | 683.17194,0.062927224,0.013857673,0.02789428 478 | 683.8397,0.06026727,0.012609276,0.028331215 479 | 684.5075,0.05760732,0.011360879,0.028768146 480 | 685.1753,0.055268575,0.010112482,0.029205078 481 | 685.8431,0.053181607,0.009891883,0.02964201 482 | 686.51086,0.05109464,0.009790842,0.030078942 483 | 687.17865,0.049007673,0.009689802,0.030515874 484 | 687.84644,0.04692071,0.009588762,0.030952806 485 | 688.51416,0.044833742,0.009487722,0.03126286 486 | 689.18195,0.042746775,0.009386682,0.030755907 487 | 689.84973,0.04065981,0.009285642,0.030248955 488 | 690.5175,0.038572844,0.009184602,0.029742002 489 | 691.1853,0.036485877,0.009083562,0.029235052 490 | 691.8531,0.034398913,0.0089825215,0.0287281 491 | 692.5209,0.032311946,0.009106587,0.028221147 492 | 693.18866,0.032162666,0.0096203415,0.027714197 493 | 693.85645,0.032225665,0.010134096,0.027207244 494 | 694.52423,0.032288663,0.010647852,0.027261566 495 | 695.192,0.032351658,0.011161607,0.027779724 496 | 695.85974,0.032414656,0.011675362,0.028297884 497 | 696.5275,0.032477655,0.012189116,0.028816042 498 | 697.1953,0.032540653,0.012702871,0.0293342 499 | 697.8631,0.03260365,0.013216626,0.02985236 500 | 698.5309,0.03266665,0.012102432,0.030370519 501 | 699.19867,0.032729648,0.0109015005,0.030888677 502 | 699.86646,0.032792646,0.009700569,0.031406835 503 | 700.53424,0.032855645,0.008499637,0.03147308 504 | 701.202,0.032918643,0.007298706,0.031513304 505 | 701.8698,0.03298164,0.0060977745,0.031553525 506 | 702.53754,0.03304464,0.004896843,0.031593747 507 | 703.2053,0.03310764,0.0036959115,0.031633966 508 | 703.8731,0.033170633,0.0031432922,0.031674188 509 | 704.5409,0.03323363,0.0035920744,0.03171441 510 | 705.2087,0.03329663,0.0040408564,0.03175463 511 | 705.87646,0.03335963,0.004489639,0.031666998 512 | 706.54425,0.033422627,0.004938421,0.03134255 513 | 707.21204,0.033485625,0.005387203,0.031018103 514 | 707.8798,0.033548623,0.0058359853,0.030693656 515 | 708.5476,0.03361162,0.0062847673,0.03036921 516 | 709.21533,0.03367462,0.0067335493,0.030044762 517 | 709.8831,0.03373762,0.0071823318,0.029720316 518 | 710.5509,0.033800617,0.0076311138,0.029395869 519 | 711.2187,0.033863615,0.0076381527,0.029071422 520 | 711.8865,0.03392661,0.007617952,0.02960675 521 | 712.55426,0.03398961,0.0075977505,0.030412054 522 | 713.22205,0.034052607,0.007577549,0.031217357 523 | 713.88983,0.034115605,0.0075573483,0.03202266 524 | 714.5576,0.034178603,0.007537147,0.032827962 525 | 715.2254,0.0342416,0.007516946,0.033633266 526 | 715.8931,0.0343046,0.0072006327,0.03443857 527 | 716.5609,0.0343676,0.0067293695,0.035243873 528 | 717.2287,0.03437028,0.006258107,0.035294443 529 | 717.8965,0.03437028,0.0057868436,0.035294443 530 | 718.5643,0.03437028,0.005315581,0.035294443 531 | 719.23206,0.03437028,0.0048443177,0.035294443 532 | 719.89984,0.03437028,0.004759088,0.035294443 533 | 720.5676,0.03437028,0.004759088,0.035294443 534 | 721.2354,0.03437028,0.004759088,0.035294443 535 | 721.9032,0.03437028,0.004759088,0.035294443 536 | 722.5709,0.03437028,0.004759088,0.035294443 537 | 723.2387,0.03437028,0.004759088,0.035294443 538 | 723.9065,0.03437028,0.004759088,0.035294443 539 | 724.5743,0.03437028,0.004759088,0.035294443 540 | 725.24207,0.03437028,0.004759088,0.035294443 541 | 725.90985,0.03437028,0.004759088,0.035294443 542 | 726.57764,0.03437028,0.004759088,0.035294443 543 | 727.2454,0.03437028,0.004759088,0.035294443 544 | 727.9132,0.03437028,0.004759088,0.035294443 545 | 728.581,0.03437028,0.004759088,0.035294443 546 | 729.2487,0.03437028,0.004759088,0.035294443 547 | 729.9165,0.03437028,0.004759088,0.035294443 548 | 730.5843,0.03437028,0.004759088,0.035294443 549 | 731.2521,0.03437028,0.004759088,0.035294443 550 | 731.91986,0.03437028,0.004759088,0.035294443 551 | 732.58765,0.03437028,0.004759088,0.035294443 552 | 733.25543,0.03437028,0.004759088,0.035294443 553 | 733.9232,0.03437028,0.004759088,0.035294443 554 | 734.591,0.03437028,0.004759088,0.035294443 555 | 735.2588,0.03437028,0.004759088,0.035294443 556 | 735.9266,0.03437028,0.004759088,0.035294443 557 | 736.5943,0.03437028,0.004759088,0.035294443 558 | 737.2621,0.03437028,0.004759088,0.035294443 559 | 737.9299,0.03437028,0.004759088,0.035294443 560 | 738.59766,0.03437028,0.004759088,0.035294443 561 | 739.26544,0.03437028,0.004759088,0.035294443 562 | 739.9332,0.03437028,0.004759088,0.035294443 563 | 740.601,0.03437028,0.004759088,0.035294443 564 | 741.2688,0.03437028,0.004759088,0.035294443 565 | 741.9366,0.03437028,0.004759088,0.035294443 566 | 742.6044,0.03437028,0.004759088,0.035294443 567 | 743.2721,0.03437028,0.004759088,0.035294443 568 | 743.9399,0.03437028,0.004759088,0.035294443 569 | 744.60767,0.03437028,0.004759088,0.035294443 570 | 745.27545,0.03437028,0.004759088,0.035294443 571 | 745.94324,0.03437028,0.004759088,0.035294443 572 | 746.611,0.03437028,0.004759088,0.035294443 573 | 747.2788,0.03437028,0.004759088,0.035294443 574 | 747.9466,0.03437028,0.004759088,0.035294443 575 | 748.6144,0.03437028,0.004759088,0.035294443 576 | 749.28217,0.03437028,0.004759088,0.035294443 577 | 749.9499,0.03437028,0.004759088,0.035294443 578 | 750.6177,0.03437028,0.004759088,0.035294443 579 | 751.28546,0.03437028,0.004759088,0.035294443 580 | 751.95325,0.03437028,0.004759088,0.035294443 581 | 752.62103,0.03437028,0.004759088,0.035294443 582 | 753.2888,0.03437028,0.004759088,0.035294443 583 | 753.9566,0.03437028,0.004759088,0.035294443 584 | 754.6244,0.03437028,0.004759088,0.035294443 585 | 755.2922,0.03437028,0.004759088,0.035294443 586 | 755.95996,0.03437028,0.004759088,0.035294443 587 | 756.6277,0.03437028,0.004759088,0.035294443 588 | 757.2955,0.03437028,0.004759088,0.035294443 589 | 757.96326,0.03437028,0.004759088,0.035294443 590 | 758.63104,0.03437028,0.004759088,0.035294443 591 | 759.2988,0.03437028,0.004759088,0.035294443 592 | 759.9666,0.03437028,0.004759088,0.035294443 593 | 760.6344,0.03437028,0.004759088,0.035294443 594 | 761.3022,0.03437028,0.004759088,0.035294443 595 | 761.97,0.03437028,0.004759088,0.035294443 596 | 762.63776,0.03437028,0.004759088,0.035294443 597 | 763.3055,0.03437028,0.004759088,0.035294443 598 | 763.97327,0.03437028,0.004759088,0.035294443 599 | 764.64105,0.03437028,0.004759088,0.035294443 600 | 765.30884,0.03437028,0.004759088,0.035294443 601 | 765.9766,0.03437028,0.004759088,0.035294443 602 | 766.6444,0.03437028,0.004759088,0.035294443 603 | 767.3122,0.03437028,0.004759088,0.035294443 604 | 767.98,0.03437028,0.004759088,0.035294443 605 | 768.64777,0.03437028,0.004759088,0.035294443 606 | 769.31555,0.03437028,0.004759088,0.035294443 607 | 769.9833,0.03437028,0.004759088,0.035294443 608 | 770.65106,0.03437028,0.004759088,0.035294443 609 | 771.31885,0.03437028,0.004759088,0.035294443 610 | 771.98663,0.03437028,0.004759088,0.035294443 611 | 772.6544,0.03437028,0.004759088,0.035294443 612 | 773.3222,0.03437028,0.004759088,0.035294443 613 | 773.99,0.03437028,0.004759088,0.035294443 614 | 774.6578,0.03437028,0.004759088,0.035294443 615 | 775.32556,0.03437028,0.004759088,0.035294443 616 | 775.99335,0.03437028,0.004759088,0.035294443 617 | 776.6611,0.03437028,0.004759088,0.035294443 618 | 777.32886,0.03437028,0.004759088,0.035294443 619 | 777.99664,0.03437028,0.004759088,0.035294443 620 | 778.6644,0.03437028,0.004759088,0.035294443 621 | 779.3322,0.03437028,0.004759088,0.035294443 622 | 780.0,0.03437028,0.004759088,0.035294443]; 623 | 624 | fullLambda = data(:, 1); 625 | R = data(:, 2); 626 | G = data(:, 3); 627 | B = data(:, 4); 628 | 629 | end 630 | -------------------------------------------------------------------------------- /matlab/data/get_D65_spectrum.m: -------------------------------------------------------------------------------- 1 | 2 | function D65_spectral_power = get_D65_spectrum(lambda) 3 | 4 | data = D65_spectrum_data(); 5 | full_lambda = data(:, 1); 6 | full_spectral_power = data(:, 2); 7 | 8 | full_lambda = [-Inf; full_lambda; Inf]; 9 | full_spectral_power = [full_spectral_power(1); ... 10 | full_spectral_power; ... 11 | full_spectral_power(end)]; 12 | idx = knnsearch(full_lambda,lambda); 13 | idx(lambda <= full_lambda(idx)) = idx(lambda <= full_lambda(idx)) - 1; 14 | t = (lambda - full_lambda(idx))./(full_lambda(idx+1) - full_lambda(idx)); 15 | [full_lambda(idx) lambda full_lambda(idx+1) t]; 16 | D65_spectral_power = (1-t).*full_spectral_power(idx) + t.*full_spectral_power(idx+1); 17 | D65_spectral_power(isnan(D65_spectral_power))=0; 18 | 19 | end 20 | 21 | 22 | function data = D65_spectrum_data() 23 | 24 | data = [ ... 25 | 300, 0.034100 26 | 301, 0.360140 27 | 302, 0.686180 28 | 303, 1.012220 29 | 304, 1.338260 30 | 305, 1.664300 31 | 306, 1.990340 32 | 307, 2.316380 33 | 308, 2.642420 34 | 309, 2.968460 35 | 310, 3.294500 36 | 311, 4.988650 37 | 312, 6.682800 38 | 313, 8.376950 39 | 314, 10.071100 40 | 315, 11.765200 41 | 316, 13.459400 42 | 317, 15.153500 43 | 318, 16.847700 44 | 319, 18.541800 45 | 320, 20.236000 46 | 321, 21.917700 47 | 322, 23.599500 48 | 323, 25.281200 49 | 324, 26.963000 50 | 325, 28.644700 51 | 326, 30.326500 52 | 327, 32.008200 53 | 328, 33.690000 54 | 329, 35.371700 55 | 330, 37.053500 56 | 331, 37.343000 57 | 332, 37.632600 58 | 333, 37.922100 59 | 334, 38.211600 60 | 335, 38.501100 61 | 336, 38.790700 62 | 337, 39.080200 63 | 338, 39.369700 64 | 339, 39.659300 65 | 340, 39.948800 66 | 341, 40.445100 67 | 342, 40.941400 68 | 343, 41.437700 69 | 344, 41.934000 70 | 345, 42.430200 71 | 346, 42.926500 72 | 347, 43.422800 73 | 348, 43.919100 74 | 349, 44.415400 75 | 350, 44.911700 76 | 351, 45.084400 77 | 352, 45.257000 78 | 353, 45.429700 79 | 354, 45.602300 80 | 355, 45.775000 81 | 356, 45.947700 82 | 357, 46.120300 83 | 358, 46.293000 84 | 359, 46.465600 85 | 360, 46.638300 86 | 361, 47.183400 87 | 362, 47.728500 88 | 363, 48.273500 89 | 364, 48.818600 90 | 365, 49.363700 91 | 366, 49.908800 92 | 367, 50.453900 93 | 368, 50.998900 94 | 369, 51.544000 95 | 370, 52.089100 96 | 371, 51.877700 97 | 372, 51.666400 98 | 373, 51.455000 99 | 374, 51.243700 100 | 375, 51.032300 101 | 376, 50.820900 102 | 377, 50.609600 103 | 378, 50.398200 104 | 379, 50.186900 105 | 380, 49.975500 106 | 381, 50.442800 107 | 382, 50.910000 108 | 383, 51.377300 109 | 384, 51.844600 110 | 385, 52.311800 111 | 386, 52.779100 112 | 387, 53.246400 113 | 388, 53.713700 114 | 389, 54.180900 115 | 390, 54.648200 116 | 391, 57.458900 117 | 392, 60.269500 118 | 393, 63.080200 119 | 394, 65.890900 120 | 395, 68.701500 121 | 396, 71.512200 122 | 397, 74.322900 123 | 398, 77.133600 124 | 399, 79.944200 125 | 400, 82.754900 126 | 401, 83.628000 127 | 402, 84.501100 128 | 403, 85.374200 129 | 404, 86.247300 130 | 405, 87.120400 131 | 406, 87.993600 132 | 407, 88.866700 133 | 408, 89.739800 134 | 409, 90.612900 135 | 410, 91.486000 136 | 411, 91.680600 137 | 412, 91.875200 138 | 413, 92.069700 139 | 414, 92.264300 140 | 415, 92.458900 141 | 416, 92.653500 142 | 417, 92.848100 143 | 418, 93.042600 144 | 419, 93.237200 145 | 420, 93.431800 146 | 421, 92.756800 147 | 422, 92.081900 148 | 423, 91.406900 149 | 424, 90.732000 150 | 425, 90.057000 151 | 426, 89.382100 152 | 427, 88.707100 153 | 428, 88.032200 154 | 429, 87.357200 155 | 430, 86.682300 156 | 431, 88.500600 157 | 432, 90.318800 158 | 433, 92.137100 159 | 434, 93.955400 160 | 435, 95.773600 161 | 436, 97.591900 162 | 437, 99.410200 163 | 438, 101.228000 164 | 439, 103.047000 165 | 440, 104.865000 166 | 441, 106.079000 167 | 442, 107.294000 168 | 443, 108.508000 169 | 444, 109.722000 170 | 445, 110.936000 171 | 446, 112.151000 172 | 447, 113.365000 173 | 448, 114.579000 174 | 449, 115.794000 175 | 450, 117.008000 176 | 451, 117.088000 177 | 452, 117.169000 178 | 453, 117.249000 179 | 454, 117.330000 180 | 455, 117.410000 181 | 456, 117.490000 182 | 457, 117.571000 183 | 458, 117.651000 184 | 459, 117.732000 185 | 460, 117.812000 186 | 461, 117.517000 187 | 462, 117.222000 188 | 463, 116.927000 189 | 464, 116.632000 190 | 465, 116.336000 191 | 466, 116.041000 192 | 467, 115.746000 193 | 468, 115.451000 194 | 469, 115.156000 195 | 470, 114.861000 196 | 471, 114.967000 197 | 472, 115.073000 198 | 473, 115.180000 199 | 474, 115.286000 200 | 475, 115.392000 201 | 476, 115.498000 202 | 477, 115.604000 203 | 478, 115.711000 204 | 479, 115.817000 205 | 480, 115.923000 206 | 481, 115.212000 207 | 482, 114.501000 208 | 483, 113.789000 209 | 484, 113.078000 210 | 485, 112.367000 211 | 486, 111.656000 212 | 487, 110.945000 213 | 488, 110.233000 214 | 489, 109.522000 215 | 490, 108.811000 216 | 491, 108.865000 217 | 492, 108.920000 218 | 493, 108.974000 219 | 494, 109.028000 220 | 495, 109.082000 221 | 496, 109.137000 222 | 497, 109.191000 223 | 498, 109.245000 224 | 499, 109.300000 225 | 500, 109.354000 226 | 501, 109.199000 227 | 502, 109.044000 228 | 503, 108.888000 229 | 504, 108.733000 230 | 505, 108.578000 231 | 506, 108.423000 232 | 507, 108.268000 233 | 508, 108.112000 234 | 509, 107.957000 235 | 510, 107.802000 236 | 511, 107.501000 237 | 512, 107.200000 238 | 513, 106.898000 239 | 514, 106.597000 240 | 515, 106.296000 241 | 516, 105.995000 242 | 517, 105.694000 243 | 518, 105.392000 244 | 519, 105.091000 245 | 520, 104.790000 246 | 521, 105.080000 247 | 522, 105.370000 248 | 523, 105.660000 249 | 524, 105.950000 250 | 525, 106.239000 251 | 526, 106.529000 252 | 527, 106.819000 253 | 528, 107.109000 254 | 529, 107.399000 255 | 530, 107.689000 256 | 531, 107.361000 257 | 532, 107.032000 258 | 533, 106.704000 259 | 534, 106.375000 260 | 535, 106.047000 261 | 536, 105.719000 262 | 537, 105.390000 263 | 538, 105.062000 264 | 539, 104.733000 265 | 540, 104.405000 266 | 541, 104.369000 267 | 542, 104.333000 268 | 543, 104.297000 269 | 544, 104.261000 270 | 545, 104.225000 271 | 546, 104.190000 272 | 547, 104.154000 273 | 548, 104.118000 274 | 549, 104.082000 275 | 550, 104.046000 276 | 551, 103.641000 277 | 552, 103.237000 278 | 553, 102.832000 279 | 554, 102.428000 280 | 555, 102.023000 281 | 556, 101.618000 282 | 557, 101.214000 283 | 558, 100.809000 284 | 559, 100.405000 285 | 560, 100.000000 286 | 561, 99.633400 287 | 562, 99.266800 288 | 563, 98.900300 289 | 564, 98.533700 290 | 565, 98.167100 291 | 566, 97.800500 292 | 567, 97.433900 293 | 568, 97.067400 294 | 569, 96.700800 295 | 570, 96.334200 296 | 571, 96.279600 297 | 572, 96.225000 298 | 573, 96.170300 299 | 574, 96.115700 300 | 575, 96.061100 301 | 576, 96.006500 302 | 577, 95.951900 303 | 578, 95.897200 304 | 579, 95.842600 305 | 580, 95.788000 306 | 581, 95.077800 307 | 582, 94.367500 308 | 583, 93.657300 309 | 584, 92.947000 310 | 585, 92.236800 311 | 586, 91.526600 312 | 587, 90.816300 313 | 588, 90.106100 314 | 589, 89.395800 315 | 590, 88.685600 316 | 591, 88.817700 317 | 592, 88.949700 318 | 593, 89.081800 319 | 594, 89.213800 320 | 595, 89.345900 321 | 596, 89.478000 322 | 597, 89.610000 323 | 598, 89.742100 324 | 599, 89.874100 325 | 600, 90.006200 326 | 601, 89.965500 327 | 602, 89.924800 328 | 603, 89.884100 329 | 604, 89.843400 330 | 605, 89.802600 331 | 606, 89.761900 332 | 607, 89.721200 333 | 608, 89.680500 334 | 609, 89.639800 335 | 610, 89.599100 336 | 611, 89.409100 337 | 612, 89.219000 338 | 613, 89.029000 339 | 614, 88.838900 340 | 615, 88.648900 341 | 616, 88.458900 342 | 617, 88.268800 343 | 618, 88.078800 344 | 619, 87.888700 345 | 620, 87.698700 346 | 621, 87.257700 347 | 622, 86.816700 348 | 623, 86.375700 349 | 624, 85.934700 350 | 625, 85.493600 351 | 626, 85.052600 352 | 627, 84.611600 353 | 628, 84.170600 354 | 629, 83.729600 355 | 630, 83.288600 356 | 631, 83.329700 357 | 632, 83.370700 358 | 633, 83.411800 359 | 634, 83.452800 360 | 635, 83.493900 361 | 636, 83.535000 362 | 637, 83.576000 363 | 638, 83.617100 364 | 639, 83.658100 365 | 640, 83.699200 366 | 641, 83.332000 367 | 642, 82.964700 368 | 643, 82.597500 369 | 644, 82.230200 370 | 645, 81.863000 371 | 646, 81.495800 372 | 647, 81.128500 373 | 648, 80.761300 374 | 649, 80.394000 375 | 650, 80.026800 376 | 651, 80.045600 377 | 652, 80.064400 378 | 653, 80.083100 379 | 654, 80.101900 380 | 655, 80.120700 381 | 656, 80.139500 382 | 657, 80.158300 383 | 658, 80.177000 384 | 659, 80.195800 385 | 660, 80.214600 386 | 661, 80.420900 387 | 662, 80.627200 388 | 663, 80.833600 389 | 664, 81.039900 390 | 665, 81.246200 391 | 666, 81.452500 392 | 667, 81.658800 393 | 668, 81.865200 394 | 669, 82.071500 395 | 670, 82.277800 396 | 671, 81.878400 397 | 672, 81.479100 398 | 673, 81.079700 399 | 674, 80.680400 400 | 675, 80.281000 401 | 676, 79.881600 402 | 677, 79.482300 403 | 678, 79.082900 404 | 679, 78.683600 405 | 680, 78.284200 406 | 681, 77.427900 407 | 682, 76.571600 408 | 683, 75.715300 409 | 684, 74.859000 410 | 685, 74.002700 411 | 686, 73.146500 412 | 687, 72.290200 413 | 688, 71.433900 414 | 689, 70.577600 415 | 690, 69.721300 416 | 691, 69.910100 417 | 692, 70.098900 418 | 693, 70.287600 419 | 694, 70.476400 420 | 695, 70.665200 421 | 696, 70.854000 422 | 697, 71.042800 423 | 698, 71.231500 424 | 699, 71.420300 425 | 700, 71.609100 426 | 701, 71.883100 427 | 702, 72.157100 428 | 703, 72.431100 429 | 704, 72.705100 430 | 705, 72.979000 431 | 706, 73.253000 432 | 707, 73.527000 433 | 708, 73.801000 434 | 709, 74.075000 435 | 710, 74.349000 436 | 711, 73.074500 437 | 712, 71.800000 438 | 713, 70.525500 439 | 714, 69.251000 440 | 715, 67.976500 441 | 716, 66.702000 442 | 717, 65.427500 443 | 718, 64.153000 444 | 719, 62.878500 445 | 720, 61.604000 446 | 721, 62.432200 447 | 722, 63.260300 448 | 723, 64.088500 449 | 724, 64.916600 450 | 725, 65.744800 451 | 726, 66.573000 452 | 727, 67.401100 453 | 728, 68.229300 454 | 729, 69.057400 455 | 730, 69.885600 456 | 731, 70.405700 457 | 732, 70.925900 458 | 733, 71.446000 459 | 734, 71.966200 460 | 735, 72.486300 461 | 736, 73.006400 462 | 737, 73.526600 463 | 738, 74.046700 464 | 739, 74.566900 465 | 740, 75.087000 466 | 741, 73.937600 467 | 742, 72.788100 468 | 743, 71.638700 469 | 744, 70.489300 470 | 745, 69.339800 471 | 746, 68.190400 472 | 747, 67.041000 473 | 748, 65.891600 474 | 749, 64.742100 475 | 750, 63.592700 476 | 751, 61.875200 477 | 752, 60.157800 478 | 753, 58.440300 479 | 754, 56.722900 480 | 755, 55.005400 481 | 756, 53.288000 482 | 757, 51.570500 483 | 758, 49.853100 484 | 759, 48.135600 485 | 760, 46.418200 486 | 761, 48.456900 487 | 762, 50.495600 488 | 763, 52.534400 489 | 764, 54.573100 490 | 765, 56.611800 491 | 766, 58.650500 492 | 767, 60.689200 493 | 768, 62.728000 494 | 769, 64.766700 495 | 770, 66.805400 496 | 771, 66.463100 497 | 772, 66.120900 498 | 773, 65.778600 499 | 774, 65.436400 500 | 775, 65.094100 501 | 776, 64.751800 502 | 777, 64.409600 503 | 778, 64.067300 504 | 779, 63.725100 505 | 780, 63.382800 506 | 781, 63.474900 507 | 782, 63.567000 508 | 783, 63.659200 509 | 784, 63.751300 510 | 785, 63.843400 511 | 786, 63.935500 512 | 787, 64.027600 513 | 788, 64.119800 514 | 789, 64.211900 515 | 790, 64.304000 516 | 791, 63.818800 517 | 792, 63.333600 518 | 793, 62.848400 519 | 794, 62.363200 520 | 795, 61.877900 521 | 796, 61.392700 522 | 797, 60.907500 523 | 798, 60.422300 524 | 799, 59.937100 525 | 800, 59.451900 526 | 801, 58.702600 527 | 802, 57.953300 528 | 803, 57.204000 529 | 804, 56.454700 530 | 805, 55.705400 531 | 806, 54.956200 532 | 807, 54.206900 533 | 808, 53.457600 534 | 809, 52.708300 535 | 810, 51.959000 536 | 811, 52.507200 537 | 812, 53.055300 538 | 813, 53.603500 539 | 814, 54.151600 540 | 815, 54.699800 541 | 816, 55.248000 542 | 817, 55.796100 543 | 818, 56.344300 544 | 819, 56.892400 545 | 820, 57.440600 546 | 821, 57.727800 547 | 822, 58.015000 548 | 823, 58.302200 549 | 824, 58.589400 550 | 825, 58.876500 551 | 826, 59.163700 552 | 827, 59.450900 553 | 828, 59.738100 554 | 829, 60.025300 555 | 830, 60.312500]; 556 | 557 | end 558 | 559 | -------------------------------------------------------------------------------- /matlab/data/get_datasets.m: -------------------------------------------------------------------------------- 1 | 2 | % clc; 3 | % clear; 4 | % close all; 5 | 6 | function [XYZ, ECD] = get_datasets 7 | % 8 | % ECD - experimantal color differences 9 | % 10 | 11 | XYZ = cell(1,2); 12 | XYZ{1} = zeros(0, 3); 13 | XYZ{2} = zeros(0, 3); 14 | ECD = zeros(0, 1); 15 | 16 | %% rit-dupont: alman1989 17 | 18 | path = 'color-data-master\rit-dupont\alman1989'; 19 | data = load(path); 20 | data = data.data; 21 | n = size(data, 1); 22 | Lab = cell(1, 2); 23 | Lab{1} = zeros(n, 3); 24 | Lab{2} = zeros(n, 3); 25 | ECD_part = zeros(n, 1); 26 | for i = 1:n 27 | Lab{1}(i, :) = [data{i,1}, data{i,2}, data{i,3}]; 28 | Lab{2}(i, :) = Lab{1}(i, :) + [data{i,4}, data{i,5}, data{i,6}]; 29 | ECD_part(i, 1) = data{i,8}; 30 | end 31 | XYZ_part = Lab2XYZ(Lab); 32 | for j = 1:2 33 | XYZ{j} = [XYZ{j}; XYZ_part{j}]; 34 | end 35 | ECD = [ECD; ECD_part]; 36 | 37 | %% rit-dupont: berns 38 | 39 | path = 'color-data-master\rit-dupont\berns'; 40 | data = load(path); 41 | data = data.data; 42 | n = size(data, 1); 43 | Lab = cell(1, 2); 44 | Lab{1} = zeros(n, 3); 45 | Lab{2} = zeros(n, 3); 46 | ECD_part = zeros(n, 1); 47 | for i = 1:n 48 | Lab{1}(i, :) = [data{i,8}, data{i,9}, data{i,10}]; 49 | Lab{2}(i, :) = Lab{1}(i, :) + [data{i,11}, data{i,12}, data{i,13}]; 50 | ECD_part(i, 1) = data{i,3}; 51 | end 52 | XYZ_part = Lab2XYZ(Lab); 53 | for j = 1:2 54 | XYZ{j} = [XYZ{j}; XYZ_part{j}]; 55 | end 56 | ECD = [ECD; ECD_part]; 57 | 58 | %% witt 59 | 60 | % path = 'color-data-master\witt\table_a1'; 61 | % data = load(path); 62 | % data = data.data; 63 | % n = size(data, 1); 64 | % C = 5; 65 | % xyY_raw = cell(1, C); 66 | % for c = 1:C 67 | % xyY_raw{c} = zeros(n, 3); 68 | % for i = 1:n 69 | % xyY_raw{c}(i, :) = [data{i,1+3*(c-1)}, data{i,2+3*(c-1)}, data{i,3+3*(c-1)}]; 70 | % end 71 | % end 72 | % path = 'color-data-master\witt\table_a2'; 73 | % data = load(path); 74 | % data = data.data; 75 | % n = size(data, 1); 76 | % xyY_C = cell(1,C); 77 | % ECD_C = cell(1,C); 78 | % for c = 1:C 79 | % xyY_C{c} = cell(1, 2); 80 | % for j = 1:2 81 | % xyY_C{c}{j} = zeros(n, 3); 82 | % end 83 | % ECD_C{c} = zeros(n, 1); 84 | % for i = 1:n 85 | % n1 = 1 + data{i,1}; 86 | % n2 = 1 + data{i,2}; 87 | % xyY_C{c}{1}(i, :) = xyY_raw{c}(n1,:); 88 | % xyY_C{c}{2}(i, :) = xyY_raw{c}(n2,:); 89 | % ECD_C{c}(i, 1) = data{i,1+2*c}; 90 | % end 91 | % end 92 | % xyY = cell(1, 2); 93 | % xyY{1} = zeros(n*C, 3); 94 | % xyY{2} = zeros(n*C, 3); 95 | % ECD_part = zeros(n*C, 1); 96 | % for c = 1:C 97 | % idx = (1:n)+n*(c-1); 98 | % for j = 1:2 99 | % xyY{j}(idx, :) = xyY_C{c}{j}; 100 | % end 101 | % ECD_part(idx) = ECD_C{c}; 102 | % end 103 | % for j = 1:2 104 | % xyY{j}(:, 3) = xyY{j}(:, 3)/100; 105 | % end 106 | % % XYZ_part = xyY2XYZ(xyY); 107 | % XYZ_part = xyY; 108 | % for j = 1:2 109 | % XYZ{j} = [XYZ{j}; XYZ_part{j}]; 110 | % end 111 | % ECD = [ECD; ECD_part]; 112 | 113 | %% 114 | 115 | idx = isnan(ECD); 116 | for j = 1:2 117 | XYZ{j}(idx, :) = []; 118 | end 119 | ECD(idx, :) = []; 120 | 121 | % [(1:size(XYZ{1},1))', XYZ{1}, XYZ{2}, ECD] 122 | 123 | end 124 | 125 | 126 | -------------------------------------------------------------------------------- /matlab/data/testing_on_datasets.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath('color_conversions'); 7 | 8 | [XYZ, ECD] = get_datasets; 9 | [(1:size(XYZ{1},1))', XYZ{1}, XYZ{2}, ECD] 10 | 11 | % distance_CIEDE2000 = get_CIEDE2000(XYZ); 12 | % criter_name = 'pca'; 13 | % Criterion(distance_CIEDE2000, ECD, criter_name); 14 | % plot(ECD, distance_CIEDE2000, '.b'); 15 | % xlabel('$ECD$','Interpreter','latex','FontSize', 14); 16 | % xlabel('Experimantal color difference','FontSize', 14); 17 | % ylabel('$\Delta E^*_{00}$','Interpreter','latex','FontSize', 14); -------------------------------------------------------------------------------- /matlab/images/README.md: -------------------------------------------------------------------------------- 1 | This directory is for storing images that are generated by the code. -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/XYZ2proLab.m: -------------------------------------------------------------------------------- 1 | 2 | function proLab = XYZ2proLab(XYZ, ref_illum) 3 | if nargin == 1 4 | ref_illum = reference_illuminant; 5 | end 6 | param = proLab_param; 7 | proLab = XYZ2proLab_model(XYZ, ref_illum, param); 8 | end 9 | 10 | -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/XYZ2proLab_model.m: -------------------------------------------------------------------------------- 1 | 2 | function proLab = XYZ2proLab_model(XYZ, ref_illum, param) 3 | if iscell(XYZ) 4 | proLab = cell(1, 2); 5 | for i = 1:2 6 | proLab{i} = f(XYZ{i}, ref_illum, param); 7 | end 8 | else 9 | proLab = f(XYZ, ref_illum, param); 10 | end 11 | end 12 | 13 | function proLab = f(XYZ, ref_illum, param) 14 | isImage = false; 15 | if size(size(XYZ), 2) == 3 16 | [s1, s2, s3] = size(XYZ); 17 | XYZ = reshape(XYZ, [s1*s2, s3]); 18 | isImage = true; 19 | end 20 | XYZ = XYZ ./ ref_illum; 21 | if isfield(param, 'Q') 22 | proLab = projTrans3D(XYZ, param.Q); 23 | else 24 | M = m2M(param.m); 25 | proLab = projTrans3D(XYZ, M); 26 | end 27 | if isImage 28 | proLab = reshape(proLab, [s1, s2, s3]); 29 | end 30 | end -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/proLab2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = proLab2XYZ(proLab, ref_illum) 3 | if nargin == 1 4 | ref_illum = reference_illuminant; 5 | end 6 | param = proLab_param; 7 | XYZ = proLab2XYZ_model(proLab, ref_illum, param); 8 | end 9 | 10 | -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/proLab2XYZ_model.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = proLab2XYZ_model(proLab, ref_illum, param) 3 | if iscell(proLab) 4 | XYZ = cell(1, 2); 5 | for i = 1:2 6 | XYZ{i} = f_reverse(proLab{i}, ref_illum, param); 7 | end 8 | else 9 | XYZ = f_reverse(proLab, ref_illum, param); 10 | end 11 | end 12 | 13 | function XYZ = f_reverse(proLab, ref_illum, param) 14 | isImage = false; 15 | if size(size(proLab), 2) == 3 16 | [s1, s2, s3] = size(proLab); 17 | proLab = reshape(proLab, [s1*s2, s3]); 18 | isImage = true; 19 | end 20 | if isfield(param, 'Q') 21 | XYZ = projTrans3D(proLab, param.Q^(-1)); 22 | else 23 | M = m2M(param.m); 24 | XYZ = projTrans3D(proLab, M^(-1)); 25 | end 26 | XYZ = XYZ .* ref_illum; 27 | if isImage 28 | XYZ = reshape(XYZ, [s1, s2, s3]); 29 | end 30 | end -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/proLab_param.m: -------------------------------------------------------------------------------- 1 | 2 | function param = proLab_param 3 | param.Q = [ 4 | 75.54, 486.66, 167.39, 0; 5 | 617.72, -595.45, -22.27, 0; 6 | 48.34, 194.94, -243.28, 0; 7 | 0.7554, 3.8666, 1.6739, 1]; 8 | end 9 | 10 | -------------------------------------------------------------------------------- /matlab/proLab_color_conversions/projTrans3D.m: -------------------------------------------------------------------------------- 1 | 2 | function proLab = projTrans3D(XYZ, proj_matrix) 3 | proLab_homog = [XYZ, ones(size(XYZ, 1), 1)] * proj_matrix'; 4 | proLab = proLab_homog(:, 1:3) ./ proLab_homog(:, 4); 5 | end -------------------------------------------------------------------------------- /matlab/proLab_reference_values.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | format long 6 | 7 | ref_illum = rand(1,3) 8 | 9 | XYZ = ref_illum .* [ ... 10 | 0 0 0; ... 11 | 0 0 1; ... 12 | 0 1 0; ... 13 | 0 1 1; ... 14 | 1 0 0; ... 15 | 1 0 1; ... 16 | 1 1 0; ... 17 | 1 1 1] 18 | 19 | proLab = XYZ2proLab(XYZ, ref_illum) %% reference result below: 20 | % proLab = 21 | % 1.0e+02 * 22 | % 0 0 0 23 | % 0.626014435842777 -0.083286585137814 -0.909832080481694 24 | % 1.000000000000000 -1.223544158139153 0.400567131056590 25 | % 1.000000000000000 -0.944453787936702 -0.073908722574727 26 | % 0.430329269682124 3.518970035319585 0.275378831035661 27 | % 0.708395299332225 1.736360190126265 -0.568454203481760 28 | % 1.000000000000000 0.039612237637851 0.432728566346496 29 | % 1.000000000000000 -0.000000000000000 0 30 | 31 | err = max(max(abs(XYZ - proLab2XYZ(proLab, ref_illum)))) % should be ~zero 32 | 33 | format 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /matlab/reference_illuminant.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = reference_illuminant() 3 | XYZ = D65; 4 | end -------------------------------------------------------------------------------- /matlab/research/estim_gain_by_discret.m: -------------------------------------------------------------------------------- 1 | 2 | function gain = estim_gain_by_discret(cc) 3 | 4 | color = {'.r', '.g', '.g', '.b'}; 5 | gain = zeros(size(color, 2),1); 6 | figure(); 7 | hold on; 8 | for i = 1:size(gain, 1) 9 | Y = unique(sort(cc(:, i))); 10 | X = (1:size(Y,1))'; 11 | plot(X,Y,color{i}); 12 | h = 10; 13 | X = X(h:end-h); 14 | Y = Y(h:end-h); 15 | gain(i) = (Y(end)-Y(1)) / (size(Y,1)-1); 16 | end 17 | end 18 | 19 | -------------------------------------------------------------------------------- /matlab/research/estim_gain_by_noise.m: -------------------------------------------------------------------------------- 1 | 2 | function [gain, M, C] = estim_gain_by_noise(cc) 3 | M = (mean(cc)); 4 | C = diag(cov(cc))'; 5 | gain = C./M; % !!!!!!! 6 | C = diag(get_covariance(cc))'; % !!!!!!! 7 | end 8 | 9 | -------------------------------------------------------------------------------- /matlab/research/noise_model_verification.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | FontSize = 20; 9 | 10 | %% 11 | 12 | data_path = 'C:\Users\alatkon\Desktop\D\proLab\mls-dataset'; 13 | % data_path = 'C:\Users\Ivan Konovalenko\Desktop\D\proLab\mls-dataset'; 14 | 15 | sources_list = { ... 16 | '2HAL' 17 | '2HAL_DESK' 18 | '2HAL_DESK_LED-B025' 19 | '2HAL_DESK_LED-B050' 20 | '2HAL_DESK_LED-B075' 21 | '2HAL_DESK_LED-B100' 22 | '2HAL_DESK_LED-BG025' 23 | '2HAL_DESK_LED-BG050' 24 | '2HAL_DESK_LED-BG075' 25 | '2HAL_DESK_LED-BG100' 26 | '2HAL_DESK_LED-R025' 27 | '2HAL_DESK_LED-R050' 28 | '2HAL_DESK_LED-R075' 29 | '2HAL_DESK_LED-R100' 30 | '2HAL_DESK_LED-RG025' 31 | '2HAL_DESK_LED-RG050' 32 | '2HAL_DESK_LED-RG075' 33 | '2HAL_DESK_LED-RG100' 34 | }; 35 | 36 | sources_list_bug = { ... 37 | '2HAL' 38 | '2HAL_DESK' 39 | '2HAL_DESK_LED-B025' 40 | '2HAL_DESK_LED-B050' 41 | '2HAL_DESK_LED-B075' 42 | '2HAL_DESK_LED-B100' 43 | '2HAL_DESK_LED-BG025' 44 | '2HAL_DESK_LED-BG050' 45 | '2HAL_DESK_LED-BG075' 46 | '2HAL_DESK_LED-BG100' 47 | '2HAL_DESK_R025' 48 | '2HAL_DESK_R050' 49 | '2HAL_DESK_R075' 50 | '2HAL_DESK_R100' 51 | '2HAL_DESK_RG025' 52 | '2HAL_DESK_RG050' 53 | '2HAL_DESK_RG075' 54 | '2HAL_DESK_RG100' 55 | }; 56 | 57 | % GAIN_by_noise = []; 58 | MS = zeros(0, 4); 59 | CS = zeros(0, 4); 60 | 61 | for scene_number = 1:1 62 | 63 | lim_idx.I = 401:900; 64 | lim_idx.J = 251:950; 65 | 66 | scene_name = num2str(scene_number); 67 | if size(scene_name,2) < 2 68 | scene_name = ['0', scene_name]; 69 | end 70 | 71 | for sources_number = 2:2 72 | % for sources_number = 10:10 73 | 74 | sources_name = sources_list{sources_number}; 75 | 76 | folder = 'images_16bit_raw'; 77 | 78 | path = [data_path, '\', folder, '\', scene_name, '\', scene_name '_', sources_name, '.png']; 79 | pic_1C = imread(path); 80 | pic_4C = zeros(size(pic_1C,1)/2,size(pic_1C,2)/2,4,'uint16'); 81 | for i = 1:size(pic_1C,1)/2 82 | for j = 1:size(pic_1C,2)/2 83 | Bayer_pixel = pic_1C(2*i-1:2*i, 2*j-1:2*j); 84 | pic_4C(i,j,1) = Bayer_pixel(1,1); 85 | pic_4C(i,j,2) = Bayer_pixel(1,2); 86 | pic_4C(i,j,3) = Bayer_pixel(2,1); 87 | pic_4C(i,j,4) = Bayer_pixel(2,2); 88 | end 89 | end 90 | 91 | folder = 'masks_16bit_color'; 92 | path = [data_path, '\', folder, '\', scene_name, '.png']; 93 | mask = imread(path); 94 | mask_lim = mask(lim_idx.I, lim_idx.J, :); 95 | figure(); 96 | imshow(mask_lim); 97 | imwrite(mask_lim, 'images/mask_lim.png'); 98 | 99 | path = [data_path, '\reverse_engineering_sRGB.png']; 100 | true_sRGB = imread(path); 101 | true_sRGB = double(true_sRGB) / 255; 102 | true_sRGB_lim = true_sRGB(lim_idx.I, lim_idx.J, :); 103 | figure(); 104 | imshow(true_sRGB_lim); 105 | imwrite(true_sRGB_lim, 'images/true_sRGB_lim.png'); 106 | 107 | mv = [ ... 108 | 225 252 103; ... 109 | 62 161 65; ... 110 | 99 51 159; ... 111 | 201 154 102; ... 112 | 62 1 126; ... 113 | 237 28 36; ... 114 | 251 50 175; ... 115 | 242 251 227; ... 116 | 118 90 46; ... 117 | 107 150 143; ... 118 | 205 186 171; ... 119 | 84 248 27; ... 120 | 115 81 255; ... 121 | 151 234 220; ... 122 | 198 155 180; ... 123 | 103 198 105; ... 124 | 49 88 163; ... 125 | 5 23 88]; 126 | 127 | color = zeros(size(mv)); 128 | % bin = true_sRGB / 3; 129 | bin = true_sRGB; 130 | % bin = zeros(size(true_sRGB)); 131 | % for i = 1:size(bin, 1) 132 | % for j = 1:size(bin, 2) 133 | % bin(i, j, :) = mean(true_sRGB(i, j, :)); 134 | % end 135 | % end 136 | CC = reshape(pic_4C, [size(pic_4C,1)*size(pic_4C,2), 4]); 137 | ii = (1:size(mask,1))' * ones(1,size(mask,2)); 138 | jj = ones(1,size(mask,1))' * (1:size(mask,2)); 139 | for cl = 1:size(mv, 1) 140 | % for cl = 1 141 | idx = (mask(:,:,1) == mv(cl, 1)) & (mask(:,:,2) == mv(cl, 2)) & (mask(:,:,3) == mv(cl, 3)); 142 | se = strel('disk',5,0); 143 | idx = imerode(idx,se); 144 | center = fix([sum(sum(ii.*idx))/sum(sum(idx)), sum(sum(jj.*idx))/sum(sum(idx))]); 145 | idx = zeros(size(idx)); 146 | l = 10; 147 | idx((-l:l)+center(1), (-l:l)+center(2)) = 1; 148 | idx_frame = zeros(size(idx)); 149 | idx_frame([-l+(-1:+1), l+(-1:+1)]+center(1), (-l:l)+center(2)) = 1; 150 | idx_frame((-l:l)+center(1), [-l+(-1:+1), l+(-1:+1)]+center(2)) = 1; 151 | 152 | count = 0; 153 | for i = 1:size(bin,1) 154 | for j = 1:size(bin,2) 155 | if idx(i,j) 156 | count = count + 1; 157 | color(cl, :) = color(cl, :) + squeeze(true_sRGB(i,j,:))'; 158 | end 159 | end 160 | end 161 | color(cl, :) = color(cl, :) / count; 162 | for i = 1:size(bin,1) 163 | for j = 1:size(bin,2) 164 | if idx_frame(i,j) 165 | % bin(i,j,:) = color(cl, :); 166 | % bin(i,j,:) = pic_4C(i,j,[1 2 4]); 167 | % bin(i,j,:) = true_sRGB(i,j,:)/2; 168 | bin(i,j,:) = [1, 0, 1]; 169 | end 170 | end 171 | end 172 | idx_v = reshape(idx, [size(idx,1)*size(idx,2), 1]); 173 | cc = double(CC); 174 | cc(~idx_v, :) = []; 175 | 176 | % m = mean(cc) 177 | % m = hwRGB2XYZ(m); 178 | % m = m / m(2) 179 | 180 | % gain_by_discret = estim_gain_by_discret(cc); 181 | [gain_by_noise, mS, cS] = estim_gain_by_noise(cc); 182 | MS = [MS; mS]; 183 | CS = [CS; cS]; 184 | % GAIN_by_noise = [GAIN_by_noise; gain_by_noise]; 185 | 186 | % c = double(cc(:,4)); 187 | % figure(); 188 | % hold on; 189 | % set(gca,'FontSize',15); 190 | % title('Sensor data histogram'); 191 | % xlabel('$\mathbf{B}$','Interpreter','latex','FontSize', FontSize); 192 | % ylabel('$\#$','Interpreter','latex','FontSize', FontSize); 193 | % hist(c, 1000); 194 | 195 | figure(51); 196 | hold on; 197 | grid on; 198 | plot3(cc(:,1),cc(:,2),cc(:,4),'.','MarkerSize',7,'MarkerEdgeColor', color(cl, :)); 199 | view(0,0); 200 | xlabel('$\mathbf{R}$','Interpreter','latex','FontSize', FontSize); 201 | ylabel('$\mathbf{G}$','Interpreter','latex','FontSize', FontSize); 202 | zlabel('$\mathbf{B}$','Interpreter','latex','FontSize', FontSize); 203 | % xticks(0:100:10000); 204 | % yticks(0:100:10000); 205 | % zticks(0:100:10000); 206 | axis tight; 207 | axis equal; 208 | % xlim([0 3500]); 209 | % zlim([0 2500]); 210 | end 211 | bin_lim = bin(lim_idx.I, lim_idx.J, :); 212 | figure(); 213 | imshow(bin_lim); 214 | imwrite(bin_lim, 'images/bin_lim.png'); 215 | 216 | 217 | % bin = bin(500:end-300, 300:end-600, :); 218 | % bin = bin ./ max(max(bin)); 219 | % figure(); 220 | % imshow(bin); 221 | % miB = min(min(bin)); 222 | % maB = max(max(bin)); 223 | % bin = (bin - miB) ./ (maB - miB); 224 | % figure(); 225 | % imshow(bin); 226 | 227 | disp([scene_number, sources_number]); 228 | end 229 | end 230 | 231 | X = MS(:); 232 | Y = CS(:); 233 | mX = mean(X); 234 | mY = mean(Y); 235 | X = X - mX; 236 | Y = Y - mY; 237 | K = [X'; Y'] * [X, Y]; 238 | [U, S, V] = svd(K); 239 | k = U(2,1) / U(1,1); 240 | b = mY - mX * k; 241 | % F = [X, ones(size(X))]; 242 | % b = (F' * F)^(-1) * F' * Y 243 | % sqrt(b(2)) 244 | x = [0; 6000]; 245 | y = b + x * k; 246 | [k, b] 247 | 248 | 249 | figure(); 250 | hold on; 251 | grid on; 252 | set(gca,'FontSize',15); 253 | plot(MS(:,1), CS(:,1), '.r', 'MarkerSize', 15); 254 | plot(MS(:,2), CS(:,2), '.g', 'MarkerSize', 15); 255 | plot(MS(:,3), CS(:,3), '.g', 'MarkerSize', 15); 256 | plot(MS(:,4), CS(:,4), '.b', 'MarkerSize', 15); 257 | plot(x, y, '-black'); 258 | % xticks(0:2000:100000); 259 | % yticks(0:2000:100000); 260 | % xlabel('$\overline{S}$','Interpreter','latex','FontSize', FontSize); 261 | % ylabel('$\overline{(S-\overline{S})^2}$','Interpreter','latex','FontSize', FontSize); 262 | xlabel('$\mathbb{E}$','Interpreter','latex','FontSize', FontSize); 263 | ylabel('$\overline{(S-\overline{S})^2}$','Interpreter','latex','FontSize', FontSize); 264 | 265 | 266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /matlab/research/statistical_test.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | X = [4.0802 9 | 4.2983 10 | 4.2271 11 | 5.7617 12 | 4.0613 13 | 4.2753 14 | 4.4739 15 | 5.4224 16 | 4.1484 17 | 4.7647 18 | 4.7466 19 | 6.2331 20 | 4.6573 21 | 4.2026 22 | 4.1168 23 | 5.5466 24 | 3.9278 25 | 4.3667 26 | 4.2979 27 | 6.4295 28 | 4.5881 29 | 4.6770 30 | 4.6931 31 | 7.6319 32 | 3.6282 33 | 4.3823 34 | 4.1646 35 | 6.5088 36 | 5.7199 37 | 5.4501 38 | 5.4762 39 | 10.0202 40 | 4.4306 41 | 4.3159 42 | 4.1391 43 | 4.5244 44 | 4.5752 45 | 3.9665 46 | 3.9926 47 | 5.4314 48 | 4.0910 49 | 4.0057 50 | 3.8486 51 | 4.3497 52 | 4.0135 53 | 4.2355 54 | 4.2155 55 | 6.8132 56 | 6.2206 57 | 5.9539 58 | 5.9177 59 | 12.2066 60 | 5.3636 61 | 5.3928 62 | 5.4338 63 | 7.8848 64 | 4.8691 65 | 4.7555 66 | 4.7576 67 | 6.3117 68 | 4.0915 69 | 4.1690 70 | 4.2395 71 | 5.2074 72 | 4.3634 73 | 4.5854 74 | 4.4649 75 | 4.8707 76 | 6.8681 77 | 6.9166 78 | 6.9298 79 | 5.1372]; 80 | 81 | n = size(X, 1) 82 | m = 5; 83 | t = sqrt(n)*(mean(X)-m) / sqrt(var(X)) 84 | t = abs(t); 85 | p = tcdf(-t, n-1) + (1-tcdf(t, n-1)) 86 | 87 | N = 100000; 88 | T = zeros(N, 1); 89 | sigma = 10; 90 | for i = 1:N 91 | X = m + sigma * randn(n, 1); 92 | T(i, 1) = sqrt(n)*(mean(X)-m) / sqrt(var(X)); 93 | end 94 | t = -4:0.01:4; 95 | f = tpdf(t, n-1); 96 | figure(); 97 | hold on; 98 | histogram(T, 200, 'Normalization', 'pdf'); 99 | plot(t, f, 'r'); 100 | 101 | %% 102 | 103 | % lambda = 3; 104 | % n = 10; 105 | % g = 5; 106 | % NN = 10000; 107 | % gg = zeros(NN, 1); 108 | % for i = 1:NN 109 | % N = poissrnd(lambda, [n 1]); 110 | % S = g*N; 111 | % gg(i, 1) = (1/(n-1))*sum((S-mean(S)).^2) / mean(S); 112 | % end 113 | % mean(gg) 114 | -------------------------------------------------------------------------------- /matlab/research/test_Canon5DMarkIII_spectralSensitivity.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | d_lambda = 1; 9 | lambda = (380:d_lambda:780)'; 10 | RGB = Canon5DMarkIII_spectralSensitivity(lambda); 11 | x = sum(RGB); 12 | x = x ./ x(2) 13 | x = 1./x 14 | 15 | figure(1); 16 | hold on; 17 | grid on; 18 | plot(lambda, RGB(:,1), 'r'); 19 | plot(lambda, RGB(:,2), 'g'); 20 | plot(lambda, RGB(:,3), 'b'); 21 | plot(lambda, RGB(:,1), '.r'); 22 | plot(lambda, RGB(:,2), '.g'); 23 | plot(lambda, RGB(:,3), '.b'); 24 | -------------------------------------------------------------------------------- /matlab/research/test_central_linearity.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | % CS_list = {'CIEXYZ'; 'CIExyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 9 | CS_list = {'sRGB'; 'CIELAB'}; 10 | FontSize = 20; 11 | t = (0:0.001:1)'; 12 | linRGB = t * [1.0, 0.5, 0.1]; 13 | XYZ = linRGB2XYZ(linRGB); 14 | for CS_num = 1:size(CS_list, 1) 15 | CS = color_spaces_collection(CS_list{CS_num}); 16 | AO = CS.axis_Lab_order; 17 | CC = CS.transform_into(XYZ); 18 | figure(); 19 | hold on; 20 | grid on; 21 | set(gca,'FontSize',15); 22 | title(CS.name); 23 | plot3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),'.'); 24 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 25 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 26 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 27 | end 28 | 29 | -------------------------------------------------------------------------------- /matlab/research/view_raw.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | %% 9 | 10 | data_path = 'C:\Users\alatkon\Desktop\D\proLab\mls-dataset'; 11 | % data_path = 'C:\Users\Ivan Konovalenko\Desktop\D\proLab\mls-dataset'; 12 | 13 | sources_list = { ... 14 | '2HAL' 15 | '2HAL_DESK' 16 | '2HAL_DESK_LED-B025' 17 | '2HAL_DESK_LED-B050' 18 | '2HAL_DESK_LED-B075' 19 | '2HAL_DESK_LED-B100' 20 | '2HAL_DESK_LED-BG025' 21 | '2HAL_DESK_LED-BG050' 22 | '2HAL_DESK_LED-BG075' 23 | '2HAL_DESK_LED-BG100' 24 | '2HAL_DESK_LED-R025' 25 | '2HAL_DESK_LED-R050' 26 | '2HAL_DESK_LED-R075' 27 | '2HAL_DESK_LED-R100' 28 | '2HAL_DESK_LED-RG025' 29 | '2HAL_DESK_LED-RG050' 30 | '2HAL_DESK_LED-RG075' 31 | '2HAL_DESK_LED-RG100' 32 | }; 33 | 34 | sources_list_bug = { ... 35 | '2HAL' 36 | '2HAL_DESK' 37 | '2HAL_DESK_LED-B025' 38 | '2HAL_DESK_LED-B050' 39 | '2HAL_DESK_LED-B075' 40 | '2HAL_DESK_LED-B100' 41 | '2HAL_DESK_LED-BG025' 42 | '2HAL_DESK_LED-BG050' 43 | '2HAL_DESK_LED-BG075' 44 | '2HAL_DESK_LED-BG100' 45 | '2HAL_DESK_R025' 46 | '2HAL_DESK_R050' 47 | '2HAL_DESK_R075' 48 | '2HAL_DESK_R100' 49 | '2HAL_DESK_RG025' 50 | '2HAL_DESK_RG050' 51 | '2HAL_DESK_RG075' 52 | '2HAL_DESK_RG100' 53 | }; 54 | 55 | for scene_number = 1:1 56 | 57 | scene_name = num2str(scene_number); 58 | if size(scene_name,2) < 2 59 | scene_name = ['0', scene_name]; 60 | end 61 | 62 | % for sources_number = [1,2,6,10,14,18] 63 | for sources_number = 2:2 64 | 65 | sources_name = sources_list{sources_number}; 66 | 67 | % folder = 'images_16bit_raw'; 68 | % folder = 'images_16bit_color'; 69 | % folder = 'images_preview'; 70 | % folder = 'masks_16bit_raw'; 71 | % folder = 'masks_16bit_color'; 72 | % folder = 'masks_preview'; 73 | 74 | % path = [data_path, '\', folder, '\', scene_name, '\', scene_name '_', sources_name, '.png']; 75 | % pic = imread(path); 76 | % I = zeros(size(pic,1)/2,size(pic,2)/2,3,'uint16'); 77 | % for i = 1:size(pic,1)/2 78 | % for j = 1:size(pic,2)/2 79 | % Bayer_pixel = pic(2*i-1:2*i, 2*j-1:2*j); 80 | % I(i,j,1) = Bayer_pixel(1,1); 81 | % I(i,j,2) = (Bayer_pixel(1,2)+Bayer_pixel(2,1))/2; 82 | % I(i,j,3) = Bayer_pixel(2,2); 83 | % end 84 | % end 85 | % figure(2*sources_number-1); 86 | % imshow(I); 87 | 88 | folder = 'images_16bit_color'; 89 | path = [data_path, '\', folder, '\', scene_name, '\', scene_name '_', sources_name, '.png']; 90 | pic = imread(path); 91 | figure(); 92 | imshow(pic); 93 | 94 | J = zeros(size(pic,1),size(pic,2),3); 95 | for i = 1:size(pic,1) 96 | deviceRGB = double(squeeze(pic(i,:,:))); 97 | XYZ = deviceRGB2XYZ(deviceRGB); 98 | % linRGB = XYZ2linRGB(XYZ); 99 | % J(i,:,:) = linRGB; 100 | sRGB = XYZ2sRGB(XYZ); 101 | J(i,:,:) = sRGB; 102 | end 103 | % min(min(J)) 104 | % max(max(J)) 105 | % J(1:100, 1:100, :) = 1; 106 | % J = J / max(max(max(J))); 107 | figure(); 108 | hold on; 109 | title(sources_name); 110 | imshow(J); 111 | imwrite(J, [data_path, '\reverse_engineering_sRGB.png']); 112 | % imwrite(J, [data_path, '\reverse_engineering_linRGB.png']); 113 | 114 | folder = 'images_preview'; 115 | sources_name_bug = sources_list_bug{sources_number}; 116 | path = [data_path, '\', folder, '\', scene_name, '\', scene_name '_', sources_name_bug, '.jpg']; 117 | preview = double(imread(path)); 118 | preview = preview / max(max(max(preview))); 119 | figure(); 120 | hold on; 121 | title(sources_name); 122 | imshow(preview); 123 | 124 | disp([scene_number, sources_number]); 125 | end 126 | end 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath(pwd)); 7 | 8 | %% set criterion 9 | 10 | criter_name = 'Uniformity'; 11 | % criter_name = 'Homoscedasticity'; 12 | % criter_name = 'Mixed'; 13 | 14 | sample_size.Train.Uniformity = 10000; 15 | sample_size.Train.Homoscedasticity = 100; 16 | sample_size.Test.Uniformity = 10000; 17 | sample_size.Test.Homoscedasticity = 10000; 18 | 19 | %% train 20 | 21 | XYZ_Uni = get_sample(sample_size.Train.Uniformity); 22 | options.check_camera_sane = true; 23 | XYZ_Het = get_sample(sample_size.Train.Homoscedasticity, options); 24 | XYZ_Het = XYZ_Het{1,1}; 25 | CDB_train = CritDataBase(XYZ_Uni, XYZ_Het); 26 | 27 | disp('Train ...'); 28 | ObjFunc = @(m) CDB_train.get('proLab', m, criter_name); 29 | param.m = find_optimal_m(ObjFunc); 30 | param.Q = m2Q(param); 31 | m = param.m 32 | Q = param.Q 33 | clear m Q 34 | % param = proLab_param; 35 | 36 | %% test 37 | 38 | XYZ_Uni = get_sample(sample_size.Test.Uniformity); 39 | options.check_camera_sane = true; 40 | XYZ_Het = get_sample(sample_size.Test.Homoscedasticity, options); 41 | XYZ_Het = XYZ_Het{1,1}; 42 | CDB_test = CritDataBase(XYZ_Uni, XYZ_Het); 43 | 44 | disp('TEST ...'); 45 | criterion_report(CDB_test, 'Uniformity', param); 46 | criterion_report(CDB_test, 'Homoscedasticity', param); 47 | 48 | plot_sRGB_gamut(param); 49 | 50 | 51 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/CritDataBase.m: -------------------------------------------------------------------------------- 1 | 2 | classdef CritDataBase < handle 3 | properties 4 | XYZ_Uni; 5 | XYZ_Het; 6 | distance_CIEDE2000; 7 | end 8 | methods 9 | function obj = CritDataBase(XYZ_Uni, XYZ_Het) 10 | obj.XYZ_Uni = XYZ_Uni; 11 | obj.XYZ_Het = XYZ_Het; 12 | obj.distance_CIEDE2000 = get_CIEDE2000(XYZ_Uni, 'CIE XYZ'); 13 | end 14 | function value = get(obj, CS_name, x, criter_name) 15 | if size(x, 2) == 8 16 | param.m = x; 17 | else 18 | param = x; 19 | end 20 | 21 | switch criter_name 22 | % case 'Uniformity_PCA' 23 | % handle = color_dist(CS_name, param); 24 | % CD = handle(obj.XYZ_uniform); 25 | % value = get_STRESS(CD.^2, (obj.distance_CIEDE2000).^2); 26 | case 'Uniformity' 27 | handle = color_dist(CS_name, param); 28 | CD = handle(obj.XYZ_Uni); 29 | value = get_STRESS(CD, obj.distance_CIEDE2000); 30 | case 'Homoscedasticity' 31 | % sigma = get_sigma(obj.XYZ_noisy, CS_name, param); 32 | sigma = get_sigma_linearization(obj.XYZ_Het, CS_name, param); 33 | value = get_STRESS(sigma, ones(size(sigma))); 34 | case 'Mixed' 35 | uniformity_part = 0.7; 36 | handle = color_dist(CS_name, param); 37 | CD = handle(obj.XYZ_Uni); 38 | % sigma = get_sigma(obj.XYZ_Het, CS_name, param); 39 | sigma = get_sigma_linearization(obj.XYZ_Het, CS_name, param); 40 | value = ... 41 | uniformity_part * get_STRESS(CD, obj.distance_CIEDE2000) + ... 42 | (1-uniformity_part) * get_STRESS(sigma, ones(size(sigma))); 43 | end 44 | value = value + penalty(param); 45 | end 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/cache/README.md: -------------------------------------------------------------------------------- 1 | This directory is for storing cache, which makes code faster. -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/color_dist.m: -------------------------------------------------------------------------------- 1 | 2 | function handle = color_dist(METHOD, param) 3 | switch METHOD 4 | case 'LMS' 5 | handle = @(XYZ) get_Eucl_distance(@XYZ2LMS, XYZ); 6 | case 'deviceRGB' 7 | handle = @(XYZ) get_Eucl_distance(@XYZ2deviceRGB, XYZ); 8 | case 'CIE XYZ' 9 | handle = @(XYZ) get_Eucl_distance(@XYZ2XYZ, XYZ); 10 | case 'CIE xyY' 11 | handle = @(XYZ) get_Eucl_distance(@XYZ2xyY, XYZ); 12 | case 'linRGB' 13 | handle = @(XYZ) get_Eucl_distance(@XYZ2linRGB, XYZ); 14 | case 'sRGB' 15 | handle = @(XYZ) get_Eucl_distance(@XYZ2sRGB, XYZ); 16 | case 'CIELAB' 17 | handle = @(XYZ) get_Eucl_distance(@XYZ2Lab, XYZ); 18 | case 'proLab' 19 | handle = @(XYZ) get_Eucl_distance(@(XYZ)XYZ2proLab_model(XYZ, reference_illuminant, param), XYZ); 20 | case 'CAM16-UCS' 21 | handle = @(XYZ) get_Eucl_distance(@XYZ2CAM16UCS, XYZ); 22 | case 'CAM16-UCS^p' 23 | handle = @(XYZ) 1.41 * (get_Eucl_distance(@XYZ2CAM16UCS, XYZ)).^(0.63); 24 | case 'CIEDE2000' 25 | handle = @(XYZ) get_CIEDE2000(XYZ, 'XYZ'); 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/color_spaces_collection.m: -------------------------------------------------------------------------------- 1 | 2 | function CS = color_spaces_collection(name, param) 3 | switch name 4 | case 'LMS' 5 | CS.name = 'LMS'; 6 | CS.axis_names = {'$L$', '$M$', '$S$'}; 7 | CS.axis_Lab_order = [2 1 -3]; 8 | CS.transform_into = @(XYZ)XYZ2LMS(XYZ); 9 | CS.transform_from = @(CC)LMS2XYZ(CC); 10 | case 'deviceRGB' 11 | CS.name = 'deviceRGB'; 12 | CS.axis_names = {'$R$', '$G$', '$B$'}; 13 | CS.axis_Lab_order = [2 1 -3]; 14 | CS.transform_into = @(XYZ)XYZ2deviceRGB(XYZ); 15 | CS.transform_from = @(CC)deviceRGB2XYZ(CC); 16 | case 'CIE XYZ' 17 | CS.name = 'CIE XYZ'; 18 | CS.axis_names = {'$X$', '$Y$', '$Z$'}; 19 | CS.axis_Lab_order = [2 1 -3]; % (L,a,b) -> (Y,X,-Z) 20 | CS.transform_into = @(XYZ)XYZ2XYZ(XYZ); 21 | CS.transform_from = @(CC)XYZ2XYZ(CC); 22 | case 'CIE xyY' 23 | CS.name = 'CIE xyY'; 24 | CS.axis_names = {'$x$', '$y$', '$Y$'}; 25 | CS.axis_Lab_order = [3 1 2]; % (L,a,b) -> (Y,x,y) 26 | CS.transform_into = @(XYZ)XYZ2xyY(XYZ); 27 | CS.transform_from = @(CC)xyY2XYZ(CC); 28 | case 'linRGB' 29 | CS.name = 'linRGB'; 30 | CS.axis_names = {'$R$', '$G$', '$B$'}; 31 | CS.axis_Lab_order = [2 1 -3]; % (L,a,b) -> (G,R,-B) 32 | CS.transform_into = @(XYZ)XYZ2linRGB(XYZ); 33 | CS.transform_from = @(CC)linRGB2XYZ(CC); 34 | case 'sRGB' 35 | CS.name = 'sRGB'; 36 | CS.axis_names = {'$R$', '$G$', '$B$'}; 37 | CS.axis_Lab_order = [2 1 -3]; % (L,a,b) -> (G,R,-B) 38 | CS.transform_into = @(XYZ)XYZ2sRGB(XYZ); 39 | CS.transform_from = @(CC)sRGB2XYZ(CC); 40 | case 'CIELAB' 41 | CS.name = 'CIELAB'; 42 | CS.axis_names = {'$L^*$', '$a^*$', '$b^*$'}; 43 | CS.axis_Lab_order = [1 2 3]; 44 | CS.transform_into = @(XYZ)XYZ2Lab(XYZ); 45 | CS.transform_from = @(CC)Lab2XYZ(CC); 46 | case 'proLab' 47 | CS.name = 'proLab'; 48 | CS.axis_names = {'$L^+$', '$a^+$', '$b^+$'}; 49 | CS.axis_Lab_order = [1 2 3]; 50 | CS.transform_into = @(XYZ)XYZ2proLab_model(XYZ, reference_illuminant, param); 51 | CS.transform_from = @(CC)proLab2XYZ_model(CC, reference_illuminant, param); 52 | case 'CAM16-UCS' 53 | CS.name = 'CAM16-UCS'; 54 | CS.axis_names = {'$J''$', '$a''$', '$b''$'}; 55 | CS.axis_Lab_order = [1 2 3]; 56 | CS.transform_into = @(XYZ)XYZ2CAM16UCS(XYZ); 57 | end 58 | end 59 | 60 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/criterion_report.m: -------------------------------------------------------------------------------- 1 | 2 | function criterion_report(CDB, criter_name, param) 3 | disp(['Criterion : ', criter_name]); 4 | CD_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 5 | % CD_list = {'proLab'}; 6 | for CD_num = 1:size(CD_list, 1) 7 | CD_name = CD_list{CD_num}; 8 | crit_val = CDB.get(CD_name, param, criter_name); 9 | n = size(CD_name, 2); 10 | for j = 10:-1:n 11 | CD_name = [CD_name, ' ']; 12 | end 13 | CD_name = [' ', CD_name]; 14 | disp([CD_name, ': ', num2str(crit_val)]); 15 | end 16 | end 17 | 18 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/culc_P.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | param = proLab_param; 6 | format long 7 | N = (diag([D65 1])^(-1)) 8 | P = param.Q * N 9 | format -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/delete_duplicate_rows.m: -------------------------------------------------------------------------------- 1 | 2 | % This function does not guarantee removal of ALL identical rows!!! 3 | 4 | function X = delete_duplicate_rows(X) 5 | % X = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7; 5 6 7 8; 2 3 4 5; 6 7 8 9] 6 | n = size(X,1); 7 | S = sum(X,2); 8 | [S, idx] = sort(S); 9 | for i = 2:n 10 | if S(i-1)==S(i) 11 | if norm(X(idx(i-1)) - X(idx(i)))==0 12 | X(idx(i-1), :) = NaN; 13 | end 14 | end 15 | end 16 | X = X(~isnan(X(:, 1)),:); 17 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/deltaE2000.m: -------------------------------------------------------------------------------- 1 | 2 | function de00 = deltaE2000(Labstd,Labsample, KLCH) 3 | %function de00 = deltaE2000(Labstd,Labsample, KLCH ) 4 | % Compute the CIEDE2000 color-difference between the sample between a reference 5 | % with CIELab coordinates Labsample and a standard with CIELab coordinates 6 | % Labstd 7 | % The function works on multiple standard and sample vectors too 8 | % provided Labstd and Labsample are K x 3 matrices with samples and 9 | % standard specification in corresponding rows of Labstd and Labsample 10 | % The optional argument KLCH is a 1x3 vector containing the 11 | % the value of the parametric weighting factors kL, kC, and kH 12 | % these default to 1 if KLCH is not specified. 13 | 14 | % Based on the article: 15 | % "The CIEDE2000 Color-Difference Formula: Implementation Notes, 16 | % Supplementary Test Data, and Mathematical Observations,", G. Sharma, 17 | % W. Wu, E. N. Dalal, Color Research and Application, vol. 30. No. 1, pp. 18 | % 21-30, February 2005. 19 | % available at http://www.ece.rochester.edu/~/gsharma/ciede2000/ 20 | 21 | de00 = []; 22 | 23 | % Error checking to ensure that sample and Std vectors are of correct sizes 24 | v=size(Labstd); w = size(Labsample); 25 | if ( v(1) ~= w(1) | v(2) ~= w(2) ) 26 | disp('deltaE00: Standard and Sample sizes do not match'); 27 | return 28 | end % if ( v(1) ~= w(1) | v(2) ~= w(2) ) 29 | if ( v(2) ~= 3) 30 | disp('deltaE00: Standard and Sample Lab vectors should be Kx3 vectors'); 31 | return 32 | end 33 | 34 | % Parametric factors 35 | if (nargin <3 ) 36 | % Values of Parametric factors not specified use defaults 37 | kl = 1; kc=1; kh =1; 38 | else 39 | % Use specified Values of Parametric factors 40 | if ( (size(KLCH,1) ~=1) | (size(KLCH,2) ~=3)) 41 | disp('deltaE00: KLCH must be a 1x3 vector'); 42 | return; 43 | else 44 | kl =KLCH(1); kc=KLCH(2); kh =KLCH(3); 45 | end 46 | end 47 | 48 | Lstd = Labstd(:,1)'; 49 | astd = Labstd(:,2)'; 50 | bstd = Labstd(:,3)'; 51 | Cabstd = sqrt(astd.^2+bstd.^2); 52 | 53 | Lsample = Labsample(:,1)'; 54 | asample = Labsample(:,2)'; 55 | bsample = Labsample(:,3)'; 56 | Cabsample = sqrt(asample.^2+bsample.^2); 57 | 58 | Cabarithmean = (Cabstd + Cabsample)/2; 59 | 60 | G = 0.5* ( 1 - sqrt( (Cabarithmean.^7)./(Cabarithmean.^7 + 25^7))); 61 | 62 | apstd = (1+G).*astd; % aprime in paper 63 | apsample = (1+G).*asample; % aprime in paper 64 | Cpsample = sqrt(apsample.^2+bsample.^2); 65 | Cpstd = sqrt(apstd.^2+bstd.^2); 66 | % Compute product of chromas and locations at which it is zero for use later 67 | Cpprod = (Cpsample.*Cpstd); 68 | zcidx = find(Cpprod == 0); 69 | 70 | 71 | % Ensure hue is between 0 and 2pi 72 | % NOTE: MATLAB already defines atan2(0,0) as zero but explicitly set it 73 | % just in case future definitions change 74 | hpstd = atan2(bstd,apstd); 75 | hpstd = hpstd+2*pi*(hpstd < 0); % rollover ones that come -ve 76 | hpstd(find( (abs(apstd)+abs(bstd))== 0) ) = 0; 77 | hpsample = atan2(bsample,apsample); 78 | hpsample = hpsample+2*pi*(hpsample < 0); 79 | hpsample(find( (abs(apsample)+abs(bsample))==0) ) = 0; 80 | 81 | dL = (Lsample-Lstd); 82 | dC = (Cpsample-Cpstd); 83 | % Computation of hue difference 84 | dhp = (hpsample-hpstd); 85 | dhp = dhp - 2*pi* (dhp > pi ); 86 | dhp = dhp + 2*pi* (dhp < (-pi) ); 87 | % set chroma difference to zero if the product of chromas is zero 88 | dhp(zcidx ) = 0; 89 | 90 | % Note that the defining equations actually need 91 | % signed Hue and chroma differences which is different 92 | % from prior color difference formulae 93 | 94 | dH = 2*sqrt(Cpprod).*sin(dhp/2); 95 | %dH2 = 4*Cpprod.*(sin(dhp/2)).^2; 96 | 97 | % weighting functions 98 | Lp = (Lsample+Lstd)/2; 99 | Cp = (Cpstd+Cpsample)/2; 100 | % Average Hue Computation 101 | % This is equivalent to that in the paper but simpler programmatically. 102 | % Note average hue is computed in radians and converted to degrees only 103 | % where needed 104 | hp = (hpstd+hpsample)/2; 105 | % Identify positions for which abs hue diff exceeds 180 degrees 106 | hp = hp - ( abs(hpstd-hpsample) > pi ) *pi; 107 | % rollover ones that come -ve 108 | hp = hp+ (hp < 0) *2*pi; 109 | % Check if one of the chroma values is zero, in which case set 110 | % mean hue to the sum which is equivalent to other value 111 | hp(zcidx) = hpsample(zcidx)+hpstd(zcidx); 112 | 113 | Lpm502 = (Lp-50).^2; 114 | Sl = 1 + 0.015*Lpm502./sqrt(20+Lpm502); 115 | Sc = 1+0.045*Cp; 116 | T = 1 - 0.17*cos(hp - pi/6 ) + 0.24*cos(2*hp) + 0.32*cos(3*hp+pi/30) ... 117 | -0.20*cos(4*hp-63*pi/180); 118 | Sh = 1 + 0.015*Cp.*T; 119 | delthetarad = (30*pi/180)*exp(- ( (180/pi*hp-275)/25).^2); 120 | Rc = 2*sqrt((Cp.^7)./(Cp.^7 + 25^7)); 121 | RT = - sin(2*delthetarad).*Rc; 122 | 123 | klSl = kl*Sl; 124 | kcSc = kc*Sc; 125 | khSh = kh*Sh; 126 | 127 | % The CIE 00 color difference 128 | de00 = sqrt( (dL./klSl).^2 + (dC./kcSc).^2 + (dH./khSh).^2 + RT.*(dC./kcSc).*(dH./khSh) ); 129 | 130 | return 131 | 132 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/find_optimal_m.m: -------------------------------------------------------------------------------- 1 | 2 | function m_optimal = find_optimal_m(ObjectiveFunction) 3 | best_minimum = +Inf; 4 | m_init = [... 5 | 2.1590, -1.7823, -0.0713, 2.0865, 0.2102, 0.7553, 3.8666, 1.6738; ... 6 | 2.4089, -1.8582, -0.1487, 2.2070, -0.1002, 0.7808, 2.2124, 0.9633; ... 7 | -2.3580, 2.4150, 0.0872, 2.5877, 0.1380, 0.0758, 5.4585, 2.5247; ... 8 | -3.0756, 2.0115, 0.2698, 3.0838, 0.1181, 1.3477, 2.8796, 0.6876; ... 9 | ]; 10 | multistart_number = 1; 11 | for i = 1:multistart_number 12 | if i <= size(m_init, 1) 13 | m = m_init(i, :); 14 | else 15 | m = m_init(1, :) + 10*randn(1, 8); 16 | end 17 | % options = optimset('Display','iter','PlotFcns',@optimplotfval); 18 | options.MaxFunEvals = +Inf; 19 | options.MaxIter = +Inf; 20 | m_opt = fminsearch(ObjectiveFunction,m,options); 21 | minimum = ObjectiveFunction(m_opt); 22 | if minimum < best_minimum 23 | best_minimum = minimum; 24 | m_optimal = m_opt; 25 | end 26 | end 27 | best_minimum 28 | end 29 | 30 | 31 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_CIEDE2000.m: -------------------------------------------------------------------------------- 1 | 2 | function delta_E = get_CIEDE2000(CC, CS) 3 | switch CS 4 | case 'CIELAB' 5 | delta_E = (deltaE2000(CC{1},CC{2}))'; 6 | case 'CIE XYZ' 7 | Lab = XYZ2Lab(CC); 8 | delta_E = (deltaE2000(Lab{1},Lab{2}))'; 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_Eucl_distance.m: -------------------------------------------------------------------------------- 1 | 2 | function space_distance = get_Eucl_distance(XYZ_transform, XYZ) 3 | XYZ_transformed = XYZ_transform(XYZ); 4 | diff_XYZ_transformed = XYZ_transformed{1}-XYZ_transformed{2}; 5 | space_distance = sqrt(sum(diff_XYZ_transformed.^2, 2)); 6 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_STRESS.m: -------------------------------------------------------------------------------- 1 | 2 | % "Measurement of the relationship ... 3 | % between perceived and computed 4 | % color differences", Formula (9). 5 | 6 | function [STRESS, F] = get_STRESS(achi, goal) 7 | achi = achi(:); 8 | goal = goal(:); 9 | F = (achi'*goal) / (achi'*achi); 10 | STRESS = sqrt(sum((F*achi - goal).^2) / sum(goal.^2)); 11 | end 12 | 13 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_XYZ_sRGB_planes.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ_sRGB_planes = get_XYZ_sRGB_planes() 3 | XYZ_sRGB_vertex = (linRGB_matrix^(-1)*vertex')'; 4 | idx = [1 2 3; ... 5 | 1 3 4; ... 6 | 1 4 2; ... 7 | 6 5 8; ... 8 | 7 6 8; ... 9 | 5 7 8]; 10 | XYZ_sRGB_planes = zeros(6, 4); 11 | for i = 1:6 12 | normal = cross( ... 13 | XYZ_sRGB_vertex(idx(i, 2), :) - XYZ_sRGB_vertex(idx(i, 1), :), ... 14 | XYZ_sRGB_vertex(idx(i, 3), :) - XYZ_sRGB_vertex(idx(i, 1), :)); 15 | const = - normal * XYZ_sRGB_vertex(idx(i, 1), :)'; 16 | XYZ_sRGB_planes(i, :) = - [normal, const]; 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_color_body_boundary_mesh.m: -------------------------------------------------------------------------------- 1 | 2 | function boundary_mesh = get_color_body_boundary_mesh(d_lambda) 3 | cache_path = ['search_optimal_proLab_param/cache/color_body_boundary_mesh_',num2str(d_lambda),'.mat']; 4 | if exist(cache_path, 'file') == 0 5 | formulary = '1931_FULL'; 6 | lambda = (300:d_lambda:830)'; 7 | XYZ_spectrum = get_XYZ_spectrum(lambda, formulary); 8 | XYZ_spectrum = XYZ_spectrum / max(XYZ_spectrum(:, 2)); 9 | source = XYZ_spectrum .* get_D65_spectrum(lambda); 10 | source = source ./ (sum(source(:, 2)) * d_lambda); 11 | 12 | step_1 = @(l,l1,l2) (l1 0 20 | constr = - constr; 21 | end 22 | constraints(j, :) = constr; 23 | end 24 | constraints = delete_duplicate_rows(constraints); 25 | save(cache_path, 'constraints', 'DT', 'C'); 26 | else 27 | load(cache_path); 28 | end 29 | end 30 | 31 | 32 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_covariance.m: -------------------------------------------------------------------------------- 1 | 2 | function Cov = get_covariance(X) 3 | X = X - mean(X); 4 | Cov = X'*X/size(X,1); 5 | end 6 | 7 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_quantum_noise.m: -------------------------------------------------------------------------------- 1 | 2 | function N = get_quantum_noise(mean_N, local_size, model) 3 | c = size(mean_N, 2); 4 | switch model 5 | case 'Poisson' 6 | N = zeros(local_size, c); 7 | for i = 1:c 8 | N(:, i) = poissrnd(mean_N(i), [local_size 1]); 9 | end 10 | case 'Normal_approx' 11 | N = mean_N + sqrt(mean_N) .* randn(local_size, c); 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_sample.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = get_sample(N, options) 3 | if nargin < 2 4 | options.check_camera_sane = false; 5 | end 6 | d_lambda = 30; 7 | XYZ = zeros(0, 3); 8 | while true 9 | % disp(' Iteration ...'); 10 | Lab = [100 400 300] .* rand(3*N, 3) - [0 200 150]; 11 | % if nargin == 2 12 | % CIEDE2000 = get_CIEDE2000(Lab, 'CIELAB'); 13 | % idx_1 = (borders(1) <= CIEDE2000); 14 | % idx_2 = (CIEDE2000 <= borders(2)); 15 | % idx = idx_1 & idx_2; 16 | % Lab{1} = Lab{1}(idx,:); 17 | % Lab{2} = Lab{2}(idx,:); 18 | % end 19 | XYZ_part = Lab2XYZ(Lab); 20 | idx = is_color_body(XYZ_part,d_lambda); 21 | XYZ_part = XYZ_part(idx, :); 22 | if options.check_camera_sane 23 | idx = is_camera_sane(XYZ_part); 24 | XYZ_part = XYZ_part(idx, :); 25 | end 26 | XYZ = [XYZ; XYZ_part]; 27 | if size(XYZ, 1) >= 2*N 28 | break; 29 | end 30 | end 31 | XYZ(2*N+1:end,:) = []; 32 | XYZ = {XYZ(1:N,:), XYZ(N+1:2*N,:)}; 33 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_sample_temp.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = get_sample_temp 3 | 4 | M = linRGB_matrix^(-1); 5 | 6 | principal_colors{1} = [0 0 0]; % Black 7 | principal_colors{2} = (M(:,1))'; % Red 8 | principal_colors{3} = (M(:,2))'; % Green 9 | principal_colors{4} = (M(:,3))'; % Blue 10 | principal_colors{5} = (M(:,2)+M(:,3))'; % Yellow 11 | principal_colors{6} = (M(:,3)+M(:,1))'; % Magenta 12 | principal_colors{7} = (M(:,1)+M(:,2))'; % Cyan 13 | principal_colors{8} = (sum(M,2))'; % White 14 | n = 8; 15 | XYZ{1} = zeros(0, 3); 16 | XYZ{2} = zeros(0, 3); 17 | for i = 1:n 18 | for j = (i+1):n 19 | XYZ{1} = [XYZ{1}; principal_colors{i}]; 20 | XYZ{2} = [XYZ{2}; principal_colors{j}]; 21 | end 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_sigma.m: -------------------------------------------------------------------------------- 1 | 2 | function [Sigma, Mean] = get_sigma(XYZ, CS_name, param) 3 | 4 | CS = color_spaces_collection(CS_name, param); 5 | [g, sample_size, ~] = size(XYZ); 6 | XYZ = reshape(XYZ, [g * sample_size, 3]); 7 | CC = CS.transform_into(XYZ); 8 | CC = reshape(CC, [g, sample_size, 3]); 9 | Mean = zeros(g, 3); 10 | Sigma = zeros(g, 3); 11 | for i = 1:g 12 | CC_sample = squeeze(CC(i, :, :)); 13 | Mean(i, :) = mean(CC_sample); 14 | Cov = get_covariance(CC_sample); 15 | lambda = max(0, eig(Cov)); 16 | Sigma(i, :) = sort(sqrt(lambda)); 17 | % Sigma(i, :) = sort(lambda); 18 | end 19 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/get_sigma_linearization.m: -------------------------------------------------------------------------------- 1 | 2 | function Sigma = get_sigma_linearization(XYZ, CS_name, param) 3 | CS_own = color_spaces_collection('deviceRGB'); 4 | CC_own = CS_own.transform_into(XYZ); 5 | CC_own_max = CS_own.transform_into(reference_illuminant); 6 | 7 | [gain, var_0] = sensor_noize_param; 8 | 9 | g = size(CC_own, 1); 10 | dCC_own = zeros(g, 3, 2, 3); 11 | h = norm(CC_own_max)*10^(-8); 12 | for j = 1:3 13 | cc1 = CC_own; 14 | cc2 = CC_own; 15 | cc1(:, j) = cc1(:, j) - h; 16 | cc2(:, j) = cc2(:, j) + h; 17 | dCC_own(:, j, 1, :) = cc1; 18 | dCC_own(:, j, 2, :) = cc2; 19 | end 20 | dCC_own = reshape(dCC_own, [6 * g, 3]); 21 | dXYZ = CS_own.transform_from(dCC_own); 22 | CS = color_spaces_collection(CS_name, param); 23 | dCC = CS.transform_into(dXYZ); 24 | CC = reshape(dCC, [g, 3, 2, 3]); 25 | Sigma = zeros(g, 3); 26 | CC_deriv = (CC(:, :, 2, :) - CC(:, :, 1, :)) / (2 * h); 27 | CC_deriv = permute(CC_deriv, [4 2 1 3]); 28 | for i = 1:g 29 | J = CC_deriv(:, :, i); 30 | Cov_CC_own = [1 0 0; 0 1/2 0; 0 0 1] * diag(gain .* CC_own(i, :) + var_0); 31 | Cov_CC = J * Cov_CC_own * J'; 32 | lambda = max(0, eig(Cov_CC)); 33 | Sigma(i, :) = sort(sqrt(lambda)); 34 | end 35 | end 36 | 37 | % function Sigma = get_sigma_linearization(XYZ, CS_name, param, gain) 38 | % 39 | % CS_own = color_spaces_collection('hwRGB', param); 40 | % CC_own = CS_own.transform_into(XYZ); 41 | % CC_own_max = CS_own.transform_into(D65'); 42 | % 43 | % g = size(CC_own, 1); 44 | % dCC_own = zeros(g, 3, 2, 3); 45 | % h = norm(CC_own_max)*10^(-8); 46 | % for j = 1:3 47 | % cc1 = CC_own; 48 | % cc2 = CC_own; 49 | % cc1(:, j) = cc1(:, j) - h; 50 | % cc2(:, j) = cc2(:, j) + h; 51 | % dCC_own(:, j, 1, :) = cc1; 52 | % dCC_own(:, j, 2, :) = cc2; 53 | % end 54 | % dCC_own = reshape(dCC_own, [6 * g, 3]); 55 | % dXYZ = CS_own.transform_from(dCC_own); 56 | % CS = color_spaces_collection(CS_name, param); 57 | % dCC = CS.transform_into(dXYZ); 58 | % CC = reshape(dCC, [g, 3, 2, 3]); 59 | % Sigma = zeros(g, 3); 60 | % CC_deriv = (CC(:, :, 2, :) - CC(:, :, 1, :)) / (2 * h); 61 | % CC_deriv = permute(CC_deriv, [4 2 1 3]); 62 | % for i = 1:g 63 | % J = CC_deriv(:, :, i); 64 | % Cov_CC_own = diag(CC_own_max .* abs(CC_own(i, :)) ./ gain); 65 | % Cov_CC = J * Cov_CC_own * J'; 66 | % lambda = max(0, eig(Cov_CC)); 67 | % Sigma(i, :) = sort(sqrt(lambda)); 68 | % end 69 | % end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/is_camera_sane.m: -------------------------------------------------------------------------------- 1 | 2 | function idx = is_camera_sane(XYZ) 3 | hwRGB = XYZ2deviceRGB(XYZ); 4 | idx = all(hwRGB>=0, 2); 5 | end 6 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/is_color_body.m: -------------------------------------------------------------------------------- 1 | 2 | function idx = is_color_body(XYZ, d_lambda) 3 | constraints = get_color_body_constraints(d_lambda); 4 | N = size(XYZ, 1); 5 | b = [XYZ, ones(N, 1)] * constraints' < 0; 6 | idx = all(b, 2); 7 | end 8 | 9 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/is_color_cone.m: -------------------------------------------------------------------------------- 1 | 2 | function idx = is_color_cone(X) 3 | lambda = [361; (400:1:690)'; 700]; 4 | formulary = '1931_FULL'; 5 | XYZ = get_XYZ_spectrum(lambda, formulary); 6 | S = sum(XYZ, 2); 7 | x = XYZ(:,1) ./ S; 8 | y = XYZ(:,2) ./ S; 9 | 10 | y1 = y; 11 | y2 = y(2: end); 12 | y2 = [y2; y(1)]; 13 | 14 | x1 = x; 15 | x2 = x(2: end); 16 | x2 = [x2; x(1)]; 17 | 18 | A = y1-y2; 19 | B = x2-x1; 20 | C = x1.*y2 - x2.*y1; 21 | if size(X, 2) == 3 22 | X = X(:, 1:2) ./ sum(X, 2); 23 | end 24 | idx = false(size(X, 1), 1); 25 | for i = 1:size(X, 1) 26 | if size(A, 1) == -sum(sign(A*X(i, 1) + B*X(i, 2) + C)) 27 | idx(i) = 1; 28 | end 29 | end 30 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/m2M.m: -------------------------------------------------------------------------------- 1 | 2 | function M = m2M(m) 3 | M = zeros(4,4); 4 | M(1, 1:3) = m(1:3); 5 | M(2, 2:3) = m(4:5); 6 | M(3, 3) = 1; 7 | M(4, 1:3) = m(6:8); 8 | M(4, 4) = 1; 9 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/m2Q.m: -------------------------------------------------------------------------------- 1 | 2 | function Q = m2Q(param) 3 | if isfield(param, 'Q') 4 | param = rmfield(param, 'Q'); 5 | end 6 | param.Q = m2M(param.m); 7 | Lab_goal = [ 50, -80, 0; ... 8 | 50, 80, 0; ... 9 | 50, 0, -80; ... 10 | 50, 0, 80; ... 11 | 100, 0, 0]; 12 | XYZ_points = Lab2XYZ(Lab_goal); 13 | proLab_points = XYZ2proLab_model(XYZ_points, reference_illuminant, param); 14 | k = norm(Lab_goal(end,:)) / norm(proLab_points(end,:)); 15 | param.Q = [[k * eye(3, 3), [0; 0; 0]]; 0 0 0 1] * param.Q; 16 | 17 | proLab_points = XYZ2proLab_model(XYZ_points, reference_illuminant, param); 18 | white_direct = Lab_goal(end, :) / norm(Lab_goal(end, :)); 19 | K = proLab_points(end, :)' * white_direct; 20 | try 21 | R = K2R(K); 22 | catch 23 | R = eye(3,3); 24 | end 25 | param.Q = [[R, [0; 0; 0]]; 0 0 0 1] * param.Q; 26 | proLab_points = XYZ2proLab_model(XYZ_points, reference_illuminant, param); 27 | X = proLab_points * (eye(3,3) - white_direct' * white_direct); 28 | Y = Lab_goal * (eye(3,3) - white_direct' * white_direct); 29 | K = X' * Y; 30 | try 31 | R = K2R(K); 32 | catch 33 | R = eye(3,3); 34 | end 35 | Q = [[R, [0; 0; 0]]; 0 0 0 1] * param.Q; 36 | end 37 | 38 | function R = K2R(K) 39 | [U,~,V] = svd(K); 40 | R = V*U'; 41 | if det(R)<0 42 | V(:,3)=-V(:,3); 43 | R = V*U'; 44 | end 45 | end 46 | 47 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/penalty.m: -------------------------------------------------------------------------------- 1 | 2 | % https://en.wikipedia.org/wiki/Penalty_method 3 | 4 | function g = penalty(param) 5 | 6 | m = param.m; 7 | M = m2M(m); 8 | 9 | c1 = - m(1) * m(4); 10 | 11 | linRGB = vertex; 12 | c2 = - (linRGB(2:end, :) * (m(6:8))' + 1); 13 | 14 | mm0 = [m(1)+m(2)+m(3); m(4)+m(5); 1]; 15 | m0 = m(6)+m(7)+m(8)+1; 16 | l = [m0*mm0', 0; m0*mm0', - mm0'*mm0]; 17 | CIEXYZ_normal = l * M(:, 1:3); 18 | c3 = - CIEXYZ_normal; 19 | c3 = c3(:); 20 | 21 | c = [c1; c2; c3]; 22 | g = 100*sum((max(0,c)).^1); % !!! 23 | 24 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/proLab_Jacobian.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | syms x y z 9 | syms h11 h12 h13 h14 10 | syms h21 h22 h23 h24 11 | syms h31 h32 h33 h34 12 | syms h41 h42 h43 h44 13 | 14 | X = (h11*x + h12*y + h13*z + h14) / (h41*x + h42*y + h43*z + h44); 15 | Y = (h21*x + h22*y + h23*z + h24) / (h41*x + h42*y + h43*z + h44); 16 | Z = (h31*x + h32*y + h33*z + h34) / (h41*x + h42*y + h43*z + h44); 17 | 18 | dX = diff(X, x) 19 | dX = simplify(dX) -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/reverse_permutation.m: -------------------------------------------------------------------------------- 1 | 2 | function rev_perm = reverse_permutation(perm) 3 | [~, rev_perm] = sort(perm); 4 | end 5 | 6 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/sensor_noize_param.m: -------------------------------------------------------------------------------- 1 | 2 | function [gain, var_0] = sensor_noize_param 3 | 4 | gain = 3.38; 5 | var_0 = 744; 6 | 7 | end 8 | 9 | -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/simulate_camera_noise.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = simulate_camera_noise(local_size, global_size, XYZ_set) 3 | CS = color_spaces_collection('deviceRGB'); 4 | if nargin == 2 5 | options.check_camera_sane = true; 6 | XYZ_set = get_sample(global_size, options); 7 | XYZ_set = XYZ_set{1}; 8 | end 9 | CC = CS.transform_into(XYZ_set); 10 | % CC_white = CS.transform_into(D65'); 11 | [gain, var_0] = sensor_noize_param; 12 | XYZ = zeros(global_size, local_size, 3); 13 | for g = 1:global_size 14 | mean_N = CC(g, :) / gain; 15 | mean_N = [mean_N(1:2), mean_N(2:3)]; 16 | model = 'Normal_approx'; 17 | N = get_quantum_noise(mean_N, local_size, model); 18 | N = max(0, N); 19 | CC_4 = gain * N + sqrt(var_0) * randn(size(N)); 20 | CC_sample = [CC_4(:, 1), mean(CC_4(:, 2:3), 2), CC_4(:, 4)]; 21 | XYZ(g, :, :) = CS.transform_from(CC_sample); 22 | end 23 | % XYZ = max(0, XYZ); % !!! 24 | end -------------------------------------------------------------------------------- /matlab/search_optimal_proLab_param/vertex.m: -------------------------------------------------------------------------------- 1 | 2 | function output = vertex() 3 | output = [0 0 0; 1 0 0; 0 1 0; 0 0 1; 0 1 1; 1 0 1; 1 1 0; 1 1 1]; 4 | end 5 | 6 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/LMS2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = LMS2XYZ(LMS) 3 | XYZ = LMS * (LMS_matrix')^(-1); 4 | end 5 | 6 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/LMS_matrix.m: -------------------------------------------------------------------------------- 1 | 2 | function matrix = LMS_matrix 3 | % matrix_1 = [0.38971, 0.68898, -0.07868; ... 4 | % -0.22981, 1.18340, 0.04641; ... 5 | % 0, 0, 1]; 6 | matrix_2 = [0.4002, 0.7076, -0.0808; ... 7 | -0.2263, 1.1653, 0.0457; ... 8 | 0, 0, 0.9182]; 9 | matrix = matrix_2; 10 | end 11 | 12 | % matrix_1 * [1; 1; 1] 13 | % matrix_2 * D65 -------------------------------------------------------------------------------- /matlab/standard_color_conversions/Lab2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = Lab2XYZ(Lab, ref_illum) 3 | if nargin == 1 4 | ref_illum = reference_illuminant; 5 | end 6 | if iscell(Lab) 7 | XYZ = cell(1, 2); 8 | for i = 1:2 9 | XYZ{i} = transf(Lab{i}, ref_illum); 10 | end 11 | else 12 | XYZ = transf(Lab, ref_illum); 13 | end 14 | end 15 | 16 | function XYZ = transf(Lab, ref_illum) 17 | f_y = (Lab(:, 1) + 16) / 116; 18 | f_x = f_y + Lab(:, 2) / 500; 19 | f_z = f_y - Lab(:, 3) / 200; 20 | XYZ = [f_reverse(f_x), f_reverse(f_y), f_reverse(f_z)]; 21 | XYZ = ref_illum .* XYZ; 22 | end 23 | 24 | function ret_val = f_reverse(t) 25 | delta = 6/29; 26 | logic = t > delta; 27 | ret_val = zeros(size(t)); 28 | ret_val(logic) = t(logic).^3; 29 | ret_val(~logic) = 3 * delta^2 * (t(~logic) - 16/116); 30 | end 31 | 32 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2CAM16UCS.m: -------------------------------------------------------------------------------- 1 | 2 | function CAM16UCS = XYZ2CAM16UCS(XYZ, ref_illum) 3 | if nargin == 1 4 | ref_illum = reference_illuminant; 5 | end 6 | if iscell(XYZ) 7 | CAM16UCS = cell(1, 2); 8 | for i = 1:2 9 | CAM16UCS{i} = transf(XYZ{i}, ref_illum); 10 | end 11 | else 12 | CAM16UCS = transf(XYZ, ref_illum); 13 | end 14 | end 15 | 16 | function CAM16UCS = transf(XYZ, ref_illum) 17 | save('../python/reference_illuminant.mat', 'ref_illum'); 18 | save('../python/request.mat', 'XYZ'); 19 | system('python ../python/XYZ_to_CAM16UCS.py'); 20 | response = load('../python/response.mat'); 21 | CAM16UCS = response.CAM16UCS; 22 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2LMS.m: -------------------------------------------------------------------------------- 1 | 2 | function LMS = XYZ2LMS(XYZ) 3 | if iscell(XYZ) 4 | LMS = cell(1, 2); 5 | for i = 1:2 6 | LMS{i} = transf(XYZ{i}); 7 | end 8 | else 9 | LMS = transf(XYZ); 10 | end 11 | end 12 | 13 | function LMS = transf(XYZ) 14 | LMS = XYZ * LMS_matrix'; 15 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2Lab.m: -------------------------------------------------------------------------------- 1 | 2 | function Lab = XYZ2Lab(XYZ, ref_illum) 3 | if nargin == 1 4 | ref_illum = reference_illuminant; 5 | end 6 | if iscell(XYZ) 7 | Lab = cell(1, 2); 8 | for i = 1:2 9 | Lab{i} = transf(XYZ{i}, ref_illum); 10 | end 11 | else 12 | Lab = transf(XYZ, ref_illum); 13 | end 14 | end 15 | 16 | function Lab = transf(XYZ, ref_illum) 17 | XYZ = XYZ ./ ref_illum; 18 | Lab = [116 * f(XYZ(:, 2)) - 16, ... 19 | 500 * (f(XYZ(:, 1)) - f(XYZ(:, 2))), ... 20 | 200 * (f(XYZ(:, 2)) - f(XYZ(:, 3)))]; 21 | end 22 | 23 | function ret_val = f(t) 24 | delta = 6/29; 25 | logic = t > delta^3; 26 | ret_val = zeros(size(t)); 27 | ret_val(~logic) = t(~logic) / (3 * delta^2) + 4/29; 28 | ret_val(logic) = t(logic).^(1/3); 29 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = XYZ2XYZ(XYZ) 3 | 4 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2deviceRGB.m: -------------------------------------------------------------------------------- 1 | 2 | function deviceRGB = XYZ2deviceRGB(XYZ) 3 | if iscell(XYZ) 4 | deviceRGB = cell(1, 2); 5 | for i = 1:2 6 | deviceRGB{i} = transf(XYZ{i}); 7 | end 8 | else 9 | deviceRGB = transf(XYZ); 10 | end 11 | end 12 | 13 | function deviceRGB = transf(XYZ) 14 | deviceRGB = XYZ * deviceRGB_matrix'; 15 | end 16 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2linRGB.m: -------------------------------------------------------------------------------- 1 | 2 | function linRGB = XYZ2linRGB(XYZ) 3 | if iscell(XYZ) 4 | linRGB = cell(1, 2); 5 | for i = 1:2 6 | linRGB{i} = transf(XYZ{i}); 7 | end 8 | else 9 | linRGB = transf(XYZ); 10 | end 11 | end 12 | 13 | function linRGB = transf(XYZ) 14 | linRGB = XYZ * linRGB_matrix'; 15 | end 16 | 17 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2sRGB.m: -------------------------------------------------------------------------------- 1 | 2 | function sRGB = XYZ2sRGB(XYZ) 3 | if iscell(XYZ) 4 | sRGB = cell(1, 2); 5 | for i = 1:2 6 | sRGB{i} = transf(XYZ{i}); 7 | end 8 | else 9 | sRGB = transf(XYZ); 10 | end 11 | end 12 | 13 | function sRGB = transf(XYZ) 14 | linRGB = XYZ2linRGB(XYZ); 15 | sRGB = linRGB2sRGB(linRGB); 16 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/XYZ2xyY.m: -------------------------------------------------------------------------------- 1 | 2 | function xyY = XYZ2xyY(XYZ) 3 | if iscell(XYZ) 4 | xyY = cell(1, 2); 5 | for i = 1:2 6 | xyY{i} = transf(XYZ{i}); 7 | end 8 | else 9 | xyY = transf(XYZ); 10 | end 11 | end 12 | 13 | function xyY = transf(XYZ) 14 | xyY = zeros(size(XYZ)); 15 | xyY(:, 1) = XYZ(:, 1) ./ sum(XYZ, 2); 16 | xyY(:, 2) = XYZ(:, 2) ./ sum(XYZ, 2); 17 | xyY(:, 3) = XYZ(:, 2); 18 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/deviceRGB2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = deviceRGB2XYZ(deviceRGB) 3 | XYZ = deviceRGB * (deviceRGB_matrix')^(-1); 4 | end 5 | 6 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/deviceRGB2linRGB_matrix.m: -------------------------------------------------------------------------------- 1 | 2 | function matrix = deviceRGB2linRGB_matrix 3 | %% mls-dataset 4 | M1 = 0.1*(0.3 / (2^16)) * [ ... 5 | 41.93, -2.08, -37.24; ... 6 | -14.32, 39.13, 10.79; ... 7 | -0.02, -35.39, 185.52]; 8 | matrix = M1; 9 | % matrix = M1^(-1); 10 | % matrix = (M1')^(-1); 11 | % matrix = M1'; 12 | 13 | %% dxomark 14 | 15 | % M2 = [2.27, -1.42, 0.15; -0.28, 1.67, -0.39; 0.04, -0.8, 1.75]; 16 | % matrix = M2; 17 | % matrix = M2^(-1); 18 | % matrix = (M2')^(-1); 19 | % matrix = M2'; 20 | end 21 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/deviceRGB_matrix.m: -------------------------------------------------------------------------------- 1 | 2 | function matrix = deviceRGB_matrix 3 | matrix = (deviceRGB2linRGB_matrix)^(-1) * linRGB_matrix; 4 | end 5 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/linRGB2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = linRGB2XYZ(linRGB) 3 | XYZ = linRGB * (linRGB_matrix')^(-1); 4 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/linRGB2sRGB.m: -------------------------------------------------------------------------------- 1 | 2 | function sRGB = linRGB2sRGB(linRGB) 3 | sRGB = zeros(size(linRGB)); 4 | a = 0.055; 5 | C = 0.0031308; 6 | k = 12.92; 7 | p = 1 / 2.4; 8 | 9 | abs_sRGB_linear = abs(linRGB); 10 | ind = (abs_sRGB_linear > C); 11 | sRGB(~ind) = k*abs_sRGB_linear(~ind); 12 | sRGB(ind) = (1+a)*abs_sRGB_linear(ind).^p - a; 13 | sRGB = sign(linRGB).*sRGB; 14 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/linRGB_matrix.m: -------------------------------------------------------------------------------- 1 | 2 | function matrix = linRGB_matrix 3 | matrix = [3.2404542 -1.5371385 -0.4985314; ... 4 | -0.9692660 1.8760108 0.0415560; ... 5 | 0.0556434 -0.2040259 1.0572252]; 6 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/sRGB2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = sRGB2XYZ(sRGB) 3 | linRGB = sRGB2linRGB(sRGB); 4 | XYZ = linRGB2XYZ(linRGB); 5 | end 6 | 7 | function linRGB = sRGB2linRGB(sRGB) 8 | 9 | linRGB = zeros(size(sRGB)); 10 | a = 0.055; 11 | C = 0.0031308; 12 | k = 12.92; 13 | p = 2.4; 14 | 15 | abs_sRGB = abs(sRGB); 16 | ind = (abs_sRGB > k*C); 17 | linRGB(~ind) = (1/k)*abs_sRGB(~ind); 18 | linRGB(ind) = ((abs_sRGB(ind)+a)/(1+a)).^p; 19 | linRGB = sign(sRGB).*linRGB; 20 | end -------------------------------------------------------------------------------- /matlab/standard_color_conversions/sRGB2linRGB.m: -------------------------------------------------------------------------------- 1 | 2 | function linRGB = sRGB2linRGB(sRGB) 3 | linRGB = zeros(size(sRGB)); 4 | a = 0.055; 5 | C = 0.0031308; 6 | k = 12.92; 7 | p = 2.4; 8 | 9 | abs_sRGB = abs(sRGB); 10 | ind = (abs_sRGB > k*C); 11 | linRGB(~ind) = (1/k)*abs_sRGB(~ind); 12 | linRGB(ind) = ((abs_sRGB(ind)+a)/(1+a)).^p; 13 | linRGB = sign(sRGB).*linRGB; 14 | end 15 | -------------------------------------------------------------------------------- /matlab/standard_color_conversions/xyY2XYZ.m: -------------------------------------------------------------------------------- 1 | 2 | function XYZ = xyY2XYZ(xyY) 3 | if iscell(xyY) 4 | XYZ = cell(1, 2); 5 | for i = 1:2 6 | XYZ{i} = transf(xyY{i}); 7 | end 8 | else 9 | XYZ = transf(xyY); 10 | end 11 | end 12 | 13 | function XYZ = transf(xyY) 14 | XYZ = zeros(size(xyY)); 15 | XYZ(:, 1) = (xyY(:, 3) ./ xyY(:, 2)) .* xyY(:, 1); 16 | XYZ(:, 2) = xyY(:, 3); 17 | XYZ(:, 3) = (xyY(:, 3) ./ xyY(:, 2)) .* (1 - xyY(:, 1) - xyY(:, 2)); 18 | end -------------------------------------------------------------------------------- /matlab/test/check_conditions.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | param_m.m = [2.1591 -1.7823 -0.0713 2.0865 0.2103 0.7554 3.8666 1.6739]; 8 | g = penalty(param_m) 9 | 10 | param = proLab_param; 11 | Q = param.Q; 12 | 13 | disp(det(Q)) 14 | disp(Q(4, 1:3) * vertex' + 1) 15 | l = [1 0 0 0; 1 0 0 -100]; 16 | disp(l * Q) -------------------------------------------------------------------------------- /matlab/test/check_mQ_compliance.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | param_m.m = [2.1591 -1.7823 -0.0713 2.0865 0.2103 0.7554 3.8666 1.6739]; 6 | Q_m = m2Q(param_m) 7 | param = proLab_param; 8 | Q = param.Q 9 | 10 | abs((Q - Q_m) ./ Q_m) 11 | 12 | param_m 13 | param 14 | 15 | XYZ = get_sample(10); 16 | handle_m = color_dist('proLab', param_m); 17 | CD_m = handle_m(XYZ); 18 | handle = color_dist('proLab', param); 19 | CD = handle(XYZ); 20 | CD./CD_m -------------------------------------------------------------------------------- /matlab/test/compare_data.m: -------------------------------------------------------------------------------- 1 | 2 | function err = compare_data(A, B) 3 | if iscell(A) 4 | err = max(max(max(abs([A{1}; A{2}] - [B{1}; B{2}])))); 5 | else 6 | err = max(max(max(abs(A - B)))); 7 | end 8 | end -------------------------------------------------------------------------------- /matlab/test/executbity_test.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | %% trunk\matlab 9 | 10 | code_examples 11 | D65 12 | proLab_param 13 | proLab_reference_values 14 | reference_illuminant 15 | search_optimal_proLab_param 16 | 17 | %% trunk\matlab\color_conversions 18 | 19 | deviceRGB_matrix 20 | deviceRGB2linRGB_matrix 21 | linRGB_matrix 22 | LMS_matrix 23 | 24 | %% trunk\matlab\data 25 | 26 | get_datasets 27 | testing_on_datasets 28 | 29 | %% trunk\matlab\research 30 | 31 | % noise_model_verification 32 | statistical_test 33 | test_Canon5DMarkIII_spectralSensitivity 34 | test_central_linearity 35 | view_raw 36 | 37 | %% trunk\matlab\search_optimal_proLab_param 38 | 39 | culc_P 40 | get_sample_temp 41 | get_XYZ_sRGB_planes 42 | proLab_Jacobian 43 | sensor_noize_param 44 | vertex 45 | 46 | %% trunk\matlab\test 47 | 48 | check_conditions 49 | check_mQ_compliance 50 | test_any 51 | test_CIEDE2000_symmetry 52 | test_CIEDE2000_tria_ineq 53 | test_color_body 54 | test_completeness 55 | test_decomposition 56 | test_deviceRGB 57 | test_get_D65_spectrum 58 | test_get_quantum_noise 59 | test_get_sample 60 | test_get_STRESS 61 | test_get_XYZ_spectrum 62 | test_get_XYZ_sRGB_planes 63 | test_is_camera_sane 64 | test_is_color_cone 65 | test_Lab 66 | test_linRGB_Y_const 67 | test_LMS 68 | test_proLab_model 69 | test_spectral_math 70 | test_sRGB 71 | test_xyY 72 | 73 | %% trunk\matlab\visualization 74 | 75 | for_introduction 76 | generate_all_images 77 | plot_any_spectrum 78 | plot_chromaticity_frame 79 | % plot_image_color_distribution 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /matlab/test/test_CIEDE2000_symmetry.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | n = 20; 8 | x = 10*rand(n,3); 9 | y = 10*rand(n,3); 10 | get_CIEDE2000({x y}, 'CIE XYZ') - get_CIEDE2000({y x}, 'CIE XYZ') 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /matlab/test/test_CIEDE2000_tria_ineq.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | n = 200; 8 | x = 1*rand(n,3); 9 | y = 1*rand(n,3); 10 | z = 1*rand(n,3); 11 | d_lambda = 10; 12 | idx_x = is_color_body(x, d_lambda); 13 | idx_y = is_color_body(y, d_lambda); 14 | idx_z = is_color_body(z, d_lambda); 15 | idx = idx_x & idx_y & idx_z; 16 | x = x(idx, :); 17 | y = y(idx, :); 18 | z = z(idx, :); 19 | is_color_body(x, d_lambda)' 20 | is_color_body(y, d_lambda)' 21 | is_color_body(z, d_lambda)' 22 | 23 | get_CIEDE2000({x y}, 'CIE XYZ') + get_CIEDE2000({y z}, 'CIE XYZ') - get_CIEDE2000({x z}, 'CIE XYZ') 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /matlab/test/test_LMS.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | %% Invertibility test 9 | 10 | sizes = {... 11 | [1, 3], ... % one color 12 | [5, 3] ... % vector of colors 13 | }; 14 | max_err = 0; 15 | for i = 1:size(sizes, 2) 16 | XYZ = rand(sizes{i}); 17 | LMS = rand(sizes{i}); 18 | err = zeros(1,2); 19 | err(1) = compare_data( XYZ, LMS2XYZ( XYZ2LMS(XYZ))); 20 | err(2) = compare_data( LMS, XYZ2LMS( LMS2XYZ(LMS))); 21 | err = max(max(err)); 22 | max_err = max(err, max_err); 23 | end 24 | max_err % should be ~zero -------------------------------------------------------------------------------- /matlab/test/test_Lab.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | XYZ = rand(1, 3); 8 | Lab = rand(1, 3); 9 | 10 | max(abs(XYZ2Lab(XYZ) - xyz2lab(XYZ,'WhitePoint','d65'))) 11 | max(abs(Lab2XYZ(Lab) - lab2xyz(Lab,'WhitePoint','d65'))) 12 | 13 | max(abs(Lab - xyz2lab(lab2xyz(Lab,'WhitePoint','d65'),'WhitePoint','d65'))) 14 | max(abs(XYZ - lab2xyz(xyz2lab(XYZ,'WhitePoint','d65'),'WhitePoint','d65'))) 15 | 16 | %% Invertibility test 17 | 18 | sizes = {... 19 | [1, 3], ... % one color 20 | [5, 3] ... % vector of colors 21 | }; 22 | max_err = 0; 23 | for i = 1:size(sizes, 2) 24 | for j = 1:2 25 | ref_illum = rand(1,3); 26 | if j == 1 27 | XYZ = rand(sizes{i}); 28 | Lab = rand(sizes{i}); 29 | elseif j == 2 30 | XYZ = {rand(sizes{i}), rand(sizes{i})}; 31 | Lab = {rand(sizes{i}), rand(sizes{i})}; 32 | end 33 | err = zeros(2,2); 34 | err(1,1) = compare_data( XYZ, Lab2XYZ( XYZ2Lab(XYZ))); 35 | err(1,2) = compare_data( XYZ, Lab2XYZ( XYZ2Lab(XYZ, ref_illum), ref_illum)); 36 | err(2,1) = compare_data( Lab, XYZ2Lab( Lab2XYZ(Lab))); 37 | err(2,2) = compare_data( Lab, XYZ2Lab( Lab2XYZ(Lab, ref_illum), ref_illum)); 38 | err = max(max(err)); 39 | max_err = max(err, max_err); 40 | end 41 | end 42 | max_err % should be ~zero -------------------------------------------------------------------------------- /matlab/test/test_any.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | %% 9 | 10 | % XYZ = get_sample(1000); 11 | % XYZ = XYZ{1,1}; 12 | % % CC = XYZ2LMS(XYZ); 13 | % CC = XYZ2deviceRGB(XYZ); 14 | % sum(CC<0) 15 | 16 | %% 17 | 18 | % % % m = deviceRGB2linRGB_matrix 19 | % % c_v = [2.02; 1; 1.73]; 20 | % c_m = [2.27, -1.42, 0.15; -0.28, 1.67, -0.39; 0.04, -0.8, 1.75]; 21 | % 22 | % M = (c_m)^(-1); 23 | % c_m * [1; 1; 1] 24 | % M * [1; 1; 1] 25 | % 26 | % % % xyY = [0.31271 0.32902 1]; % D65 27 | % % % xyY = [0.34567 0.35850 1]; % D50 28 | % % xyY = [0.44757 0.40745 1]; % A 29 | % % 30 | % % XYZ = xyY2XYZ(xyY) 31 | % % linRGB = XYZ2linRGB(XYZ) 32 | 33 | %% 34 | 35 | % X = randn(10, 3); 36 | % K = X'*X; 37 | % k11 = K(1,1); 38 | % k12 = K(1,2); 39 | % k13 = K(1,3); 40 | % k22 = K(2,2); 41 | % k23 = K(2,3); 42 | % k33 = K(3,3); 43 | % x = randn(1,1); 44 | % 45 | % N = 10000; 46 | % 47 | % tic; 48 | % for i = 1:N 49 | % p = [-1, k11+k22+k33, k12^2 + k13^2 + k23^2 - k11*k22 - k11*k33 - k22*k33, 2*k12*k13*k23 + k11*k22*k33 - k22*k13^2 - k33*k12^2 - k11*k23^2]; 50 | % e = roots(p); 51 | % end 52 | % toc; 53 | % 54 | % tic; 55 | % for i = 1:N 56 | % e = eig(K); 57 | % end 58 | % toc; 59 | 60 | %% 61 | 62 | % P = randn(2,3); 63 | % [X,Y] = meshgrid(-10:0.01:10); 64 | % for i = 1:size(X,1) 65 | % for j = 1:size(X,2) 66 | % x = X(i,j); 67 | % y = Y(i,j); 68 | % z = P*[x;y;1]; 69 | % z = z ./ z(2); 70 | % Z(i,j) = z(1); 71 | % end 72 | % end 73 | % Z(Z>4) = NaN; 74 | % Z(Z<-4) = NaN; 75 | % % Z = min(Z,+4); 76 | % % Z = max(Z,-4); 77 | % mesh(X,Y,Z); 78 | % % surf(X,Y,Z); 79 | % % contour(X,Y,Z); 80 | 81 | %% 82 | 83 | % N = 1000; 84 | % XYZ = get_sample(N); 85 | % XYZ = XYZ{1,1}; 86 | % deviceRGB = XYZ2deviceRGB(XYZ); 87 | % sum(any(deviceRGB<0, 2)) 88 | 89 | %% 90 | 91 | % A = [1 0 0 0; 0 0.5 0.5 0; 0 0 0 1] 92 | % B = A'*(A*A')^(-1) 93 | % B = [1 0 0; 0 1 0; 0 1 0; 0 0 1] 94 | % A*B 95 | % B*A 96 | 97 | %% 98 | 99 | % % D = [1 0 0 0; 0 0.5 0.5 0; 0 0 0 1] 100 | % M1 = deviceRGB2linRGB_matrix; 101 | % (2^16/0.03)*M1 102 | % M2 = linRGB_matrix^(-1) 103 | % S = (M2 * M1); 104 | % 10^6 * S 105 | % DD = [1 0 0; 0 1 0; 0 1 0; 0 0 1] 106 | % SS = (M2 * M1)^(-1); 107 | % S * SS 108 | % 109 | % syms a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34 real 110 | % S = [a11 a12 a13 a14; a21 a22 a23 a24; a31 a32 a33 a34]; 111 | % syms b11 b12 b13 b21 b22 b23 b31 b32 b33 b41 b42 b43 real 112 | % SS = [b11 b12 b13; b21 b22 b23; b31 b32 b33; b41 b42 b43]; 113 | % 114 | % syms x y z g real 115 | % r = [x; y; z]; 116 | % diag(r) 117 | % diag(SS * r) 118 | % % S * diag(SS * r) 119 | % % diag(SS * r) * S' 120 | % W = S * diag(SS * r) * S' 121 | % % W(1,1) 122 | 123 | %% 124 | 125 | syms m1 m2 m3 m4 m5 m6 m7 m8 126 | M = [m1 m2 m3 0; 0 m4 m5 0; 0 0 1 0; m6 m7 m8 1] 127 | det(M) 128 | syms x y z 129 | X = M(1,1) * x + M(1,2) * y + M(1,3) * z + M(1,4); 130 | Y = M(2,1) * x + M(2,2) * y + M(2,3) * z + M(2,4); 131 | Z = M(3,1) * x + M(3,2) * y + M(3,3) * z + M(3,4); 132 | W = M(4,1) * x + M(4,2) * y + M(4,3) * z + M(4,4); 133 | 134 | XX = X / W; 135 | YY = Y / W; 136 | ZZ = Z / W; 137 | 138 | J = [diff(XX,x) diff(XX,y) diff(XX,z); ... 139 | diff(YY,x) diff(YY,y) diff(YY,z); ... 140 | diff(ZZ,x) diff(ZZ,y) diff(ZZ,z)]; 141 | det(J) 142 | 143 | %% 144 | 145 | % M = randn(4,4); 146 | % M(1:3, 4) = 0; 147 | % M(2,1) = 0; 148 | % M(3,1:3) = [0 0 1]; 149 | % M(4,1:3) = abs(M(4,1:3)); 150 | % M(4,4) = 1; 151 | % m = [M(1,1) M(1,2) M(1,3) M(2,2) M(2,3) M(4,1) M(4,2) M(4,3)]; 152 | % % m 153 | % % regularization(m) 154 | % % M 155 | % param.m = m; 156 | % penalty(param); 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /matlab/test/test_color_body.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | d_lambda = 30; 9 | tic 10 | boundary_mesh = get_color_body_boundary_mesh(d_lambda); 11 | toc 12 | 13 | tic 14 | [constraints, DT, C] = get_color_body_constraints(d_lambda); 15 | toc 16 | size(constraints) 17 | mfilename('fullpath') 18 | %% 19 | 20 | figure(); 21 | hold on; 22 | grid on; 23 | plot3(boundary_mesh(:,1),boundary_mesh(:,2),boundary_mesh(:,3),'.'); 24 | axis equal; 25 | xlabel('X'); 26 | ylabel('Y'); 27 | zlabel('Z'); 28 | 29 | %% 30 | 31 | figure(); 32 | faceColor = [0.6875 0.8750 0.8984]; 33 | tetramesh(DT,'FaceColor',faceColor,'FaceAlpha',0.3); 34 | 35 | N = 10000; 36 | XYZ_sample = reference_illuminant.*rand(N, 3); 37 | idx = is_color_body(XYZ_sample, d_lambda); 38 | XYZ_sample = XYZ_sample(idx, :); 39 | 40 | figure(); 41 | hold on; 42 | grid on; 43 | camlight('headlight'); 44 | plot3(XYZ_sample(:, 1), XYZ_sample(:, 2), XYZ_sample(:, 3), '.b'); 45 | s = trisurf(C,DT.Points(:,1),DT.Points(:,2),DT.Points(:,3),'FaceColor','b','FaceAlpha',1.0); 46 | s.EdgeColor = 'none'; 47 | xlabel('X'); 48 | ylabel('Y'); 49 | zlabel('Z'); 50 | ax = gca; 51 | ax.Projection = 'perspective'; 52 | -------------------------------------------------------------------------------- /matlab/test/test_completeness.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | %% 8 | 9 | % syms a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34 b1 b2 b3 b4 10 | 11 | % A = [a11 a12 a13 a14; a21 a22 a23 a24; a31 a32 a33 a34; 0 0 0 1] 12 | % B = [1 0 0 0; 0 1 0 0; 0 0 1 0; b1 b2 b3 1] 13 | % A*B 14 | 15 | %% 16 | 17 | % syms h11 h12 h13 h14 h21 h22 h23 h24 h31 h32 h33 h34 h41 h42 h43 18 | % H = [h11 h12 h13 h14; h21 h22 h23 h24; h31 h32 h33 h34; h41 h42 h43 1] 19 | % 20 | % b1 = h41; 21 | % b2 = h42; 22 | % b3 = h43; 23 | % 24 | % a14 = h14; 25 | % a24 = h24; 26 | % a34 = h34; 27 | % 28 | % a11 = h11 - h14*h41; 29 | % a12 = h12 - h14*h42; 30 | % a13 = h13 - h14*h43; 31 | % 32 | % a21 = h21 - h24*h41; 33 | % a22 = h22 - h24*h42; 34 | % a23 = h23 - h24*h43; 35 | % 36 | % a31 = h31 - h34*h41; 37 | % a32 = h32 - h34*h42; 38 | % a33 = h33 - h34*h43; 39 | % 40 | % A = [a11 a12 a13 a14; a21 a22 a23 a24; a31 a32 a33 a34; 0 0 0 1] 41 | % B = [1 0 0 0; 0 1 0 0; 0 0 1 0; b1 b2 b3 1] 42 | % A*B 43 | % H - A*B 44 | 45 | %% 46 | 47 | % syms c11 c12 c13 c21 c22 c23 c31 c32 c33 48 | % syms t1 t2 t3 49 | % C = [c11 c12 c13 0; c21 c22 c23 0; c31 c32 c33 0; 0 0 0 1] 50 | % T = [1 0 0 t1; 0 1 0 t2; 0 0 1 t3; 0 0 0 1] 51 | % T*C 52 | 53 | %% 54 | 55 | % syms r11 r12 r13 r21 r22 r23 r31 r32 r33 56 | 57 | %% 58 | 59 | syms v11 v12 v13 v22 v23 p1 p2 p3 60 | V = [v11 v12 v13 0; 0 v22 v23 0; 0 0 1 0; 0 0 0 1]; 61 | P = [1 0 0 0; 0 1 0 0; 0 0 1 0; p1 p2 p3 1]; 62 | V*P -------------------------------------------------------------------------------- /matlab/test/test_decomposition.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | P = rand_P(); 8 | U = rand_U(); 9 | 10 | x = randn(4, 1); 11 | y = randn(4, 1); 12 | 13 | for i = 1:10 14 | T = rand_T(); 15 | R = rand_R(); 16 | % T = eye(4); 17 | % R = eye(4); 18 | M = R*T*U*P; 19 | xx = M*x; 20 | yy = M*y; 21 | xx = xx / (xx(4)); 22 | yy = yy / (yy(4)); 23 | % xx = xx(1:3); 24 | % yy = yy(1:3); 25 | disp(norm(xx-yy)) 26 | end 27 | 28 | function T = rand_T() 29 | T = eye(4); 30 | T(1:3, 4) = randn(3, 1); 31 | end 32 | 33 | function P = rand_P() 34 | P = eye(4); 35 | P(4, 1:3) = randn(1, 3); 36 | end 37 | 38 | function U = rand_U() 39 | U = eye(4); 40 | U(1:3, 1:3) = randn(3, 3); 41 | U(3, 1:2) = 0; 42 | U(2, 1) = 0; 43 | end 44 | 45 | function R = rand_R() 46 | a = 2*pi*rand(1,1); 47 | R_x = [ 1 0 0; 0 cos(a) -sin(a);0 sin(a) cos(a)]; 48 | a = 2*pi*rand(1,1); 49 | R_y = [cos(a) 0 -sin(a); 0 1 0; sin(a) 0 cos(a)]; 50 | a = 2*pi*rand(1,1); 51 | R_z = [cos(a) -sin(a) 0; sin(a) cos(a) 0; 0 0 1]; 52 | R = R_x * R_y * R_z; 53 | % R'*R-eye(3) 54 | % R*R'-eye(3) 55 | R = [R [0; 0; 0;]; [0 0 0 1]]; 56 | end 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /matlab/test/test_deviceRGB.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | %% Invertibility test 9 | 10 | sizes = {... 11 | [1, 3], ... % one color 12 | [5, 3] ... % vector of colors 13 | }; 14 | max_err = 0; 15 | for i = 1:size(sizes, 2) 16 | XYZ = rand(sizes{i}); 17 | deviceRGB = rand(sizes{i}); 18 | err = zeros(1,2); 19 | err(1) = compare_data( XYZ , deviceRGB2XYZ( XYZ2deviceRGB(XYZ ))); 20 | err(2) = compare_data( deviceRGB, XYZ2deviceRGB( deviceRGB2XYZ(deviceRGB))); 21 | err = max(max(err)); 22 | max_err = max(err, max_err); 23 | end 24 | max_err % should be ~zero -------------------------------------------------------------------------------- /matlab/test/test_get_D65_spectrum.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | d_lambda = 0.5; 9 | lambda = (200:d_lambda:900)'; 10 | D65_spectrum = get_D65_spectrum(lambda); 11 | 12 | figure(1); 13 | plot(lambda, D65_spectrum, '.'); 14 | 15 | formulary = '1931_FULL'; 16 | XYZ = get_XYZ_spectrum(lambda, formulary); 17 | 18 | source = XYZ .* D65_spectrum; 19 | D_65 = sum(source, 1); 20 | D_65 = D_65/D_65(2); 21 | [D_65 D65] -------------------------------------------------------------------------------- /matlab/test/test_get_STRESS.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | X = rand(3, 1); 9 | Y = rand(3, 1); 10 | % get_STRESS(X,Y) - get_STRESS(Y,X) 11 | 12 | get_STRESS(X,Y) 13 | sqrt(((X'*X)*(Y'*Y)-(Y'*X).^2)./ ((Y'*Y)*(X'*X))) 14 | 15 | Cos2 = (Y'*X).^2 / ((Y'*Y)*(X'*X)); 16 | Sin = sqrt(1-Cos2) -------------------------------------------------------------------------------- /matlab/test/test_get_XYZ_sRGB_planes.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | 5 | addpath(genpath('..')); 6 | 7 | XYZ_sRGB_planes = get_XYZ_sRGB_planes() 8 | XYZ_sRGB_vertex = (linRGB_matrix^(-1)*vertex')'; 9 | homogen_XYZ_sRGB_vertex = [XYZ_sRGB_vertex, ones(8, 1)] 10 | 11 | XYZ_sRGB_planes * homogen_XYZ_sRGB_vertex' 12 | 13 | -------------------------------------------------------------------------------- /matlab/test/test_get_XYZ_spectrum.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | d_lambda = 0.5; 9 | lambda = (300:d_lambda:800)'; 10 | formulary = '1931_FULL'; 11 | XYZ = get_XYZ_spectrum(lambda, formulary); 12 | sum(XYZ, 1) 13 | 14 | figure(1); 15 | hold on; 16 | plot(lambda, XYZ(:,1), 'r'); 17 | plot(lambda, XYZ(:,2), 'g'); 18 | plot(lambda, XYZ(:,3), 'b'); 19 | % plot(lambda, log(XYZ(:,1)), 'r'); 20 | % plot(lambda, log(XYZ(:,2)), 'g'); 21 | % plot(lambda, log(XYZ(:,3)), 'b'); 22 | 23 | figure(2); 24 | plot3(XYZ(:,1),XYZ(:,2),XYZ(:,3)); 25 | xlabel('X'); 26 | ylabel('Y'); 27 | zlabel('Z'); 28 | 29 | figure(3); 30 | hold on; 31 | % plot_color_triangle_Y('CIExyY', 0.5); 32 | 33 | lambda = [361; (400:2:690)'; 700]; 34 | formulary = '1931_FULL'; 35 | XYZ = get_XYZ_spectrum(lambda, formulary); 36 | x = XYZ(:,1) ./ sum(XYZ, 2); 37 | y = XYZ(:,2) ./ sum(XYZ, 2); 38 | for i = 1:size(lambda) 39 | text(x(i), y(i), num2str(lambda(i))); 40 | plot(x(i), y(i), '.r'); 41 | end 42 | axis equal; 43 | xlabel('x'); 44 | ylabel('y'); 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /matlab/test/test_get_quantum_noise.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | local_size = 1000; 9 | mean_N = [10 10 10]; 10 | models = {'Poisson', 'Normal_approx'}; 11 | 12 | for m = 1:size(models,2) 13 | tic; 14 | N = get_quantum_noise(mean_N, local_size, models{m}); 15 | toc; 16 | N = N(:); 17 | figure(m); 18 | histfit(N); 19 | end 20 | -------------------------------------------------------------------------------- /matlab/test/test_get_sample.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | sample_size = 1000; 9 | XYZ_sample = get_sample(sample_size); 10 | % borders = [20, 140]; 11 | % XYZ_sample = get_sample(sample_size, borders); 12 | size(XYZ_sample{1}) 13 | CIEDE2000 = get_CIEDE2000(XYZ_sample, 'CIE XYZ'); 14 | 15 | figure(1); 16 | hold on; 17 | for i = 1:size(XYZ_sample{1}, 1) 18 | % plot3(XYZ_sample{1}(i,1), ... 19 | % XYZ_sample{1}(i,2), ... 20 | % XYZ_sample{1}(i,3), '.b'); 21 | plot3([XYZ_sample{1}(i,1) XYZ_sample{2}(i,1)], ... 22 | [XYZ_sample{1}(i,2) XYZ_sample{2}(i,2)], ... 23 | [XYZ_sample{1}(i,3) XYZ_sample{2}(i,3)], 'b'); 24 | end 25 | xlabel('X'); 26 | ylabel('Y'); 27 | zlabel('Z'); 28 | % axis equal; 29 | 30 | Lab_sample = XYZ2Lab(XYZ_sample); 31 | 32 | figure(2); 33 | hold on; 34 | for i = 1:size(Lab_sample{1}, 1) 35 | plot3([Lab_sample{1}(i,1) Lab_sample{2}(i,1)], ... 36 | [Lab_sample{1}(i,2) Lab_sample{2}(i,2)], ... 37 | [Lab_sample{1}(i,3) Lab_sample{2}(i,3)], 'b'); 38 | end 39 | xlabel('L'); 40 | ylabel('a'); 41 | zlabel('b'); 42 | % axis equal; 43 | % sqrt(sum((Lab_sample{1} - Lab_sample{2}).^2, 2)) 44 | 45 | figure(3); 46 | hold on; 47 | grid on; 48 | % title('Uniform random visible gamut D65 XYZ color couples'); 49 | hist(CIEDE2000, 100, 'kernel'); 50 | xlabel('CIEDE2000'); 51 | ylabel('frequence'); 52 | 53 | handle = color_dist('CIELAB'); 54 | LabDist = handle(XYZ_sample); 55 | 56 | figure(4); 57 | hold on; 58 | grid on; 59 | % title('Uniform random visible gamut D65 XYZ color couples'); 60 | hist(LabDist, 100, 'kernel'); 61 | xlabel('||Lab||'); 62 | ylabel('frequence'); 63 | 64 | XYZ_sample = XYZ_sample{1}; 65 | Lab_sample = Lab_sample{1}; 66 | 67 | % idx_1 = 0.5-0.05 0 67 | plot3(C(1:end-1, abs(AO(1))), C(1:end-1, abs(AO(2))), C(1:end-1, abs(AO(3))), 'LineWidth', 1, 'color', color); 68 | plot3(C(end, abs(AO(1))), C(end, abs(AO(2))), C(end, abs(AO(3))), '.', 'MarkerSize', 5, 'color', color); 69 | end 70 | else 71 | plot3(C(1:end-1, abs(AO(1))), C(1:end-1, abs(AO(2))), C(1:end-1, abs(AO(3))), 'LineWidth', 1, 'color', color); 72 | plot3(C(end, abs(AO(1))), C(end, abs(AO(2))), C(end, abs(AO(3))), '.', 'MarkerSize', 5, 'color', color); 73 | end 74 | % text(C(end, abs(AO(1))), C(end, abs(AO(2))), C(end, abs(AO(3))), num2str(ell)); 75 | % if strcmp(colorSpace, 'proLab') 76 | % plane = (saved_proLab_matrix^(-1))' * [0; 1; 0; -Y]; 77 | % [C(end, 1:3), 1] * plane 78 | % end 79 | end 80 | end 81 | 82 | -------------------------------------------------------------------------------- /matlab/visualization/plot_any_spectrum.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | d_lambda = 0.5; 9 | lambda = (300:d_lambda:800)'; 10 | formulary = '1931_FULL'; 11 | XYZ = get_XYZ_spectrum(lambda, formulary); 12 | 13 | fig = figure(1); 14 | hold on; 15 | grid on; 16 | title('CIEXYZ'); 17 | plot(lambda, XYZ(:,1), 'r'); 18 | plot(lambda, XYZ(:,2), 'g'); 19 | plot(lambda, XYZ(:,3), 'b'); 20 | pic_name = 'images/CIEXYZ.png'; 21 | % saveas(fig, pic_name); 22 | 23 | % CC = XYZ * LMS_matrix'; 24 | CC = XYZ2deviceRGB(XYZ); 25 | 26 | fig = figure(2); 27 | hold on; 28 | grid on; 29 | % title('LMS'); 30 | title('deviceRGB'); 31 | plot(lambda, CC(:,1), 'r'); 32 | plot(lambda, CC(:,2), 'g'); 33 | plot(lambda, CC(:,3), 'b'); 34 | % pic_name = ['images/linRGB.png']; 35 | % saveas(fig, pic_name); -------------------------------------------------------------------------------- /matlab/visualization/plot_chromaticity.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | %% 7 | 8 | % type = 'gray'; 9 | type = 'color'; 10 | brightness = 'const'; 11 | % brightness = 'max'; 12 | 13 | %% 14 | 15 | addpath(genpath('..')); 16 | 17 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 18 | % CS_list = {'linRGB'; 'sRGB'}; 19 | FontSize = 20; 20 | h = 0.05; % 0.005 21 | [x, y] = meshgrid(h:h:1, h:h:1); 22 | x = reshape(x, [numel(x), 1]); 23 | y = reshape(y, [numel(y), 1]); 24 | L = 50; 25 | XYZ = Lab2XYZ([L 0 0]); 26 | Y = XYZ(2); 27 | xyY = [x, y, Y*ones(size(x))]; 28 | XYZ = xyY2XYZ(xyY); 29 | linRGB = XYZ2linRGB(XYZ); 30 | switch brightness 31 | case 'const' 32 | Th = 1; 33 | case 'max' 34 | Th = +Inf; 35 | end 36 | for i = size(linRGB, 1):-1:1 37 | if ~(0 <= min(linRGB(i, :)) && max(linRGB(i, :)) <= Th) 38 | x(i, :) = []; 39 | y(i, :) = []; 40 | end 41 | end 42 | DT = delaunayTriangulation([x y]); 43 | CL = DT.ConnectivityList; 44 | xyY = [x, y, Y*ones(size(x))]; 45 | XYZ = xyY2XYZ(xyY); 46 | switch type 47 | case 'gray' 48 | sRGB = XYZ2sRGB(Lab2XYZ([L 0 0])); 49 | case 'color' 50 | sRGB = XYZ2sRGB(XYZ); 51 | end 52 | if strcmp(brightness, 'max') 53 | sRGB = sRGB ./ max(sRGB,[],2); 54 | end 55 | for CS_num = 1:size(CS_list, 1) 56 | CS = color_spaces_collection(CS_list{CS_num}, proLab_param); 57 | AO = CS.axis_Lab_order; 58 | CC = CS.transform_into(XYZ); 59 | fig = figure(CS_num); 60 | hold on; 61 | grid on; 62 | set(gca,'FontSize',15); 63 | T = size(CL, 1); 64 | for i = 1:T 65 | v = [CC(CL(i, 1), :); CC(CL(i, 2), :); CC(CL(i, 3), :)]; 66 | switch type 67 | case 'gray' 68 | color = sRGB; 69 | case 'color' 70 | color = mean(sRGB([CL(i, 1), CL(i, 2), CL(i, 3)], :)); 71 | end 72 | fill3(v(:, abs(AO(1))), v(:, abs(AO(2))), v(:, abs(AO(3))), color, 'LineStyle', 'none'); 73 | end 74 | plot_MacAd_Ell(CS.name, Y); 75 | % plot_lazer_triangle(CS.name, Y); 76 | plot_color_body_projection(CS.name); 77 | plot_color_body_cut(CS.name, Y); 78 | % if strcmp(CS.name, 'CIELAB') 79 | % noise_verification(L); 80 | % end 81 | 82 | % title(CS.name, 'FontSize', FontSize); 83 | % title(CS.name, 'Interpreter','latex', 'FontSize', FontSize); 84 | % title(['MacAdam ellipses (L* = ', num2str(L),')',newline, ... 85 | % 'projected into ', CS.name, ' color space'], ... 86 | % 'Interpreter','latex', 'FontSize', FontSize); 87 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 88 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 89 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 90 | % ax = gca; 91 | % ax.Projection = 'perspective'; 92 | view(90,0); 93 | if AO(1) < 0 94 | set(gca,'XDir', 'reverse'); 95 | end 96 | if AO(2) < 0 97 | set(gca,'YDir', 'reverse'); 98 | end 99 | if AO(3) < 0 100 | set(gca,'ZDir', 'reverse'); 101 | end 102 | axis tight; 103 | axis equal; 104 | % xlim([-100, 100]); 105 | % ylim([-100, 100]); 106 | % plot3([L, L], [-100, 100], [0, 0], 'black'); 107 | % plot3([L, L], [0, 0], [-100, 100], 'black'); 108 | switch brightness 109 | case 'const' 110 | saveas(fig,['images/chromaticity/', CS.name, '_const.png']); 111 | case 'max' 112 | saveas(fig,['images/chromaticity/', CS.name, '_max.png']); 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /matlab/visualization/plot_chromaticity_frame.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | CS_list = {'CIE XYZ'; 'CIE xyY'; 'sRGB'; 'CIELAB'; 'proLab'}; 9 | for CS_num = 1:size(CS_list, 1) 10 | CS = color_spaces_collection(CS_list{CS_num}, proLab_param); 11 | AO = CS.axis_Lab_order; 12 | switch CS.name 13 | case 'sRGB' 14 | L = 0.5; 15 | xl = [-0.25 1.25]; 16 | yl = [-0.25 1.25]; 17 | case 'CIE XYZ' 18 | L = 0.5; 19 | xl = [0 1]; 20 | yl = [0 1]; 21 | case 'CIE xyY' 22 | L = 0.5; 23 | xl = [0.1 0.55]; 24 | yl = [0.2 0.65]; 25 | case 'CIELAB' 26 | L = 75; 27 | xl = [-100 75]; 28 | yl = [-50 100]; 29 | case 'proLab' 30 | L = 75; 31 | xl = [-50 50]; 32 | yl = [-40 40]; 33 | end 34 | dt = (xl(2)-xl(1)) / 100; 35 | nx = fix((xl(2)-xl(1))/dt); 36 | ny = fix((yl(2)-yl(1))/dt); 37 | pic = ones(ny,nx,3); 38 | AlphaData = zeros(ny,nx); 39 | for j = 1:nx 40 | for i = 1:ny 41 | A = j*dt + xl(1); 42 | B = i*dt + yl(1); 43 | CC_disordered = [L A B]; 44 | CC = CC_disordered; 45 | for k = 1:3 46 | CC(abs(AO(k))) = CC_disordered(k); 47 | end 48 | if strcmp(CS.name, 'sRGB') 49 | linRGB = sRGB2linRGB(CC); 50 | else 51 | XYZ = CS.transform_from(CC); 52 | linRGB = XYZ2linRGB(XYZ); 53 | end 54 | if 0 <= min(linRGB) && max(linRGB) <= 1%+Inf 55 | sRGB = linRGB2sRGB(linRGB); 56 | % sRGB_max = sRGB / max(sRGB); 57 | pic(i,j,:) = sRGB; 58 | AlphaData(i,j) = 1; 59 | end 60 | end 61 | end 62 | fig = figure(CS_num); 63 | hold on; 64 | grid on; 65 | image(xl, yl, pic, 'AlphaData', AlphaData); 66 | set(gca,'FontSize',15); 67 | FontSize = 20; 68 | if strcmp(CS.name, 'CIExyY') 69 | plot_lazer_triangle('CIExyY', 0.5); 70 | end 71 | title([CS.name, ' (',CS.axis_names{abs(AO(1))},'=',num2str(L), ... 72 | '), showing only colors that', newline, ... 73 | 'can be displayed on a typical (sRGB) display'], ... 74 | 'Interpreter','latex', 'FontSize', FontSize); 75 | xlabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 76 | ylabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 77 | if AO(2) < 0 78 | set(gca,'XDir', 'reverse'); 79 | end 80 | if AO(3) < 0 81 | set(gca,'YDir', 'reverse'); 82 | end 83 | axis equal; 84 | saveas(fig,['images/chromaticity/', CS.name, '.png']); 85 | end 86 | 87 | 88 | -------------------------------------------------------------------------------- /matlab/visualization/plot_color_body.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 9 | % CS_list = {'CIE XYZ'; 'proLab'}; 10 | 11 | d_lambda = 10; % 2 12 | 13 | % XYZ = get_color_body_boundary_mesh(d_lambda); 14 | [~, DT, CL] = get_color_body_constraints(d_lambda); 15 | XYZ = DT.Points; 16 | linRGB = XYZ2linRGB(XYZ); 17 | linRGB = 0.5 + 0.5*(linRGB-0.5) ./ max(abs(linRGB - 0.5),[],2); 18 | sRGB = linRGB2sRGB(linRGB); 19 | 20 | % XYZ = get_color_body_boundary_mesh(d_lambda); 21 | % DT = delaunayTriangulation(XYZ); 22 | % CL = DT.ConnectivityList; 23 | for CS_num = 1:size(CS_list, 1) 24 | CS = color_spaces_collection(CS_list{CS_num}, proLab_param); 25 | AO = CS.axis_Lab_order; 26 | fig = figure(); 27 | hold on; 28 | % ax = gca; 29 | % ax.FontSmoothing = 'on'; 30 | % fig.GraphicsSmoothing = 'on'; 31 | % set(gcf, 'renderer', 'zbuffer'); 32 | grid on; 33 | CC = CS.transform_into(XYZ); 34 | T = size(CL, 1); 35 | for i = 1:T 36 | v = [CC(CL(i, 1), :); CC(CL(i, 2), :); CC(CL(i, 3), :)]; 37 | color = mean(sRGB([CL(i, 1), CL(i, 2), CL(i, 3)], :)); 38 | fill3(v(:, abs(AO(1))), v(:, abs(AO(2))), v(:, abs(AO(3))), color, 'LineStyle', 'none', 'FaceAlpha', 1.0); 39 | end 40 | % lighting none; 41 | % camlight('headlight'); 42 | % % plot3(XYZ_sample(:, 1), XYZ_sample(:, 2), XYZ_sample(:, 3), '.b'); 43 | % s = trisurf(CL,CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),'FaceColor','b','FaceAlpha',0.5); 44 | % s.EdgeColor = 'none'; 45 | 46 | set(gca,'FontSize',15); 47 | FontSize = 20; 48 | % pic_name = ['The sRGB gamut projected',newline, 'into ', CS.name,' color space']; 49 | % title(pic_name); 50 | % title(CS.name, 'FontSize', FontSize); 51 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 52 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 53 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 54 | ax = gca; 55 | % ax.Projection = 'perspective'; 56 | axis tight; 57 | axis equal; 58 | switch CS.name 59 | case {'linRGB', 'sRGB'} 60 | view(150,-16); 61 | case 'LMS' 62 | view(139,-33); 63 | case 'deviceRGB' 64 | view(143,-18); 65 | case 'CIE XYZ' 66 | view(139,-33); 67 | case 'CIE xyY' 68 | view(107,11); 69 | case 'CIELAB' 70 | view(105,14); 71 | case 'proLab' 72 | view(101,10); 73 | case 'CAM16-UCS' 74 | view(102,8); 75 | end 76 | if AO(1) < 0 77 | set(gca,'XDir', 'reverse'); 78 | end 79 | if AO(2) < 0 80 | set(gca,'YDir', 'reverse'); 81 | end 82 | if AO(3) < 0 83 | set(gca,'ZDir', 'reverse'); 84 | end 85 | 86 | % XYZ_D65 = vertex*diag(D65); 87 | % CC_D65 = CS.transform_into(XYZ_D65); 88 | % plot_cube([CC_D65(:, abs(AO(1))), CC_D65(:, abs(AO(2))), CC_D65(:, abs(AO(3)))], [0 0 0]); 89 | 90 | pic_name = ['images/body/', CS.name, '_color_body.png']; 91 | saveas(fig, pic_name); 92 | % RGB = AntiAlias(gcf, 4, 'lanczos3'); 93 | % imwrite(RGB, pic_name); 94 | end 95 | 96 | -------------------------------------------------------------------------------- /matlab/visualization/plot_color_body_cut.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_color_body_cut(CS_name, Y) 3 | 4 | % d_lambda = 0.5; 5 | d_lambda = 4; 6 | 7 | cache_path = ['search_optimal_proLab_param/cache/color_body_cut_',num2str(d_lambda),'.mat']; 8 | if exist(cache_path, 'file') == 0 9 | 10 | XYZ = get_color_body_boundary_mesh(d_lambda); 11 | h = 0.0015; 12 | idx = abs(XYZ(:, 2)-Y) <= h; 13 | XYZ(:, 2) = Y; 14 | XYZ = XYZ(idx, :); 15 | % figure(); 16 | % hold on; 17 | % plot3(XYZ(:, 1), XYZ(:, 2), XYZ(:, 3), '.b'); 18 | k = convhull(XYZ(:, [1 3])); 19 | XYZ = XYZ(k, :); 20 | % plot3(XYZ(:, 1), XYZ(:, 2), XYZ(:, 3), 'or'); 21 | % xlabel('X'); 22 | % ylabel('Y'); 23 | % zlabel('Z'); 24 | % view(0,0); 25 | % axis tight; 26 | % axis equal; 27 | cut = zeros(0, 3); 28 | n = size(XYZ, 1); 29 | for i = 1:n 30 | cc_1 = XYZ(i, :); 31 | cc_2 = XYZ(mod(i,n)+1, :); 32 | l = 1+fix(1000*norm(cc_2-cc_1)); 33 | t = (1:l)'/l; 34 | CC = cc_1 + t * (cc_2-cc_1); 35 | cut = [cut; CC]; 36 | end 37 | % figure(); 38 | % hold on; 39 | % plot3(XYZ(:, 1), XYZ(:, 2), XYZ(:, 3), '.black'); 40 | % xlabel('X'); 41 | % ylabel('Y'); 42 | % zlabel('Z'); 43 | % view(0,0); 44 | % axis tight; 45 | % axis equal; 46 | save(cache_path, 'cut'); 47 | else 48 | load(cache_path); 49 | end 50 | CS = color_spaces_collection(CS_name, proLab_param); 51 | CC = CS.transform_into(cut); 52 | AO = CS.axis_Lab_order; 53 | % plot3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),'.r');; 54 | CC(:,CS.axis_Lab_order(1)) = -0.9; 55 | s = fill3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),0.5*[1 1 1]); 56 | s.EdgeColor = 'none'; 57 | % if strcmp(CS_name, 'CIELAB') 58 | % quasars = [50, -80, 0; 50, 80, 0; 50, 0, -80; 50, 0, 80]; 59 | % quasars 60 | % plot3(quasars(:,abs(AO(1))),quasars(:,abs(AO(2))),quasars(:,abs(AO(3))),'.black','MarkerSize',20); 61 | % end 62 | end 63 | 64 | 65 | -------------------------------------------------------------------------------- /matlab/visualization/plot_color_body_projection.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_color_body_projection(CS_name) 3 | % d_lambda = 0.5; 4 | d_lambda = 4; 5 | CS = color_spaces_collection(CS_name, proLab_param); 6 | AO = CS.axis_Lab_order; 7 | cache_path = ['search_optimal_proLab_param/cache/color_body_', CS_name, '_projection_',num2str(d_lambda),'.mat']; 8 | if exist(cache_path, 'file') == 0 9 | XYZ = get_color_body_boundary_mesh(d_lambda); 10 | CC = CS.transform_into(XYZ); 11 | CC(:,CS.axis_Lab_order(1)) = -1; 12 | % plot3(CC(:,1),CC(:,2),CC(:,3),'.r','MarkerSize',4); 13 | idx = sum(isnan(CC),2) == 0; 14 | CC = CC(idx, :); 15 | 16 | % k = convhull(CC(:, abs(AO(2:3)))); 17 | k = boundary(CC(:, abs(AO(2:3)))); 18 | % s = trisurf(k,CC(:,1),CC(:,2),CC(:,3),'Facecolor',0.4*[1 1 1],'FaceAlpha',0.3); 19 | % s.EdgeColor = 'none'; 20 | % 1 21 | CC = CC(k, :); 22 | save(cache_path, 'CC'); 23 | else 24 | load(cache_path); 25 | end 26 | s = fill3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),0.8*[1 1 1]); 27 | s.EdgeColor = 'none'; 28 | % plot3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),'.black'); 29 | % plot3(CC(:,1),CC(:,2),CC(:,3),'r','LineWidth',2); 30 | 31 | % DT = delaunayTriangulation(CC(:, abs(AO(2:3)))); 32 | % CL = DT.ConnectivityList; 33 | % T = size(CL, 1); 34 | % for i = 1:T 35 | % v = [CC(CL(i, 1), :); CC(CL(i, 2), :); CC(CL(i, 3), :)]; 36 | % color = 0.3*[1 1 1]; 37 | % fill3(v(:, abs(AO(1))), v(:, abs(AO(2))), v(:, abs(AO(3))), color, 'LineStyle', 'none', 'FaceAlpha', 0.6); 38 | % end 39 | 40 | end 41 | 42 | 43 | -------------------------------------------------------------------------------- /matlab/visualization/plot_cube.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_cube(X, color) 3 | 4 | plot3([X(1, 1) X(2, 1)], [X(1, 2) X(2, 2)], [X(1, 3) X(2, 3)], 'color', color); 5 | plot3([X(1, 1) X(3, 1)], [X(1, 2) X(3, 2)], [X(1, 3) X(3, 3)], 'color', color); 6 | plot3([X(1, 1) X(4, 1)], [X(1, 2) X(4, 2)], [X(1, 3) X(4, 3)], 'color', color); 7 | 8 | plot3([X(5, 1) X(8, 1)], [X(5, 2) X(8, 2)], [X(5, 3) X(8, 3)], 'color', color); 9 | plot3([X(6, 1) X(8, 1)], [X(6, 2) X(8, 2)], [X(6, 3) X(8, 3)], 'color', color); 10 | plot3([X(7, 1) X(8, 1)], [X(7, 2) X(8, 2)], [X(7, 3) X(8, 3)], 'color', color); 11 | 12 | plot3([X(2, 1) X(7, 1)], [X(2, 2) X(7, 2)], [X(2, 3) X(7, 3)], 'color', color); 13 | plot3([X(7, 1) X(3, 1)], [X(7, 2) X(3, 2)], [X(7, 3) X(3, 3)], 'color', color); 14 | plot3([X(3, 1) X(5, 1)], [X(3, 2) X(5, 2)], [X(3, 3) X(5, 3)], 'color', color); 15 | plot3([X(5, 1) X(4, 1)], [X(5, 2) X(4, 2)], [X(5, 3) X(4, 3)], 'color', color); 16 | plot3([X(4, 1) X(6, 1)], [X(4, 2) X(6, 2)], [X(4, 3) X(6, 3)], 'color', color); 17 | plot3([X(6, 1) X(2, 1)], [X(6, 2) X(2, 2)], [X(6, 3) X(2, 3)], 'color', color); 18 | 19 | end 20 | 21 | -------------------------------------------------------------------------------- /matlab/visualization/plot_heteroscedasticity.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | global_size = 10000; % 100000 9 | % global_size = 5; 10 | options.check_camera_sane = true; 11 | XYZ_set = get_sample(global_size, options); 12 | XYZ_set = XYZ_set{1}; 13 | 14 | % local_size = 1000; 15 | % XYZ = simulate_camera_noise(local_size, global_size, XYZ_set); 16 | 17 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 18 | % CS_list = {'CIELAB'}; 19 | FontSize = 20; 20 | for CS_num = 1:size(CS_list, 1) 21 | CS = color_spaces_collection(CS_list{CS_num}, proLab_param); 22 | % Sigma_prac = get_sigma(XYZ, CS.name, param); 23 | Sigma_teor = get_sigma_linearization(XYZ_set, CS.name, proLab_param); 24 | % Delta = max(max(abs(Sigma_prac-Sigma_teor))) 25 | Sigma = Sigma_teor; 26 | Sigma = Sigma(:); 27 | [STRESS, F] = get_STRESS(Sigma, ones(size(Sigma))); 28 | Sigma = F * Sigma; 29 | disp(CS.name); 30 | disp([' STRESS = ', num2str(STRESS)]); 31 | fig = figure; 32 | hold on; 33 | grid on; 34 | % set(gca,'YScale','log') 35 | % title(CS.name); 36 | h = histogram(Sigma); 37 | % h = histogram(Sigma,(0:0.02:2)); 38 | % H = max(h.Values); 39 | H = 20000; 40 | % hist(Sigma,100); 41 | % [n, xout] = hist(Sigma,100); 42 | % bar(xout, n, 'barwidth', 1, 'basevalue', 1); 43 | % set(gca,'YScale','log') 44 | plot([1 1], [0 H], 'g', 'LineWidth',3); 45 | % xlim([0, 2]); 46 | % ylim([0, H]); 47 | set(gca,'FontSize',15); 48 | % xlabel('$F\sqrt{\mathbf{e}_{j}(\hat{\Sigma} [\Phi(\mathbf{X}(\mathbf{x}_i))])}$','Interpreter','latex','FontSize', FontSize); 49 | % ylabel(['$\sigma[',lightness_name(2:end-1),']$'],'Interpreter','latex','FontSize', FontSize); 50 | saveas(fig,['images/heteroscedasticity/', CS.name, '_hist.png']); 51 | end 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /matlab/visualization/plot_image_color_distribution.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | frame = imread('images/X-RITE-ColorChecker-Classic-Card-MSCCC.jpg'); 9 | % frame = imread('images/300px-Gretag-Macbeth_ColorChecker.jpg'); 10 | % frame = imread('images/01_2HAL_DESK_LED-BG100_cropped.jpg'); 11 | % frame = imread('images/02_2HAL_DESK_LED-BG100_cropped.jpg'); 12 | % frame = imread('images/03_2HAL_DESK_LED-BG100_cropped.jpg'); 13 | [h, w, c] = size(frame); 14 | sRGB = reshape(frame, h*w, c); 15 | sRGB = double(sRGB); 16 | sRGB = sRGB + rand(size(sRGB)); 17 | sRGB = sRGB / 256; 18 | 19 | set(gca, 'FontSize', 15); 20 | FontSize = 20; 21 | CS = color_spaces_collection('sRGB'); 22 | AO = CS.axis_Lab_order; 23 | 24 | figure(1); 25 | hold on; 26 | % grid on; 27 | % plot3(sRGB(:, 1), sRGB(:, 2), sRGB(:, 3), '.r'); 28 | s = scatter3(sRGB(:, 1), sRGB(:, 2), sRGB(:, 3), 7, sRGB, 'filled'); 29 | s.MarkerEdgeAlpha = 1.0; 30 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 31 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 32 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 33 | xlim([0 1]); 34 | ylim([0 1]); 35 | zlim([0 1]); 36 | ax.Projection = 'perspective'; 37 | axis equal; 38 | -------------------------------------------------------------------------------- /matlab/visualization/plot_lazer_triangle.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_lazer_triangle(CS_name, Y) 3 | lambda = (400:660)'; 4 | formulary = '1931_FULL'; 5 | XYZ = get_XYZ_spectrum(lambda, formulary); 6 | XYZ = Y * XYZ ./ XYZ(:, 2); 7 | CS = color_spaces_collection(CS_name, RECORD); 8 | CC = CS.transform_into(XYZ); 9 | AO = CS.axis_Lab_order; 10 | plot3(CC(:,abs(AO(1))),CC(:,abs(AO(2))),CC(:,abs(AO(3))),'black','LineWidth',2); 11 | plot3([CC(1,abs(AO(1))),CC(end,abs(AO(1)))], ... 12 | [CC(1,abs(AO(2))),CC(end,abs(AO(2)))], ... 13 | [CC(1,abs(AO(3))),CC(end,abs(AO(3)))],'--black','LineWidth',2); 14 | end -------------------------------------------------------------------------------- /matlab/visualization/plot_sRGB_gamut.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_sRGB_gamut(param) 3 | 4 | addpath(genpath('..')); 5 | 6 | if nargin == 0 7 | param = proLab_param; 8 | proLabOnly = false; 9 | else 10 | proLabOnly = true; 11 | end 12 | 13 | addpath(genpath('..')); 14 | 15 | if proLabOnly 16 | CS_list = {'proLab'}; 17 | else 18 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 19 | % CS_list = {'proLab'}; 20 | end 21 | TX = (0:0.05:1)'; 22 | T0 = zeros(size(TX)); 23 | T1 = ones(size(TX)); 24 | linRGB_mesh = [T0, T0, TX; T0, T1, TX; T1, T0, TX; T1, T1, TX; ... 25 | T0, TX, T0; T0, TX, T1; T1, TX, T0; T1, TX, T1; ... 26 | TX, T0, T0; TX, T1, T0; TX, T0, T1; TX, T1, T1]; 27 | 28 | XYZ_linRGB_mesh = (linRGB_matrix^(-1)*linRGB_mesh')'; 29 | % XYZ_linRGB_vertex = (sRGB_matrix^(-1) * vertex')'; 30 | 31 | % CS_list = {'CIEXYZ';}; 32 | h = 0.1; % 0.05 33 | [A, B] = meshgrid(0:h:1, 0:h:1); 34 | A = reshape(A, [numel(A), 1]); 35 | B = reshape(B, [numel(B), 1]); 36 | DT = delaunayTriangulation([A B]); 37 | CL = DT.ConnectivityList; 38 | for CS_num = 1:size(CS_list, 1) 39 | CS = color_spaces_collection(CS_list{CS_num}, param); 40 | AO = CS.axis_Lab_order; 41 | 42 | CS_linRGB_mesh = CS.transform_into(XYZ_linRGB_mesh); 43 | % CS_linRGB_vertex = CS.transform_into(XYZ_linRGB_vertex); 44 | fig = figure(); 45 | hold on; 46 | % ax = gca; 47 | % ax.FontSmoothing = 'on'; 48 | % fig.GraphicsSmoothing = 'on'; 49 | % set(gcf, 'renderer', 'zbuffer'); 50 | grid on; 51 | for ax = 1:3 52 | for c = 0:1 53 | C = c*ones(size(A)); 54 | switch ax 55 | case 1 56 | linRGB = [A, B, C]; 57 | case 2 58 | linRGB = [B, C, A]; 59 | case 3 60 | linRGB = [C, A, B]; 61 | end 62 | sRGB = linRGB2sRGB(linRGB); 63 | XYZ = linRGB2XYZ(linRGB); 64 | % min(XYZ) 65 | % max(XYZ) 66 | CC = CS.transform_into(XYZ); 67 | T = size(CL, 1); 68 | for i = 1:T 69 | v = [CC(CL(i, 1), :); CC(CL(i, 2), :); CC(CL(i, 3), :)]; 70 | color = mean(sRGB([CL(i, 1), CL(i, 2), CL(i, 3)], :)); 71 | % fill3(v(:, abs(AO(1))), v(:, abs(AO(2))), v(:, abs(AO(3))), color, 'LineStyle', 'none'); 72 | fill3(v(:, abs(AO(1))), v(:, abs(AO(2))), v(:, abs(AO(3))), color, 'LineStyle', 'none', 'FaceAlpha', 0.6); 73 | end 74 | end 75 | end 76 | plot3(CS_linRGB_mesh(:, abs(AO(1))), ... 77 | CS_linRGB_mesh(:, abs(AO(2))), ... 78 | CS_linRGB_mesh(:, abs(AO(3))), ... 79 | '.', 'color',0.5*[1 1 1], 'MarkerSize', 13); 80 | set(gca,'FontSize',15); 81 | FontSize = 20; 82 | % pic_name = ['The sRGB gamut projected',newline, 'into ', CS.name,' color space']; 83 | % title(pic_name); 84 | % title(CS.name, 'FontSize', FontSize); 85 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 86 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 87 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 88 | ax = gca; 89 | ax.Projection = 'perspective'; 90 | axis tight; 91 | axis equal; 92 | switch CS.name 93 | case {'linRGB', 'sRGB'} 94 | view(150,-16); 95 | case 'LMS' 96 | view(139,-33); 97 | case 'deviceRGB' 98 | view(143,-18); 99 | case 'CIE XYZ' 100 | view(139,-33); 101 | case 'CIE xyY' 102 | view(107,11); 103 | case 'CIELAB' 104 | view(105,14); 105 | case 'proLab' 106 | view(101,10); 107 | case 'CAM16-UCS' 108 | view(102,8); 109 | end 110 | if AO(1) < 0 111 | set(gca,'XDir', 'reverse'); 112 | end 113 | if AO(2) < 0 114 | set(gca,'YDir', 'reverse'); 115 | end 116 | if AO(3) < 0 117 | set(gca,'ZDir', 'reverse'); 118 | end 119 | if ~proLabOnly 120 | pic_name = ['images/body/', CS.name, '_sRGB_gamut.png']; 121 | saveas(fig, pic_name); 122 | end 123 | % RGB = AntiAlias(gcf, 4, 'lanczos3'); 124 | % imwrite(RGB, pic_name); 125 | end 126 | end 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /matlab/visualization/plot_sample.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | sample_size = 30000; % 300000 9 | XYZ = get_sample(sample_size); 10 | FontSize = 20; 11 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 12 | % CS_list = {'proLab'}; 13 | dist_CIEDE2000 = get_CIEDE2000(XYZ, 'CIE XYZ'); 14 | for CS_num = 1:size(CS_list, 1) 15 | CS_name = CS_list{CS_num}; 16 | handle = color_dist(CS_name, proLab_param); 17 | dist = handle(XYZ); 18 | fig = figure(); 19 | hold on; 20 | set(gca,'FontSize',15); 21 | % set(gcf, 'Position', [100, 100, 350, 300]); 22 | % title('Sample'); 23 | s = scatter(dist_CIEDE2000, dist,'.','MarkerEdgeColor',[0 0 0]); 24 | s.MarkerEdgeAlpha = 0.02; 25 | xlabel('$\mathrm{\Delta E^*_{00}}$','Interpreter','latex','FontSize', FontSize); 26 | ylabel(['$\mathrm{\Delta E_{', CS_name, '}}$'],'Interpreter','latex','FontSize', FontSize); 27 | saveas(fig,['images/sample/', CS_name, '.png']); 28 | % saveas(fig,['pic/sample_', CS_name, '.png']); 29 | end 30 | %% 31 | 32 | % M = sRGB_matrix^(-1); 33 | % colors{1} = [0 0 0]; 34 | % colors{2} = (M(:,1))'; 35 | % colors{3} = (M(:,2))'; 36 | % colors{4} = (M(:,3))'; 37 | % colors{5} = (M(:,2)+M(:,3))'; 38 | % colors{6} = (M(:,3)+M(:,1))'; 39 | % colors{7} = (M(:,1)+M(:,2))'; 40 | % colors{8} = (sum(M,2))'; 41 | % n = 8; 42 | % 43 | % dist_XYZ = zeros(n,n); 44 | % dist_Lab = zeros(n,n); 45 | % dist_proLab = zeros(n,n); 46 | % dist_CIEDE2000 = zeros(n,n); 47 | % % optimal_param = [-45.1686, 362.3583, 35.9817, -59.2676, 106.1844, -70.1276, 1.5045, 0.7608, 0.9413]; 48 | % % optimal_param = [1241.9,865.4,669.5,1765,658.6,497.1,4.7,7.1,5.8] 49 | % for i = 1:n 50 | % for j = 1:n 51 | % XYZ = {colors{i}, colors{j}}; 52 | % XYZ_dist(i,j) = get_space_distance(@XYZ2XYZ, XYZ, params.XYZ); 53 | % dist_Lab(i,j) = get_space_distance(@XYZ2Lab, XYZ, params.Lab); 54 | % dist_proLab(i,j) = get_space_distance(@XYZ2proLab, XYZ, params.proLab); 55 | % dist_CIEDE2000(i,j) = get_CIEDE2000(XYZ); 56 | % end 57 | % end 58 | % 59 | % % sqrt(sum(sum((CIEDE2000 - proLab_dist).^2))/28) 60 | % % sqrt(sum(sum(((proLab_dist - CIEDE2000)./(CIEDE2000+0.01)).^2))/28) 61 | % % proLab_dist 62 | % % (Lab_dist - CIEDE2000)./ CIEDE2000 63 | % dist_proLab 64 | % % CIEDE2000 65 | % % proLab_dist - CIEDE2000 66 | % % Lab_dist - CIEDE2000 67 | % % Lab_dist - proLab_dist 68 | % % XYZ_dist/66.9044 69 | 70 | 71 | -------------------------------------------------------------------------------- /matlab/visualization/plot_sigma.m: -------------------------------------------------------------------------------- 1 | 2 | function plot_sigma(x, y_l, y_u, h, w) 3 | plot([x-(h/2), x+(h/2)],[y_l, y_l],'r','LineWidth',w); 4 | plot([x, x],[y_l, y_u],'r','LineWidth',w); 5 | plot([x-(h/2), x+(h/2)],[y_u, y_u],'r','LineWidth',w); 6 | end 7 | 8 | -------------------------------------------------------------------------------- /matlab/visualization/plot_simulate_camera_noise.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | close all; 5 | 6 | addpath(genpath('..')); 7 | 8 | local_size = 100; % 1000 9 | global_size = 200; % 2000 10 | 11 | XYZ = simulate_camera_noise(local_size, global_size); 12 | XYZ = reshape(XYZ, [local_size * global_size, 3]); 13 | % min(XYZ) 14 | % max(XYZ) 15 | sRGB = XYZ2sRGB(XYZ); 16 | sRGB = reshape(sRGB, [global_size, local_size, 3]); 17 | CS_list = {'LMS'; 'deviceRGB'; 'CIE XYZ'; 'CIE xyY'; 'linRGB'; 'sRGB'; 'CIELAB'; 'CAM16-UCS'; 'proLab'}; 18 | % CS_list = {'proLab'}; 19 | FontSize = 20; 20 | for CS_num = 1:size(CS_list, 1) 21 | CS = color_spaces_collection(CS_list{CS_num}, proLab_param); 22 | AO = CS.axis_Lab_order; 23 | CC = CS.transform_into(XYZ); 24 | % size(CC) 25 | % CS.name 26 | % sum(CC<0) 27 | CC = reshape(CC, [global_size, local_size, 3]); 28 | sides = {'white'; 'black'}; 29 | % sides = {'white'}; 30 | for s = 1:size(sides, 1) 31 | side = sides{s, 1}; 32 | fig = figure(); 33 | grid on; 34 | hold on; 35 | for g = 1:global_size 36 | % color = rand(1, 3); 37 | color = mean(sRGB(g,:,:),2); 38 | if all(0 <= color) && all(color <= 1) 39 | plot3(CC(g,:,abs(AO(1))),CC(g,:,abs(AO(2))),CC(g,:,abs(AO(3))),'.','MarkerSize', 7, 'color', color); 40 | end 41 | end 42 | % title(CS.name); 43 | xlabel(CS.axis_names{abs(AO(1))},'Interpreter','latex','FontSize', FontSize); 44 | ylabel(CS.axis_names{abs(AO(2))},'Interpreter','latex','FontSize', FontSize); 45 | zlabel(CS.axis_names{abs(AO(3))},'Interpreter','latex','FontSize', FontSize); 46 | set(gca,'FontSize',15); 47 | switch side 48 | case 'white' 49 | view(+90,0); 50 | case 'black' 51 | view(-90,0); 52 | end 53 | if AO(1) < 0 54 | set(gca,'XDir', 'reverse'); 55 | end 56 | if AO(2) < 0 57 | set(gca,'YDir', 'reverse'); 58 | end 59 | if AO(3) < 0 60 | set(gca,'ZDir', 'reverse'); 61 | end 62 | axis tight; 63 | axis equal; 64 | % saveas(fig,['pic/noise_white_', CS.name, '.png']); 65 | saveas(fig,['images/heteroscedasticity/', CS.name, '_', side, '.png']); 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /matlab/visualization/save_plot.m: -------------------------------------------------------------------------------- 1 | 2 | function save_plot(fig, fullname) 3 | 4 | saveas(fig, fullname); 5 | pic = imread(fullname); 6 | isWhite = sum(pic,3) == (255 * size(pic,3)); 7 | XS = sum(isWhite,1) < size(pic, 1); 8 | YS = sum(isWhite,2) < size(pic, 2); 9 | pic = pic(YS, XS, :); 10 | imwrite(pic, fullname); 11 | 12 | end 13 | 14 | -------------------------------------------------------------------------------- /python/XYZ_to_CAM16UCS.py: -------------------------------------------------------------------------------- 1 | import colour 2 | import numpy as np 3 | from scipy.io import loadmat 4 | from scipy.io import savemat 5 | 6 | request = loadmat('../python/request.mat') 7 | XYZ = request['XYZ'] 8 | reference_illuminant = loadmat('../python/reference_illuminant.mat') 9 | XYZ_w = reference_illuminant['ref_illum'] 10 | L_A = 0.20 11 | Y_b = 0.20 12 | surround = colour.CAM16_VIEWING_CONDITIONS['Average'] 13 | CAM16 = colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround) 14 | JMh = np.array([CAM16.J, CAM16.M, CAM16.h]) 15 | JMh = JMh.transpose() 16 | CAM16UCS = colour.JMh_CAM16_to_CAM16UCS(JMh) 17 | mdict={'CAM16UCS': CAM16UCS} 18 | savemat('../python/response.mat', mdict) --------------------------------------------------------------------------------