00001
00002 #include "droid.h"
00003
00004 #include <vcl_cmath.h>
00005 #include <vcl_cstring.h>
00006
00007 #include <osl/osl_roi_window.h>
00008
00009
00010
00011
00012
00013
00014 void droid::compute_gradx_grady (osl_roi_window *window_str,
00015 vil1_memory_image_of<vxl_byte> *image_ptr,
00016 vil1_memory_image_of<int> *image_gradx_ptr,
00017 vil1_memory_image_of<int> *image_grady_ptr)
00018
00019 {
00020 int row_start = window_str->row_start_index;
00021 int col_start = window_str->col_start_index;
00022 int row_end = window_str->row_end_index;
00023 int col_end = window_str->col_end_index;
00024
00025 for (int row = row_start; row < row_end; row++) {
00026 for (int col = col_start; col < col_end; col++) {
00027 #if 1
00028 (*image_gradx_ptr)[row][col]
00029 = 2*((*image_ptr)[row][col+2]-(*image_ptr)[row][col-2])
00030 +((*image_ptr)[row][col+1]-(*image_ptr)[row][col-1]);
00031
00032 (*image_grady_ptr) [row][col]
00033 = 2*((*image_ptr)[row+2][col]-(*image_ptr)[row-2][col])
00034 +((*image_ptr)[row+1][col]-(*image_ptr)[row-1][col]);
00035 #else
00036 (*image_gradx_ptr)[row][col] = (*image_ptr)[row][col+1] - (*image_ptr)[row][col-1];
00037 (*image_grady_ptr)[row][col] = (*image_ptr)[row+1][col] - (*image_ptr)[row-1][col];
00038 #endif
00039 }
00040 }
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 void droid::compute_fxx_fxy_fyy (osl_roi_window *window_str,
00057 vil1_memory_image_of<int> *image_gradx_ptr,
00058 vil1_memory_image_of<int> *image_grady_ptr,
00059 vil1_memory_image_of<float> *image_fxx_ptr,
00060 vil1_memory_image_of<float> *image_fxy_ptr,
00061 vil1_memory_image_of<float> *image_fyy_ptr)
00062 {
00063 float gradx,grady;
00064
00065 int row_start = window_str->row_start_index;
00066 int col_start = window_str->col_start_index;
00067 int row_end = window_str->row_end_index;
00068 int col_end = window_str->col_end_index;
00069
00070 for (int row = row_start; row < row_end; row++) {
00071 for (int col = col_start; col < col_end; col++) {
00072
00073 gradx = (float) ((*image_gradx_ptr) [row-2][col ] +
00074 (*image_gradx_ptr) [row-1][col ] +
00075 (*image_gradx_ptr) [row ][col ] +
00076 (*image_gradx_ptr) [row+1][col ] +
00077 (*image_gradx_ptr) [row+2][col ]);
00078
00079 grady = (float) ((*image_grady_ptr) [row ][col-2] +
00080 (*image_grady_ptr) [row ][col-1] +
00081 (*image_grady_ptr) [row ][col ] +
00082 (*image_grady_ptr) [row ][col+1] +
00083 (*image_grady_ptr) [row ][col+2]);
00084
00085 (*image_fxx_ptr) [row][col] = gradx * gradx;
00086 (*image_fxy_ptr) [row][col] = gradx * grady;
00087 (*image_fyy_ptr) [row][col] = grady * grady;
00088 }
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 float droid::compute_cornerness (osl_roi_window *window_str,
00099 vil1_memory_image_of<float> *image_fxx_ptr,
00100 vil1_memory_image_of<float> *image_fxy_ptr,
00101 vil1_memory_image_of<float> *image_fyy_ptr,
00102 float scale,
00103 vil1_memory_image_of<float> *pixel_cornerness)
00104 {
00105 float corner_max = 0;
00106
00107 for (int row = window_str->row_start_index; row < window_str->row_end_index; row++) {
00108 for (int col = window_str->col_start_index; col < window_str->col_end_index; col++) {
00109
00110
00111 #if 0
00112 float determinant
00113 = (*image_fxx_ptr) [row][col] * (*image_fyy_ptr) [row][col]
00114 - (*image_fxy_ptr) [row][col] * (*image_fxy_ptr) [row][col];
00115 float trace
00116 = (*image_fxx_ptr) [row][col] + (*image_fyy_ptr) [row][col];
00117 #else
00118 float fxx = (*image_fxx_ptr) [row][col];
00119 float fxy = (*image_fxy_ptr) [row][col];
00120 float fyy = (*image_fyy_ptr) [row][col];
00121 float determinant = fxx*fyy - fxy*fxy;
00122 float trace = fxx + fyy;
00123 #endif
00124 (*pixel_cornerness) [row][col] = determinant - scale*trace*trace;
00125
00126
00127 if ((*pixel_cornerness) [row][col] > corner_max)
00128 corner_max = (*pixel_cornerness) [row][col];
00129 }
00130 }
00131
00132 return corner_max;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 int droid::find_corner_maxima (float corner_min,
00144 osl_roi_window *window_str,
00145 vil1_memory_image_of<float> *pixel_cornerness,
00146 vil1_memory_image_of<bool> *image_corner_max_ptr)
00147 {
00148
00149
00150
00151 int row, col;
00152
00153
00154
00155
00156 row = window_str->row_start_index;
00157 for (col = window_str->col_start_index; col < window_str->col_end_index; col++)
00158 (*image_corner_max_ptr) [row][col] = false;
00159 row++;
00160 for (col = window_str->col_start_index; col < window_str->col_end_index; col++)
00161 (*image_corner_max_ptr) [row][col] = false;
00162
00163
00164 row = window_str->row_end_index-1;
00165 for (col = window_str->col_start_index; col < window_str->col_end_index; col++)
00166 (*image_corner_max_ptr) [row][col] = false;
00167 row--;
00168 for (col = window_str->col_start_index; col < window_str->col_end_index; col++)
00169 (*image_corner_max_ptr) [row][col] = false;
00170
00171
00172 col = window_str->col_start_index;
00173 for (row = window_str->row_start_index; row < window_str->row_end_index; row++)
00174 (*image_corner_max_ptr) [row][col] = false;
00175 col++;
00176 for (row = window_str->row_start_index; row < window_str->row_end_index; row++)
00177 (*image_corner_max_ptr) [row][col] = false;
00178
00179
00180 col = window_str->col_end_index-1;
00181 for (row = window_str->row_start_index; row < window_str->row_end_index; row++)
00182 (*image_corner_max_ptr) [row][col] = false;
00183 col--;
00184 for (row = window_str->row_start_index; row < window_str->row_end_index; row++)
00185 (*image_corner_max_ptr) [row][col] = false;
00186
00187
00188
00189
00190
00191
00192
00193
00194 int maxima_count = 0;
00195 for (row = window_str->row_start_index+2; row < window_str->row_end_index-2; row++) {
00196 for (col = window_str->col_start_index+2; col < window_str->col_end_index-2; col++) {
00197
00198 float pc=(*pixel_cornerness)[row][col];
00199
00200
00201 if ((pc > corner_min)
00202
00203 && (pc >= (*pixel_cornerness) [row-2][col-2])
00204 && (pc >= (*pixel_cornerness) [row-2][col-1])
00205 && (pc >= (*pixel_cornerness) [row-2][col ])
00206 && (pc >= (*pixel_cornerness) [row-2][col+1])
00207 && (pc >= (*pixel_cornerness) [row-2][col+2])
00208
00209 && (pc >= (*pixel_cornerness) [row-1][col-2])
00210 && (pc >= (*pixel_cornerness) [row-1][col-1])
00211 && (pc >= (*pixel_cornerness) [row-1][col ])
00212 && (pc >= (*pixel_cornerness) [row-1][col+1])
00213 && (pc >= (*pixel_cornerness) [row-1][col+2])
00214
00215 && (pc >= (*pixel_cornerness) [row ][col-2])
00216 && (pc >= (*pixel_cornerness) [row ][col-1])
00217
00218 && (pc > (*pixel_cornerness) [row ][col+1])
00219 && (pc > (*pixel_cornerness) [row ][col+2])
00220
00221 && (pc > (*pixel_cornerness) [row+1][col-2])
00222 && (pc > (*pixel_cornerness) [row+1][col-1])
00223 && (pc > (*pixel_cornerness) [row+1][col ])
00224 && (pc > (*pixel_cornerness) [row+1][col+1])
00225 && (pc > (*pixel_cornerness) [row+1][col+2])
00226
00227 && (pc > (*pixel_cornerness) [row+2][col-2])
00228 && (pc > (*pixel_cornerness) [row+2][col-1])
00229 && (pc > (*pixel_cornerness) [row+2][col ])
00230 && (pc > (*pixel_cornerness) [row+2][col+1])
00231 && (pc > (*pixel_cornerness) [row+2][col+2]))
00232 {
00233 (*image_corner_max_ptr) [row][col] = true;
00234 maxima_count++;
00235 }
00236
00237 else
00238 (*image_corner_max_ptr) [row][col] = false;
00239 }
00240 }
00241 return maxima_count;
00242 }
00243
00244
00245
00246
00247
00248
00249 float droid::compute_corner_min (float ,
00250 float corner_max,
00251 int corner_count_max,
00252 osl_roi_window *window_str,
00253 vil1_memory_image_of<float> *pixel_cornerness,
00254 vil1_memory_image_of<bool> *image_corner_max_ptr)
00255 {
00256 #define DR_BIN_COUNT 200
00257
00258 float
00259 corner_4throot,
00260 corner_max_4throot;
00261
00262 int
00263 bin_array [DR_BIN_COUNT],
00264 bin_index,
00265 corner_count;
00266
00267 vcl_memset (bin_array, 0, sizeof (bin_array));
00268 corner_max_4throot = (float)vcl_pow ((double) corner_max, 0.25);
00269
00270 for (int row = window_str->row_start_index; row < window_str->row_end_index; row++) {
00271 for (int col = window_str->col_start_index; col < window_str->col_end_index; col++) {
00272 if ((*image_corner_max_ptr) [row][col]) {
00273 corner_4throot = (float)vcl_pow ((double) (*pixel_cornerness) [row][col], 0.25);
00274 bin_index = (int) ((DR_BIN_COUNT-1) * corner_4throot / corner_max_4throot);
00275 bin_array [bin_index]++;
00276 }
00277 }
00278 }
00279
00280 corner_count = 0;
00281 bin_index = DR_BIN_COUNT-1;
00282 while ((corner_count < corner_count_max) && (bin_index > 0)) {
00283 corner_count += bin_array [bin_index];
00284 bin_index--;
00285 }
00286
00287
00288
00289
00290 bin_index += 2;
00291
00292 return (float)vcl_pow ((double) bin_index / (double) (DR_BIN_COUNT-1) * corner_max_4throot, 4.0);
00293
00294 #undef DR_BIN_COUNT
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 bool droid::compute_subpixel_max (vil1_memory_image_of<float> *pixel_cornerness,
00305 int row, int col,
00306 double &x, double &y,
00307 bool pab_emulate)
00308 {
00309
00310 #define DR_P11 (*pixel_cornerness) [row-1][col-1]
00311 #define DR_P12 (*pixel_cornerness) [row-1][col ]
00312 #define DR_P13 (*pixel_cornerness) [row-1][col+1]
00313 #define DR_P21 (*pixel_cornerness) [row ][col-1]
00314 #define DR_P22 (*pixel_cornerness) [row ][col ]
00315 #define DR_P23 (*pixel_cornerness) [row ][col+1]
00316 #define DR_P31 (*pixel_cornerness) [row+1][col-1]
00317 #define DR_P32 (*pixel_cornerness) [row+1][col ]
00318 #define DR_P33 (*pixel_cornerness) [row+1][col+1]
00319
00320
00321
00322 float b,c,d,e,f;
00323
00324 if (pab_emulate) {
00325
00326
00327
00328 b=0.125f*(-DR_P11 -2*DR_P21 - DR_P31 + DR_P13 +2*DR_P23 + DR_P33);
00329
00330
00331
00332
00333 c=0.125f*(-DR_P11 + DR_P31 -2*DR_P12 +2*DR_P32 - DR_P13 + DR_P33);
00334
00335
00336
00337
00338 d=0.25f*( DR_P11 +2*DR_P21 + DR_P31 -2*DR_P12 -4*DR_P22 -2*DR_P32 +DR_P13 +2*DR_P23+DR_P33);
00339
00340
00341
00342
00343 e=0.25f*( DR_P11 - DR_P31 - DR_P13 + DR_P33);
00344
00345
00346
00347
00348 f=0.25f*( DR_P11 -2*DR_P21 + DR_P31 +2*DR_P12 -4*DR_P22 +2*DR_P32 +DR_P13 -2*DR_P23+DR_P33);
00349 }
00350 else {
00351
00352
00353
00354
00355
00356
00357
00358
00359 b=(-DR_P11 + DR_P13 - DR_P21 + DR_P23 - DR_P31 + DR_P33)/6.0f;
00360
00361
00362
00363
00364 c=(-DR_P11 - DR_P12 - DR_P13 + DR_P31 + DR_P32 + DR_P33)/6.0f;
00365
00366
00367
00368
00369 d=( DR_P11 -2*DR_P12 + DR_P13 + DR_P21 -2*DR_P22 + DR_P23 +DR_P31 -2*DR_P32+DR_P33)/3.0f;
00370
00371
00372
00373
00374 e=( DR_P11 - DR_P31 - DR_P13 + DR_P33)/4.0f;
00375
00376
00377
00378
00379 f=( DR_P11 + DR_P12 + DR_P13 -2*DR_P21 -2*DR_P22 -2*DR_P23 +DR_P31 + DR_P32+DR_P33)/3.0f;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 float det = d*f - e*e;
00394 if ((pab_emulate && (det != 0)) ||
00395 (!pab_emulate && (det > 0))) {
00396 float off_x = (c*e - b*f) / det;
00397 float off_y = (b*e - c*d) / det;
00398
00399
00400 if (vcl_fabs (off_x) > 1.0 || vcl_fabs (off_y) > 1.0)
00401 return false;
00402 else {
00403 x = col+off_x;
00404 y = row+off_y;
00405 return true;
00406 }
00407 }
00408
00409 else if (!pab_emulate && det<0) {
00410 x = col;
00411 y = row;
00412 return true;
00413 }
00414
00415 else
00416 return false;
00417
00418 #undef DR_P11
00419 #undef DR_P12
00420 #undef DR_P13
00421 #undef DR_P21
00422 #undef DR_P22
00423 #undef DR_P23
00424 #undef DR_P31
00425 #undef DR_P32
00426 #undef DR_P33
00427 }
00428
00429
00430
00431
00432
00433
00434 int droid::find_local_maxima(float min,int winsize,
00435 int x1,int y1,
00436 int x2,int y2,
00437 vil1_memory_image_of<float> *bitmap,
00438 vil1_memory_image_of<bool> *max_p)
00439 {
00440
00441 for (int i=x1;i<x2;i++)
00442 for (int j=y1;j<y2;j++)
00443 (*max_p)[i][j] = (*bitmap)[i][j]>=min;
00444
00445
00446
00447
00448 for (int k=1;k<=winsize;k++) {
00449
00450 for (int i=x1;i<x2;i++)
00451 for (int j=y1;j<y2-k;j++)
00452 if ((*bitmap)[i][j] < (*bitmap)[i][j+k])
00453 (*max_p)[i][j ]=false;
00454 else
00455 (*max_p)[i][j+k]=false;
00456
00457
00458 for (int i=x1;i<x2-k;i++)
00459 for (int j=y1;j<y2;j++)
00460 if ((*bitmap)[i][j] < (*bitmap)[i+k][j])
00461 (*max_p)[i ][j]=false;
00462 else
00463 (*max_p)[i+k][j]=false;
00464 }
00465
00466 int count=0;
00467
00468
00469
00470 for (int i=x1+winsize;i<x2-winsize;i++) {
00471 for (int j=y1+winsize;j<y2-winsize;j++) {
00472 if (!(*max_p)[i][j])
00473 continue;
00474
00475 for (int r=1;r<=winsize;r++) {
00476 for (int s=1;s<=winsize;s++) {
00477 if ((*bitmap)[i][j] < (*bitmap)[i+r][j+s] ||
00478 (*bitmap)[i][j] < (*bitmap)[i-r][j+s] ||
00479 (*bitmap)[i][j] < (*bitmap)[i+r][j-s] ||
00480 (*bitmap)[i][j] < (*bitmap)[i-r][j-s]) {
00481 (*max_p)[i][j]=false;
00482 goto skip;
00483 }
00484 }
00485 }
00486 if ((*max_p)[i][j])
00487 count ++;
00488 skip: {;}
00489 }
00490 }
00491 return count;
00492 }