1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "precomp.hpp"
43
44 namespace cv
45 {
46
47 /*! */
48 class NormHistogramCostExtractorImpl : public NormHistogramCostExtractor
49 {
50 public:
51 /* Constructors */
NormHistogramCostExtractorImpl(int _flag,int _nDummies,float _defaultCost)52 NormHistogramCostExtractorImpl(int _flag, int _nDummies, float _defaultCost)
53 {
54 flag=_flag;
55 nDummies=_nDummies;
56 defaultCost=_defaultCost;
57 name_ = "HistogramCostExtractor.NOR";
58 }
59
60 /* Destructor */
~NormHistogramCostExtractorImpl()61 ~NormHistogramCostExtractorImpl()
62 {
63 }
64
65 //! the main operator
66 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix);
67
68 //! Setters/Getters
setNDummies(int _nDummies)69 void setNDummies(int _nDummies)
70 {
71 nDummies=_nDummies;
72 }
73
getNDummies() const74 int getNDummies() const
75 {
76 return nDummies;
77 }
78
setDefaultCost(float _defaultCost)79 void setDefaultCost(float _defaultCost)
80 {
81 defaultCost=_defaultCost;
82 }
83
getDefaultCost() const84 float getDefaultCost() const
85 {
86 return defaultCost;
87 }
88
setNormFlag(int _flag)89 virtual void setNormFlag(int _flag)
90 {
91 flag=_flag;
92 }
93
getNormFlag() const94 virtual int getNormFlag() const
95 {
96 return flag;
97 }
98
99 //! write/read
write(FileStorage & fs) const100 virtual void write(FileStorage& fs) const
101 {
102 fs << "name" << name_
103 << "flag" << flag
104 << "dummies" << nDummies
105 << "default" << defaultCost;
106 }
107
read(const FileNode & fn)108 virtual void read(const FileNode& fn)
109 {
110 CV_Assert( (String)fn["name"] == name_ );
111 flag = (int)fn["flag"];
112 nDummies = (int)fn["dummies"];
113 defaultCost = (float)fn["default"];
114 }
115
116 private:
117 int flag;
118 int nDummies;
119 float defaultCost;
120
121 protected:
122 String name_;
123 };
124
buildCostMatrix(InputArray _descriptors1,InputArray _descriptors2,OutputArray _costMatrix)125 void NormHistogramCostExtractorImpl::buildCostMatrix(InputArray _descriptors1, InputArray _descriptors2, OutputArray _costMatrix)
126 {
127 // size of the costMatrix with dummies //
128 Mat descriptors1=_descriptors1.getMat();
129 Mat descriptors2=_descriptors2.getMat();
130 int costrows = std::max(descriptors1.rows, descriptors2.rows)+nDummies;
131 _costMatrix.create(costrows, costrows, CV_32F);
132 Mat costMatrix=_costMatrix.getMat();
133
134
135 // Obtain copies of the descriptors //
136 cv::Mat scd1 = descriptors1.clone();
137 cv::Mat scd2 = descriptors2.clone();
138
139 // row normalization //
140 for(int i=0; i<scd1.rows; i++)
141 {
142 scd1.row(i)/=(sum(scd1.row(i))[0]+FLT_EPSILON);
143 }
144 for(int i=0; i<scd2.rows; i++)
145 {
146 scd2.row(i)/=(sum(scd2.row(i))[0]+FLT_EPSILON);
147 }
148
149 // Compute the Cost Matrix //
150 for(int i=0; i<costrows; i++)
151 {
152 for(int j=0; j<costrows; j++)
153 {
154 if (i<scd1.rows && j<scd2.rows)
155 {
156 Mat columnDiff = scd1.row(i)-scd2.row(j);
157 costMatrix.at<float>(i,j)=(float)norm(columnDiff, flag);
158 }
159 else
160 {
161 costMatrix.at<float>(i,j)=defaultCost;
162 }
163 }
164 }
165 }
166
createNormHistogramCostExtractor(int flag,int nDummies,float defaultCost)167 Ptr <HistogramCostExtractor> createNormHistogramCostExtractor(int flag, int nDummies, float defaultCost)
168 {
169 return Ptr <HistogramCostExtractor>( new NormHistogramCostExtractorImpl(flag, nDummies, defaultCost) );
170 }
171
172 /*! */
173 class EMDHistogramCostExtractorImpl : public EMDHistogramCostExtractor
174 {
175 public:
176 /* Constructors */
EMDHistogramCostExtractorImpl(int _flag,int _nDummies,float _defaultCost)177 EMDHistogramCostExtractorImpl(int _flag, int _nDummies, float _defaultCost)
178 {
179 flag=_flag;
180 nDummies=_nDummies;
181 defaultCost=_defaultCost;
182 name_ = "HistogramCostExtractor.EMD";
183 }
184
185 /* Destructor */
~EMDHistogramCostExtractorImpl()186 ~EMDHistogramCostExtractorImpl()
187 {
188 }
189
190 //! the main operator
191 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix);
192
193 //! Setters/Getters
setNDummies(int _nDummies)194 void setNDummies(int _nDummies)
195 {
196 nDummies=_nDummies;
197 }
198
getNDummies() const199 int getNDummies() const
200 {
201 return nDummies;
202 }
203
setDefaultCost(float _defaultCost)204 void setDefaultCost(float _defaultCost)
205 {
206 defaultCost=_defaultCost;
207 }
208
getDefaultCost() const209 float getDefaultCost() const
210 {
211 return defaultCost;
212 }
213
setNormFlag(int _flag)214 virtual void setNormFlag(int _flag)
215 {
216 flag=_flag;
217 }
218
getNormFlag() const219 virtual int getNormFlag() const
220 {
221 return flag;
222 }
223
224 //! write/read
write(FileStorage & fs) const225 virtual void write(FileStorage& fs) const
226 {
227 fs << "name" << name_
228 << "flag" << flag
229 << "dummies" << nDummies
230 << "default" << defaultCost;
231 }
232
read(const FileNode & fn)233 virtual void read(const FileNode& fn)
234 {
235 CV_Assert( (String)fn["name"] == name_ );
236 flag = (int)fn["flag"];
237 nDummies = (int)fn["dummies"];
238 defaultCost = (float)fn["default"];
239 }
240
241 private:
242 int flag;
243 int nDummies;
244 float defaultCost;
245
246 protected:
247 String name_;
248 };
249
buildCostMatrix(InputArray _descriptors1,InputArray _descriptors2,OutputArray _costMatrix)250 void EMDHistogramCostExtractorImpl::buildCostMatrix(InputArray _descriptors1, InputArray _descriptors2, OutputArray _costMatrix)
251 {
252 // size of the costMatrix with dummies //
253 Mat descriptors1=_descriptors1.getMat();
254 Mat descriptors2=_descriptors2.getMat();
255 int costrows = std::max(descriptors1.rows, descriptors2.rows)+nDummies;
256 _costMatrix.create(costrows, costrows, CV_32F);
257 Mat costMatrix=_costMatrix.getMat();
258
259 // Obtain copies of the descriptors //
260 cv::Mat scd1=descriptors1.clone();
261 cv::Mat scd2=descriptors2.clone();
262
263 // row normalization //
264 for(int i=0; i<scd1.rows; i++)
265 {
266 cv::Mat row = scd1.row(i);
267 scd1.row(i)/=(sum(row)[0]+FLT_EPSILON);
268 }
269 for(int i=0; i<scd2.rows; i++)
270 {
271 cv::Mat row = scd2.row(i);
272 scd2.row(i)/=(sum(row)[0]+FLT_EPSILON);
273 }
274
275 // Compute the Cost Matrix //
276 for(int i=0; i<costrows; i++)
277 {
278 for(int j=0; j<costrows; j++)
279 {
280 if (i<scd1.rows && j<scd2.rows)
281 {
282 cv::Mat sig1(scd1.cols,2,CV_32F), sig2(scd2.cols,2,CV_32F);
283 sig1.col(0)=scd1.row(i).t();
284 sig2.col(0)=scd2.row(j).t();
285 for (int k=0; k<sig1.rows; k++)
286 {
287 sig1.at<float>(k,1)=float(k);
288 }
289 for (int k=0; k<sig2.rows; k++)
290 {
291 sig2.at<float>(k,1)=float(k);
292 }
293
294 costMatrix.at<float>(i,j) = cv::EMD(sig1, sig2, flag);
295 }
296 else
297 {
298 costMatrix.at<float>(i,j) = defaultCost;
299 }
300 }
301 }
302 }
303
createEMDHistogramCostExtractor(int flag,int nDummies,float defaultCost)304 Ptr <HistogramCostExtractor> createEMDHistogramCostExtractor(int flag, int nDummies, float defaultCost)
305 {
306 return Ptr <HistogramCostExtractor>( new EMDHistogramCostExtractorImpl(flag, nDummies, defaultCost) );
307 }
308
309 /*! */
310 class ChiHistogramCostExtractorImpl : public ChiHistogramCostExtractor
311 {
312 public:
313 /* Constructors */
ChiHistogramCostExtractorImpl(int _nDummies,float _defaultCost)314 ChiHistogramCostExtractorImpl(int _nDummies, float _defaultCost)
315 {
316 name_ = "HistogramCostExtractor.CHI";
317 nDummies=_nDummies;
318 defaultCost=_defaultCost;
319 }
320
321 /* Destructor */
~ChiHistogramCostExtractorImpl()322 ~ChiHistogramCostExtractorImpl()
323 {
324 }
325
326 //! the main operator
327 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix);
328
329 //! setters / getters
setNDummies(int _nDummies)330 void setNDummies(int _nDummies)
331 {
332 nDummies=_nDummies;
333 }
334
getNDummies() const335 int getNDummies() const
336 {
337 return nDummies;
338 }
339
setDefaultCost(float _defaultCost)340 void setDefaultCost(float _defaultCost)
341 {
342 defaultCost=_defaultCost;
343 }
344
getDefaultCost() const345 float getDefaultCost() const
346 {
347 return defaultCost;
348 }
349
350 //! write/read
write(FileStorage & fs) const351 virtual void write(FileStorage& fs) const
352 {
353 fs << "name" << name_
354 << "dummies" << nDummies
355 << "default" << defaultCost;
356 }
357
read(const FileNode & fn)358 virtual void read(const FileNode& fn)
359 {
360 CV_Assert( (String)fn["name"] == name_ );
361 nDummies = (int)fn["dummies"];
362 defaultCost = (float)fn["default"];
363 }
364
365 protected:
366 String name_;
367 int nDummies;
368 float defaultCost;
369 };
370
buildCostMatrix(InputArray _descriptors1,InputArray _descriptors2,OutputArray _costMatrix)371 void ChiHistogramCostExtractorImpl::buildCostMatrix(InputArray _descriptors1, InputArray _descriptors2, OutputArray _costMatrix)
372 {
373 // size of the costMatrix with dummies //
374 Mat descriptors1=_descriptors1.getMat();
375 Mat descriptors2=_descriptors2.getMat();
376 int costrows = std::max(descriptors1.rows, descriptors2.rows)+nDummies;
377 _costMatrix.create(costrows, costrows, CV_32FC1);
378 Mat costMatrix=_costMatrix.getMat();
379
380 // Obtain copies of the descriptors //
381 cv::Mat scd1=descriptors1.clone();
382 cv::Mat scd2=descriptors2.clone();
383
384 // row normalization //
385 for(int i=0; i<scd1.rows; i++)
386 {
387 cv::Mat row = scd1.row(i);
388 scd1.row(i)/=(sum(row)[0]+FLT_EPSILON);
389 }
390 for(int i=0; i<scd2.rows; i++)
391 {
392 cv::Mat row = scd2.row(i);
393 scd2.row(i)/=(sum(row)[0]+FLT_EPSILON);
394 }
395
396 // Compute the Cost Matrix //
397 for(int i=0; i<costrows; i++)
398 {
399 for(int j=0; j<costrows; j++)
400 {
401 if (i<scd1.rows && j<scd2.rows)
402 {
403 float csum = 0;
404 for(int k=0; k<scd2.cols; k++)
405 {
406 float resta=scd1.at<float>(i,k)-scd2.at<float>(j,k);
407 float suma=scd1.at<float>(i,k)+scd2.at<float>(j,k);
408 csum += resta*resta/(FLT_EPSILON+suma);
409 }
410 costMatrix.at<float>(i,j)=csum/2;
411 }
412 else
413 {
414 costMatrix.at<float>(i,j)=defaultCost;
415 }
416 }
417 }
418 }
419
createChiHistogramCostExtractor(int nDummies,float defaultCost)420 Ptr <HistogramCostExtractor> createChiHistogramCostExtractor(int nDummies, float defaultCost)
421 {
422 return Ptr <HistogramCostExtractor>( new ChiHistogramCostExtractorImpl(nDummies, defaultCost) );
423 }
424
425 /*! */
426 class EMDL1HistogramCostExtractorImpl : public EMDL1HistogramCostExtractor
427 {
428 public:
429 /* Constructors */
EMDL1HistogramCostExtractorImpl(int _nDummies,float _defaultCost)430 EMDL1HistogramCostExtractorImpl(int _nDummies, float _defaultCost)
431 {
432 name_ = "HistogramCostExtractor.CHI";
433 nDummies=_nDummies;
434 defaultCost=_defaultCost;
435 }
436
437 /* Destructor */
~EMDL1HistogramCostExtractorImpl()438 ~EMDL1HistogramCostExtractorImpl()
439 {
440 }
441
442 //! the main operator
443 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix);
444
445 //! setters / getters
setNDummies(int _nDummies)446 void setNDummies(int _nDummies)
447 {
448 nDummies=_nDummies;
449 }
450
getNDummies() const451 int getNDummies() const
452 {
453 return nDummies;
454 }
455
setDefaultCost(float _defaultCost)456 void setDefaultCost(float _defaultCost)
457 {
458 defaultCost=_defaultCost;
459 }
460
getDefaultCost() const461 float getDefaultCost() const
462 {
463 return defaultCost;
464 }
465
466 //! write/read
write(FileStorage & fs) const467 virtual void write(FileStorage& fs) const
468 {
469 fs << "name" << name_
470 << "dummies" << nDummies
471 << "default" << defaultCost;
472 }
473
read(const FileNode & fn)474 virtual void read(const FileNode& fn)
475 {
476 CV_Assert( (String)fn["name"] == name_ );
477 nDummies = (int)fn["dummies"];
478 defaultCost = (float)fn["default"];
479 }
480
481 protected:
482 String name_;
483 int nDummies;
484 float defaultCost;
485 };
486
buildCostMatrix(InputArray _descriptors1,InputArray _descriptors2,OutputArray _costMatrix)487 void EMDL1HistogramCostExtractorImpl::buildCostMatrix(InputArray _descriptors1, InputArray _descriptors2, OutputArray _costMatrix)
488 {
489 // size of the costMatrix with dummies //
490 Mat descriptors1=_descriptors1.getMat();
491 Mat descriptors2=_descriptors2.getMat();
492 int costrows = std::max(descriptors1.rows, descriptors2.rows)+nDummies;
493 _costMatrix.create(costrows, costrows, CV_32F);
494 Mat costMatrix=_costMatrix.getMat();
495
496 // Obtain copies of the descriptors //
497 cv::Mat scd1=descriptors1.clone();
498 cv::Mat scd2=descriptors2.clone();
499
500 // row normalization //
501 for(int i=0; i<scd1.rows; i++)
502 {
503 cv::Mat row = scd1.row(i);
504 scd1.row(i)/=(sum(row)[0]+FLT_EPSILON);
505 }
506 for(int i=0; i<scd2.rows; i++)
507 {
508 cv::Mat row = scd2.row(i);
509 scd2.row(i)/=(sum(row)[0]+FLT_EPSILON);
510 }
511
512 // Compute the Cost Matrix //
513 for(int i=0; i<costrows; i++)
514 {
515 for(int j=0; j<costrows; j++)
516 {
517 if (i<scd1.rows && j<scd2.rows)
518 {
519 cv::Mat sig1(scd1.cols,1,CV_32F), sig2(scd2.cols,1,CV_32F);
520 sig1.col(0)=scd1.row(i).t();
521 sig2.col(0)=scd2.row(j).t();
522 costMatrix.at<float>(i,j) = cv::EMDL1(sig1, sig2);
523 }
524 else
525 {
526 costMatrix.at<float>(i,j) = defaultCost;
527 }
528 }
529 }
530 }
531
createEMDL1HistogramCostExtractor(int nDummies,float defaultCost)532 Ptr <HistogramCostExtractor> createEMDL1HistogramCostExtractor(int nDummies, float defaultCost)
533 {
534 return Ptr <HistogramCostExtractor>( new EMDL1HistogramCostExtractorImpl(nDummies, defaultCost) );
535 }
536
537 } // cv
538