@@ -49,28 +49,12 @@ enum DISTANCE_TYPE
4949 RGBL
5050};
5151
52- double deltaCIE76 (cv::Vec3d lab1, cv::Vec3d lab2);
53- double deltaCIE94 (cv::Vec3d lab1, cv::Vec3d lab2, double kH = 1.0 ,
54- double kC = 1.0 , double kL = 1.0 , double k1 = 0.045 ,
55- double k2 = 0.015 );
56- double deltaCIE94GraphicArts (cv::Vec3d lab1, cv::Vec3d lab2);
57- double toRad (double degree);
58- double deltaCIE94Textiles (cv::Vec3d lab1, cv::Vec3d lab2);
59- double deltaCIEDE2000_ (cv::Vec3d lab1, cv::Vec3d lab2, double kL = 1.0 ,
60- double kC = 1.0 , double kH = 1.0 );
61- double deltaCIEDE2000 (cv::Vec3d lab1, cv::Vec3d lab2);
62- double deltaCMC (cv::Vec3d lab1, cv::Vec3d lab2, double kL = 1 , double kC = 1 );
63- double deltaCMC1To1 (cv::Vec3d lab1, cv::Vec3d lab2);
64- double deltaCMC2To1 (cv::Vec3d lab1, cv::Vec3d lab2);
65- cv::Mat distance (cv::Mat src, cv::Mat ref, DISTANCE_TYPE distance_type);
66-
67-
6852/* *\ brief distance between two points in formula CIE76
6953 *\ param lab1 a 3D vector
7054 *\ param lab2 a 3D vector
7155 *\ return distance between lab1 and lab2
7256*/
73- double deltaCIE76 (cv::Vec3d lab1, cv::Vec3d lab2) { return norm (lab1 - lab2); } ;
57+ double deltaCIE76 (cv::Vec3d lab1, cv::Vec3d lab2);
7458
7559/* *\ brief distance between two points in formula CIE94
7660 *\ param lab1 a 3D vector
@@ -82,36 +66,15 @@ double deltaCIE76(cv::Vec3d lab1, cv::Vec3d lab2) { return norm(lab1 - lab2); };
8266 *\ param k2 second scale parameter
8367 *\ return distance between lab1 and lab2
8468*/
85- double deltaCIE94 (cv::Vec3d lab1, cv::Vec3d lab2, double kH ,
86- double kC , double kL , double k1, double k2)
87- {
88- double dl = lab1[0 ] - lab2[0 ];
89- double c1 = sqrt (pow (lab1[1 ], 2 ) + pow (lab1[2 ], 2 ));
90- double c2 = sqrt (pow (lab2[1 ], 2 ) + pow (lab2[2 ], 2 ));
91- double dc = c1 - c2;
92- double da = lab1[1 ] - lab2[1 ];
93- double db = lab1[2 ] - lab2[2 ];
94- double dh = pow (da, 2 ) + pow (db, 2 ) - pow (dc, 2 );
95- double sc = 1.0 + k1 * c1;
96- double sh = 1.0 + k2 * c1;
97- double sl = 1.0 ;
98- double res =
99- pow (dl / (kL * sl), 2 ) + pow (dc / (kC * sc), 2 ) + dh / pow (kH * sh, 2 );
100-
101- return res > 0 ? sqrt (res) : 0 ;
102- }
69+ double deltaCIE94 (cv::Vec3d lab1, cv::Vec3d lab2, double kH = 1.0 ,
70+ double kC = 1.0 , double kL = 1.0 , double k1 = 0.045 ,
71+ double k2 = 0.015 );
10372
104- double deltaCIE94GraphicArts (cv::Vec3d lab1, cv::Vec3d lab2)
105- {
106- return deltaCIE94 (lab1, lab2);
107- }
73+ double deltaCIE94GraphicArts (cv::Vec3d lab1, cv::Vec3d lab2);
10874
109- double toRad (double degree) { return degree / 180 * CV_PI; } ;
75+ double toRad (double degree);
11076
111- double deltaCIE94Textiles (cv::Vec3d lab1, cv::Vec3d lab2)
112- {
113- return deltaCIE94 (lab1, lab2, 1.0 , 1.0 , 2.0 , 0.048 , 0.014 );
114- }
77+ double deltaCIE94Textiles (cv::Vec3d lab1, cv::Vec3d lab2);
11578
11679/* *\ brief distance between two points in formula CIE2000
11780 *\ param lab1 a 3D vector
@@ -121,99 +84,9 @@ double deltaCIE94Textiles(cv::Vec3d lab1, cv::Vec3d lab2)
12184 *\ param kH Hue scale
12285 *\ return distance between lab1 and lab2
12386*/
124- double deltaCIEDE2000_ (cv::Vec3d lab1, cv::Vec3d lab2, double kL ,
125- double kC , double kH )
126- {
127- double delta_L_apo = lab2[0 ] - lab1[0 ];
128- double l_bar_apo = (lab1[0 ] + lab2[0 ]) / 2.0 ;
129- double C1 = sqrt (pow (lab1[1 ], 2 ) + pow (lab1[2 ], 2 ));
130- double C2 = sqrt (pow (lab2[1 ], 2 ) + pow (lab2[2 ], 2 ));
131- double C_bar = (C1 + C2) / 2.0 ;
132- double G = sqrt (pow (C_bar, 7 ) / (pow (C_bar, 7 ) + pow (25 , 7 )));
133- double a1_apo = lab1[1 ] + lab1[1 ] / 2.0 * (1.0 - G);
134- double a2_apo = lab2[1 ] + lab2[1 ] / 2.0 * (1.0 - G);
135- double C1_apo = sqrt (pow (a1_apo, 2 ) + pow (lab1[2 ], 2 ));
136- double C2_apo = sqrt (pow (a2_apo, 2 ) + pow (lab2[2 ], 2 ));
137- double C_bar_apo = (C1_apo + C2_apo) / 2.0 ;
138- double delta_C_apo = C2_apo - C1_apo;
139-
140- double h1_apo;
141- if (C1_apo == 0 )
142- {
143- h1_apo = 0.0 ;
144- }
145- else
146- {
147- h1_apo = atan2 (lab1[2 ], a1_apo);
148- if (h1_apo < 0.0 ) h1_apo += 2 . * CV_PI;
149- }
150-
151- double h2_apo;
152- if (C2_apo == 0 )
153- {
154- h2_apo = 0.0 ;
155- }
156- else
157- {
158- h2_apo = atan2 (lab2[2 ], a2_apo);
159- if (h2_apo < 0.0 ) h2_apo += 2 . * CV_PI;
160- }
161-
162- double delta_h_apo;
163- if (abs (h2_apo - h1_apo) <= CV_PI)
164- {
165- delta_h_apo = h2_apo - h1_apo;
166- }
167- else if (h2_apo <= h1_apo)
168- {
169- delta_h_apo = h2_apo - h1_apo + 2 . * CV_PI;
170- }
171- else
172- {
173- delta_h_apo = h2_apo - h1_apo - 2 . * CV_PI;
174- }
175-
176- double H_bar_apo;
177- if (C1_apo == 0 || C2_apo == 0 )
178- {
179- H_bar_apo = h1_apo + h2_apo;
180- }
181- else if (abs (h1_apo - h2_apo) <= CV_PI)
182- {
183- H_bar_apo = (h1_apo + h2_apo) / 2.0 ;
184- }
185- else if (h1_apo + h2_apo < 2 . * CV_PI)
186- {
187- H_bar_apo = (h1_apo + h2_apo + 2 . * CV_PI) / 2.0 ;
188- }
189- else
190- {
191- H_bar_apo = (h1_apo + h2_apo - 2 . * CV_PI) / 2.0 ;
192- }
193-
194- double delta_H_apo = 2.0 * sqrt (C1_apo * C2_apo) * sin (delta_h_apo / 2.0 );
195- double T = 1.0 - 0.17 * cos (H_bar_apo - toRad (30 .)) +
196- 0.24 * cos (2.0 * H_bar_apo) +
197- 0.32 * cos (3.0 * H_bar_apo + toRad (6.0 )) -
198- 0.2 * cos (4.0 * H_bar_apo - toRad (63.0 ));
199- double sC = 1.0 + 0.045 * C_bar_apo;
200- double sH = 1.0 + 0.015 * C_bar_apo * T;
201- double sL = 1.0 + ((0.015 * pow (l_bar_apo - 50.0 , 2.0 )) /
202- sqrt (20.0 + pow (l_bar_apo - 50.0 , 2.0 )));
203- double RT = -2.0 * G *
204- sin (toRad (60.0 ) *
205- exp (-pow ((H_bar_apo - toRad (275.0 )) / toRad (25.0 ), 2.0 )));
206- double res =
207- (pow (delta_L_apo / (kL * sL ), 2.0 ) + pow (delta_C_apo / (kC * sC ), 2.0 ) +
208- pow (delta_H_apo / (kH * sH ), 2.0 ) +
209- RT * (delta_C_apo / (kC * sC )) * (delta_H_apo / (kH * sH )));
210- return res > 0 ? sqrt (res) : 0 ;
211- }
212-
213- double deltaCIEDE2000 (cv::Vec3d lab1, cv::Vec3d lab2)
214- {
215- return deltaCIEDE2000_ (lab1, lab2);
216- }
87+ double deltaCIEDE2000_ (cv::Vec3d lab1, cv::Vec3d lab2, double kL = 1.0 ,
88+ double kC = 1.0 , double kH = 1.0 );
89+ double deltaCIEDE2000 (cv::Vec3d lab1, cv::Vec3d lab2);
21790
21891/* *\ brief distance between two points in formula CMC
21992 *\ param lab1 a 3D vector
@@ -222,77 +95,16 @@ double deltaCIEDE2000(cv::Vec3d lab1, cv::Vec3d lab2)
22295 *\ param kC Chroma scale
22396 *\ return distance between lab1 and lab2
22497*/
225- double deltaCMC (cv::Vec3d lab1, cv::Vec3d lab2, double kL , double kC )
226- {
227- double dL = lab2[0 ] - lab1[0 ];
228- double da = lab2[1 ] - lab1[1 ];
229- double db = lab2[2 ] - lab1[2 ];
230- double C1 = sqrt (pow (lab1[1 ], 2.0 ) + pow (lab1[2 ], 2.0 ));
231- double C2 = sqrt (pow (lab2[1 ], 2.0 ) + pow (lab2[2 ], 2.0 ));
232- double dC = C2 - C1;
233- double dH = sqrt (pow (da, 2 ) + pow (db, 2 ) - pow (dC, 2 ));
234-
235- double H1;
236- if (C1 == 0 .)
237- {
238- H1 = 0.0 ;
239- }
240- else
241- {
242- H1 = atan2 (lab1[2 ], lab1[1 ]);
243- if (H1 < 0.0 ) H1 += 2 . * CV_PI;
244- }
245-
246- double F = pow (C1, 2 ) / sqrt (pow (C1, 4 ) + 1900 );
247- double T = (H1 > toRad (164 ) && H1 <= toRad (345 ))
248- ? 0.56 + abs (0.2 * cos (H1 + toRad (168 )))
249- : 0.36 + abs (0.4 * cos (H1 + toRad (35 )));
250- double sL =
251- lab1[0 ] < 16 . ? 0.511 : (0.040975 * lab1[0 ]) / (1.0 + 0.01765 * lab1[0 ]);
252- double sC = (0.0638 * C1) / (1.0 + 0.0131 * C1) + 0.638 ;
253- double sH = sC * (F * T + 1.0 - F);
98+ double deltaCMC (cv::Vec3d lab1, cv::Vec3d lab2, double kL = 1 , double kC = 1 );
25499
255- return sqrt (pow (dL / (kL * sL ), 2.0 ) + pow (dC / (kC * sC ), 2.0 ) +
256- pow (dH / sH , 2.0 ));
257- }
100+ double deltaCMC1To1 (cv::Vec3d lab1, cv::Vec3d lab2);
258101
259- double deltaCMC1To1 (cv::Vec3d lab1, cv::Vec3d lab2)
260- {
261- return deltaCMC (lab1, lab2);
262- }
102+ double deltaCMC2To1 (cv::Vec3d lab1, cv::Vec3d lab2);
263103
264- double deltaCMC2To1 (cv::Vec3d lab1, cv::Vec3d lab2)
265- {
266- return deltaCMC (lab1, lab2, 2 , 1 );
267- }
104+ Mat distance (Mat src, Mat ref, DISTANCE_TYPE distance_type);
268105
269- cv::Mat distance (cv::Mat src, cv::Mat ref, DISTANCE_TYPE distance_type)
270- {
271- switch (distance_type)
272- {
273- case cv::ccm::CIE76:
274- return distanceWise (src, ref, deltaCIE76);
275- case cv::ccm::CIE94_GRAPHIC_ARTS:
276- return distanceWise (src, ref, deltaCIE94GraphicArts);
277- case cv::ccm::CIE94_TEXTILES:
278- return distanceWise (src, ref, deltaCIE94Textiles);
279- case cv::ccm::CIE2000:
280- return distanceWise (src, ref, deltaCIEDE2000);
281- case cv::ccm::CMC_1TO1:
282- return distanceWise (src, ref, deltaCMC1To1);
283- case cv::ccm::CMC_2TO1:
284- return distanceWise (src, ref, deltaCMC2To1);
285- case cv::ccm::RGB:
286- return distanceWise (src, ref, deltaCIE76);
287- case cv::ccm::RGBL:
288- return distanceWise (src, ref, deltaCIE76);
289- default :
290- throw std::invalid_argument{ " Wrong distance_type!" };
291- break ;
292- }
293- };
106+ } // namespace ccm
107+ } // namespace cv
294108
295- } // namespace ccm
296- } // namespace cv
297109
298- #endif
110+ #endif
0 commit comments