Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages
hugin_base/vigra_ext/InterestPoints.h
Go to the documentation of this file.00001 // -*- c-basic-offset: 4 -*- 00002 00027 #ifndef VIGRA_EXT_INTEREST_POINTS 00028 #define VIGRA_EXT_INTEREST_POINTS 00029 00030 #include <vector> 00031 #include <map> 00032 00033 #include <vigra/error.hxx> 00034 #include <vigra/impex.hxx> 00035 #include <vigra/cornerdetection.hxx> 00036 #include <vigra/localminmax.hxx> 00037 #include <vigra/diff2d.hxx> 00038 00039 namespace vigra_ext 00040 { 00041 00042 template <class ImageIter, class ImageAcc> 00043 void findInterestPointsOnGrid(vigra::triple<ImageIter, ImageIter, ImageAcc> img, double scale, 00044 unsigned nPoints, unsigned grid, std::vector<std::multimap<double, vigra::Diff2D> > &allPoints 00045 ) 00046 { 00048 // find interesting corners using harris corner detector 00049 00050 vigra::Diff2D size2 = img.second - img.first; 00051 vigra::Size2D size(size2.x, size2.y); 00052 00053 for (unsigned party=0;party<grid;party++) { 00054 for (unsigned partx=0;partx<grid;partx++) { 00055 std::multimap<double, vigra::Diff2D> points; 00056 DEBUG_TRACE("selecting points for grid partition (" << partx << ", " << party << ")"); 00057 // select the nPoints with the highest response 00058 // some distribution criteria might be useful, too 00059 // to avoid clustering all points on a single object. 00060 00061 // run corner detector only in current sub-region (saves a lot of memory for big images) 00062 vigra::Rect2D rect(partx*size.x/grid, party*size.y/grid, 00063 (partx+1)*size.x/grid, (party+1)*size.y/grid); 00064 00065 rect &= vigra::Rect2D(size); 00066 00067 vigra::BImage leftCorners(rect.size(), vigra::UInt8(0)); 00068 vigra::FImage leftCornerResponse(rect.size()); 00069 00070 DEBUG_DEBUG("running corner detector. nPoints: " << nPoints << ", scale: " << scale ); 00071 // find corner response at scale scale 00072 vigra::cornerResponseFunction(srcIterRange(img.first + rect.upperLeft(), img.first + rect.lowerRight(), img.third), 00073 vigra::destImage(leftCornerResponse), 00074 scale); 00075 00076 // find local maxima of corner response, mark with 1 00077 vigra::localMaxima(vigra::srcImageRange(leftCornerResponse), vigra::destImage(leftCorners), 255); 00078 00079 double minResponse = 0; 00080 // sample grid on img1 and try to add ctrl points 00081 for (int y=0; y < rect.height(); y++ ) { 00082 for (int x=0; x < rect.width(); x++ ) { 00083 if (leftCorners(x,y) == 0) { 00084 continue; 00085 } 00086 double resp = leftCornerResponse(x,y); 00087 if (resp > minResponse) { 00088 // add to point map 00089 points.insert(std::make_pair(resp, vigra::Diff2D(x,y) + rect.upperLeft())); 00090 // if we have reached the maximum 00091 // number of points, increase the threshold, to avoid 00092 // growing the points map too much. 00093 // extract more than nPoints, because some might be bad 00094 // and cannot be matched with the other image. 00095 if (points.size() > nPoints) { 00096 // remove the point with the lowest corner response. 00097 // leftCorners(points.begin()->second.x,points.begin()->second.y)=0; 00098 points.erase(points.begin()); 00099 // use new threshold for next selection. 00100 minResponse = points.begin()->first; 00101 } 00102 } 00103 } 00104 } 00105 00106 allPoints.push_back(points); 00107 } 00108 } 00109 } 00110 00111 } // namespace 00112 00113 #endif
1.3.9.1