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 | |||