OriChamferMatching.C
Go to the documentation of this file.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 #ifndef ORICHAMFERMATCHING_C_DEFINED
00040 #define ORICHAMFERMATCHING_C_DEFINED
00041
00042 #include "FeatureMatching/OriChamferMatching.H"
00043 #include "Image/DrawOps.H"
00044 #include "Image/MathOps.H"
00045 #include "GUI/DebugWin.H"
00046 #include "Util/FastMathFunctions.H"
00047
00048 #include <stdio.h>
00049
00050
00051 OriChamferMatching::OriChamferMatching() :
00052 itsUseOpenCV(false),
00053 itsMaxCost(100)
00054 {
00055 }
00056
00057
00058 OriChamferMatching::OriChamferMatching(const std::vector<Line>& inLines,
00059 const int numDirections,
00060 const double oriCost,
00061 const Dims dims) :
00062 itsUseOpenCV(false),
00063 itsMaxCost(100)
00064 {
00065 setLines(inLines, numDirections, oriCost, dims);
00066 };
00067
00068
00069 void OriChamferMatching::setLines(const std::vector<Line>& inLines,
00070 const int numDirections,
00071 const double oriCost,
00072 const Dims dims)
00073 {
00074 itsLines = inLines;
00075
00076
00077
00078 itsOriDistImages = ImageSet<float>(numDirections, dims);
00079
00080 for(uint i=0; i<inLines.size(); i++)
00081 {
00082 Line l = inLines[i];
00083 l.quantize(numDirections);
00084
00085 int oriIdx = l.getDirectionIdx();
00086 if (oriIdx < 0 || oriIdx > numDirections)
00087 LFATAL("OriIdx %i is out of range %i", oriIdx, numDirections);
00088
00089
00090 drawLine(itsOriDistImages[oriIdx], (Point2D<int>)l.getP1(),
00091 (Point2D<int>)l.getP2(), 255.0F);
00092 }
00093
00094
00095 for(int oriIdx = 0; oriIdx < numDirections; oriIdx++)
00096 {
00097 if (itsUseOpenCV)
00098 {
00099 Image<byte> linesImg = binaryReverse(itsOriDistImages[oriIdx], 255.0F);
00100 linesImg.deepcopy();
00101 cvDistTransform(img2ipl(linesImg), img2ipl(itsOriDistImages[oriIdx]), CV_DIST_L2, 5);
00102 } else {
00103
00104 itsOriDistImages[oriIdx] = chamfer34(itsOriDistImages[oriIdx]);
00105 }
00106
00107 }
00108
00109
00110 updateOriCost(oriCost);
00111 buildIntegralDistances();
00112
00113
00114
00115
00116
00117
00118
00119 };
00120
00121 void OriChamferMatching::updateOriCost(const double oriCost)
00122 {
00123 Dims d = itsOriDistImages[0].getDims();
00124
00125 int size=d.w()*d.h();
00126 const int numDirections = itsOriDistImages.size();
00127
00128 for(int k=0; k<size; k++)
00129 {
00130 std::vector<float> costs(numDirections);
00131
00132 for(uint i=0; i<costs.size(); i++)
00133 {
00134 costs[i] = itsOriDistImages[i][k];
00135 if (costs[i] > itsMaxCost)
00136 costs[i] = itsMaxCost;
00137 }
00138
00139
00140 if (costs[0] > costs[numDirections-1] + oriCost)
00141 costs[0] = costs[numDirections-1] + oriCost;
00142
00143 for (int i=1 ; i<numDirections; i++)
00144 {
00145 if (costs[i] > costs[i-1] + oriCost)
00146 costs[i] = costs[i-1] + oriCost;
00147 }
00148
00149 if (costs[0] > costs[numDirections-1] + oriCost)
00150 costs[0] = costs[numDirections-1] + oriCost;
00151
00152 for (int i=1 ; i<numDirections ; i++)
00153 {
00154 if (costs[i] > costs[i-1] + oriCost)
00155 costs[i] = costs[i-1] + oriCost;
00156 else
00157 break;
00158 }
00159
00160
00161 if (costs[numDirections-1] > costs[0] + oriCost)
00162 costs[numDirections-1] = costs[0] + oriCost;
00163 for (int i=numDirections-1 ; i>0 ; i--)
00164 {
00165 if (costs[i-1] > costs[i] + oriCost)
00166 costs[i-1] = costs[i] + oriCost;
00167 }
00168
00169 if (costs[numDirections-1] > costs[0] + oriCost)
00170 costs[numDirections-1] = costs[0] + oriCost;
00171 for (int i=numDirections-1 ; i>0 ; i--)
00172 {
00173 if (costs[i-1] > costs[i] + oriCost)
00174 costs[i-1] = costs[i] + oriCost;
00175 else
00176 break;
00177 }
00178
00179
00180 for (int i=0 ; i<numDirections ; i++)
00181 itsOriDistImages[i][k] = costs[i];
00182
00183 }
00184 }
00185
00186
00187 void OriChamferMatching::buildIntegralDistances()
00188 {
00189 int numDirections = itsOriDistImages.size();
00190 itsOriIntDistImages.resize(numDirections);
00191
00192 for(int i=0; i<numDirections; i++)
00193 {
00194 double theta = (i*M_PI)/numDirections + M_PI/(2*numDirections);
00195
00196
00197 itsOriIntDistImages[i] = OriIntegralImage(itsOriDistImages[i], cos(theta), sin(theta));
00198 }
00199 }
00200
00201
00202 OriIntegralImage::OriIntegralImage(const Image<float>& distImage, float dx, float dy)
00203 {
00204 if (fabs(dx) > fabs(dy))
00205 {
00206 itsDS = dy / (dx + 1e-9f);
00207 itsXindexed = 1;
00208 }
00209 else
00210 {
00211 itsDS = dx / (dy + 1e-9f);
00212 itsXindexed = 0;
00213 }
00214
00215 itsFactor = sqrt(itsDS*itsDS + 1);
00216
00217
00218 int width = distImage.getWidth();
00219 int height = distImage.getHeight();
00220
00221 if (itsXindexed)
00222 itsIndices.resize(width);
00223 else
00224 itsIndices.resize(height);
00225
00226 for(uint i=0; i<itsIndices.size(); i++)
00227 itsIndices[i] = (int)ceil(i*itsDS - 0.5);
00228
00229 itsIntegralImage = Image<float>(width, height, NO_INIT);
00230
00231
00232 for(int x=0; x<width; x++)
00233 itsIntegralImage.setVal(x,0, 0.0F);
00234
00235 for(int y=0; y<height; y++)
00236 itsIntegralImage.setVal(0,y, 0.0F);
00237
00238
00239 if (itsXindexed)
00240 {
00241 int miny=0, maxy=0;
00242
00243 if (itsIndices[width-1] > 0)
00244 {
00245 miny = -itsIndices[width-1];
00246 maxy = height;
00247 } else {
00248 miny = 0;
00249 maxy = height - itsIndices[width-1];
00250 }
00251
00252
00253 for(int y=miny; y<=maxy; y++)
00254 for(int x=1; x<width; x++)
00255 {
00256 int py = y + itsIndices[x-1];
00257 int cy = y + itsIndices[x];
00258
00259 if (cy > 0 && cy < height - 1)
00260 itsIntegralImage.setVal(x, cy,
00261 itsIntegralImage.getVal(x-1,py) + itsIntegralImage.getVal(x,cy));
00262 }
00263 } else {
00264 int minx =0, maxx = 0;
00265
00266 if(itsIndices[height-1]>0)
00267 {
00268 minx = -itsIndices[height-1];
00269 maxx = width;
00270 } else {
00271 minx = 0;
00272 maxx = width - itsIndices[height-1];
00273 }
00274
00275
00276 for(int x=minx; x<=maxx; x++)
00277 for(int y=1; y<height; y++)
00278 {
00279 int px = x + itsIndices[y-1];
00280 int cx = x + itsIndices[y];
00281
00282 if (cx > 0 && cx < width - 1)
00283 itsIntegralImage.setVal(cx, y,
00284 itsIntegralImage.getVal(px, y-1) + itsIntegralImage.getVal(cx,y));
00285 }
00286
00287 }
00288
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 #endif
00300