$search
00001 /* 00002 * Copyright (c) 2010, Dejan Pangercic <dejan.pangercic@cs.tum.edu>, 00003 Vladimir Haltakov <vladimir.haltakov@gmail.com> 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * * Neither the name of Willow Garage, Inc. nor the names of its 00015 * contributors may be used to endorse or promote products derived from 00016 * this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00028 * POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 #ifndef ODU_FINDER_COMMON_H_ 00031 #define ODU_FINDER_COMMON_H_ 00032 #include <ANN/ANN.h> 00033 #include <vocabulary_tree/simple_kmeans.h> 00034 #include <vocabulary_tree/vocabulary_tree.h> 00035 #include <vocabulary_tree/database.h> 00036 #include <vocabulary_tree/tree_builder.h> 00037 #include <vocabulary_tree/simple_kmeans.h> 00038 00039 #include <siftfast/siftfast.h> 00040 00041 /* 00042 * Define standard C methods and C++ classes that are common to all methods 00043 */ 00044 namespace odu_finder 00045 { 00046 00047 double logsig(double x) 00048 { 00049 return 1.0 / (1.0 + exp(-x)); 00050 } 00051 00063 int cluster_points(ANNpointArray points, int points_count, 00064 std::vector<int>& membership, float r_max = 00065 600.0f, float r_min = 200.0f, float A = 800.0f, float K = 0.02f) 00066 { 00067 // adaptive radius calculation 00068 // (see paper Fast and Robust Object Detection in Household Environments 00069 // Using Vocabulary Trees with SIFT Descriptors by Pangercic and Haltakov) 00070 double radius = (1 - logsig((points_count - A) * K)) * (r_max - r_min) + r_min; 00071 //radius = (1-logsig((points_count-800.0)/50.0))*300 + 300; 00072 printf("\n\n NEW RADIUS = %f\n\n", radius); 00073 ANNidxArray nnIdx = new ANNidx[points_count]; 00074 // ANNdistArray dists = new ANNdist[points_count]; 00075 ANNkd_tree* kdTree = new ANNkd_tree(points, points_count, 2); 00076 membership.assign(points_count, -1); 00077 int last_unassigned_id = 0; 00078 int current_cluster = 0; 00079 00080 while (last_unassigned_id < points_count) 00081 { 00082 std::vector<int> points_stack; 00083 points_stack.push_back(last_unassigned_id); 00084 while (points_stack.size() > 0) 00085 { 00086 // printf("STACK SIZE = %d\n", points_stack.size()); 00087 int current_point_id = points_stack.back(); 00088 points_stack.pop_back(); 00089 membership[current_point_id] = current_cluster; 00090 int points_found = kdTree->annkFRSearch(points[current_point_id], 00091 radius, points_count, nnIdx); 00092 // printf("Neighbours found = %d\n", points_found); 00093 int newPointsCount = 0; 00094 for (int i = 0; i < points_found; ++i) 00095 if (membership[nnIdx[i]] == -1) 00096 ++newPointsCount; 00097 00098 if (newPointsCount > 3) 00099 { 00100 for (int i = 0; i < points_found; ++i) 00101 if (membership[nnIdx[i]] == -1) 00102 points_stack.push_back(nnIdx[i]); 00103 } 00104 } 00105 00106 ++current_cluster; 00107 ++last_unassigned_id; 00108 while (last_unassigned_id < points_count 00109 && membership[last_unassigned_id] != -1) 00110 ++last_unassigned_id; 00111 } 00112 00113 delete[] nnIdx; 00114 // delete [] dists; 00115 delete kdTree; 00116 annClose(); 00117 return current_cluster; 00118 } 00119 00123 class KeypointExt 00124 { 00125 public: 00126 Keypoint keypoint; 00127 vt::Word word; 00128 unsigned int cluster; 00129 00130 KeypointExt(Keypoint keypoint, vt::Word word, unsigned int cluster = 0): 00131 keypoint(keypoint), 00132 word(word), 00133 cluster(cluster) 00134 {} 00135 }; 00136 00137 bool compare_keypoint_ext(KeypointExt* k1, KeypointExt* k2) 00138 { 00139 return (k1->word < k2->word); 00140 } 00141 00142 bool compare_pairs(std::pair<uint32_t, float> p1, std::pair<uint32_t, float> p2) 00143 { 00144 return (p1.second > p2.second); 00145 } 00146 00147 bool compare_pairs2(std::pair<std::string, int> p1, std::pair<std::string, int> p2) 00148 { 00149 return (p1.second > p2.second); 00150 } 00151 00152 } 00153 00154 #endif //#ifndef ODU_FINDER_COMMON_H_