00001
00002 #include "sdet_detector.h"
00003
00004
00005
00006
00007
00008
00009 #include <vil1/vil1_image.h>
00010 #include <vcl_iostream.h>
00011 #include <gevd/gevd_float_operators.h>
00012 #include <gevd/gevd_step.h>
00013 #include <gevd/gevd_bufferxy.h>
00014 #include <sdet/sdet_contour.h>
00015 #include <vil/vil_new.h>
00016 #include <vil/vil_image_view.h>
00017 #include <brip/brip_vil_float_ops.h>
00018 #include <vdgl/vdgl_digital_curve.h>
00019 #include <vdgl/vdgl_edgel_chain.h>
00020 #include <vdgl/vdgl_interpolator.h>
00021 #include <vsol/vsol_point_2d.h>
00022
00023
00024
00025
00026 sdet_detector::sdet_detector(sdet_detector_params& params)
00027 : sdet_detector_params(params),
00028 edgel(NULL), direction(NULL),
00029 locationx(NULL), locationy(NULL), grad_mag(NULL),
00030 angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00031 vertices(NULL), edges(NULL),
00032 filterFactor(2), hysteresisFactor(2.0), noiseThreshold(0.0)
00033 {
00034 if (params.automatic_threshold)
00035 noise = -params.noise_weight;
00036 else
00037 noise = params.noise_multiplier;
00038
00039 use_vil_image = true;
00040 image=0;
00041 vimage=0;
00042 use_roi_ = false;
00043 }
00044
00045 sdet_detector::sdet_detector(vil1_image img, float smoothSigma, float noiseSigma,
00046 float contour_factor, float junction_factor, int min_length,
00047 float maxgap, float min_jump)
00048 : image(img), vimage(0), noise(noiseSigma), edgel(NULL), direction(NULL),
00049 locationx(NULL), locationy(NULL), grad_mag(NULL),
00050 angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00051 vertices(NULL), edges(NULL),
00052 filterFactor(2), hysteresisFactor(2.0f), noiseThreshold(0.0f)
00053 {
00054 use_vil_image = false;
00055 sdet_detector_params::smooth = smoothSigma;
00056 sdet_detector_params::contourFactor = contour_factor;
00057 sdet_detector_params::junctionFactor = junction_factor;
00058 sdet_detector_params::minLength = min_length;
00059 sdet_detector_params::maxGap = maxgap;
00060 sdet_detector_params::minJump = min_jump;
00061 use_roi_ = false;
00062 }
00063
00064 sdet_detector::sdet_detector(vil_image_resource_sptr & img, float smoothSigma, float noiseSigma,
00065 float contour_factor, float junction_factor, int min_length,
00066 float maxgap, float min_jump)
00067 : image(0),vimage(img), noise(noiseSigma), edgel(NULL), direction(NULL),
00068 locationx(NULL), locationy(NULL), grad_mag(NULL),
00069 angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00070 vertices(NULL), edges(NULL),
00071 filterFactor(2), hysteresisFactor(2.0f), noiseThreshold(0.0f)
00072 {
00073 use_vil_image = true;
00074 sdet_detector_params::smooth = smoothSigma;
00075 sdet_detector_params::contourFactor = contour_factor;
00076 sdet_detector_params::junctionFactor = junction_factor;
00077 sdet_detector_params::minLength = min_length;
00078 sdet_detector_params::maxGap = maxgap;
00079 sdet_detector_params::minJump = min_jump;
00080 use_roi_ = false;
00081 }
00082
00083
00084
00085
00086 sdet_detector::~sdet_detector()
00087 {
00088 ClearData();
00089 }
00090
00091
00092
00093
00094 void sdet_detector::ClearData()
00095 {
00096 delete edgel; delete direction; delete locationx; delete locationy;
00097 delete grad_mag; delete angle;
00098 delete [] junctionx; delete [] junctiony;
00099 if (vertices)
00100 vertices->clear();
00101 if (edges)
00102 edges->clear();
00103 delete vertices;
00104 vertices = 0;
00105 delete edges;
00106 edges = 0;
00107 }
00108
00109
00110
00111
00112 bool sdet_detector::DoContour()
00113 {
00114 if (edges && vertices) return true;
00115
00116 if (!DoStep()) {
00117 vcl_cout << "***Fail on DoContour.\n";
00118 return false;
00119 }
00120
00121 sdet_contour::ClearNetwork(edges, vertices);
00122 sdet_contour contour(this->hysteresisFactor*this->noiseThreshold,
00123 this->minLength, this->minJump*this->noiseThreshold,
00124 this->maxGap);
00125
00126
00127 bool find_net = contour.FindNetwork(*edgel, junctionp,
00128 njunction,
00129 junctionx, junctiony,
00130 edges, vertices);
00131 if (!find_net) {
00132 vcl_cout << "***Fail on FindNetwork.\n";
00133 return false;
00134 }
00135
00136
00137 if (this->borderp)
00138 contour.InsertBorder(*edges, *vertices);
00139
00140
00141 contour.SubPixelAccuracy(*edges, *vertices,
00142 *locationx, *locationy);
00143
00144
00145 if (this->spacingp)
00146 sdet_contour::EqualizeSpacing(*edges);
00147
00148
00149 if (grad_mag&&angle)
00150 sdet_contour::SetEdgelData(*grad_mag, *angle, *edges);
00151
00152
00153 #if 0 // TargetJr
00154 const RectROI* roi = image->GetROI();
00155 sdet_contour::Translate(*edges, *vertices,
00156 roi->GetOrigX()+0.5,
00157 roi->GetOrigY()+0.5);
00158 #endif
00159 if (!use_roi_)
00160 return true;
00161 sdet_contour::Translate(*edges, *vertices,
00162 static_cast<float>(roi_.cmin(0)),
00163 static_cast<float>(roi_.rmin(0)));
00164 return true;
00165 }
00166
00167
00168
00169
00170
00171 bool sdet_detector::DoFoldContour()
00172 {
00173 if (edges && vertices) return true;
00174
00175 #if 0
00176 if (!DoFold()) {
00177 vcl_cout << "***Fail on DoFoldContour.\n";
00178 return false;
00179 }
00180 #endif
00181 sdet_contour::ClearNetwork(edges, vertices);
00182 sdet_contour contour(this->hysteresisFactor*this->noiseThreshold,
00183 this->minLength, this->minJump*this->noiseThreshold,
00184 this->maxGap);
00185
00186
00187 bool t = contour.FindNetwork(*edgel, junctionp,
00188 njunction,
00189 junctionx, junctiony,
00190 edges, vertices);
00191 if (!t) {
00192 vcl_cout << "***Fail on FindNetwork.\n";
00193 return false;
00194 }
00195 contour.SubPixelAccuracy(*edges, *vertices,
00196 *locationx, *locationy);
00197 if (this->spacingp)
00198 sdet_contour::EqualizeSpacing(*edges);
00199 if (this->borderp)
00200 contour.InsertBorder(*edges, *vertices);
00201 if (grad_mag&&angle)
00202 sdet_contour::SetEdgelData(*grad_mag, *angle, *edges);
00203 #if 0 // TargetJr
00204 sdet_contour::add_vertex_edgels(*edges);
00205 const RectROI* roi = image->GetROI();
00206 sdet_contour::Translate(*edges, *vertices,
00207 roi->GetOrigX()+0.5,
00208 roi->GetOrigY()+0.5);
00209 #endif
00210 return true;
00211 }
00212
00213
00214
00215
00216
00217 bool sdet_detector::DoStep()
00218 {
00219 if (edgel) return true;
00220
00221 const gevd_bufferxy* source;
00222 if (use_vil_image)
00223 source = GetBufferFromVilImage();
00224 else
00225 source = GetBufferFromImage();
00226 if (!source) {
00227 vcl_cout << " cannot get image buffer\n";
00228 return false;
00229 }
00230 gevd_step step(this->smooth, this->noise, this->contourFactor, this->junctionFactor);
00231
00232 step.DetectEdgels(*source, edgel, direction, locationx, locationy, grad_mag, angle);
00233
00234 if (this->junctionp) {
00235 njunction = step.RecoverJunctions(*source,
00236 *edgel, *direction,
00237 *locationx, *locationy,
00238 junctionx, junctiony);
00239 }
00240 else {
00241 njunction = 0;
00242 delete [] junctionx; junctionx = NULL;
00243 delete [] junctiony; junctiony = NULL;
00244 }
00245
00246 this->noiseThreshold = step.NoiseThreshold();
00247 delete source;
00248 return edgel!=NULL;
00249 }
00250
00251 #if 0 // commented out
00252
00253
00254
00255
00256 bool sdet_detector::DoFold()
00257 {
00258 if (edgel) return true;
00259
00260 const BufferXY* source = GetBufferFromImage();
00261 if (!source) {
00262 vcl_cout << " cannot get image buffer\n";
00263 return false;
00264 }
00265
00266 Fold fold(this->smooth, this->noise,
00267 this->contourFactor,
00268 this->junctionFactor);
00269 fold.DetectEdgels(*source, edgel, direction,
00270 locationx, locationy, true,
00271 grad_mag, angle);
00272
00273 if (this->junctionp) {
00274 njunction = fold.RecoverJunctions(*source,
00275 *edgel, *direction,
00276 *locationx, *locationy,
00277 junctionx, junctiony);
00278 }
00279 else {
00280 njunction = 0;
00281 delete [] junctionx; junctionx = NULL;
00282 delete [] junctiony; junctiony = NULL;
00283 }
00284
00285 this->noiseThreshold = fold.NoiseThreshold();
00286 return edgel!=NULL;
00287 }
00288 #endif // 0
00289
00290
00291
00292
00293
00294
00295
00296 gevd_bufferxy* sdet_detector::GetBufferFromImage()
00297 {
00298 gevd_bufferxy* image_float_buf = 0;
00299
00300 if (image_float_buf) return image_float_buf;
00301
00302 if (!image)
00303 {
00304 vcl_cout << "In sdet_detector::GetBufferFromImage() - no image\n";
00305 return 0;
00306 }
00307 if (image.components()!=1)
00308 {
00309 vcl_cout << "In sdet_detector::GetBufferFromImage() -"
00310 << " not exactly one component\n";
00311 return 0;
00312 }
00313
00314 #if 0 // TargetJr
00315 RectROI* roi = image->GetROI();
00316 int sizex = roi->GetSizeX();
00317 int sizey = roi->GetSizeY();
00318 #endif
00319 int sizey= image.rows();
00320 int sizex= image.cols();
00321
00322 image_float_buf = new gevd_bufferxy(sizex, sizey,8*sizeof(float));
00323
00324 #if 0 // commented out
00325 if (image->GetPixelType() == Image::FLOAT)
00326 {
00327 image->GetSection(image_float_buf->GetBuffer(),
00328 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00329 return image_float_buf;
00330 }
00331 #endif
00332
00333 gevd_bufferxy image_buf(sizex, sizey, image.bits_per_component());
00334
00335 #if 0 // commented out
00336 image->GetSection(image_buf.GetBuffer(),
00337 roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00338 #endif
00339
00340 image.get_section(image_buf.GetBuffer(),
00341 0, 0, sizex, sizey);
00342
00343 if (! gevd_float_operators::BufferToFloat(image_buf, *image_float_buf))
00344 {
00345 delete image_float_buf;
00346 image_float_buf = 0;
00347 }
00348
00349 return image_float_buf;
00350 }
00351
00352 gevd_bufferxy* sdet_detector::GetBufferFromVilImage()
00353 {
00354 gevd_bufferxy* image_float_buf = 0;
00355
00356 if (image_float_buf) return image_float_buf;
00357
00358
00359 if (!use_vil_image||!vimage->ni()||!vimage->nj())
00360 {
00361 vcl_cout << "In sdet_detector::GetBufferFromVilImage() - no image\n";
00362 return 0;
00363 }
00364
00365 vil_image_resource_sptr process_region = vimage;
00366
00367
00368 if (use_roi_)
00369 {
00370 if (roi_.n_regions()!=1)
00371 return 0;
00372 vil_image_view_base_sptr vb =
00373 vimage->get_view(roi_.cmin(0), roi_.csize(0), roi_.rmin(0), roi_.rsize(0));
00374 if (!vb)
00375 return 0;
00376 process_region = vil_new_image_resource_of_view(*vb);
00377 }
00378
00379 if (vimage->nplanes()!=1)
00380 {
00381 vil_image_view<unsigned short> sview
00382 = brip_vil_float_ops::convert_to_short(process_region);
00383 process_region = vil_new_image_resource_of_view(sview);
00384 }
00385
00386 int sizey= process_region->nj();
00387 int sizex= process_region->ni();
00388
00389 image_float_buf = new gevd_bufferxy(sizex, sizey,8*sizeof(float));
00390
00391 gevd_bufferxy image_buf(process_region);
00392
00393 if (! gevd_float_operators::BufferToFloat(image_buf, *image_float_buf))
00394 {
00395 delete image_float_buf;
00396 image_float_buf = 0;
00397 }
00398
00399 return image_float_buf;
00400 }
00401
00402 void sdet_detector::print(vcl_ostream &strm) const
00403 {
00404 strm << "sdet_detector:\n"
00405 << " noise " << noise << vcl_endl
00406 << " njunction " << njunction << vcl_endl
00407 << " num vertices " << vertices->size() << vcl_endl
00408 << " num edges " << edges->size() << vcl_endl
00409 << " filterfactor " << filterFactor << vcl_endl
00410 << " hysteresisfactor " << hysteresisFactor << vcl_endl
00411 << " noiseThreshold " << noiseThreshold << vcl_endl
00412 << " smooth " << smooth << vcl_endl
00413 << " noise_weight " << noise_weight << vcl_endl
00414 << " noise_multiplier " << noise_multiplier << vcl_endl
00415 << " automatic_threshold " << automatic_threshold << vcl_endl
00416 << " aggressive_junction_closure " << aggressive_junction_closure << vcl_endl
00417 << " minLength " << minLength << vcl_endl
00418 << " contourFactor " << contourFactor << vcl_endl
00419 << " junctionFactor " << junctionFactor << vcl_endl
00420 << " filterFactor " << filterFactor << vcl_endl
00421 << " junctionp " << junctionp << vcl_endl
00422 << " minJump " << minJump << vcl_endl
00423 << " maxGap " << maxGap << vcl_endl
00424 << " spacingp " << spacingp << vcl_endl
00425 << " borderp " << borderp << vcl_endl
00426 << " corner_angle " << corner_angle << vcl_endl
00427 << " separation " << separation << vcl_endl
00428 << " min_corner_length " << min_corner_length << vcl_endl
00429 << " cycle " << cycle << vcl_endl
00430 << " ndimension " << ndimension
00431 << vcl_endl;
00432 }
00433
00434 void sdet_detector::DoBreakCorners(vcl_vector<vtol_edge_2d_sptr >& ,
00435 vcl_vector<vtol_edge_2d_sptr >& )
00436 {
00437 vcl_cerr << "sdet_detector::DoBreakCorners() NYI\n";
00438 }
00439
00440 void sdet_detector::SetImage(vil1_image img)
00441 {
00442 use_vil_image = false;
00443 image = img;
00444 }
00445
00446 void sdet_detector::SetImage(vil_image_resource_sptr const& img, brip_roi const& roi)
00447 {
00448 use_vil_image = true;
00449 vimage = img;
00450 use_roi_ = true;
00451 roi_ = roi;
00452 }
00453
00454 void sdet_detector::SetImage(vil_image_resource_sptr const& img)
00455 {
00456 use_vil_image = true;
00457 vimage = img;
00458 }
00459
00460 bool sdet_detector::
00461 get_vdgl_edges(vcl_vector<vdgl_digital_curve_sptr>& vd_edges )
00462 {
00463 vd_edges.clear();
00464 if (!edges)
00465 return false;
00466
00467 for (vcl_vector<vtol_edge_2d_sptr >::iterator eit = edges->begin();
00468 eit != edges->end(); ++eit)
00469 {
00470 vtol_edge_2d_sptr & e = *eit;
00471 if (!e)
00472 continue;
00473 vsol_curve_2d_sptr c = e->curve();
00474 vdgl_digital_curve* dc = c->cast_to_vdgl_digital_curve();
00475 if (!dc)
00476 continue;
00477
00478 vd_edges.push_back(dc);
00479 }
00480 if (!vd_edges.size())
00481 return false;
00482 return true;
00483 }
00484
00485 bool
00486 sdet_detector::get_vsol_edges(vcl_vector<vsol_digital_curve_2d_sptr>& edges )
00487 {
00488 vcl_vector<vdgl_digital_curve_sptr> vd_edges;
00489 if (!this->get_vdgl_edges(vd_edges))
00490 return false;
00491 edges.clear();
00492 for (vcl_vector<vdgl_digital_curve_sptr>::iterator eit = vd_edges.begin();
00493 eit != vd_edges.end(); ++eit)
00494 {
00495
00496 vdgl_interpolator_sptr itrp = (*eit)->get_interpolator();
00497 vdgl_edgel_chain_sptr ech = itrp->get_edgel_chain();
00498 unsigned int n = ech->size();
00499
00500 vsol_digital_curve_2d_sptr vsdc = new vsol_digital_curve_2d();
00501 for (unsigned int i=0; i<n;i++)
00502 {
00503 vdgl_edgel ed = (*ech)[i];
00504 double x = ed.get_x(), y = ed.get_y();
00505 vsdc->add_vertex(new vsol_point_2d(x, y));
00506 }
00507
00508 edges.push_back(vsdc);
00509 }
00510 return true;
00511 }