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 */ 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 */ 61 ~NormHistogramCostExtractorImpl() 62 { 63 } 64 65 //! the main operator 66 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix); 67 68 //! Setters/Getters 69 void setNDummies(int _nDummies) 70 { 71 nDummies=_nDummies; 72 } 73 74 int getNDummies() const 75 { 76 return nDummies; 77 } 78 79 void setDefaultCost(float _defaultCost) 80 { 81 defaultCost=_defaultCost; 82 } 83 84 float getDefaultCost() const 85 { 86 return defaultCost; 87 } 88 89 virtual void setNormFlag(int _flag) 90 { 91 flag=_flag; 92 } 93 94 virtual int getNormFlag() const 95 { 96 return flag; 97 } 98 99 //! write/read 100 virtual void write(FileStorage& fs) const 101 { 102 fs << "name" << name_ 103 << "flag" << flag 104 << "dummies" << nDummies 105 << "default" << defaultCost; 106 } 107 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 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 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 */ 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 */ 186 ~EMDHistogramCostExtractorImpl() 187 { 188 } 189 190 //! the main operator 191 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix); 192 193 //! Setters/Getters 194 void setNDummies(int _nDummies) 195 { 196 nDummies=_nDummies; 197 } 198 199 int getNDummies() const 200 { 201 return nDummies; 202 } 203 204 void setDefaultCost(float _defaultCost) 205 { 206 defaultCost=_defaultCost; 207 } 208 209 float getDefaultCost() const 210 { 211 return defaultCost; 212 } 213 214 virtual void setNormFlag(int _flag) 215 { 216 flag=_flag; 217 } 218 219 virtual int getNormFlag() const 220 { 221 return flag; 222 } 223 224 //! write/read 225 virtual void write(FileStorage& fs) const 226 { 227 fs << "name" << name_ 228 << "flag" << flag 229 << "dummies" << nDummies 230 << "default" << defaultCost; 231 } 232 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 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 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 */ 314 ChiHistogramCostExtractorImpl(int _nDummies, float _defaultCost) 315 { 316 name_ = "HistogramCostExtractor.CHI"; 317 nDummies=_nDummies; 318 defaultCost=_defaultCost; 319 } 320 321 /* Destructor */ 322 ~ChiHistogramCostExtractorImpl() 323 { 324 } 325 326 //! the main operator 327 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix); 328 329 //! setters / getters 330 void setNDummies(int _nDummies) 331 { 332 nDummies=_nDummies; 333 } 334 335 int getNDummies() const 336 { 337 return nDummies; 338 } 339 340 void setDefaultCost(float _defaultCost) 341 { 342 defaultCost=_defaultCost; 343 } 344 345 float getDefaultCost() const 346 { 347 return defaultCost; 348 } 349 350 //! write/read 351 virtual void write(FileStorage& fs) const 352 { 353 fs << "name" << name_ 354 << "dummies" << nDummies 355 << "default" << defaultCost; 356 } 357 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 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 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 */ 430 EMDL1HistogramCostExtractorImpl(int _nDummies, float _defaultCost) 431 { 432 name_ = "HistogramCostExtractor.CHI"; 433 nDummies=_nDummies; 434 defaultCost=_defaultCost; 435 } 436 437 /* Destructor */ 438 ~EMDL1HistogramCostExtractorImpl() 439 { 440 } 441 442 //! the main operator 443 virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix); 444 445 //! setters / getters 446 void setNDummies(int _nDummies) 447 { 448 nDummies=_nDummies; 449 } 450 451 int getNDummies() const 452 { 453 return nDummies; 454 } 455 456 void setDefaultCost(float _defaultCost) 457 { 458 defaultCost=_defaultCost; 459 } 460 461 float getDefaultCost() const 462 { 463 return defaultCost; 464 } 465 466 //! write/read 467 virtual void write(FileStorage& fs) const 468 { 469 fs << "name" << name_ 470 << "dummies" << nDummies 471 << "default" << defaultCost; 472 } 473 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 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 532 Ptr <HistogramCostExtractor> createEMDL1HistogramCostExtractor(int nDummies, float defaultCost) 533 { 534 return Ptr <HistogramCostExtractor>( new EMDL1HistogramCostExtractorImpl(nDummies, defaultCost) ); 535 } 536 537 } // cv 538