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 class HausdorffDistanceExtractorImpl : public HausdorffDistanceExtractor 48 { 49 public: 50 /* Constructor */ 51 HausdorffDistanceExtractorImpl(int _distanceFlag = NORM_L1, float _rankProportion=0.6) 52 { 53 distanceFlag = _distanceFlag; 54 rankProportion = _rankProportion; 55 name_ = "ShapeDistanceExtractor.HAU"; 56 } 57 58 /* Destructor */ 59 ~HausdorffDistanceExtractorImpl() 60 { 61 } 62 63 //! the main operator 64 virtual float computeDistance(InputArray contour1, InputArray contour2); 65 66 //! Setters/Getters 67 virtual void setDistanceFlag(int _distanceFlag) {distanceFlag=_distanceFlag;} 68 virtual int getDistanceFlag() const {return distanceFlag;} 69 70 virtual void setRankProportion(float _rankProportion) 71 { 72 CV_Assert((_rankProportion>0) && (_rankProportion<=1)); 73 rankProportion=_rankProportion; 74 } 75 virtual float getRankProportion() const {return rankProportion;} 76 77 //! write/read 78 virtual void write(FileStorage& fs) const 79 { 80 fs << "name" << name_ 81 << "distance" << distanceFlag 82 << "rank" << rankProportion; 83 } 84 85 virtual void read(const FileNode& fn) 86 { 87 CV_Assert( (String)fn["name"] == name_ ); 88 distanceFlag = (int)fn["distance"]; 89 rankProportion = (float)fn["rank"]; 90 } 91 92 private: 93 int distanceFlag; 94 float rankProportion; 95 96 protected: 97 String name_; 98 }; 99 100 //! Hausdorff distance for a pair of set of points 101 static float _apply(const Mat &set1, const Mat &set2, int distType, double propRank) 102 { 103 // Building distance matrix // 104 Mat disMat(set1.cols, set2.cols, CV_32F); 105 int K = int(propRank*(disMat.rows-1)); 106 107 for (int r=0; r<disMat.rows; r++) 108 { 109 for (int c=0; c<disMat.cols; c++) 110 { 111 Point2f diff = set1.at<Point2f>(0,r)-set2.at<Point2f>(0,c); 112 disMat.at<float>(r,c) = (float)norm(Mat(diff), distType); 113 } 114 } 115 116 Mat shortest(disMat.rows,1,CV_32F); 117 for (int ii=0; ii<disMat.rows; ii++) 118 { 119 Mat therow = disMat.row(ii); 120 double mindis; 121 minMaxIdx(therow, &mindis); 122 shortest.at<float>(ii,0) = float(mindis); 123 } 124 Mat sorted; 125 cv::sort(shortest, sorted, SORT_EVERY_ROW | SORT_DESCENDING); 126 return sorted.at<float>(K,0); 127 } 128 129 float HausdorffDistanceExtractorImpl::computeDistance(InputArray contour1, InputArray contour2) 130 { 131 Mat set1=contour1.getMat(), set2=contour2.getMat(); 132 if (set1.type() != CV_32F) 133 set1.convertTo(set1, CV_32F); 134 if (set2.type() != CV_32F) 135 set2.convertTo(set2, CV_32F); 136 CV_Assert((set1.channels()==2) && (set1.cols>0)); 137 CV_Assert((set2.channels()==2) && (set2.cols>0)); 138 return std::max( _apply(set1, set2, distanceFlag, rankProportion), 139 _apply(set2, set1, distanceFlag, rankProportion) ); 140 } 141 142 Ptr <HausdorffDistanceExtractor> createHausdorffDistanceExtractor(int distanceFlag, float rankProp) 143 { 144 return Ptr<HausdorffDistanceExtractor>(new HausdorffDistanceExtractorImpl(distanceFlag, rankProp)); 145 } 146 147 } // cv 148