00001
00002 #include "gevd_detector.h"
00003
00004
00005
00006
00007
00008
00009 #include <vil1/vil1_image.h>
00010 #include <vcl_iostream.h>
00011 #include "gevd_pixel.h"
00012 #include "gevd_float_operators.h"
00013 #include "gevd_step.h"
00014 #include "gevd_bufferxy.h"
00015 #include "gevd_contour.h"
00016 #include <vtol/vtol_edge_2d.h>
00017
00018
00019
00020
00021
00022 gevd_detector::gevd_detector(gevd_detector_params& params)
00023 : gevd_detector_params(params),
00024 edgel(NULL), direction(NULL),
00025 locationx(NULL), locationy(NULL), grad_mag(NULL),
00026 angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00027 vertices(NULL), edges(NULL),
00028 filterFactor(2), hysteresisFactor(2.0), noiseThreshold(0.0)
00029 {
00030 if (params.automatic_threshold)
00031 noise = -params.noise_weight;
00032 else
00033 noise = params.noise_multiplier;
00034
00035 image_float_buf_ = 0;
00036 }
00037
00038 gevd_detector::gevd_detector(vil1_image img, float smoothSigma, float noiseSigma,
00039 float contour_factor, float junction_factor, int min_length,
00040 float maxgap, float min_jump)
00041 : image(img), noise(noiseSigma), edgel(NULL), direction(NULL),
00042 locationx(NULL), locationy(NULL), grad_mag(NULL),
00043 angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00044 vertices(NULL), edges(NULL),
00045 filterFactor(2), hysteresisFactor(2.0f), noiseThreshold(0.0f)
00046 {
00047 gevd_detector_params::smooth = smoothSigma;
00048 gevd_detector_params::contourFactor = contour_factor;
00049 gevd_detector_params::junctionFactor = junction_factor;
00050 gevd_detector_params::minLength = min_length;
00051 gevd_detector_params::maxGap = maxgap;
00052 gevd_detector_params::minJump = min_jump;
00053 image_float_buf_ = 0;
00054 }
00055
00056
00057
00058 void gevd_detector::UnProtectLists()
00059 {
00060 #if 0 // commented out
00061 if (edges)
00062 for (CoolListP<Edge*>::iterator eit = edges->begin();
00063 eit != edges->end(); eit++)
00064 (*eit)->UnProtect();
00065 if (vertices)
00066 for (CoolListP<Vertex*>::iterator vit = vertices->begin();
00067 vit != vertices->end(); vit++)
00068 (*vit)->UnProtect();
00069 #endif
00070 }
00071
00072
00073
00074
00075 gevd_detector::~gevd_detector()
00076 {
00077 ClearData();
00078 }
00079
00080
00081
00082
00083 void gevd_detector::ClearData()
00084 {
00085 delete edgel; delete direction; delete locationx; delete locationy;
00086 delete grad_mag; delete angle;
00087 delete [] junctionx; delete [] junctiony;
00088 delete vertices;
00089 delete edges;
00090 if (image_float_buf_) delete image_float_buf_;
00091 }
00092
00093
00094
00095
00096 bool gevd_detector::DoContour()
00097 {
00098 if (edges && vertices) return true;
00099
00100 if (!DoStep()) {
00101 vcl_cout << "***Fail on DoContour.\n";
00102 return false;
00103 }
00104 gevd_contour::ClearNetwork(edges, vertices);
00105 gevd_contour contour(this->hysteresisFactor*this->noiseThreshold, this->minLength,
00106 this->minJump*this->noiseThreshold, this->maxGap);
00107 bool t = contour.FindNetwork(*edgel, njunction,
00108 junctionx, junctiony,
00109 edges, vertices);
00110 if (!t) {
00111 vcl_cout << "***Fail on FindNetwork.\n";
00112 return false;
00113 }
00114
00115 vcl_vector<vtol_edge_2d_sptr>::iterator edge;
00116 vcl_cout << "IN DoContour before SubPixelAccuracy\n";
00117 this->print(vcl_cout);
00118 for ( edge = edges->begin() ; edge != edges->end(); ++edge)
00119 {
00120 vcl_cout << "Edgel output from DoContour:";
00121 (*edge)->describe(vcl_cout, 2);
00122 }
00123
00124 contour.SubPixelAccuracy(*edges, *vertices,
00125 *locationx, *locationy);
00126 if (this->spacingp)
00127 gevd_contour::EqualizeSpacing(*edges);
00128 if (this->borderp)
00129 contour.InsertBorder(*edges, *vertices);
00130 if (grad_mag&&angle)
00131 gevd_contour::SetEdgelData(*grad_mag, *angle, *edges);
00132
00133
00134
00135
00136
00137
00138 return true;
00139 }
00140
00141
00142
00143
00144
00145 bool gevd_detector::DoFoldContour()
00146 {
00147 if (edges && vertices) return true;
00148
00149
00150
00151
00152
00153 gevd_contour::ClearNetwork(edges, vertices);
00154 gevd_contour contour(this->hysteresisFactor*this->noiseThreshold,
00155 this->minLength, this->minJump*this->noiseThreshold,
00156 this->maxGap);
00157
00158 bool t = contour.FindNetwork(*edgel, njunction,
00159 junctionx, junctiony,
00160 edges, vertices);
00161 if (!t) {
00162 vcl_cout << "***Fail on FindNetwork.\n";
00163 return false;
00164 }
00165 contour.SubPixelAccuracy(*edges, *vertices,
00166 *locationx, *locationy);
00167 if (this->spacingp)
00168 gevd_contour::EqualizeSpacing(*edges);
00169 if (this->borderp)
00170 contour.InsertBorder(*edges, *vertices);
00171 if (grad_mag&&angle)
00172 gevd_contour::SetEdgelData(*grad_mag, *angle, *edges);
00173
00174
00175
00176
00177
00178
00179 return true;
00180 }
00181
00182
00183
00184
00185
00186 bool gevd_detector::DoStep()
00187 {
00188 if (edgel) return true;
00189
00190 const gevd_bufferxy* source = GetBufferFromImage();
00191 if (!source) {
00192 vcl_cout << " cannot get image buffer\n";
00193 return false;
00194 }
00195
00196 gevd_step step(this->smooth, this->noise, this->contourFactor, this->junctionFactor);
00197 step.DetectEdgels(*source, edgel, direction, locationx, locationy, grad_mag, angle);
00198
00199 if (this->junctionp) {
00200 njunction = step.RecoverJunctions(*source,
00201 *edgel, *direction,
00202 *locationx, *locationy,
00203 junctionx, junctiony);
00204 }
00205 else {
00206 njunction = 0;
00207 delete [] junctionx; junctionx = NULL;
00208 delete [] junctiony; junctiony = NULL;
00209 }
00210
00211 this->noiseThreshold = step.NoiseThreshold();
00212
00213 return edgel!=NULL;
00214 }
00215
00216 #if 0 // commented out
00217
00218
00219
00220
00221 bool gevd_detector::DoFold()
00222 {
00223 if (edgel) return true;
00224
00225 const BufferXY* source = GetBufferFromImage();
00226 if (!source) {
00227 vcl_cout << " cannot get image buffer\n";
00228 return false;
00229 }
00230
00231 Fold fold(this->smooth, this->noise,
00232 this->contourFactor,
00233 this->junctionFactor);
00234 fold.DetectEdgels(*source, edgel, direction,
00235 locationx, locationy, true,
00236 grad_mag, angle);
00237
00238 if (this->junctionp) {
00239 njunction = fold.RecoverJunctions(*source,
00240 *edgel, *direction,
00241 *locationx, *locationy,
00242 junctionx, junctiony);
00243 }
00244 else {
00245 njunction = 0;
00246 delete [] junctionx; junctionx = NULL;
00247 delete [] junctiony; junctiony = NULL;
00248 }
00249
00250 this->noiseThreshold = fold.NoiseThreshold();
00251 return edgel!=NULL;
00252 }
00253 #endif // 0
00254
00255
00256
00257
00258
00259 gevd_bufferxy* gevd_detector::GetBufferFromImage()
00260 {
00261 if (image_float_buf_) return image_float_buf_;
00262
00263 if (!image)
00264 {
00265 vcl_cout << "No image\n";
00266 return 0;
00267 }
00268
00269
00270
00271
00272 int sizey= image.rows();
00273 int sizex= image.cols();
00274
00275 image_float_buf_ = new gevd_bufferxy(sizex, sizey,8*sizeof(float));
00276
00277 #if 0 // commented out
00278 if (image->GetPixelType() == Image::FLOAT)
00279 {
00280 image->GetSection(image_float_buf_->GetBuffer(),
00281 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00282 return image_float_buf_;
00283 }
00284 #endif
00285
00286
00287 gevd_bufferxy image_buf(sizex, sizey, image.bits_per_component());
00288
00289 #if 0 // commented out
00290 image->GetSection(image_buf.GetBuffer(),
00291 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00292 #endif
00293
00294 image.get_section(image_buf.GetBuffer(),
00295 0, 0, sizex, sizey);
00296
00297 if (! gevd_float_operators::BufferToFloat(image_buf, *image_float_buf_))
00298 {
00299 delete image_float_buf_;
00300 image_float_buf_ = 0;
00301 }
00302
00303 return image_float_buf_;
00304 }
00305
00306
00307 void gevd_detector::SetImage(vil1_image img)
00308 {
00309 image = img;
00310 if (image_float_buf_) {
00311 delete image_float_buf_;
00312 image_float_buf_ = 0;
00313 }
00314 if (edgel) delete edgel;
00315 if (vertices) delete vertices;
00316 if (direction) delete direction;
00317 if (locationx) delete locationx;
00318 if (locationy) delete locationy;
00319 if (grad_mag) delete grad_mag;
00320 if (angle) delete angle;
00321 if (junctionx) delete [] junctionx;
00322 if (junctiony) delete [] junctiony;
00323 }
00324
00325 void gevd_detector::print(vcl_ostream &strm) const
00326 {
00327 strm << "gevd_Detector:\n"
00328 << " noise " << noise << vcl_endl
00329 << " njunction " << njunction << vcl_endl
00330 << " num vertices " << vertices->size() << vcl_endl
00331 << " num edges " << edges->size() << vcl_endl
00332 << " filterfactor " << filterFactor << vcl_endl
00333 << " hysteresisfactor " << hysteresisFactor << vcl_endl
00334 << " noiseThreshold " << noiseThreshold << vcl_endl
00335 << " smooth " << smooth << vcl_endl
00336 << " noise_weight " << noise_weight << vcl_endl
00337 << " noise_multiplier " << noise_multiplier << vcl_endl
00338 << " automatic_threshold " << automatic_threshold << vcl_endl
00339 << " aggressive_junction_closure " << aggressive_junction_closure << vcl_endl
00340 << " minLength " << minLength << vcl_endl
00341 << " contourFactor " << contourFactor << vcl_endl
00342 << " junctionFactor " << junctionFactor << vcl_endl
00343 << " filterFactor " << filterFactor << vcl_endl
00344 << " junctionp " << junctionp << vcl_endl
00345 << " minJump " << minJump << vcl_endl
00346 << " maxGap " << maxGap << vcl_endl
00347 << " spacingp " << spacingp << vcl_endl
00348 << " borderp " << borderp << vcl_endl
00349 << " corner_angle " << corner_angle << vcl_endl
00350 << " separation " << separation << vcl_endl
00351 << " min_corner_length " << min_corner_length << vcl_endl
00352 << " cycle " << cycle << vcl_endl
00353 << " ndimension " << ndimension << vcl_endl
00354 << vcl_endl;
00355 }