00001 #include "brip_para_cvrg.h"
00002
00003
00004
00005 #include <vul/vul_timer.h>
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_cmath.h>
00008 #include <vcl_cassert.h>
00009 #include "brip_vil_float_ops.h"
00010
00011
00012
00013 void brip_para_cvrg::init_variables()
00014 {
00015 width_ = int(3*sigma_);
00016 proj_n_ = 2*proj_width_ + 1;
00017 sup_proj_ = vcl_vector<float>(proj_n_, 0.0f);
00018 proj_0_ = vcl_vector<float>(proj_n_, 0.0f);
00019 proj_45_ = vcl_vector<float>(proj_n_, 0.0f);
00020 proj_90_ = vcl_vector<float>(proj_n_, 0.0f);
00021 proj_135_ = vcl_vector<float>(proj_n_, 0.0f);
00022 }
00023
00024
00025
00026
00027 void brip_para_cvrg::init(vil_image_resource_sptr const & image)
00028 {
00029 vul_timer t;
00030
00031 int w = image->ni(), h = image->nj();
00032 xstart_ = 0;
00033 ystart_ = 0;
00034 xsize_ = w;
00035 ysize_ = h;
00036
00037 vcl_cout << "xstart = " << xstart_ << " ystart_ = " << ystart_ << '\n'
00038 << "xsize = " << xsize_ << " ysize_ = " << ysize_ << '\n'
00039 << vcl_flush;
00040
00041 image_ = brip_vil_float_ops::convert_to_float(image);
00042 avg_.set_size(w,h);
00043 grad0_.set_size(w,h);
00044 grad45_.set_size(w,h);
00045 grad90_.set_size(w,h);
00046 grad135_.set_size(w,h);
00047 det_.set_size(w,h);
00048 dir_.set_size(w,h);
00049 this->init_variables();
00050 vcl_cout << "Do Initialization in " << t.real() << " msecs\n"
00051 << vcl_flush;
00052 }
00053
00054
00055
00056 brip_para_cvrg::brip_para_cvrg(float sigma, float thresh,
00057 float gauss_tail, int proj_width,
00058 int proj_height, int sup_radius,
00059 bool v) :
00060 brip_para_cvrg_params(sigma, thresh, gauss_tail, proj_width, proj_height,
00061 sup_radius, v)
00062 {
00063 this->init_variables();
00064 }
00065
00066 brip_para_cvrg::brip_para_cvrg(brip_para_cvrg_params& pdp) :
00067 brip_para_cvrg_params(pdp)
00068 {
00069 this->init_variables();
00070 }
00071
00072
00073
00074 brip_para_cvrg::~brip_para_cvrg()
00075 {
00076 }
00077
00078
00079
00080 void brip_para_cvrg::smooth_image()
00081 {
00082 vul_timer t;
00083 smooth_ = brip_vil_float_ops::gaussian(image_, sigma_);
00084 vcl_cout << "Smooth image in " << t.real() << " msecs\n"
00085 << vcl_flush;
00086 }
00087
00088
00089
00090
00091 void brip_para_cvrg::avg(int x, int y, vil_image_view<float> const& smooth, vil_image_view<float>& avg)
00092 {
00093 float sum =0;
00094 for (int i = -3; i<=3; i++)
00095 for (int j = -3; j<=3; j++)
00096 {
00097 sum += smooth(x+i, y+j);
00098 }
00099
00100 avg(x,y) = sum/49.0f;
00101 }
00102
00103
00104
00105
00106 void brip_para_cvrg::grad0(int x, int y, vil_image_view<float> const& smooth,
00107 vil_image_view<float>& grad0)
00108 {
00109 float plus = 0.5f*smooth(x+1,y+3) + smooth(x+1,y+2) + smooth(x+1,y+1) +
00110 smooth(x+1,y) + smooth(x+1,y-1) + smooth(x+1,y-2)
00111 + 0.5f*smooth(x+1,y-3);
00112 float minus = 0.5f*smooth(x-1,y+3) + smooth(x-1,y+2) + smooth(x-1,y+1) +
00113 smooth(x-1,y) + smooth(x-1,y-1) + smooth(x-1,y-2) + 0.5f*smooth(x-1,y-3);
00114 grad0(x,y) = (plus-minus);
00115 }
00116
00117
00118
00119
00120 void brip_para_cvrg::grad45(int x, int y, vil_image_view<float> const& smooth,
00121 vil_image_view<float>& grad45)
00122 {
00123 float plus = smooth(x-2,y+3) + smooth(x-1,y+2) + smooth(x,y+1)
00124 + smooth(x+1,y) + smooth(x+2,y-1) + smooth(x+3,y-2);
00125 float minus = smooth(x-3,y+2) + smooth(x-2,y+1) + smooth(x-1,y)
00126 + smooth(x,y-1) + smooth(x+1,y-2) + smooth(x+2,y-3);
00127
00128 grad45(x,y) = 1.30f*(plus-minus);
00129 }
00130
00131
00132
00133
00134 void brip_para_cvrg::grad90(int x, int y, vil_image_view<float> const& smooth,
00135 vil_image_view<float>& grad90)
00136 {
00137 float plus = 0.5f*smooth(x+3,y+1) + smooth(x+2,y+1) + + smooth(x+1,y+1) +
00138 smooth(x,y+1) + smooth(x-1,y+1) + smooth(x-2,y+1) + 0.5f*smooth(x-3,y+1);
00139 float minus =0.5f*smooth(x+3,y-1) + smooth(x+2,y-1)+ smooth(x+1,y-1) +
00140 smooth(x,y-1) + smooth(x-1,y-1) + smooth(x-2,y-1) + 0.5f*smooth(x-3,y-1);
00141 grad90(x, y) = (plus-minus);
00142 }
00143
00144
00145
00146
00147 void brip_para_cvrg::grad135(int x, int y, vil_image_view<float> const& smooth,
00148 vil_image_view<float>& grad135)
00149 {
00150 float plus = smooth(x+3,y+2) + smooth(x+2,y+1) + smooth(x+1,y)
00151 + smooth(x,y-1) + smooth(x-1,y-2) + smooth(x-2,y-3);
00152 float minus = smooth(x+2,y+3) + smooth(x+1,y+2) + smooth(x,y+1)
00153 + smooth(x-1,y) + smooth(x-2,y-1) + smooth(x-3,y-2);
00154
00155 grad135(x, y) = 1.3f*(plus-minus);
00156 }
00157
00158
00159
00160
00161
00162 void brip_para_cvrg::compute_gradients()
00163 {
00164 vul_timer t;
00165 int x,y;
00166 int radius = width_+3;
00167 grad0_.fill(0.0f);
00168 grad45_.fill(0.0f);
00169 grad90_.fill(0.0f);
00170 grad135_.fill(0.0f);
00171 for (y=radius;y<ysize_ - radius;y++)
00172 for (x=radius;x<xsize_ - radius;x++)
00173 {
00174 this->avg(x, y, smooth_, avg_);
00175 this->grad0(x, y, smooth_, grad0_);
00176 this->grad45(x, y, smooth_, grad45_);
00177 this->grad90(x, y, smooth_, grad90_);
00178 this->grad135(x, y, smooth_, grad135_);
00179 }
00180 vcl_cout << "Compute gradients in " << t.real() << " msecs\n"
00181 << vcl_flush;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 float brip_para_cvrg::project(int x, int y, int dir,
00199 vcl_vector<float>& projection)
00200 {
00201 int w,h;
00202 int w0 = proj_width_;
00203
00204 for (h=-proj_height_; h<=proj_height_; h++)
00205 for (w=-w0; w<=w0; w++)
00206 {
00207 switch (dir)
00208 {
00209 case 0:
00210 projection[w+w0] += grad0_(x+w,y+h);
00211 break;
00212 case 45:
00213 projection[w+w0] += grad45_(x+h+w,y+w-h);
00214 break;
00215 case 90:
00216 projection[w+w0] += grad90_(x+h,y+w);
00217 break;
00218 case 135:
00219 projection[w+w0] += grad135_(x+h-w,y+w+h);
00220 break;
00221 default:
00222 projection[w+w0] += 0;
00223 break;
00224 }
00225 }
00226 float max_energy = 0;
00227 for (int i =0; i<proj_n_; i++)
00228 {
00229 float val = vcl_fabs(projection[i]);
00230 if (val>max_energy)
00231 max_energy = val;
00232 }
00233 return max_energy;
00234 }
00235
00236
00237
00238
00239
00240
00241 void brip_para_cvrg::remove_flat_peaks(int n, vcl_vector<float>& array)
00242 {
00243 int nbm = n-1;
00244
00245
00246
00247 bool init= array[0]==0;
00248 int init_end =0;
00249
00250
00251 bool start=false;
00252 int start_index=0;
00253
00254
00255 for (int i = 0; i < n; i++)
00256 {
00257 float v = array[i];
00258
00259
00260 if (init&&v!=0)
00261 continue;
00262
00263 if (init&&v==0)
00264 {
00265 init_end = i;
00266 init = false;
00267 continue;
00268 }
00269
00270
00271 if (!start&&v==0)
00272 continue;
00273
00274
00275 if (!start&&v!=0)
00276 {
00277 start_index = i;
00278 start = true;
00279 continue;
00280 }
00281
00282 if (start&&v==0)
00283 {
00284 int peak_location = (start_index+i-1)/2;
00285 for (int k = start_index; k<=(i-1); k++)
00286 if (k!=peak_location)
00287 array[k] = 0;
00288 start = false;
00289 }
00290 }
00291
00292 if (init_end!=0)
00293 {
00294 int init_location = (init_end-1)/2;
00295 for (int k = 0; k<init_end; k++)
00296 if (k!=init_location)
00297 array[k] = 0;
00298 }
00299 if (start)
00300 {
00301 int end_location = (start_index + nbm)/2;
00302 for (int k = start_index; k<n; k++)
00303 if (k!=end_location)
00304 array[k] = 0;
00305 }
00306 }
00307
00308
00309
00310
00311 void brip_para_cvrg::non_maximum_supress(vcl_vector<float> const& input_array,
00312 vcl_vector<float>& sup_array)
00313 {
00314 if ((2*sup_radius_ +1)> proj_width_)
00315 {
00316 vcl_cout << "In brip_para_cvrg::NonMaximumSupress(..) the kernel is too large\n";
00317 }
00318 vcl_vector<float> tmp(proj_n_);
00319 for (int i=0; i<proj_n_; i++)
00320 tmp[i]=vcl_fabs(input_array[i]);
00321
00322
00323
00324 for (int i = sup_radius_; i < (proj_n_-sup_radius_); i++)
00325 {
00326
00327 float max_val = 0;
00328 for (int k = -sup_radius_; k <= sup_radius_ ;k++)
00329 {
00330 int index = i+k;
00331 if (tmp[index] > max_val)
00332 max_val = tmp[index];
00333 }
00334
00335 if (vcl_fabs(max_val-tmp[i])<1e-03)
00336 sup_array[i] = max_val;
00337 }
00338 this->remove_flat_peaks(proj_n_, sup_array);
00339 }
00340
00341
00342
00343
00344 float brip_para_cvrg::parallel_coverage(vcl_vector<float> const& input_array)
00345 {
00346 sup_proj_.resize(proj_n_, 0.0f);
00347 this->non_maximum_supress(input_array, sup_proj_);
00348 int n_peaks = 0;
00349 float proj_sum = 0;
00350 for (int i = 0; i<proj_n_; i++)
00351 if (sup_proj_[i]>0)
00352 {
00353 n_peaks++;
00354 proj_sum += sup_proj_[i];
00355 }
00356 if (n_peaks<2)
00357 return 0;
00358 return proj_sum/float(n_peaks);
00359 }
00360
00361
00362
00363
00364 void brip_para_cvrg::compute_parallel_coverage()
00365 {
00366 vul_timer t;
00367
00368 det_.fill(0.0f);
00369 dir_.fill(0.0f);
00370 float direct;
00371 int radius = proj_width_+proj_height_ + 3;
00372
00373 for (int y=radius; y<(ysize_-radius);y++)
00374 for (int x=radius ;x<(xsize_-radius);x++)
00375 {
00376
00377 proj_0_ = vcl_vector<float>(proj_n_, 0.0f);
00378 proj_45_ = vcl_vector<float>(proj_n_, 0.0f);
00379 proj_90_ = vcl_vector<float>(proj_n_, 0.0f);
00380 proj_135_ = vcl_vector<float>(proj_n_, 0.0f);
00381 float coverage[4];
00382 this->project(x, y, 0, proj_0_);
00383 coverage[0] = this->parallel_coverage(proj_0_);
00384 float max_coverage = coverage[0];
00385 direct = 0.f;
00386 this->project(x, y, 45, proj_45_);
00387 coverage[1] = this->parallel_coverage(proj_45_);
00388 if (coverage[1]>max_coverage)
00389 {
00390 max_coverage = coverage[1];
00391 direct = 45.f;
00392 }
00393 this->project(x, y, 90, proj_90_);
00394 coverage[2] = this->parallel_coverage(proj_90_);
00395 if (coverage[2]>max_coverage)
00396 {
00397 max_coverage = coverage[2];
00398 direct = 90.f;
00399 }
00400 this->project(x, y, 135, proj_135_);
00401 coverage[3] = this->parallel_coverage(proj_135_);
00402 if (coverage[3]>max_coverage)
00403 {
00404 max_coverage = coverage[3];
00405 direct = 135.f;
00406 }
00407 #ifdef DEBUG
00408 vcl_cout << '(' << x << ',' << y << ") coverage:\n"
00409 << " O degrees = " << coverage[0] << '\n'
00410 << " 45 degrees = " << coverage[1] << '\n'
00411 << " 90 degrees = " << coverage[2] << '\n'
00412 << " 135 degrees = " << coverage[3] << '\n'
00413 << "max_coverage = " << max_coverage << '\n';
00414 #endif
00415
00416 det_(x,y) = max_coverage;
00417 dir_(x,y) = direct;
00418 }
00419 vcl_cout << "Do parallel coverage in " << t.real() << " msecs\n"
00420 << vcl_flush;
00421 }
00422
00423
00424
00425
00426 void brip_para_cvrg::compute_image(vil_image_view<float> const& data,
00427 vil_image_view<unsigned char>& image)
00428 {
00429 image = vil_image_view<unsigned char>(xsize_, ysize_);
00430
00431 float max_val = 0;
00432 for (int y = 0; y<ysize_; y++)
00433 for (int x = 0; x<xsize_; x++)
00434 if (data(x,y)>max_val)
00435 max_val = data(x,y);
00436 if (max_val<1e-06)
00437 max_val = 1e-06f;
00438
00439 for (int y = 0; y<ysize_; y++)
00440 for (int x = 0; x<xsize_; x++)
00441 {
00442 float temp = 255*data(x,y)/max_val;
00443 unsigned char val;
00444 val = (unsigned char)temp;
00445 image(x, y)=val;
00446 }
00447 }
00448
00449
00450 void brip_para_cvrg::do_coverage(vil_image_resource_sptr const& image)
00451 {
00452 this->init(image);
00453 this->smooth_image();
00454 this->compute_gradients();
00455 this->compute_parallel_coverage();
00456 }
00457
00458
00459
00460
00461 vil_image_view<float>
00462 brip_para_cvrg::get_float_detection_image(const float max)
00463 {
00464 vil_image_view<float> out(xsize_, ysize_);
00465 out.fill(0);
00466 float max_val = 0;
00467 for (int y = 0; y<ysize_; y++)
00468 for (int x = 0; x<xsize_; x++)
00469 if (det_(x,y)>max_val)
00470 max_val = det_(x,y);
00471
00472 if (max_val==0)
00473 return out;
00474 float s = max/max_val;
00475 for (int y = 0; y<ysize_; y++)
00476 for (int x = 0; x<xsize_; x++)
00477 out(x,y) = s*det_(x,y);
00478 return out;
00479 }
00480
00481
00482
00483
00484 vil_image_view<unsigned char> brip_para_cvrg::get_detection_image()
00485 {
00486 if (!det_image_)
00487 this->compute_image(det_, det_image_);
00488 return det_image_;
00489 }
00490
00491
00492
00493
00494 vil_image_view<unsigned char> brip_para_cvrg::get_dir_image()
00495 {
00496 if (!dir_image_) {
00497 dir_image_ = vil_image_view<unsigned char>(xsize_, ysize_);
00498 }
00499 for (int y = 0; y<ysize_; y++)
00500 for (int x = 0; x<xsize_; x++)
00501 dir_image_(x,y) = static_cast<unsigned char>(dir_(x,y));
00502 return dir_image_;
00503 }
00504
00505
00506
00507 vil_image_view<vil_rgb<unsigned char> >
00508 brip_para_cvrg::get_combined_image()
00509 {
00510
00511 unsigned char r[4] ={0, 255, 0, 255};
00512 unsigned char g[4] ={255, 0, 255, 0};
00513 unsigned char b[4] ={255, 255, 0, 0};
00514 vil_image_view<unsigned char> cvrg_image = this->get_detection_image();
00515 vil_image_view<unsigned char> dir_image = this->get_dir_image();
00516 vil_image_view<vil_rgb<unsigned char> > out(xsize_, ysize_);
00517 for (int y = 0; y<ysize_; y++)
00518 for (int x = 0; x<xsize_; x++)
00519 {
00520 unsigned int direct = ((unsigned int)dir_image(x,y))/45;
00521
00522 if (direct>3) continue;
00523 unsigned char c = cvrg_image(x,y),
00524 red = r[direct]&c,
00525 green= g[direct]&c,
00526 blue = b[direct]&c;
00527 out(x, y) = vil_rgb<unsigned char>(red, green, blue);
00528 }
00529 return out;
00530 }