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
00040
00041
00042 #include <queue>
00043 #include <sstream>
00044
00045 #include <qgarlib/GeodesicRecEroBinaryImage.H>
00046 #include <qgarlib/QgarErrorDomain.H>
00047
00048
00049
00050 using namespace std;
00051
00052
00053 namespace qgar
00054 {
00055
00056
00057
00058
00059
00060 GeodesicRecEroBinaryImage::GeodesicRecEroBinaryImage(BinaryImage& aMarkImg,
00061 BinaryImage& aResImg)
00062 throw(QgarErrorDomain)
00063 : BinaryImage(aMarkImg)
00064 {
00065 if ( (aMarkImg.width() != aResImg.width())
00066 || (aMarkImg.height() != aResImg.height()))
00067 {
00068 std::ostringstream os;
00069 os << "Marker image size ["
00070 << aMarkImg.width()
00071 << " X "
00072 << aMarkImg.height()
00073 << "] does not match result image size ["
00074 << aResImg.width()
00075 << " X "
00076 << aResImg.height()
00077 << "]";
00078 throw QgarErrorDomain(__FILE__, __LINE__,
00079 "qgar::GeodesicRecEroBinaryImage::GeodesicRecEroBinaryImage(qgar::BinaryImage&, qgar::BinaryImage&)",
00080 os.str());
00081 }
00082
00083 perform(this, &aResImg);
00084 }
00085
00086
00087
00088
00089
00090
00091 void GeodesicRecEroBinaryImage::perform(BinaryImage* aMarkImg,
00092 BinaryImage* aResImg)
00093 {
00094
00095 int width = aMarkImg->width();
00096 int height = aMarkImg->height();
00097
00098
00099
00100
00101
00102
00103 queue< long > boundary;
00104
00105 long indice;
00106
00107 BinaryImage::value_type* Jp;
00108 BinaryImage::value_type* Ip;
00109 BinaryImage::value_type* Jq;
00110 BinaryImage::value_type* Iq;
00111
00112 BinaryImage::value_type* markerPixMap = aMarkImg->pPixMap();
00113 BinaryImage::value_type* goalPixMap = aResImg->pPixMap();
00114
00115 Jp = markerPixMap;
00116 Ip = goalPixMap;
00117
00118 int minK, minL;
00119 int maxK, maxL;
00120
00121 for (int i = 0; i < height; ++i)
00122 {
00123 for (int j = 0; j < width; ++j, ++Jp, ++Ip)
00124 {
00125 if (!*Jp && !*Ip)
00126 {
00127
00128
00129
00130
00131
00132 if ( (i > 0) && (i < height - 1) )
00133 {
00134 minK = -1;
00135 maxK = 2;
00136
00137
00138 if (j == 0)
00139 {
00140 minL = 0;
00141 maxL = 2;
00142 }
00143
00144 else if (j < width - 1)
00145 {
00146 minL = -1;
00147 maxL = 2;
00148 }
00149 else
00150 {
00151 minL = -1;
00152 maxL = 1;
00153 }
00154 }
00155
00156 else if (Jp == markerPixMap)
00157 {
00158 minK = minL = 0;
00159 maxK = maxL = 2;
00160 }
00161
00162 else if (Jp < markerPixMap + width - 1)
00163 {
00164 minK = 0;
00165 minL = -1;
00166 maxK = maxL = 2;
00167 }
00168
00169 else if (Jp == markerPixMap + width - 1)
00170 {
00171 minK = 0;
00172 minL = -1;
00173 maxK = 2;
00174 maxL = 1;
00175 }
00176
00177 else if (j == 0)
00178 {
00179 minK = -1;
00180 minL = 0;
00181 maxK = 1;
00182 maxL = 2;
00183 }
00184
00185 else if (j < width - 1)
00186 {
00187 minK = minL = -1;
00188 maxL = 2;
00189 maxK = 1;
00190 }
00191
00192 else
00193 {
00194 minL = minK = -1;
00195 maxL = maxK = 1;
00196 }
00197
00198 for (int k = minK; k < maxK; ++k)
00199 {
00200 for (int l = minL ; l < maxL; ++l)
00201 {
00202 Jq = Jp + k*width + l;
00203
00204 if (*Jq)
00205 {
00206 boundary.push(Jp - markerPixMap);
00207
00208
00209
00210 k = 2;
00211 break;
00212
00213 }
00214 }
00215 }
00216
00217 }
00218
00219 }
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229 while (!boundary.empty())
00230 {
00231 indice = boundary.front();
00232 boundary.pop();
00233
00234 Jp = markerPixMap + indice;
00235 Ip = goalPixMap + indice;
00236
00237
00238
00239
00240 if ( (Jp > markerPixMap + width - 1) &&
00241 (Jp < markerPixMap + (height - 1)*width) )
00242 {
00243 minK = -1;
00244 maxK = 2;
00245
00246
00247 if ((Jp - markerPixMap) % width == 0)
00248 {
00249 minL = 0;
00250 maxL = 2;
00251 }
00252
00253 else if ((Jp - markerPixMap) % width == width - 1)
00254 {
00255 minL = -1;
00256 maxL = 1;
00257 }
00258
00259 else
00260 {
00261 minL = -1;
00262 maxL = 2;
00263 }
00264 }
00265
00266 else if (Jp == markerPixMap)
00267 {
00268 minK = minL = 0;
00269 maxK = maxL = 2;
00270 }
00271
00272 else if (Jp < markerPixMap + width - 1)
00273 {
00274 minK = 0;
00275 minL = -1;
00276 maxK = maxL = 2;
00277 }
00278
00279 else if (Jp == markerPixMap + width - 1)
00280 {
00281 minK = 0;
00282 minL = -1;
00283 maxK = 2;
00284 maxL = 1;
00285 }
00286
00287 else if (Jp == markerPixMap + (height - 1)*width)
00288 {
00289 minK = -1;
00290 minL = 0;
00291 maxK = 1;
00292 maxL = 2;
00293 }
00294
00295 else if (Jp < markerPixMap + height*width - 1)
00296 {
00297 minK = minL = -1;
00298 maxL = 2;
00299 maxK = 1;
00300 }
00301
00302 else
00303 {
00304 minL = minK = -1;
00305 maxL = maxK = 1;
00306 }
00307
00308 for (int k = minK; k < maxK; ++k)
00309 {
00310 for (int l = minL ; l < maxL; ++l)
00311 {
00312 indice = (k * width) + l;
00313 Jq = Jp + indice;
00314 Iq = Ip + indice;
00315
00316 if ( *Jq && (!*Iq) )
00317 {
00318 *Jq = 0;
00319 boundary.push(Jq - markerPixMap);
00320 }
00321
00322 }
00323 }
00324
00325 }
00326 }
00327
00328
00329
00330 }
00331