00001
00015 #ifndef _DLRCOMPUTERVISION_EUCLIDEANDISTANCE_H_
00016 #define _DLRCOMPUTERVISION_EUCLIDEANDISTANCE_H_
00017
00018 #include <list>
00019 #include <dlrComputerVision/imageFormat.h>
00020 #include <dlrComputerVision/imageIO.h>
00021 #include <dlrComputerVision/image.h>
00022
00023 namespace dlr {
00024
00025 namespace computerVision {
00026
00027 template<ImageFormat FORMAT>
00028 Array2D<double>
00029 getEuclideanDistance(const Image<FORMAT>& inputImage,
00030 size_t maxNumberOfPasses=10);
00031
00032
00033 template<ImageFormat FORMAT>
00034 Array2D<double>
00035 getEuclideanDistance(const Image<FORMAT>& inputImage,
00036 size_t maxNumberOfPasses,
00037 size_t& numberOfPassesUsed);
00038
00039 }
00040
00041 }
00042
00043
00044
00045
00046
00047 #include <cmath>
00048 #include <dlrNumeric/index2D.h>
00049
00050 namespace dlr {
00051
00052 namespace computerVision {
00053
00055 namespace privateCode {
00056
00057 inline bool
00058 eucDistPropagate(size_t toIndex,
00059 size_t fromIndex,
00060 Array2D<double>& distanceMap,
00061 Array2D<Index2D>& referentMap,
00062 int row,
00063 int column)
00064 {
00065
00066 if(distanceMap(fromIndex) < distanceMap(toIndex)) {
00067 Index2D& referent = referentMap(fromIndex);
00068 double deltaU = column - referent.getColumn();
00069 double deltaV = row - referent.getRow();
00070 double newDistance = deltaU * deltaU + deltaV * deltaV;
00071 if(newDistance < distanceMap(toIndex)) {
00072 distanceMap(toIndex) = newDistance;
00073 referentMap(toIndex) = referent;
00074 return true;
00075 }
00076 }
00077 return false;
00078 }
00079
00080 }
00082
00083
00084 template<ImageFormat FORMAT>
00085 Array2D<double>
00086 getEuclideanDistance(const Image<FORMAT>& inputImage,
00087 size_t maxNumberOfPasses)
00088 {
00089 size_t numberOfPassesUsed;
00090 return getEuclideanDistance(inputImage, maxNumberOfPasses,
00091 numberOfPassesUsed);
00092 }
00093
00094
00095 template<ImageFormat FORMAT>
00096 Array2D<double>
00097 getEuclideanDistance(const Image<FORMAT>& inputImage,
00098 size_t maxNumberOfPasses,
00099 size_t& numberOfPassesUsed)
00100 {
00101 Array2D<double> distanceMap(inputImage.rows(), inputImage.columns());
00102 Array2D<Index2D> referentMap(inputImage.rows(), inputImage.columns());
00103
00104
00105 double maxSqDistance = (inputImage.rows() * inputImage.rows()
00106 + inputImage.columns() * inputImage.columns());
00107 size_t index0 = 0;
00108 for(size_t row = 0; row < inputImage.rows(); ++row) {
00109 for(size_t column = 0; column < inputImage.columns(); ++column) {
00110 if(inputImage(index0)) {
00111 distanceMap(index0) = 0.0;
00112 referentMap(index0) = Index2D(static_cast<int>(row), static_cast<int>(column));
00113 } else {
00114 distanceMap(index0) = maxSqDistance;
00115 }
00116 ++index0;
00117 }
00118 }
00119
00120
00121
00122
00123 size_t columns = distanceMap.columns();
00124 size_t rows = distanceMap.rows();
00125 size_t passNumber;
00126 for(passNumber = 0; passNumber < maxNumberOfPasses; ++passNumber) {
00127
00128
00129 bool isChanged = false;
00130
00131
00132
00133
00134 index0 = 1;
00135 for(size_t column = 1; column < inputImage.columns(); ++column) {
00136 isChanged |= privateCode::eucDistPropagate(
00137 index0, index0 - 1, distanceMap, referentMap,
00138 0, static_cast<int>(column));
00139 isChanged |= privateCode::eucDistPropagate(
00140 index0, index0 + columns - 1, distanceMap, referentMap,
00141 0, static_cast<int>(column));
00142 ++index0;
00143 }
00144
00145
00146 for(size_t row = 1; row < inputImage.rows() - 1; ++row) {
00147 index0 = row * inputImage.columns() + 1;
00148 for(size_t column = 1; column < inputImage.columns(); ++column) {
00149 isChanged |= privateCode::eucDistPropagate(
00150 index0, index0 - columns - 1, distanceMap, referentMap,
00151 static_cast<int>(row), static_cast<int>(column));
00152 isChanged |= privateCode::eucDistPropagate(
00153 index0, index0 - 1, distanceMap, referentMap,
00154 static_cast<int>(row), static_cast<int>(column));
00155 isChanged |= privateCode::eucDistPropagate(
00156 index0, index0 + columns - 1, distanceMap, referentMap,
00157 static_cast<int>(row), static_cast<int>(column));
00158 ++index0;
00159 }
00160 }
00161
00162
00163 index0 = (inputImage.rows() - 1) * inputImage.columns() + 1;
00164 for(size_t column = 1; column < inputImage.columns(); ++column) {
00165 isChanged |= privateCode::eucDistPropagate(
00166 index0, index0 - columns - 1, distanceMap, referentMap,
00167 static_cast<int>(rows) - 1, static_cast<int>(column));
00168 isChanged |= privateCode::eucDistPropagate(
00169 index0, index0 - 1, distanceMap, referentMap,
00170 static_cast<int>(rows) - 1, static_cast<int>(column));
00171 ++index0;
00172 }
00173
00174
00175 index0 = columns + 1;
00176 for(size_t row = 1; row < inputImage.rows(); ++row) {
00177 index0 = row * inputImage.columns();
00178
00179
00180 isChanged |= privateCode::eucDistPropagate(
00181 index0, index0 - columns, distanceMap, referentMap,
00182 static_cast<int>(row), 0);
00183 isChanged |= privateCode::eucDistPropagate(
00184 index0, index0 - columns + 1, distanceMap, referentMap,
00185 static_cast<int>(row), 0);
00186 ++index0;
00187
00188
00189 for(size_t column = 1; column < inputImage.columns() - 1; ++column) {
00190 isChanged |= privateCode::eucDistPropagate(
00191 index0, index0 - columns - 1, distanceMap, referentMap,
00192 static_cast<int>(row), static_cast<int>(column));
00193 isChanged |= privateCode::eucDistPropagate(
00194 index0, index0 - columns, distanceMap, referentMap,
00195 static_cast<int>(row), static_cast<int>(column));
00196 isChanged |= privateCode::eucDistPropagate(
00197 index0, index0 - columns + 1, distanceMap, referentMap,
00198 static_cast<int>(row), static_cast<int>(column));
00199 ++index0;
00200 }
00201
00202
00203 isChanged |= privateCode::eucDistPropagate(
00204 index0, index0 - columns - 1, distanceMap, referentMap,
00205 static_cast<int>(row), static_cast<int>(columns) - 1);
00206 isChanged |= privateCode::eucDistPropagate(
00207 index0, index0 - columns, distanceMap, referentMap,
00208 static_cast<int>(row), static_cast<int>(columns) - 1);
00209 ++index0;
00210 }
00211
00212
00213
00214
00215 index0 = columns - 2;
00216
00217
00218
00219 for(size_t column = inputImage.columns() - 2; column < columns;
00220 --column) {
00221 isChanged |= privateCode::eucDistPropagate(
00222 index0, index0 + 1, distanceMap, referentMap,
00223 0, static_cast<int>(column));
00224 isChanged |= privateCode::eucDistPropagate(
00225 index0, index0 + columns + 1, distanceMap, referentMap,
00226 0, static_cast<int>(column));
00227 --index0;
00228 }
00229
00230
00231 for(size_t row = 1; row < inputImage.rows() - 1; ++row) {
00232 index0 = (row + 1) * inputImage.columns() - 2;
00233 for(size_t column = inputImage.columns() - 2; column < columns;
00234 --column) {
00235 isChanged |= privateCode::eucDistPropagate(
00236 index0, index0 - columns + 1, distanceMap, referentMap,
00237 static_cast<int>(row), static_cast<int>(column));
00238 isChanged |= privateCode::eucDistPropagate(
00239 index0, index0 + 1, distanceMap, referentMap,
00240 static_cast<int>(row), static_cast<int>(column));
00241 isChanged |= privateCode::eucDistPropagate(
00242 index0, index0 + columns + 1, distanceMap, referentMap,
00243 static_cast<int>(row), static_cast<int>(column));
00244 --index0;
00245 }
00246 }
00247
00248
00249 index0 = rows * columns - 2;
00250 for(size_t column = inputImage.columns() - 2; column < columns; --column) {
00251 isChanged |= privateCode::eucDistPropagate(
00252 index0, index0 - columns + 1, distanceMap, referentMap,
00253 static_cast<int>(rows - 1), static_cast<int>(column));
00254 isChanged |= privateCode::eucDistPropagate(
00255 index0, index0 + 1, distanceMap, referentMap,
00256 static_cast<int>(rows - 1), static_cast<int>(column));
00257 --index0;
00258 }
00259
00260
00261
00262
00263
00264
00265 for(size_t row = inputImage.rows() - 2; row < rows; --row) {
00266 index0 = row * columns;
00267
00268
00269 isChanged |= privateCode::eucDistPropagate(
00270 index0, index0 + columns, distanceMap, referentMap,
00271 static_cast<int>(row), 0);
00272 isChanged |= privateCode::eucDistPropagate(
00273 index0, index0 + columns + 1, distanceMap, referentMap,
00274 static_cast<int>(row), 0);
00275 ++index0;
00276
00277
00278 for(size_t column = 1; column < inputImage.columns() - 1; ++column) {
00279 isChanged |= privateCode::eucDistPropagate(
00280 index0, index0 + columns - 1, distanceMap, referentMap,
00281 static_cast<int>(row), static_cast<int>(column));
00282 isChanged |= privateCode::eucDistPropagate(
00283 index0, index0 + columns, distanceMap, referentMap,
00284 static_cast<int>(row), static_cast<int>(column));
00285 isChanged |= privateCode::eucDistPropagate(
00286 index0, index0 + columns + 1, distanceMap, referentMap,
00287 static_cast<int>(row), static_cast<int>(column));
00288 ++index0;
00289 }
00290
00291
00292 isChanged |= privateCode::eucDistPropagate(
00293 index0, index0 + columns - 1, distanceMap, referentMap,
00294 static_cast<int>(row), static_cast<int>(columns) - 1);
00295 isChanged |= privateCode::eucDistPropagate(
00296 index0, index0 + columns, distanceMap, referentMap,
00297 static_cast<int>(row), static_cast<int>(columns) - 1);
00298 ++index0;
00299 }
00300
00301
00302 if(!isChanged) {
00303 break;
00304 }
00305 }
00306
00307
00308 for(index0 = 0; index0 < distanceMap.size(); ++index0) {
00309 distanceMap(index0) = std::sqrt(distanceMap(index0));
00310 }
00311
00312 numberOfPassesUsed = passNumber;
00313 return distanceMap;
00314 }
00315
00316 }
00317
00318 }
00319
00320 #endif
00321
00322
00323
00324
00325
00326