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.0), noiseThreshold(0.0)
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 } else {
00205 njunction = 0;
00206 delete [] junctionx; junctionx = NULL;
00207 delete [] junctiony; junctiony = NULL;
00208 }
00209
00210 this->noiseThreshold = step.NoiseThreshold();
00211
00212 return edgel!=NULL;
00213 }
00214
00215 #if 0 // commented out
00216
00217
00218
00219
00220 bool gevd_detector::DoFold()
00221 {
00222 if (edgel) return true;
00223
00224 const BufferXY* source = GetBufferFromImage();
00225 if (!source) {
00226 vcl_cout << " cannot get image buffer\n";
00227 return false;
00228 }
00229
00230 Fold fold(this->smooth, this->noise,
00231 this->contourFactor,
00232 this->junctionFactor);
00233 fold.DetectEdgels(*source, edgel, direction,
00234 locationx, locationy, true,
00235 grad_mag, angle);
00236
00237 if (this->junctionp) {
00238 njunction = fold.RecoverJunctions(*source,
00239 *edgel, *direction,
00240 *locationx, *locationy,
00241 junctionx, junctiony);
00242 } else {
00243 njunction = 0;
00244 delete [] junctionx; junctionx = NULL;
00245 delete [] junctiony; junctiony = NULL;
00246 }
00247
00248 this->noiseThreshold = fold.NoiseThreshold();
00249 return edgel!=NULL;
00250 }
00251 #endif // 0
00252
00253
00254
00255
00256
00257 gevd_bufferxy* gevd_detector::GetBufferFromImage()
00258 {
00259 if (image_float_buf_) return image_float_buf_;
00260
00261 if (!image)
00262 {
00263 vcl_cout << "No image\n";
00264 return 0;
00265 }
00266
00267
00268
00269
00270 int sizey= image.rows();
00271 int sizex= image.cols();
00272
00273 image_float_buf_ = new gevd_bufferxy(sizex, sizey,8*sizeof(float));
00274
00275 #if 0 // commented out
00276 if (image->GetPixelType() == Image::FLOAT)
00277 {
00278 image->GetSection(image_float_buf_->GetBuffer(),
00279 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00280 return image_float_buf_;
00281 }
00282 #endif
00283
00284
00285 gevd_bufferxy image_buf(sizex, sizey, image.bits_per_component());
00286
00287 #if 0 // commented out
00288 image->GetSection(image_buf.GetBuffer(),
00289 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00290 #endif
00291
00292 image.get_section(image_buf.GetBuffer(),
00293 0, 0, sizex, sizey);
00294
00295 if (! gevd_float_operators::BufferToFloat(image_buf, *image_float_buf_))
00296 {
00297 delete image_float_buf_;
00298 image_float_buf_ = 0;
00299 }
00300
00301 return image_float_buf_;
00302 }
00303
00304
00305 void gevd_detector::SetImage(vil1_image img)
00306 {
00307 image = img;
00308 if (image_float_buf_) {
00309 delete image_float_buf_;
00310 image_float_buf_ = 0;
00311 }
00312 if (edgel) delete edgel;
00313 if (vertices) delete vertices;
00314 if (direction) delete direction;
00315 if (locationx) delete locationx;
00316 if (locationy) delete locationy;
00317 if (grad_mag) delete grad_mag;
00318 if (angle) delete angle;
00319 if (junctionx) delete [] junctionx;
00320 if (junctiony) delete [] junctiony;
00321 }
00322
00323 void gevd_detector::print(vcl_ostream &strm) const
00324 {
00325 strm << "gevd_Detector:\n"
00326 << " noise " << noise << vcl_endl
00327 << " njunction " << njunction << vcl_endl
00328 << " num vertices " << vertices->size() << vcl_endl
00329 << " num edges " << edges->size() << vcl_endl
00330 << " filterfactor " << filterFactor << vcl_endl
00331 << " hysteresisfactor " << hysteresisFactor << vcl_endl
00332 << " noiseThreshold " << noiseThreshold << vcl_endl
00333 << " smooth " << smooth << vcl_endl
00334 << " noise_weight " << noise_weight << vcl_endl
00335 << " noise_multiplier " << noise_multiplier << vcl_endl
00336 << " automatic_threshold " << automatic_threshold << vcl_endl
00337 << " aggressive_junction_closure " << aggressive_junction_closure << vcl_endl
00338 << " minLength " << minLength << vcl_endl
00339 << " contourFactor " << contourFactor << vcl_endl
00340 << " junctionFactor " << junctionFactor << vcl_endl
00341 << " filterFactor " << filterFactor << vcl_endl
00342 << " junctionp " << junctionp << vcl_endl
00343 << " minJump " << minJump << vcl_endl
00344 << " maxGap " << maxGap << vcl_endl
00345 << " spacingp " << spacingp << vcl_endl
00346 << " borderp " << borderp << vcl_endl
00347 << " corner_angle " << corner_angle << vcl_endl
00348 << " separation " << separation << vcl_endl
00349 << " min_corner_length " << min_corner_length << vcl_endl
00350 << " cycle " << cycle << vcl_endl
00351 << " ndimension " << ndimension << vcl_endl
00352 << vcl_endl;
00353 }