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