00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Features/JunctionHOG.H"
00040 #include "SIFT/FeatureVector.H"
00041
00042 JunctionHOG::JunctionHOG() :
00043 HistogramOfGradients(),
00044 itsNeighborDistance(0.0)
00045 {
00046
00047 }
00048
00049 JunctionHOG::JunctionHOG(bool normalize, Dims cellDims, bool fixedDims, int numOrientations, bool signedOrient, int numContinuityBins, float neighborDistance) :
00050 HistogramOfGradients(normalize,cellDims,fixedDims,numOrientations,signedOrient),
00051 itsContinuityBins(numContinuityBins),
00052 itsNeighborDistance(neighborDistance)
00053 {
00054 if(neighborDistance > 0)
00055 {
00056 for(int t=0;t<8;t++)
00057 {
00058 float ang=float(t)/8.0*M_PI;
00059 initializeNeighbors(itsRelevantNeighbors[t],itsPerpAngles[t],itsParallelAngles[t],ang);
00060 }
00061 }
00062 }
00063
00064 JunctionHOG::~JunctionHOG()
00065 {
00066 }
00067
00068
00069 std::vector<float> JunctionHOG::createHistogramFromGradient(const Image<float>& gradmag, const Image<float>& gradang)
00070 {
00071 std::vector<float> ret = HistogramOfGradients::createHistogramFromGradient(gradmag,gradang);
00072 std::vector<float> tmp = calculateJunctionHistogram(gradmag,gradang);
00073 ret.insert(ret.end(),tmp.begin(),tmp.end());
00074 return ret;
00075 }
00076
00077
00078 void JunctionHOG::initializeNeighbors(std::vector<Point2D<int> >& neighbors, std::vector<float>& perpAngles, std::vector<float>& parallelAngles, float angle)
00079 {
00080
00081
00082
00083
00084
00085 float lcprot=atan2(0,-1)+angle;
00086 Point2D<int> lcp=Point2D<int>(round(cos(lcprot)*itsNeighborDistance),round(sin(lcprot)*itsNeighborDistance));
00087 float lca=0+angle;
00088 lca=(lca>M_PI) ? lca-M_PI : lca;
00089 float lcaPerp=(lca>M_PI/2.0) ? lca-M_PI/2.0 : lca+M_PI/2.0;
00090 neighbors.push_back(lcp); parallelAngles.push_back(lca); perpAngles.push_back(lcaPerp);
00091
00092 float luprot=atan2(-1,-1)+angle;
00093 Point2D<int> lup=Point2D<int>(round(cos(luprot)*itsNeighborDistance),round(sin(luprot)*itsNeighborDistance));
00094 float lua=M_PI/4.0+angle;
00095 lua=(lua>M_PI) ? lua-M_PI : lua;
00096 float luaPerp=(lua>M_PI/2.0) ? lua-M_PI/2.0 : lua+M_PI/2.0;
00097 neighbors.push_back(lup); parallelAngles.push_back(lua); perpAngles.push_back(luaPerp);
00098
00099 float llprot=atan2(1,-1)+angle;
00100 Point2D<int> llp = Point2D<int>(round(cos(llprot)*itsNeighborDistance),round(sin(llprot)*itsNeighborDistance));
00101 float lla=M_PI-M_PI/4.0+angle;
00102 lla=(lla>M_PI) ? lla-M_PI : lla;
00103 float llaPerp=(lla>M_PI/2.0) ? lla-M_PI/2.0 : lla+M_PI/2.0;
00104 neighbors.push_back(llp); parallelAngles.push_back(lla); perpAngles.push_back(llaPerp);
00105
00106
00107 float rcprot=atan2(0,1)+angle;
00108 Point2D<int> rcp=Point2D<int>(round(cos(rcprot)*itsNeighborDistance),round(sin(rcprot)*itsNeighborDistance));
00109 float rca=0+angle;
00110 rca=(rca>M_PI) ? rca-M_PI : rca;
00111 float rcaPerp=(rca>M_PI/2.0) ? rca-M_PI/2.0 : rca+M_PI/2.0;
00112 neighbors.push_back(rcp); parallelAngles.push_back(rca); perpAngles.push_back(rcaPerp);
00113
00114 float ruprot=atan2(-1,1)+angle;
00115 Point2D<int> rup=Point2D<int>(round(cos(ruprot)*itsNeighborDistance),round(sin(ruprot)*itsNeighborDistance));
00116 float rua=M_PI/4.0+angle;
00117 rua=(rua>M_PI) ? rua-M_PI : rua;
00118 float ruaPerp=(rua>M_PI/2.0) ? rua-M_PI/2.0 : rua+M_PI/2.0;
00119 neighbors.push_back(rup); parallelAngles.push_back(rua); perpAngles.push_back(ruaPerp);
00120
00121 float rlprot=atan2(1,1)+angle;
00122 Point2D<int> rlp = Point2D<int>(round(cos(rlprot)*itsNeighborDistance),round(sin(rlprot)*itsNeighborDistance));
00123 float rla=M_PI-M_PI/4.0+angle;
00124 rla=(rla>M_PI) ? rla-M_PI : rla;
00125 float rlaPerp=(rla>M_PI/2.0) ? rla-M_PI/2.0 : rla+M_PI/2.0;
00126 neighbors.push_back(rlp); parallelAngles.push_back(rla); perpAngles.push_back(rlaPerp);
00127
00128 }
00129
00130
00131 std::vector<float> JunctionHOG::calculateJunctionHistogram(Image<float> gradmag, Image<float> gradang)
00132 {
00133
00134 Dims cells;
00135 if(itsFixedDims)
00136 cells = itsCellDims;
00137 else
00138 cells = Dims(int(round(float(gradmag.getWidth())/itsCellDims.w())),int(round(float(gradmag.getHeight())/itsCellDims.h())));
00139
00140 const int w=gradmag.getWidth(), h=gradmag.getHeight();
00141
00142
00143 FeatureVector cntfv = FeatureVector(cells.w(),cells.h(),itsContinuityBins,true);
00144 Image<float>::const_iterator gmg = gradmag.begin(), gang = gradang.begin();
00145
00146
00147 for (int i = 0; i < w; i ++)
00148 {
00149
00150 for (int j = 0; j < h; j ++)
00151 {
00152
00153 int oriBin=floor(((*gang < 0) ? *gang + M_PI : *gang)/M_PI*8);
00154 float continuityStrength=0;
00155 float continuityParallel=0;
00156 int validNeighbors = 0;
00157
00158 for(size_t n=0;n<itsRelevantNeighbors[oriBin].size();n++)
00159 {
00160 Point2D<int> neigh = itsRelevantNeighbors[oriBin][n];
00161 if(!gradmag.coordsOk(i+neigh.i,j+neigh.j))
00162 {
00163
00164 continue;
00165 }
00166 int offset=neigh.i*h+neigh.j;
00167
00168 float unsignedNeighAng=(gang[offset] < 0) ? gang[offset] + M_PI : gang[offset];
00169
00170 continuityStrength += gmg[offset];
00171
00172 float ctrParallel=itsParallelAngles[oriBin][n];
00173
00174 continuityParallel += cos(fabs(ctrParallel-unsignedNeighAng));
00175
00176 float ctrPerp=itsPerpAngles[oriBin][n];
00177 continuityParallel -= cos(fabs(ctrPerp-unsignedNeighAng));
00178 ASSERT(!isnan(continuityParallel) && !isnan(continuityStrength));
00179 validNeighbors++;
00180 }
00181
00182 if(itsNormalize && validNeighbors>0)
00183 {
00184 continuityParallel/=float(validNeighbors);
00185 continuityStrength/=float(validNeighbors);
00186 }
00187 float continuityAng = atan2(continuityParallel,continuityStrength);
00188 float continuityMag = sqrt(continuityParallel*continuityParallel+continuityStrength*continuityStrength);
00189
00190
00191 const float xf = float(i)/float(w)*cells.w();
00192 const float yf = float(j)/float(h)*cells.h();
00193
00194 addToBin(xf,yf,continuityAng,continuityMag,true,cntfv);
00195 gmg++;
00196 gang++;
00197 }
00198 }
00199
00200
00201 std::vector<float> hist;
00202 if(itsNormalize)
00203 hist = normalizeFeatureVector(cntfv);
00204 else
00205 hist = cntfv.getFeatureVector();
00206 LINFO("Calculated Junction Histogram of size %Zu",hist.size());
00207 return hist;
00208 }
00209