00001
00002
00003
00004
00005
00006
00007
00008 #include "HoughAccumulator.h"
00009 #include "Architecture/Config/Config.h"
00010
00011 #include <sstream>
00012 #include <algorithm>
00013
00014 #define THIS HoughAccumulator
00015
00016 THIS::THIS()
00017 {
00018 m_ScaleBins = Config::getInt( "ObjectRecognition.HoughClustering.iScaleBins" );
00019 m_OrientationBins = Config::getInt( "ObjectRecognition.HoughClustering.iOrientationBins" );
00020 m_XLocationBins = Config::getInt( "ObjectRecognition.HoughClustering.iXLocationBins" );
00021 m_YLocationBins = Config::getInt( "ObjectRecognition.HoughClustering.iYLocationBins" );
00022
00023 m_AccumulatorSize = m_ScaleBins*m_OrientationBins*m_XLocationBins*m_YLocationBins;
00024 m_AccumulatorArray = new std::list< KeyPointMatch >[m_AccumulatorSize];
00025
00026
00027 for (unsigned i = 0; i < m_AccumulatorSize; i++)
00028 {
00029 m_AccumulatorArray[i].clear();
00030 }
00031 }
00032
00033 std::vector< std::list< KeyPointMatch > > THIS::getClusteredMatches()
00034 {
00035 unsigned int threshold = Config::getInt( "ObjectRecognition.HoughClustering.iMinMatchNumber" );
00036
00037 std::vector< std::list< KeyPointMatch> > newMatches;
00038
00039 for(unsigned int i=0;i<m_AccumulatorSize;++i)
00040 {
00041 std::list< KeyPointMatch > entry = m_AccumulatorArray[i];
00042 if(entry.size()>=threshold)
00043 {
00044 m_Log << "(+";
00045 newMatches.push_back(entry);
00046 }
00047 else
00048 {
00049 m_Log << "(-";
00050 m_AccumulatorArray[i].clear();
00051 }
00052 m_Log << "->" << i << "/" << entry.size() << ")";
00053 }
00054
00055
00056 std::sort(newMatches.begin(), newMatches.end(), compareMatchList());
00057
00058 return newMatches;
00059 }
00060
00061 std::vector< std::list< KeyPointMatch > > THIS::getMaximumMatches()
00062 {
00063 unsigned int threshold = Config::getInt( "ObjectRecognition.HoughClustering.iMinMatchNumber" );
00064
00065 std::vector< std::list< KeyPointMatch> > newMatches;
00066
00067 for(int s=0;s<m_ScaleBins;++s)
00068 {
00069 for(int r=0;r<m_OrientationBins;++r)
00070 {
00071 for(int x=0;x<m_XLocationBins;++x)
00072 {
00073 for(int y=0;y<m_YLocationBins;++y)
00074 {
00075 std::list< KeyPointMatch > entry = m_AccumulatorArray[getIndex(s,r,x,y)];
00076 bool isMax = true;
00077 if(entry.size()>=threshold)
00078 {
00079
00080 for(int sN=s-1;sN>=0 && sN<s+1 && sN<m_ScaleBins;++sN)
00081 {
00082 for(int rN=r-1;rN>=0 && rN<r+1 && rN<m_OrientationBins && isMax;++rN)
00083 {
00084 for(int xN=x-1;xN>=0 && xN<x+1 && xN<m_XLocationBins && isMax;++xN)
00085 {
00086 for(int yN=y-1;yN>=0 && yN<y+1 && yN<m_YLocationBins && isMax;++yN)
00087 {
00088
00089 if(sN!=s && rN!=r && xN !=x && yN!=y)
00090 {
00091 if(m_AccumulatorArray[getIndex(sN,rN,xN,yN)].size()>=entry.size())
00092 {
00093 isMax=false;
00094 }
00095 }
00096 }
00097 }
00098 }
00099 }
00100 if( isMax)
00101 {
00102 m_Log << "(+";
00103 newMatches.push_back(entry);
00104 }
00105 else
00106 {
00107 m_Log << "(-";
00108 m_AccumulatorArray[getIndex(s,r,x,y)].clear();
00109 }
00110 }
00111 else
00112 {
00113 m_Log << "(-";
00114 m_AccumulatorArray[getIndex(s,r,x,y)].clear();
00115 }
00116 m_Log << "->" << getIndex(s,r,x,y) << "/" << entry.size() << ")";
00117 }
00118 }
00119 }
00120 }
00121
00122 std::sort(newMatches.begin(), newMatches.end(), compareMatchList());
00123 return newMatches;
00124 }
00125
00126 unsigned int THIS::getIndex(int scaleIndex, int orientationIndex, int xIndex, int yIndex)
00127 {
00128 return scaleIndex
00129 + orientationIndex*m_ScaleBins
00130 + xIndex*(m_ScaleBins*m_OrientationBins)
00131 + yIndex*(m_ScaleBins*m_OrientationBins*m_XLocationBins);
00132 }
00133
00134 bool THIS::incrAccumulatorValue(int scaleIndex, int orientationIndex, int xIndex, int yIndex, KeyPointMatch match)
00135 {
00136 if(verifyAccumulatorIndex(scaleIndex,orientationIndex,xIndex,yIndex))
00137 {
00138 m_AccumulatorArray[getIndex(scaleIndex,orientationIndex,xIndex,yIndex)].push_back(match);
00139 return true;
00140 }
00141 else
00142 {
00143 return false;
00144 }
00145 }
00146
00147 bool THIS::getAccumulatorValue(int scaleIndex, int orientationIndex, int xIndex, int yIndex, unsigned int& value)
00148 {
00149 if(verifyAccumulatorIndex(scaleIndex,orientationIndex,xIndex,yIndex))
00150 {
00151 value = m_AccumulatorArray[getIndex(scaleIndex,orientationIndex,xIndex,yIndex)].size();
00152 return true;
00153 }
00154 else
00155 {
00156 value = 0;
00157 return false;
00158 }
00159 }
00160
00161 void THIS::resetAccumulator()
00162 {
00163 for (unsigned i = 0; i < m_AccumulatorSize; i++)
00164 {
00165 m_AccumulatorArray[i].clear();
00166 }
00167 }
00168
00169 bool THIS::verifyAccumulatorIndex(int scale, int orientation, int xLocation, int yLocation)
00170 {
00171
00172 if(scale<m_ScaleBins && orientation<m_OrientationBins && xLocation<m_XLocationBins && yLocation<m_YLocationBins &&
00173 scale>=0 && orientation>=0 && xLocation>=0 && yLocation>=0)
00174 {
00175 return true;
00176 }
00177 else
00178 {
00179 return false;
00180 }
00181 }
00182
00183 float THIS::getVariance()
00184 {
00185 float sum = 0.0;
00186 float sumSquare = 0.0;
00187 int n = m_AccumulatorArray->size();
00188
00189 for(int i=0;i<n;++i)
00190 {
00191 int features = m_AccumulatorArray[i].size();
00192 sumSquare+=(features*features);
00193 sum+=features;
00194 }
00195
00196 return (sumSquare/n-((sum/n)*(sum/n)));
00197 }
00198
00199 unsigned int THIS::getMaxAccumulatorValue()
00200 {
00201 float max=0;
00202 for (unsigned i = 0; i < m_AccumulatorSize; i++)
00203 {
00204 int value = m_AccumulatorArray[i].size();
00205 if ( value > max )
00206 {
00207 max = value;
00208 }
00209 }
00210
00211 return max;
00212 }
00213
00214 void THIS::getImage( cv::Mat& target )
00215 {
00216
00217
00218
00219
00220
00221
00222 float norm = 255.0 / getMaxAccumulatorValue();
00223
00224 int w = (m_ScaleBins+1)*m_XLocationBins;
00225 int h = (m_OrientationBins+1)*m_YLocationBins;
00226 target.create( h, w, CV_8UC3 );
00227
00228 for ( int y=0; y<h; y++ )
00229 {
00230 for ( int x=0; x<w; x++ )
00231 {
00232 int scaleIndex = x % (m_ScaleBins+1);
00233 int orientationIndex = y % (m_OrientationBins+1);
00234 if ( ( scaleIndex >= m_ScaleBins ) || ( orientationIndex >= m_OrientationBins ) )
00235 {
00236 target.at<cv::Vec3b>(y,x) = cv::Vec3b(0,0,255);
00237 continue;
00238 }
00239 int xIndex = x / (m_ScaleBins+1);
00240 int yIndex = y / (m_OrientationBins+1);
00241
00242 unsigned int histValue;
00243
00244 getAccumulatorValue(scaleIndex, orientationIndex, xIndex, yIndex, histValue);
00245
00246 if ( histValue == 0 )
00247 {
00248 target.at<cv::Vec3b>(y,x) = cv::Vec3b(0,0,0);
00249 }
00250 else
00251 {
00252 target.at<cv::Vec3b>(y,x) = cv::Vec3b(histValue * norm,histValue * norm,histValue * norm);
00253 }
00254 }
00255 }
00256 }
00257
00258 THIS::~THIS()
00259 {
00260 delete[] m_AccumulatorArray;
00261 }
00262
00263 #undef THIS