diff options
Diffstat (limited to 'SD-VBS/benchmarks/mser/src')
| -rw-r--r-- | SD-VBS/benchmarks/mser/src/c/mser.c | 714 | ||||
| -rw-r--r-- | SD-VBS/benchmarks/mser/src/c/mser.h | 83 | ||||
| -rw-r--r-- | SD-VBS/benchmarks/mser/src/c/script_mser.c | 120 |
3 files changed, 917 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/mser/src/c/mser.c b/SD-VBS/benchmarks/mser/src/c/mser.c new file mode 100644 index 0000000..d886d7a --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/c/mser.c | |||
| @@ -0,0 +1,714 @@ | |||
| 1 | /******************************** | ||
| 2 | Author: Sravanthi Kota Venkata | ||
| 3 | ********************************/ | ||
| 4 | |||
| 5 | /*** | ||
| 6 | % MSER Maximally Stable Extremal Regions | ||
| 7 | % R=MSER(I,DELTA) computes the Maximally Stable Extremal Regions | ||
| 8 | % (MSER) of image I with stability threshold DELTA. I is any | ||
| 9 | % array of class UINT8, while DELTA is a scalar of the same class. | ||
| 10 | % R is an index set (of class UINT32) which enumerates the | ||
| 11 | % representative pixels of the detected regions. | ||
| 12 | % | ||
| 13 | % A region R can be recovered from a representative pixel X as the | ||
| 14 | % connected component of the level set {Y:I(Y) <= I(X)} which | ||
| 15 | % contains X. | ||
| 16 | ***/ | ||
| 17 | |||
| 18 | |||
| 19 | #include "mser.h" | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | /* advance N-dimensional subscript */ | ||
| 23 | void | ||
| 24 | adv(iArray *dims, int ndims, iArray *subs_pt) | ||
| 25 | { | ||
| 26 | int d = 0 ; | ||
| 27 | while(d < ndims) | ||
| 28 | { | ||
| 29 | sref(subs_pt,d) = sref(subs_pt,d) + 1; | ||
| 30 | if( sref(subs_pt,d) < sref(dims,d) ) | ||
| 31 | return ; | ||
| 32 | sref(subs_pt,d++) = 0 ; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | /** driver **/ | ||
| 37 | I2D* mser(I2D* I, int in_delta, | ||
| 38 | iArray* subs_pt, iArray* nsubs_pt, iArray* strides_pt, iArray* visited_pt, iArray* dims, | ||
| 39 | uiArray* joins_pt, | ||
| 40 | region_t* regions_pt, | ||
| 41 | pair_t* pairs_pt, | ||
| 42 | node_t* forest_pt, | ||
| 43 | ulliArray* acc_pt, ulliArray* ell_pt, | ||
| 44 | I2D* out) | ||
| 45 | { | ||
| 46 | idx_t i, rindex=0; | ||
| 47 | int k; | ||
| 48 | int nout = 1; | ||
| 49 | |||
| 50 | int OUT_REGIONS=0; | ||
| 51 | int OUT_ELL = 1; | ||
| 52 | int OUT_PARENTS = 2; | ||
| 53 | int OUT_AREA = 3; | ||
| 54 | int BUCKETS = 256; | ||
| 55 | |||
| 56 | //I2D* out; | ||
| 57 | |||
| 58 | int IN_I = 0; | ||
| 59 | int IN_DELTA = 1; | ||
| 60 | |||
| 61 | /* configuration */ | ||
| 62 | int verbose = 1 ; /* be verbose */ | ||
| 63 | int small_cleanup= 1 ; /* remove very small regions */ | ||
| 64 | int big_cleanup = 1 ; /* remove very big regions */ | ||
| 65 | int bad_cleanup = 0 ; /* remove very bad regions */ | ||
| 66 | int dup_cleanup = 1 ; /* remove duplicates */ | ||
| 67 | val_t delta ; /* stability delta */ | ||
| 68 | |||
| 69 | /* node value denoting a void node */ | ||
| 70 | idx_t const node_is_void = 0xffffffff ; | ||
| 71 | |||
| 72 | //iArray* subs_pt ; /* N-dimensional subscript | ||
| 73 | //iArray* nsubs_pt ; /* diff-subscript to point to neigh. | ||
| 74 | // uiArray* strides_pt ; /* strides to move in image array | ||
| 75 | // uiArray* visited_pt ; /* flag | ||
| 76 | |||
| 77 | int nel ; /* number of image elements (pixels) */ | ||
| 78 | int ner = 0 ; /* number of extremal regions */ | ||
| 79 | int nmer = 0 ; /* number of maximally stable */ | ||
| 80 | int ndims ; /* number of dimensions */ | ||
| 81 | // iArray* dims ; /* dimensions | ||
| 82 | int njoins = 0 ; /* number of join ops */ | ||
| 83 | |||
| 84 | I2D* I_pt ; /* source image */ | ||
| 85 | //pair_t* pairs_pt ; /* scratch buffer to sort pixels | ||
| 86 | // node_t* forest_pt ; /* the extremal regions forest | ||
| 87 | // region_t* regions_pt ; /* list of extremal regions found | ||
| 88 | int regions_pt_size; | ||
| 89 | int pairs_pt_size; | ||
| 90 | int forest_pt_size; | ||
| 91 | |||
| 92 | /* ellipses fitting */ | ||
| 93 | //ulliArray* acc_pt ; /* accumulator to integrate region moments | ||
| 94 | //ulliArray* ell_pt ; /* ellipses parameters | ||
| 95 | int gdl ; /* number of parameters of an ellipse */ | ||
| 96 | //uiArray* joins_pt ; /* sequence of joins | ||
| 97 | |||
| 98 | delta = 0; | ||
| 99 | delta = in_delta; | ||
| 100 | |||
| 101 | /* get dimensions */ | ||
| 102 | |||
| 103 | nel = I->height*I->width; /* number of elements of src image */ | ||
| 104 | ndims = 2; | ||
| 105 | //dims = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 106 | I_pt = I; | ||
| 107 | |||
| 108 | sref(dims,0) = I->height; | ||
| 109 | sref(dims,1) = I->width; | ||
| 110 | |||
| 111 | /* allocate stuff */ | ||
| 112 | //subs_pt = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 113 | //nsubs_pt = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 114 | |||
| 115 | //strides_pt = malloc(sizeof(uiArray)+sizeof(unsigned int)*ndims); | ||
| 116 | //visited_pt = malloc(sizeof(uiArray) + sizeof(unsigned int)*nel); | ||
| 117 | //joins_pt = malloc(sizeof(uiArray) + sizeof(unsigned int)*nel); | ||
| 118 | |||
| 119 | //regions_pt = (region_t*)malloc(sizeof(region_t)*nel); | ||
| 120 | regions_pt_size = nel; | ||
| 121 | |||
| 122 | //pairs_pt = (pair_t*)malloc(sizeof(pair_t)*nel); | ||
| 123 | pairs_pt_size = nel; | ||
| 124 | |||
| 125 | //forest_pt = (node_t*)malloc(sizeof(node_t)*nel); | ||
| 126 | forest_pt_size = nel; | ||
| 127 | |||
| 128 | /* compute strides to move into the N-dimensional image array */ | ||
| 129 | sref(strides_pt,0) = 1; | ||
| 130 | for(k = 1 ; k < ndims ; ++k) | ||
| 131 | { | ||
| 132 | sref(strides_pt,k) = sref(strides_pt,k-1) * sref(dims,k-1) ; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* sort pixels in increasing order of intensity: using Bucket Sort */ | ||
| 136 | { | ||
| 137 | int unsigned buckets [BUCKETS] ; | ||
| 138 | memset(buckets, 0, sizeof(int unsigned)*BUCKETS) ; | ||
| 139 | |||
| 140 | for(i = 0 ; i < nel ; ++i) | ||
| 141 | { | ||
| 142 | val_t v = asubsref(I_pt,i) ; | ||
| 143 | ++buckets[v] ; | ||
| 144 | } | ||
| 145 | |||
| 146 | for(i = 1 ; i < BUCKETS ; ++i) | ||
| 147 | { | ||
| 148 | arrayref(buckets,i) += arrayref(buckets,i-1) ; | ||
| 149 | } | ||
| 150 | |||
| 151 | for(i = nel ; i >= 1 ; ) | ||
| 152 | { | ||
| 153 | val_t v = asubsref(I_pt,--i) ; | ||
| 154 | idx_t j = --buckets[v] ; | ||
| 155 | pairs_pt[j].value = v ; | ||
| 156 | pairs_pt[j].index = i ; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | /* initialize the forest with all void nodes */ | ||
| 161 | for(i = 0 ; i < nel ; ++i) | ||
| 162 | { | ||
| 163 | forest_pt[i].parent = node_is_void ; | ||
| 164 | } | ||
| 165 | |||
| 166 | /* number of ellipse free parameters */ | ||
| 167 | gdl = ndims*(ndims+1)/2 + ndims ; | ||
| 168 | |||
| 169 | /* ----------------------------------------------------------------- | ||
| 170 | * Compute extremal regions tree | ||
| 171 | * -------------------------------------------------------------- */ | ||
| 172 | |||
| 173 | for(i = 0 ; i < nel ; ++i) | ||
| 174 | { | ||
| 175 | /* pop next node xi */ | ||
| 176 | idx_t index = pairs_pt [i].index ; | ||
| 177 | val_t value = pairs_pt [i].value ; | ||
| 178 | |||
| 179 | /* this will be needed later */ | ||
| 180 | rindex = index ; | ||
| 181 | |||
| 182 | /* push it into the tree */ | ||
| 183 | forest_pt [index] .parent = index ; | ||
| 184 | forest_pt [index] .shortcut = index ; | ||
| 185 | forest_pt [index] .area = 1 ; | ||
| 186 | #ifdef USE_RANK_UNION | ||
| 187 | forest_pt [index] .height = 1 ; | ||
| 188 | #endif | ||
| 189 | |||
| 190 | /* convert index into a subscript sub; also initialize nsubs | ||
| 191 | to (-1,-1,...,-1) */ | ||
| 192 | { | ||
| 193 | idx_t temp = index ; | ||
| 194 | for(k = ndims-1 ; k >=0 ; --k) | ||
| 195 | { | ||
| 196 | sref(nsubs_pt,k) = -1 ; | ||
| 197 | sref(subs_pt,k) = temp / sref(strides_pt,k) ; | ||
| 198 | temp = temp % sref(strides_pt,k) ; | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | /* process neighbors of xi */ | ||
| 203 | while(1) | ||
| 204 | { | ||
| 205 | int good = 1 ; | ||
| 206 | idx_t nindex = 0 ; | ||
| 207 | |||
| 208 | /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX | ||
| 209 | and check that the pixel is within image boundaries. */ | ||
| 210 | for(k = 0 ; k < ndims && good ; ++k) | ||
| 211 | { | ||
| 212 | int temp = sref(nsubs_pt,k) + sref(subs_pt,k) ; | ||
| 213 | good &= 0 <= temp && temp < sref(dims,k) ; | ||
| 214 | nindex += temp * sref(strides_pt,k) ; | ||
| 215 | } | ||
| 216 | |||
| 217 | |||
| 218 | /* keep going only if | ||
| 219 | 1 - the neighbor is within image boundaries; | ||
| 220 | 2 - the neighbor is indeed different from the current node | ||
| 221 | (this happens when nsub=(0,0,...,0)); | ||
| 222 | 3 - the nieghbor is already in the tree, meaning that | ||
| 223 | is a pixel older than xi. | ||
| 224 | */ | ||
| 225 | if(good && nindex != index && forest_pt[nindex].parent != node_is_void ) | ||
| 226 | { | ||
| 227 | idx_t nrindex = 0, nvisited ; | ||
| 228 | val_t nrvalue = 0 ; | ||
| 229 | |||
| 230 | |||
| 231 | #ifdef USE_RANK_UNION | ||
| 232 | int height = forest_pt [ rindex] .height ; | ||
| 233 | int nheight = forest_pt [nrindex] .height ; | ||
| 234 | #endif | ||
| 235 | |||
| 236 | /* RINDEX = ROOT(INDEX) might change as we merge trees, so we | ||
| 237 | need to update it after each merge */ | ||
| 238 | |||
| 239 | /* find the root of the current node */ | ||
| 240 | /* also update the shortcuts */ | ||
| 241 | nvisited = 0 ; | ||
| 242 | while( forest_pt[rindex].shortcut != rindex ) | ||
| 243 | { | ||
| 244 | sref(visited_pt,nvisited++) = rindex ; | ||
| 245 | rindex = forest_pt[rindex].shortcut ; | ||
| 246 | } | ||
| 247 | while( nvisited-- ) | ||
| 248 | { | ||
| 249 | forest_pt [ sref(visited_pt,nvisited) ] .shortcut = rindex ; | ||
| 250 | } | ||
| 251 | |||
| 252 | /* find the root of the neighbor */ | ||
| 253 | nrindex = nindex ; | ||
| 254 | nvisited = 0 ; | ||
| 255 | while( forest_pt[nrindex].shortcut != nrindex ) | ||
| 256 | { | ||
| 257 | sref(visited_pt, nvisited++) = nrindex ; | ||
| 258 | nrindex = forest_pt[nrindex].shortcut ; | ||
| 259 | } | ||
| 260 | while( nvisited-- ) | ||
| 261 | { | ||
| 262 | forest_pt [ sref(visited_pt,nvisited) ] .shortcut = nrindex ; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* | ||
| 266 | Now we join the two subtrees rooted at | ||
| 267 | |||
| 268 | RINDEX = ROOT(INDEX) and NRINDEX = ROOT(NINDEX). | ||
| 269 | |||
| 270 | Only three things can happen: | ||
| 271 | |||
| 272 | a - ROOT(INDEX) == ROOT(NRINDEX). In this case the two trees | ||
| 273 | have already been joined and we do not do anything. | ||
| 274 | |||
| 275 | b - I(ROOT(INDEX)) == I(ROOT(NRINDEX)). In this case index | ||
| 276 | is extending an extremal region with the same | ||
| 277 | value. Since ROOT(NRINDEX) will NOT be an extremal | ||
| 278 | region of the full image, ROOT(INDEX) can be safely | ||
| 279 | addedd as children of ROOT(NRINDEX) if this reduces | ||
| 280 | the height according to union rank. | ||
| 281 | |||
| 282 | c - I(ROOT(INDEX)) > I(ROOT(NRINDEX)) as index is extending | ||
| 283 | an extremal region, but increasing its level. In this | ||
| 284 | case ROOT(NRINDEX) WILL be an extremal region of the | ||
| 285 | final image and the only possibility is to add | ||
| 286 | ROOT(NRINDEX) as children of ROOT(INDEX). | ||
| 287 | */ | ||
| 288 | |||
| 289 | if( rindex != nrindex ) | ||
| 290 | { | ||
| 291 | /* this is a genuine join */ | ||
| 292 | |||
| 293 | nrvalue = asubsref(I_pt,nrindex) ; | ||
| 294 | if( nrvalue == value | ||
| 295 | #ifdef USE_RANK_UNION | ||
| 296 | && height < nheight | ||
| 297 | #endif | ||
| 298 | ) | ||
| 299 | { | ||
| 300 | /* ROOT(INDEX) becomes the child */ | ||
| 301 | forest_pt[rindex] .parent = nrindex ; | ||
| 302 | forest_pt[rindex] .shortcut = nrindex ; | ||
| 303 | forest_pt[nrindex].area += forest_pt[rindex].area ; | ||
| 304 | |||
| 305 | #ifdef USE_RANK_UNION | ||
| 306 | forest_pt[nrindex].height = MAX(nheight, height+1) ; | ||
| 307 | #endif | ||
| 308 | |||
| 309 | sref(joins_pt,njoins++) = rindex ; | ||
| 310 | |||
| 311 | } | ||
| 312 | else | ||
| 313 | { | ||
| 314 | /* ROOT(index) becomes parent */ | ||
| 315 | forest_pt[nrindex] .parent = rindex ; | ||
| 316 | forest_pt[nrindex] .shortcut = rindex ; | ||
| 317 | forest_pt[rindex] .area += forest_pt[nrindex].area ; | ||
| 318 | |||
| 319 | #ifdef USE_RANK_UNION | ||
| 320 | forest_pt[rindex].height = MAX(height, nheight+1) ; | ||
| 321 | #endif | ||
| 322 | if( nrvalue != value ) | ||
| 323 | { | ||
| 324 | /* nrindex is extremal region: save for later */ | ||
| 325 | forest_pt[nrindex].region = ner ; | ||
| 326 | regions_pt [ner] .index = nrindex ; | ||
| 327 | regions_pt [ner] .parent = ner ; | ||
| 328 | regions_pt [ner] .value = nrvalue ; | ||
| 329 | regions_pt [ner] .area = forest_pt [nrindex].area ; | ||
| 330 | regions_pt [ner] .area_top = nel ; | ||
| 331 | regions_pt [ner] .area_bot = 0 ; | ||
| 332 | ++ner ; | ||
| 333 | } | ||
| 334 | |||
| 335 | /* annote join operation for post-processing */ | ||
| 336 | sref(joins_pt,njoins++) = nrindex ; | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | } /* neighbor done */ | ||
| 341 | |||
| 342 | /* move to next neighbor */ | ||
| 343 | k = 0 ; | ||
| 344 | sref(nsubs_pt,k) = sref(nsubs_pt,k) + 1; | ||
| 345 | while( sref(nsubs_pt, k) > 1) | ||
| 346 | { | ||
| 347 | sref(nsubs_pt,k++) = -1 ; | ||
| 348 | if(k == ndims) goto done_all_neighbors ; | ||
| 349 | sref(nsubs_pt,k) = sref(nsubs_pt,k) + 1; | ||
| 350 | } | ||
| 351 | } /* next neighbor */ | ||
| 352 | done_all_neighbors : ; | ||
| 353 | } /* next pixel */ | ||
| 354 | |||
| 355 | |||
| 356 | /* the root of the last processed pixel must be a region */ | ||
| 357 | forest_pt [rindex].region = ner ; | ||
| 358 | regions_pt [ner] .index = rindex ; | ||
| 359 | regions_pt [ner] .parent = ner ; | ||
| 360 | regions_pt [ner] .value = asubsref(I_pt,rindex) ; | ||
| 361 | regions_pt [ner] .area = forest_pt [rindex] .area ; | ||
| 362 | regions_pt [ner] .area_top = nel ; | ||
| 363 | regions_pt [ner] .area_bot = 0 ; | ||
| 364 | ++ner ; | ||
| 365 | |||
| 366 | /* ----------------------------------------------------------------- | ||
| 367 | * Compute region parents | ||
| 368 | * -------------------------------------------------------------- */ | ||
| 369 | for( i = 0 ; i < ner ; ++i) | ||
| 370 | { | ||
| 371 | idx_t index = regions_pt [i].index ; | ||
| 372 | val_t value = regions_pt [i].value ; | ||
| 373 | idx_t j = i ; | ||
| 374 | |||
| 375 | while(j == i) | ||
| 376 | { | ||
| 377 | idx_t pindex = forest_pt [index].parent ; | ||
| 378 | val_t pvalue = asubsref(I_pt,pindex) ; | ||
| 379 | |||
| 380 | /* top of the tree */ | ||
| 381 | if(index == pindex) | ||
| 382 | { | ||
| 383 | j = forest_pt[index].region ; | ||
| 384 | break ; | ||
| 385 | } | ||
| 386 | |||
| 387 | /* if index is the root of a region, either this is still | ||
| 388 | i, or it is the parent region we are looking for. */ | ||
| 389 | if(value < pvalue) | ||
| 390 | { | ||
| 391 | j = forest_pt[index].region ; | ||
| 392 | } | ||
| 393 | |||
| 394 | index = pindex ; | ||
| 395 | value = pvalue ; | ||
| 396 | } | ||
| 397 | regions_pt[i]. parent = j ; | ||
| 398 | } | ||
| 399 | |||
| 400 | /* ----------------------------------------------------------------- | ||
| 401 | * Compute areas of tops and bottoms | ||
| 402 | * -------------------------------------------------------------- */ | ||
| 403 | |||
| 404 | /* We scan the list of regions from the bottom. Let x0 be the current | ||
| 405 | region and be x1 = PARENT(x0), x2 = PARENT(x1) and so on. | ||
| 406 | |||
| 407 | Here we do two things: | ||
| 408 | |||
| 409 | 1) Look for regions x for which x0 is the BOTTOM. This requires | ||
| 410 | VAL(x0) <= VAL(x) - DELTA < VAL(x1). | ||
| 411 | We update AREA_BOT(x) for each of such x found. | ||
| 412 | |||
| 413 | 2) Look for the region y which is the TOP of x0. This requires | ||
| 414 | VAL(y) <= VAL(x0) + DELTA < VAL(y+1) | ||
| 415 | We update AREA_TOP(x0) as soon as we find such y. | ||
| 416 | |||
| 417 | */ | ||
| 418 | |||
| 419 | for( i = 0 ; i < ner ; ++i) | ||
| 420 | { | ||
| 421 | /* fix xi as the region, then xj are the parents */ | ||
| 422 | idx_t parent = regions_pt [i].parent ; | ||
| 423 | int val0 = regions_pt [i].value ; | ||
| 424 | int val1 = regions_pt [parent].value ; | ||
| 425 | int val = val0 ; | ||
| 426 | idx_t j = i ; | ||
| 427 | |||
| 428 | while(1) | ||
| 429 | { | ||
| 430 | int valp = regions_pt [parent].value ; | ||
| 431 | |||
| 432 | /* i is the bottom of j */ | ||
| 433 | if(val0 <= val - delta && val - delta < val1) | ||
| 434 | { | ||
| 435 | regions_pt [j].area_bot = | ||
| 436 | MAX(regions_pt [j].area_bot, regions_pt [i].area) ; | ||
| 437 | } | ||
| 438 | |||
| 439 | /* j is the top of i */ | ||
| 440 | if(val <= val0 + delta && val0 + delta < valp) | ||
| 441 | { | ||
| 442 | regions_pt [i].area_top = regions_pt [j].area ; | ||
| 443 | } | ||
| 444 | |||
| 445 | /* stop if going on is useless */ | ||
| 446 | if(val1 <= val - delta && val0 + delta < val) | ||
| 447 | break ; | ||
| 448 | |||
| 449 | /* stop also if j is the root */ | ||
| 450 | if(j == parent) | ||
| 451 | break ; | ||
| 452 | |||
| 453 | /* next region upward */ | ||
| 454 | j = parent ; | ||
| 455 | parent = regions_pt [j].parent ; | ||
| 456 | val = valp ; | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | /* ----------------------------------------------------------------- | ||
| 461 | * Compute variation | ||
| 462 | * -------------------------------------------------------------- */ | ||
| 463 | for(i = 0 ; i < ner ; ++i) | ||
| 464 | { | ||
| 465 | int area = regions_pt [i].area ; | ||
| 466 | int area_top = regions_pt [i].area_top ; | ||
| 467 | int area_bot = regions_pt [i].area_bot ; | ||
| 468 | regions_pt [i].variation = (area_top - area_bot) / (area*1.0) ; | ||
| 469 | |||
| 470 | /* initialize .mastable to 1 for all nodes */ | ||
| 471 | regions_pt [i].maxstable = 1 ; | ||
| 472 | } | ||
| 473 | |||
| 474 | /* ----------------------------------------------------------------- | ||
| 475 | * Remove regions which are NOT maximally stable | ||
| 476 | * -------------------------------------------------------------- */ | ||
| 477 | nmer = ner ; | ||
| 478 | for(i = 0 ; i < ner ; ++i) | ||
| 479 | { | ||
| 480 | idx_t parent = regions_pt [i] .parent ; | ||
| 481 | float var = regions_pt [i] .variation ; | ||
| 482 | float pvar = regions_pt [parent] .variation ; | ||
| 483 | idx_t loser ; | ||
| 484 | |||
| 485 | /* decide which one to keep and put that in loser */ | ||
| 486 | if(var < pvar) loser = parent ; else loser = i ; | ||
| 487 | |||
| 488 | /* make loser NON maximally stable */ | ||
| 489 | if(regions_pt [loser].maxstable) --nmer ; | ||
| 490 | regions_pt [loser].maxstable = 0 ; | ||
| 491 | } | ||
| 492 | |||
| 493 | |||
| 494 | /* ----------------------------------------------------------------- | ||
| 495 | * Remove more regions | ||
| 496 | * -------------------------------------------------------------- */ | ||
| 497 | |||
| 498 | /* it is critical for correct duplicate detection to remove regions | ||
| 499 | from the bottom (smallest one first) */ | ||
| 500 | |||
| 501 | if( big_cleanup || small_cleanup || bad_cleanup || dup_cleanup ) | ||
| 502 | { | ||
| 503 | int nbig = 0 ; | ||
| 504 | int nsmall = 0 ; | ||
| 505 | int nbad = 0 ; | ||
| 506 | int ndup = 0 ; | ||
| 507 | |||
| 508 | /* scann all extremal regions */ | ||
| 509 | for(i = 0 ; i < ner ; ++i) | ||
| 510 | { | ||
| 511 | |||
| 512 | /* process only maximally stable extremal regions */ | ||
| 513 | if(! regions_pt [i].maxstable) continue ; | ||
| 514 | |||
| 515 | if( bad_cleanup && regions_pt[i].variation >= 1.0f ) | ||
| 516 | { | ||
| 517 | ++nbad ; | ||
| 518 | goto remove_this_region ; | ||
| 519 | } | ||
| 520 | |||
| 521 | if( big_cleanup && regions_pt[i].area > nel/2 ) | ||
| 522 | { | ||
| 523 | ++nbig ; | ||
| 524 | goto remove_this_region ; | ||
| 525 | } | ||
| 526 | |||
| 527 | if( small_cleanup && regions_pt[i].area < 25 ) | ||
| 528 | { | ||
| 529 | ++nsmall ; | ||
| 530 | goto remove_this_region ; | ||
| 531 | } | ||
| 532 | |||
| 533 | /** Remove duplicates */ | ||
| 534 | |||
| 535 | if( dup_cleanup ) | ||
| 536 | { | ||
| 537 | idx_t parent = regions_pt [i].parent ; | ||
| 538 | int area, parea ; | ||
| 539 | float change ; | ||
| 540 | |||
| 541 | /* the search does not apply to root regions */ | ||
| 542 | if(parent != i) | ||
| 543 | { | ||
| 544 | |||
| 545 | /* search for the maximally stable parent region */ | ||
| 546 | while(! regions_pt[parent].maxstable) | ||
| 547 | { | ||
| 548 | idx_t next = regions_pt[parent].parent ; | ||
| 549 | if(next == parent) break ; | ||
| 550 | parent = next ; | ||
| 551 | } | ||
| 552 | |||
| 553 | /* compare with the parent region; if the current and parent | ||
| 554 | regions are too similar, keep only the parent */ | ||
| 555 | |||
| 556 | area = regions_pt [i].area ; | ||
| 557 | parea = regions_pt [parent].area ; | ||
| 558 | change = (parea - area)/(area*1.0) ; | ||
| 559 | |||
| 560 | if(change < 0.5) | ||
| 561 | { | ||
| 562 | ++ndup ; | ||
| 563 | goto remove_this_region ; | ||
| 564 | } | ||
| 565 | |||
| 566 | } /* drop duplicates */ | ||
| 567 | } | ||
| 568 | |||
| 569 | continue ; | ||
| 570 | remove_this_region : | ||
| 571 | regions_pt[i].maxstable = 0 ; | ||
| 572 | --nmer ; | ||
| 573 | |||
| 574 | } /* next region to cleanup */ | ||
| 575 | |||
| 576 | if(0) | ||
| 577 | { | ||
| 578 | printf(" Bad regions: %d\n", nbad ) ; | ||
| 579 | printf(" Small regions: %d\n", nsmall ) ; | ||
| 580 | printf(" Big regions: %d\n", nbig ) ; | ||
| 581 | printf(" Duplicated regions: %d\n", ndup ) ; | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | /* printf("Cleaned-up regions: %d (%.1f%%)\n", | ||
| 586 | nmer, 100.0 * (double) nmer / ner) ; | ||
| 587 | */ | ||
| 588 | /* ----------------------------------------------------------------- | ||
| 589 | * Fit ellipses | ||
| 590 | * -------------------------------------------------------------- */ | ||
| 591 | //ell_pt = 0 ; | ||
| 592 | //memset(ell_pt, sizeof(ulliArray) + sizeof(acc_t)*gdl*nmer, 0) ; | ||
| 593 | if (nout >= 1) | ||
| 594 | { | ||
| 595 | int midx = 1 ; | ||
| 596 | int d, index, j ; | ||
| 597 | |||
| 598 | /* enumerate maxstable regions */ | ||
| 599 | for(i = 0 ; i < ner ; ++i) | ||
| 600 | { | ||
| 601 | if(! regions_pt [i].maxstable) continue ; | ||
| 602 | regions_pt [i].maxstable = midx++ ; | ||
| 603 | } | ||
| 604 | |||
| 605 | /* allocate space */ | ||
| 606 | //acc_pt = malloc(sizeof(ulliArray) + sizeof(acc_t)*nel) ; | ||
| 607 | //printf("nmer = %d\n", nmer); | ||
| 608 | //ell_pt = malloc(sizeof(ulliArray) + sizeof(acc_t)*gdl*nmer) ; | ||
| 609 | |||
| 610 | /* clear accumulators */ | ||
| 611 | for(d=0; d<(gdl*nmer); d++) | ||
| 612 | sref(ell_pt,d) = 0; | ||
| 613 | |||
| 614 | /* for each gdl */ | ||
| 615 | for(d = 0 ; d < gdl ; ++d) | ||
| 616 | { | ||
| 617 | /* initalize parameter */ | ||
| 618 | int counter_i; | ||
| 619 | for(counter_i=0; counter_i<ndims; counter_i++) | ||
| 620 | sref(subs_pt,counter_i) = 0; | ||
| 621 | |||
| 622 | if(d < ndims) | ||
| 623 | { | ||
| 624 | for(index = 0 ; index < nel ; ++ index) | ||
| 625 | { | ||
| 626 | sref(acc_pt,index) = sref(subs_pt,d) ; | ||
| 627 | adv(dims, ndims, subs_pt) ; | ||
| 628 | } | ||
| 629 | } | ||
| 630 | else | ||
| 631 | { | ||
| 632 | /* decode d-ndims into a (i,j) pair */ | ||
| 633 | i = d-ndims ; | ||
| 634 | j = 0 ; | ||
| 635 | while(i > j) | ||
| 636 | { | ||
| 637 | i -= j + 1 ; | ||
| 638 | j ++ ; | ||
| 639 | } | ||
| 640 | |||
| 641 | /* add x_i * x_j */ | ||
| 642 | for(index = 0 ; index < nel ; ++ index) | ||
| 643 | { | ||
| 644 | sref(acc_pt,index) = sref(subs_pt,i) * sref(subs_pt,j) ; | ||
| 645 | adv(dims, ndims, subs_pt) ; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | |||
| 649 | /* integrate parameter */ | ||
| 650 | for(i = 0 ; i < njoins ; ++i) | ||
| 651 | { | ||
| 652 | idx_t index = sref(joins_pt,i); | ||
| 653 | idx_t parent = forest_pt [ index ].parent ; | ||
| 654 | sref(acc_pt,parent) += sref(acc_pt,index) ; | ||
| 655 | } | ||
| 656 | |||
| 657 | /* save back to ellpises */ | ||
| 658 | for(i = 0 ; i < ner ; ++i) | ||
| 659 | { | ||
| 660 | idx_t region = regions_pt [i].maxstable ; | ||
| 661 | |||
| 662 | /* skip if not extremal region */ | ||
| 663 | if(region-- == 0) continue ; | ||
| 664 | sref(ell_pt,d + gdl*region) = sref(acc_pt, regions_pt[i].index) ; | ||
| 665 | } | ||
| 666 | |||
| 667 | /* next gdl */ | ||
| 668 | } | ||
| 669 | //free(acc_pt) ; | ||
| 670 | //free(ell_pt) ; | ||
| 671 | } | ||
| 672 | |||
| 673 | /* ----------------------------------------------------------------- | ||
| 674 | * Save back and exit | ||
| 675 | * -------------------------------------------------------------- */ | ||
| 676 | |||
| 677 | /* | ||
| 678 | * Save extremal regions | ||
| 679 | */ | ||
| 680 | { | ||
| 681 | int dims[2], j=0; | ||
| 682 | I2D* pt ; | ||
| 683 | dims[0] = nmer ; | ||
| 684 | //out = iMallocHandle(1, nmer); | ||
| 685 | out->height = 1; | ||
| 686 | out->width = nmer; | ||
| 687 | pt = out; | ||
| 688 | for (i = 0 ; i < ner ; ++i) | ||
| 689 | { | ||
| 690 | if( regions_pt[i].maxstable ) | ||
| 691 | { | ||
| 692 | /* adjust for MATLAB index compatibility */ | ||
| 693 | // *pt++ = regions_pt[i].index + 1 ; | ||
| 694 | asubsref(pt,j++) = regions_pt[i].index + 1 ; | ||
| 695 | } | ||
| 696 | } | ||
| 697 | } | ||
| 698 | |||
| 699 | /* free stuff */ | ||
| 700 | //free(dims); | ||
| 701 | //free( forest_pt ) ; | ||
| 702 | //free( pairs_pt ) ; | ||
| 703 | //free( regions_pt ) ; | ||
| 704 | //free( visited_pt ) ; | ||
| 705 | //free( strides_pt ) ; | ||
| 706 | //free( nsubs_pt ) ; | ||
| 707 | //free( subs_pt ) ; | ||
| 708 | //free( joins_pt ) ; | ||
| 709 | |||
| 710 | return out; | ||
| 711 | } | ||
| 712 | |||
| 713 | |||
| 714 | |||
diff --git a/SD-VBS/benchmarks/mser/src/c/mser.h b/SD-VBS/benchmarks/mser/src/c/mser.h new file mode 100644 index 0000000..8876311 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/c/mser.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /******************************** | ||
| 2 | Author: Sravanthi Kota Venkata | ||
| 3 | ********************************/ | ||
| 4 | |||
| 5 | #ifndef _MSER_ | ||
| 6 | #define _MSER_ | ||
| 7 | |||
| 8 | #define sref(a,i) a->data[i] | ||
| 9 | |||
| 10 | #include "sdvbs_common.h" | ||
| 11 | #define NMER_MAX 756 | ||
| 12 | |||
| 13 | typedef int val_t; | ||
| 14 | |||
| 15 | typedef struct | ||
| 16 | { | ||
| 17 | int width; | ||
| 18 | int data[]; | ||
| 19 | }iArray; | ||
| 20 | |||
| 21 | typedef struct | ||
| 22 | { | ||
| 23 | int width; | ||
| 24 | unsigned int data[]; | ||
| 25 | }uiArray; | ||
| 26 | |||
| 27 | typedef struct | ||
| 28 | { | ||
| 29 | int width; | ||
| 30 | long long int unsigned data[]; | ||
| 31 | }ulliArray; | ||
| 32 | |||
| 33 | #define MIN(a,b) (a<b)?a:b | ||
| 34 | #define MAX(a,b) (a>b)?a:b | ||
| 35 | |||
| 36 | typedef int unsigned idx_t ; | ||
| 37 | typedef long long int unsigned acc_t ; | ||
| 38 | |||
| 39 | /* pairs are used to sort the pixels */ | ||
| 40 | typedef struct | ||
| 41 | { | ||
| 42 | val_t value ; | ||
| 43 | idx_t index ; | ||
| 44 | } pair_t ; | ||
| 45 | |||
| 46 | /* forest node */ | ||
| 47 | typedef struct | ||
| 48 | { | ||
| 49 | idx_t parent ; /**< parent pixel */ | ||
| 50 | idx_t shortcut ; /**< shortcut to the root */ | ||
| 51 | idx_t region ; /**< index of the region */ | ||
| 52 | int area ; /**< area of the region */ | ||
| 53 | #ifdef USE_RANK_UNION | ||
| 54 | int height ; /**< node height */ | ||
| 55 | #endif | ||
| 56 | } node_t ; | ||
| 57 | |||
| 58 | /* extremal regions */ | ||
| 59 | typedef struct | ||
| 60 | { | ||
| 61 | idx_t parent ; /**< parent region */ | ||
| 62 | idx_t index ; /**< index of root pixel */ | ||
| 63 | val_t value ; /**< value of root pixel */ | ||
| 64 | int area ; /**< area of the region */ | ||
| 65 | int area_top ; /**< area of the region DELTA levels above */ | ||
| 66 | int area_bot ; /**< area of the region DELTA levels below */ | ||
| 67 | float variation ; /**< variation */ | ||
| 68 | int maxstable ; /**< max stable number (=0 if not maxstable) */ | ||
| 69 | } region_t ; | ||
| 70 | |||
| 71 | int script_mser(); | ||
| 72 | I2D* mser(I2D* I, int in_delta, | ||
| 73 | iArray* subs_pt, iArray* nsubs_pt, iArray* strides_pt, iArray* visited_pt, iArray* dims, | ||
| 74 | uiArray* joins_pt, | ||
| 75 | region_t* regions_pt, | ||
| 76 | pair_t* pairs_pt, | ||
| 77 | node_t* forest_pt, | ||
| 78 | ulliArray* acc_pt, ulliArray* ell_pt, | ||
| 79 | I2D* out); | ||
| 80 | |||
| 81 | #endif | ||
| 82 | |||
| 83 | |||
diff --git a/SD-VBS/benchmarks/mser/src/c/script_mser.c b/SD-VBS/benchmarks/mser/src/c/script_mser.c new file mode 100644 index 0000000..d4a98cd --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/c/script_mser.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /******************************** | ||
| 2 | Author: Sravanthi Kota Venkata | ||
| 3 | ********************************/ | ||
| 4 | |||
| 5 | #include "mser.h" | ||
| 6 | #include <malloc.h> | ||
| 7 | #include "extra.h" | ||
| 8 | #define min(a,b) (a<b)?a:b | ||
| 9 | #define max(a,b) (a>b)?a:b | ||
| 10 | |||
| 11 | int main(int argc, char* argv[]) | ||
| 12 | { | ||
| 13 | SET_UP | ||
| 14 | int which_image; | ||
| 15 | int i, j, k; | ||
| 16 | I2D *idx; | ||
| 17 | I2D *I; | ||
| 18 | I2D *It; | ||
| 19 | I2D *out; | ||
| 20 | int rows=196, cols=98; | ||
| 21 | int minVal = 1000; | ||
| 22 | int maxVal = -1000; | ||
| 23 | int lev = 10; | ||
| 24 | |||
| 25 | char im1[100], im2[100]; | ||
| 26 | |||
| 27 | iArray *subs_pt, *nsubs_pt, *strides_pt, *visited_pt, *dims; | ||
| 28 | uiArray* joins_pt; | ||
| 29 | ulliArray *acc_pt, *ell_pt; | ||
| 30 | region_t* regions_pt; | ||
| 31 | pair_t* pairs_pt; | ||
| 32 | node_t* forest_pt; | ||
| 33 | |||
| 34 | int ndims, nel, gdl, nmer; | ||
| 35 | |||
| 36 | printf("Input Image: "); | ||
| 37 | scanf("%s", im1); | ||
| 38 | |||
| 39 | I = readImage(im1); | ||
| 40 | |||
| 41 | rows = I->height; | ||
| 42 | cols = I->width; | ||
| 43 | |||
| 44 | It = readImage(im1); | ||
| 45 | |||
| 46 | k = 0; | ||
| 47 | for(i=0; i<cols; i++) | ||
| 48 | { | ||
| 49 | for(j=0; j<rows; j++) | ||
| 50 | { | ||
| 51 | asubsref(It,k++) = subsref(I,j,i); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | ndims = 2; | ||
| 56 | nel = It->height * It->width; | ||
| 57 | gdl = ndims * (ndims+1)/2 + ndims; | ||
| 58 | nmer = NMER_MAX; | ||
| 59 | |||
| 60 | dims = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 61 | /* allocate stuff */ | ||
| 62 | subs_pt = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 63 | nsubs_pt = malloc(sizeof(iArray) + sizeof(int)*ndims); | ||
| 64 | strides_pt = malloc(sizeof(uiArray)+sizeof(unsigned int)*ndims); | ||
| 65 | visited_pt = malloc(sizeof(uiArray) + sizeof(unsigned int)*nel); | ||
| 66 | joins_pt = malloc(sizeof(uiArray) + sizeof(unsigned int)*nel); | ||
| 67 | |||
| 68 | regions_pt = (region_t*)malloc(sizeof(region_t)*nel); | ||
| 69 | pairs_pt = (pair_t*)malloc(sizeof(pair_t)*nel); | ||
| 70 | forest_pt = (node_t*)malloc(sizeof(node_t)*nel); | ||
| 71 | |||
| 72 | acc_pt = malloc(sizeof(ulliArray) + sizeof(acc_t)*nel) ; | ||
| 73 | ell_pt = malloc(sizeof(ulliArray) + sizeof(acc_t)*gdl*nmer) ; | ||
| 74 | |||
| 75 | |||
| 76 | out = iMallocHandle(1, nmer); | ||
| 77 | printf("start\n"); | ||
| 78 | for_each_job{ | ||
| 79 | idx = mser(It, 2, subs_pt, nsubs_pt, strides_pt, visited_pt, dims, | ||
| 80 | joins_pt, | ||
| 81 | regions_pt, | ||
| 82 | pairs_pt, | ||
| 83 | forest_pt, | ||
| 84 | acc_pt, ell_pt, | ||
| 85 | out); | ||
| 86 | } | ||
| 87 | printf("end..\n"); | ||
| 88 | |||
| 89 | #ifdef CHECK | ||
| 90 | /** Self checking - use expected.txt from data directory **/ | ||
| 91 | { | ||
| 92 | int tol, ret=0; | ||
| 93 | tol = 1; | ||
| 94 | #ifdef GENERATE_OUTPUT | ||
| 95 | writeMatrix(idx, argv[1]); | ||
| 96 | #endif | ||
| 97 | ret = selfCheck(idx, "expected_C.txt", tol); | ||
| 98 | if (ret == -1) | ||
| 99 | printf("Error in MSER\n"); | ||
| 100 | } | ||
| 101 | /** Self checking done **/ | ||
| 102 | #endif | ||
| 103 | free(dims); | ||
| 104 | free( forest_pt ) ; | ||
| 105 | free( pairs_pt ) ; | ||
| 106 | free( regions_pt ) ; | ||
| 107 | free( visited_pt ) ; | ||
| 108 | free( strides_pt ) ; | ||
| 109 | free( nsubs_pt ) ; | ||
| 110 | free( subs_pt ) ; | ||
| 111 | free( joins_pt ) ; | ||
| 112 | free( acc_pt ) ; | ||
| 113 | free( ell_pt ) ; | ||
| 114 | iFreeHandle(idx); | ||
| 115 | iFreeHandle(I); | ||
| 116 | iFreeHandle(It); | ||
| 117 | WRITE_TO_FILE | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
