diff options
Diffstat (limited to 'SD-VBS/benchmarks/mser')
67 files changed, 4771 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/mser/.mser.mex.c.swp b/SD-VBS/benchmarks/mser/.mser.mex.c.swp new file mode 100755 index 0000000..4f3a21c --- /dev/null +++ b/SD-VBS/benchmarks/mser/.mser.mex.c.swp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/Makefile b/SD-VBS/benchmarks/mser/Makefile new file mode 100644 index 0000000..60cc0ec --- /dev/null +++ b/SD-VBS/benchmarks/mser/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | include ../../common/makefiles/Makefile.include | ||
2 | include $(MAKEFILE_COMMON_DIR)/Makefile.recurse | ||
3 | |||
diff --git a/SD-VBS/benchmarks/mser/data/Makefile b/SD-VBS/benchmarks/mser/data/Makefile new file mode 100644 index 0000000..ba33d35 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | include ../../../common/makefiles/Makefile.include | ||
2 | include $(MAKEFILE_COMMON_DIR)/Makefile.recurse | ||
3 | |||
diff --git a/SD-VBS/benchmarks/mser/data/cif/1.bmp b/SD-VBS/benchmarks/mser/data/cif/1.bmp new file mode 100644 index 0000000..df56ca3 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/cif/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/cif/Makefile b/SD-VBS/benchmarks/mser/data/cif/Makefile new file mode 100644 index 0000000..41c7f38 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/cif/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=cif | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/cif/VBS_Ver1 b/SD-VBS/benchmarks/mser/data/cif/VBS_Ver1 new file mode 100755 index 0000000..bafb9c7 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/cif/VBS_Ver1 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/cif/expected.m b/SD-VBS/benchmarks/mser/data/cif/expected.m new file mode 100644 index 0000000..b4123c3 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/cif/expected.m | |||
@@ -0,0 +1,162 @@ | |||
1 | 91080 | ||
2 | 40916 | ||
3 | 90318 | ||
4 | 48277 | ||
5 | 57285 | ||
6 | 66702 | ||
7 | 66453 | ||
8 | 15757 | ||
9 | 56228 | ||
10 | 9401 | ||
11 | 72213 | ||
12 | 62502 | ||
13 | 50676 | ||
14 | 8016 | ||
15 | 76446 | ||
16 | 4080 | ||
17 | 26989 | ||
18 | 2894 | ||
19 | 15233 | ||
20 | 25177 | ||
21 | 46411 | ||
22 | 77708 | ||
23 | 79330 | ||
24 | 79286 | ||
25 | 7639 | ||
26 | 39100 | ||
27 | 20919 | ||
28 | 24125 | ||
29 | 69034 | ||
30 | 87683 | ||
31 | 33330 | ||
32 | 9587 | ||
33 | 14591 | ||
34 | 37790 | ||
35 | 57107 | ||
36 | 2905 | ||
37 | 72581 | ||
38 | 30138 | ||
39 | 66349 | ||
40 | 69782 | ||
41 | 53208 | ||
42 | 63252 | ||
43 | 8011 | ||
44 | 20400 | ||
45 | 47661 | ||
46 | 59179 | ||
47 | 71075 | ||
48 | 3544 | ||
49 | 75352 | ||
50 | 5143 | ||
51 | 42527 | ||
52 | 49924 | ||
53 | 9933 | ||
54 | 13880 | ||
55 | 38559 | ||
56 | 45184 | ||
57 | 48697 | ||
58 | 51275 | ||
59 | 57095 | ||
60 | 27545 | ||
61 | 41718 | ||
62 | 46519 | ||
63 | 25666 | ||
64 | 31481 | ||
65 | 56792 | ||
66 | 59176 | ||
67 | 29879 | ||
68 | 42197 | ||
69 | 62643 | ||
70 | 58210 | ||
71 | 20334 | ||
72 | 5623 | ||
73 | 43569 | ||
74 | 46210 | ||
75 | 50474 | ||
76 | 62104 | ||
77 | 65808 | ||
78 | 46945 | ||
79 | 52682 | ||
80 | 63195 | ||
81 | 77194 | ||
82 | 50534 | ||
83 | 60544 | ||
84 | 41770 | ||
85 | 48717 | ||
86 | 53246 | ||
87 | 57723 | ||
88 | 3829 | ||
89 | 20457 | ||
90 | 28461 | ||
91 | 32341 | ||
92 | 6413 | ||
93 | 30286 | ||
94 | 41193 | ||
95 | 50243 | ||
96 | 55458 | ||
97 | 56851 | ||
98 | 60038 | ||
99 | 35141 | ||
100 | 59004 | ||
101 | 63503 | ||
102 | 34763 | ||
103 | 48953 | ||
104 | 55092 | ||
105 | 4534 | ||
106 | 70791 | ||
107 | 20249 | ||
108 | 28134 | ||
109 | 33971 | ||
110 | 53439 | ||
111 | 55882 | ||
112 | 30562 | ||
113 | 33993 | ||
114 | 34523 | ||
115 | 67709 | ||
116 | 60469 | ||
117 | 8591 | ||
118 | 20489 | ||
119 | 72123 | ||
120 | 20237 | ||
121 | 62971 | ||
122 | 26046 | ||
123 | 27337 | ||
124 | 27638 | ||
125 | 29497 | ||
126 | 46390 | ||
127 | 18004 | ||
128 | 41108 | ||
129 | 47659 | ||
130 | 72386 | ||
131 | 31584 | ||
132 | 52173 | ||
133 | 58091 | ||
134 | 46624 | ||
135 | 68233 | ||
136 | 25267 | ||
137 | 29768 | ||
138 | 52802 | ||
139 | 63228 | ||
140 | 39529 | ||
141 | 37092 | ||
142 | 48469 | ||
143 | 41074 | ||
144 | 44231 | ||
145 | 18653 | ||
146 | 40524 | ||
147 | 26529 | ||
148 | 32423 | ||
149 | 27131 | ||
150 | 37373 | ||
151 | 39650 | ||
152 | 65233 | ||
153 | 72920 | ||
154 | 12277 | ||
155 | 33656 | ||
156 | 33151 | ||
157 | 40026 | ||
158 | 48408 | ||
159 | 33352 | ||
160 | 91265 | ||
161 | 32307 | ||
162 | 33875 | ||
diff --git a/SD-VBS/benchmarks/mser/data/cif/mser b/SD-VBS/benchmarks/mser/data/cif/mser new file mode 100755 index 0000000..e2e5016 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/cif/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/fullhd/1.bmp b/SD-VBS/benchmarks/mser/data/fullhd/1.bmp new file mode 100644 index 0000000..c09aaf0 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/fullhd/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/fullhd/Makefile b/SD-VBS/benchmarks/mser/data/fullhd/Makefile new file mode 100644 index 0000000..5cce221 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/fullhd/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=fullhd | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/fullhd/mser b/SD-VBS/benchmarks/mser/data/fullhd/mser new file mode 100755 index 0000000..ab94dc8 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/fullhd/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/qcif/1.bmp b/SD-VBS/benchmarks/mser/data/qcif/1.bmp new file mode 100644 index 0000000..f5a4408 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/qcif/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/qcif/Makefile b/SD-VBS/benchmarks/mser/data/qcif/Makefile new file mode 100644 index 0000000..0c1d924 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/qcif/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=qcif | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/qcif/VBS_Ver1 b/SD-VBS/benchmarks/mser/data/qcif/VBS_Ver1 new file mode 100755 index 0000000..a973e58 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/qcif/VBS_Ver1 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/qcif/expected.m b/SD-VBS/benchmarks/mser/data/qcif/expected.m new file mode 100644 index 0000000..41fc7d7 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/qcif/expected.m | |||
@@ -0,0 +1,68 @@ | |||
1 | 22308 | ||
2 | 10162 | ||
3 | 14251 | ||
4 | 9500 | ||
5 | 18683 | ||
6 | 5669 | ||
7 | 1501 | ||
8 | 2813 | ||
9 | 5180 | ||
10 | 6119 | ||
11 | 3731 | ||
12 | 3939 | ||
13 | 22065 | ||
14 | 2417 | ||
15 | 5048 | ||
16 | 17994 | ||
17 | 14159 | ||
18 | 15203 | ||
19 | 17195 | ||
20 | 18926 | ||
21 | 13616 | ||
22 | 2192 | ||
23 | 2 | ||
24 | 6900 | ||
25 | 9794 | ||
26 | 11366 | ||
27 | 14679 | ||
28 | 5344 | ||
29 | 17471 | ||
30 | 11778 | ||
31 | 16661 | ||
32 | 10323 | ||
33 | 12856 | ||
34 | 13141 | ||
35 | 7022 | ||
36 | 12740 | ||
37 | 11984 | ||
38 | 14560 | ||
39 | 12982 | ||
40 | 19042 | ||
41 | 13916 | ||
42 | 1250 | ||
43 | 7680 | ||
44 | 159 | ||
45 | 5477 | ||
46 | 13909 | ||
47 | 15632 | ||
48 | 7620 | ||
49 | 6936 | ||
50 | 14660 | ||
51 | 2021 | ||
52 | 12466 | ||
53 | 16436 | ||
54 | 6556 | ||
55 | 12499 | ||
56 | 9457 | ||
57 | 6559 | ||
58 | 13998 | ||
59 | 17616 | ||
60 | 9992 | ||
61 | 12224 | ||
62 | 14654 | ||
63 | 9572 | ||
64 | 6970 | ||
65 | 8661 | ||
66 | 18900 | ||
67 | 3364 | ||
68 | 8379 | ||
diff --git a/SD-VBS/benchmarks/mser/data/qcif/mser b/SD-VBS/benchmarks/mser/data/qcif/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/qcif/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim/1.bmp b/SD-VBS/benchmarks/mser/data/sim/1.bmp new file mode 100644 index 0000000..953fe98 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim/Makefile b/SD-VBS/benchmarks/mser/data/sim/Makefile new file mode 100644 index 0000000..fc94f6e --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=sim | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim/expected.m b/SD-VBS/benchmarks/mser/data/sim/expected.m new file mode 100644 index 0000000..c52e720 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim/expected.m | |||
@@ -0,0 +1,16 @@ | |||
1 | 3611 | ||
2 | 5615 | ||
3 | 3876 | ||
4 | 2441 | ||
5 | 5556 | ||
6 | 127 | ||
7 | 1109 | ||
8 | 71 | ||
9 | 8 | ||
10 | 16 | ||
11 | 3567 | ||
12 | 817 | ||
13 | 3169 | ||
14 | 2121 | ||
15 | 4036 | ||
16 | 3985 | ||
diff --git a/SD-VBS/benchmarks/mser/data/sim/mser b/SD-VBS/benchmarks/mser/data/sim/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim_fast/1.bmp b/SD-VBS/benchmarks/mser/data/sim_fast/1.bmp new file mode 100644 index 0000000..5ec0de1 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim_fast/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim_fast/Makefile b/SD-VBS/benchmarks/mser/data/sim_fast/Makefile new file mode 100644 index 0000000..f5845eb --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim_fast/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | INPUT=sim_fast | ||
6 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
7 | |||
8 | |||
diff --git a/SD-VBS/benchmarks/mser/data/sim_fast/expected.m b/SD-VBS/benchmarks/mser/data/sim_fast/expected.m new file mode 100644 index 0000000..5ba3c55 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim_fast/expected.m | |||
@@ -0,0 +1,7 @@ | |||
1 | 1214 | ||
2 | 353 | ||
3 | 1146 | ||
4 | 29 | ||
5 | 187 | ||
6 | 829 | ||
7 | 976 | ||
diff --git a/SD-VBS/benchmarks/mser/data/sim_fast/mser b/SD-VBS/benchmarks/mser/data/sim_fast/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sim_fast/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sqcif/1.bmp b/SD-VBS/benchmarks/mser/data/sqcif/1.bmp new file mode 100644 index 0000000..9122269 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sqcif/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/sqcif/Makefile b/SD-VBS/benchmarks/mser/data/sqcif/Makefile new file mode 100644 index 0000000..42808ce --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sqcif/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=sqcif | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/sqcif/expected.m b/SD-VBS/benchmarks/mser/data/sqcif/expected.m new file mode 100644 index 0000000..a3ccbad --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sqcif/expected.m | |||
@@ -0,0 +1,27 @@ | |||
1 | 3549 | ||
2 | 5615 | ||
3 | 3941 | ||
4 | 5626 | ||
5 | 5113 | ||
6 | 1079 | ||
7 | 3840 | ||
8 | 4838 | ||
9 | 4050 | ||
10 | 7 | ||
11 | 1741 | ||
12 | 2778 | ||
13 | 2060 | ||
14 | 3911 | ||
15 | 13 | ||
16 | 1923 | ||
17 | 3918 | ||
18 | 3463 | ||
19 | 480 | ||
20 | 1488 | ||
21 | 344 | ||
22 | 33 | ||
23 | 2158 | ||
24 | 3398 | ||
25 | 1694 | ||
26 | 2420 | ||
27 | 4026 | ||
diff --git a/SD-VBS/benchmarks/mser/data/sqcif/mser b/SD-VBS/benchmarks/mser/data/sqcif/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/sqcif/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/test/1.bmp b/SD-VBS/benchmarks/mser/data/test/1.bmp new file mode 100644 index 0000000..ba8fb8b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/test/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/test/Makefile b/SD-VBS/benchmarks/mser/data/test/Makefile new file mode 100644 index 0000000..8a1c79b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/test/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | include ../../../../common/makefiles/Makefile.include | ||
2 | |||
3 | BMARK=mser | ||
4 | INPUT=test | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
7 | |||
diff --git a/SD-VBS/benchmarks/mser/data/test/expected.m b/SD-VBS/benchmarks/mser/data/test/expected.m new file mode 100644 index 0000000..30d764c --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/test/expected.m | |||
@@ -0,0 +1 @@ | |||
171 | |||
diff --git a/SD-VBS/benchmarks/mser/data/test/mser b/SD-VBS/benchmarks/mser/data/test/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/test/mser | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/vga/1.bmp b/SD-VBS/benchmarks/mser/data/vga/1.bmp new file mode 100644 index 0000000..bbb3e60 --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/vga/1.bmp | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/data/vga/Makefile b/SD-VBS/benchmarks/mser/data/vga/Makefile new file mode 100644 index 0000000..1b0032a --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/vga/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | INPUT=vga | ||
2 | include ../../../../common/makefiles/Makefile.include | ||
3 | |||
4 | BMARK=mser | ||
5 | include $(MAKEFILE_COMMON_DIR)/Makefile.common | ||
6 | |||
diff --git a/SD-VBS/benchmarks/mser/data/vga/expected.m b/SD-VBS/benchmarks/mser/data/vga/expected.m new file mode 100644 index 0000000..23ca6be --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/vga/expected.m | |||
@@ -0,0 +1,297 @@ | |||
1 | 150188 | ||
2 | 139161 | ||
3 | 226889 | ||
4 | 295683 | ||
5 | 188158 | ||
6 | 218738 | ||
7 | 24760 | ||
8 | 122860 | ||
9 | 234561 | ||
10 | 71415 | ||
11 | 184318 | ||
12 | 25237 | ||
13 | 84868 | ||
14 | 27054 | ||
15 | 73340 | ||
16 | 252342 | ||
17 | 178044 | ||
18 | 251786 | ||
19 | 38543 | ||
20 | 166539 | ||
21 | 265202 | ||
22 | 13175 | ||
23 | 230154 | ||
24 | 241697 | ||
25 | 268924 | ||
26 | 106165 | ||
27 | 87963 | ||
28 | 140157 | ||
29 | 178621 | ||
30 | 3821 | ||
31 | 49293 | ||
32 | 51544 | ||
33 | 87463 | ||
34 | 138676 | ||
35 | 146393 | ||
36 | 153034 | ||
37 | 178140 | ||
38 | 263663 | ||
39 | 35512 | ||
40 | 81293 | ||
41 | 128231 | ||
42 | 24929 | ||
43 | 38545 | ||
44 | 157836 | ||
45 | 201762 | ||
46 | 260875 | ||
47 | 53461 | ||
48 | 58270 | ||
49 | 68286 | ||
50 | 78904 | ||
51 | 123882 | ||
52 | 143979 | ||
53 | 155623 | ||
54 | 289494 | ||
55 | 17912 | ||
56 | 166189 | ||
57 | 172421 | ||
58 | 188794 | ||
59 | 258462 | ||
60 | 80809 | ||
61 | 110040 | ||
62 | 125346 | ||
63 | 193605 | ||
64 | 215682 | ||
65 | 492 | ||
66 | 242242 | ||
67 | 98477 | ||
68 | 204773 | ||
69 | 271899 | ||
70 | 305023 | ||
71 | 20339 | ||
72 | 47220 | ||
73 | 48233 | ||
74 | 48129 | ||
75 | 78890 | ||
76 | 78902 | ||
77 | 121066 | ||
78 | 157838 | ||
79 | 157696 | ||
80 | 222421 | ||
81 | 195436 | ||
82 | 202237 | ||
83 | 222353 | ||
84 | 247870 | ||
85 | 263209 | ||
86 | 60698 | ||
87 | 67419 | ||
88 | 141637 | ||
89 | 168504 | ||
90 | 225211 | ||
91 | 246839 | ||
92 | 16955 | ||
93 | 45396 | ||
94 | 75542 | ||
95 | 167666 | ||
96 | 175462 | ||
97 | 185528 | ||
98 | 186845 | ||
99 | 11725 | ||
100 | 12720 | ||
101 | 17432 | ||
102 | 90532 | ||
103 | 153694 | ||
104 | 157695 | ||
105 | 163260 | ||
106 | 166188 | ||
107 | 228166 | ||
108 | 242515 | ||
109 | 264159 | ||
110 | 24279 | ||
111 | 90873 | ||
112 | 137217 | ||
113 | 178145 | ||
114 | 85543 | ||
115 | 103800 | ||
116 | 121961 | ||
117 | 126261 | ||
118 | 142142 | ||
119 | 149331 | ||
120 | 166705 | ||
121 | 138344 | ||
122 | 192225 | ||
123 | 61171 | ||
124 | 137772 | ||
125 | 159873 | ||
126 | 183201 | ||
127 | 191826 | ||
128 | 12731 | ||
129 | 21743 | ||
130 | 41559 | ||
131 | 116677 | ||
132 | 177659 | ||
133 | 157702 | ||
134 | 163404 | ||
135 | 187318 | ||
136 | 199366 | ||
137 | 216135 | ||
138 | 174026 | ||
139 | 209457 | ||
140 | 218175 | ||
141 | 256531 | ||
142 | 109213 | ||
143 | 205085 | ||
144 | 50229 | ||
145 | 137858 | ||
146 | 155858 | ||
147 | 176013 | ||
148 | 190780 | ||
149 | 10764 | ||
150 | 169116 | ||
151 | 56443 | ||
152 | 99749 | ||
153 | 100683 | ||
154 | 184963 | ||
155 | 34340 | ||
156 | 84582 | ||
157 | 152527 | ||
158 | 225832 | ||
159 | 60575 | ||
160 | 115240 | ||
161 | 226637 | ||
162 | 161966 | ||
163 | 183392 | ||
164 | 197327 | ||
165 | 213856 | ||
166 | 241059 | ||
167 | 240186 | ||
168 | 100504 | ||
169 | 74754 | ||
170 | 81674 | ||
171 | 93395 | ||
172 | 132483 | ||
173 | 183200 | ||
174 | 197487 | ||
175 | 71281 | ||
176 | 78323 | ||
177 | 108050 | ||
178 | 115058 | ||
179 | 156455 | ||
180 | 179831 | ||
181 | 104 | ||
182 | 178270 | ||
183 | 200686 | ||
184 | 205651 | ||
185 | 54048 | ||
186 | 67055 | ||
187 | 157242 | ||
188 | 226147 | ||
189 | 264274 | ||
190 | 97314 | ||
191 | 112166 | ||
192 | 99664 | ||
193 | 112206 | ||
194 | 116049 | ||
195 | 182192 | ||
196 | 21848 | ||
197 | 66537 | ||
198 | 130426 | ||
199 | 152940 | ||
200 | 156285 | ||
201 | 197779 | ||
202 | 209053 | ||
203 | 238177 | ||
204 | 259864 | ||
205 | 61533 | ||
206 | 97798 | ||
207 | 104222 | ||
208 | 176915 | ||
209 | 180751 | ||
210 | 210478 | ||
211 | 63199 | ||
212 | 69447 | ||
213 | 224698 | ||
214 | 238313 | ||
215 | 67034 | ||
216 | 85757 | ||
217 | 85258 | ||
218 | 105388 | ||
219 | 153466 | ||
220 | 180480 | ||
221 | 88659 | ||
222 | 123185 | ||
223 | 176914 | ||
224 | 26649 | ||
225 | 101110 | ||
226 | 109718 | ||
227 | 112129 | ||
228 | 153412 | ||
229 | 169722 | ||
230 | 173098 | ||
231 | 97319 | ||
232 | 122228 | ||
233 | 126071 | ||
234 | 150970 | ||
235 | 186255 | ||
236 | 91527 | ||
237 | 149140 | ||
238 | 222949 | ||
239 | 117832 | ||
240 | 128889 | ||
241 | 129467 | ||
242 | 151042 | ||
243 | 125202 | ||
244 | 126520 | ||
245 | 173763 | ||
246 | 196324 | ||
247 | 207128 | ||
248 | 103415 | ||
249 | 137589 | ||
250 | 149105 | ||
251 | 82420 | ||
252 | 118796 | ||
253 | 137047 | ||
254 | 146660 | ||
255 | 151972 | ||
256 | 118828 | ||
257 | 127476 | ||
258 | 124086 | ||
259 | 68492 | ||
260 | 91587 | ||
261 | 90605 | ||
262 | 113982 | ||
263 | 117387 | ||
264 | 150991 | ||
265 | 152035 | ||
266 | 122974 | ||
267 | 84235 | ||
268 | 212209 | ||
269 | 114957 | ||
270 | 42000 | ||
271 | 242485 | ||
272 | 103945 | ||
273 | 143398 | ||
274 | 116457 | ||
275 | 198008 | ||
276 | 134212 | ||
277 | 257564 | ||
278 | 255173 | ||
279 | 252776 | ||
280 | 107194 | ||
281 | 289726 | ||
282 | 294096 | ||
283 | 161443 | ||
284 | 292606 | ||
285 | 277399 | ||
286 | 105290 | ||
287 | 159533 | ||
288 | 294098 | ||
289 | 276919 | ||
290 | 279700 | ||
291 | 304797 | ||
292 | 90329 | ||
293 | 57239 | ||
294 | 104324 | ||
295 | 58669 | ||
296 | 114859 | ||
297 | 185568 | ||
diff --git a/SD-VBS/benchmarks/mser/data/vga/mser b/SD-VBS/benchmarks/mser/data/vga/mser new file mode 100755 index 0000000..3a8d82b --- /dev/null +++ b/SD-VBS/benchmarks/mser/data/vga/mser | |||
Binary files differ | |||
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 | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/Makefile b/SD-VBS/benchmarks/mser/src/matlab/Makefile new file mode 100755 index 0000000..29c0982 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/Makefile | |||
@@ -0,0 +1,123 @@ | |||
1 | # file: Makefile | ||
2 | # author: Andrea Vedaldi | ||
3 | # description: Build mex files | ||
4 | |||
5 | # -------------------------------------------------------------------- | ||
6 | # | ||
7 | # -------------------------------------------------------------------- | ||
8 | |||
9 | # Determine on the flight the system we are running on | ||
10 | Darwin_ARCH := mac | ||
11 | Linux_ARCH := glx | ||
12 | ARCH := $($(shell uname)_ARCH) | ||
13 | |||
14 | mac_CFLAGS := -I. -pedantic -Wall -Wno-long-long | ||
15 | mac_MEX_CFLAGS := -g -O CFLAGS='$$CFLAGS $(mac_CFLAGS)' | ||
16 | mac_MEX_SUFFIX := mexmac | ||
17 | |||
18 | glx_CFLAGS := -I. -pedantic -Wall -Wno-long-long | ||
19 | glx_MEX_CFLAGS := -g -O CFLAGS='$$CFLAGS $(glx_CFLAGS)' | ||
20 | glx_MEX_SUFFIX := mexglx | ||
21 | |||
22 | MEX_SUFFIX := $($(ARCH)_MEX_SUFFIX) | ||
23 | MEX_CFLAGS := $($(ARCH)_MEX_CFLAGS) | ||
24 | |||
25 | VER := 0.4 | ||
26 | DIST := mser-$(VER) | ||
27 | BINDIST := $(DIST)-$(ARCH) | ||
28 | |||
29 | # -------------------------------------------------------------------- | ||
30 | # | ||
31 | # -------------------------------------------------------------------- | ||
32 | |||
33 | vpath %.mex.c . | ||
34 | |||
35 | src := $(wildcard *.mex.c) | ||
36 | msrc := $(wildcard *.m) | ||
37 | stem := $(notdir $(basename $(basename $(src)))) | ||
38 | tgt := $(addprefix ./, $(addsuffix .$(MEX_SUFFIX),$(stem))) | ||
39 | |||
40 | %.$(MEX_SUFFIX) : %.mex.c | ||
41 | mex -I. $(MEX_CFLAGS) $< -output $* | ||
42 | |||
43 | .PHONY: all | ||
44 | all: $(tgt) | ||
45 | |||
46 | .PHONY: info | ||
47 | info : | ||
48 | @echo src = $(src) | ||
49 | @echo stem = $(stem) | ||
50 | @echo tgt = $(tgt) | ||
51 | |||
52 | # PDF documentation | ||
53 | .PHONY: doc | ||
54 | doc: mser.html doc/mser.pdf | ||
55 | |||
56 | mser.html : $(msrc) | ||
57 | mdoc --output=mser.html . \ | ||
58 | --exclude='.*(_demo|_compile).*.m' | ||
59 | |||
60 | .PHONY: clean | ||
61 | clean: | ||
62 | rm -f $(tgt) | ||
63 | find . -name '.DS_Store' -exec rm -f \{\} \; | ||
64 | find . -name '.gdb_history' -exec rm -f \{\} \; | ||
65 | find . -name '*~' -exec rm -f \{\} \; | ||
66 | find . -name '*.bak' -exec rm -f \{\} \; | ||
67 | make -C doc/figures clean | ||
68 | |||
69 | .PHONY: distclean | ||
70 | distclean: clean | ||
71 | rm -f *.mexmac *.mexglx | ||
72 | rm -f mser.html | ||
73 | rm -f mser-*.tar.gz | ||
74 | rm -f doc/*.log | ||
75 | rm -f doc/*.aux | ||
76 | rm -f doc/*.toc | ||
77 | rm -f doc/*.bbl | ||
78 | rm -f doc/*.blg | ||
79 | rm -f doc/*.out | ||
80 | rm -f $(DIST).tar.gz | ||
81 | rm -f $(BINDIST).tar.gz | ||
82 | rm -rf $(BINDIST) | ||
83 | |||
84 | .PHONY: dist | ||
85 | dist: distclean | ||
86 | echo Version $(VER) >TIMESTAMP | ||
87 | echo Archive created on `date` >>TIMESTAMP | ||
88 | d=$(notdir $(CURDIR)) ; \ | ||
89 | tar chzvf $(DIST).tar.gz \ | ||
90 | --exclude mser_demo4.m \ | ||
91 | --exclude data/seq.avi \ | ||
92 | --exclude results \ | ||
93 | ../$${d} | ||
94 | |||
95 | .PHONY: bindist | ||
96 | bindist: all | ||
97 | test -e $(BINDIST) || mkdir $(BINDIST) | ||
98 | cp *.$(MEX_SUFFIX) $(BINDIST) | ||
99 | cd $(BINDIST) ; strip -S *.$(MEX_SUFFIX) | ||
100 | tar chzvf $(BINDIST).tar.gz $(BINDIST) | ||
101 | |||
102 | .PHONY: autorights | ||
103 | autorights: | ||
104 | autorights . \ | ||
105 | --verbose \ | ||
106 | --recursive \ | ||
107 | --template cal \ | ||
108 | --years 2006 \ | ||
109 | --authors "Andrea Vedaldi (UCLA VisionLab)" \ | ||
110 | --program "Video Extremal Regions" | ||
111 | |||
112 | doc/mser.pdf : doc/*.tex doc/*.bib doc/figures/*.fig | ||
113 | make -C doc/figures all | ||
114 | cd doc ; \ | ||
115 | for k in 1 2 3 ; \ | ||
116 | do \ | ||
117 | pdflatex -file-line-error-style -interaction batchmode \ | ||
118 | mser.tex ; \ | ||
119 | if test "$$k" = '1' ; \ | ||
120 | then \ | ||
121 | bibtex mser.aux ; \ | ||
122 | fi ; \ | ||
123 | done | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/TIMESTAMP b/SD-VBS/benchmarks/mser/src/matlab/TIMESTAMP new file mode 100755 index 0000000..1de1720 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/TIMESTAMP | |||
@@ -0,0 +1,2 @@ | |||
1 | Version 0.4 | ||
2 | Archive created on Wed Feb 7 11:08:47 PST 2007 | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/erfill.m b/SD-VBS/benchmarks/mser/src/matlab/erfill.m new file mode 100755 index 0000000..6e11fc6 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/erfill.m | |||
@@ -0,0 +1,13 @@ | |||
1 | % ERFILL Fill extremal region | ||
2 | % MEMBERS=ERFILL(I,ER) returns the list MEMBERS of the pixels which | ||
3 | % belongs to the extremal region represented by the pixel ER. | ||
4 | % | ||
5 | % The selected region is the one that contains pixel ER and of | ||
6 | % inensity I(ER). | ||
7 | % | ||
8 | % I must be of class UINT8 and ER must be a (scalar) index of the | ||
9 | % region representative point. | ||
10 | % | ||
11 | % See also MSER(). | ||
12 | |||
13 | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/erfill.mex.c b/SD-VBS/benchmarks/mser/src/matlab/erfill.mex.c new file mode 100755 index 0000000..893d346 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/erfill.mex.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* file: erfill.mex.c | ||
2 | ** description: Extremal Regions filling | ||
3 | ** author: Andrea Vedaldi | ||
4 | **/ | ||
5 | |||
6 | /* AUTORIGHTS | ||
7 | Copyright (C) 2006 Regents of the University of California | ||
8 | All rights reserved | ||
9 | |||
10 | Written by Andrea Vedaldi (UCLA VisionLab). | ||
11 | |||
12 | Redistribution and use in source and binary forms, with or without | ||
13 | modification, are permitted provided that the following conditions are met | ||
14 | |||
15 | * Redistributions of source code must retain the above copyright | ||
16 | notice, this list of conditions and the following disclaimer. | ||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | * Neither the name of the University of California, Berkeley nor the | ||
21 | names of its contributors may be used to endorse or promote products | ||
22 | derived from this software without specific prior written permission. | ||
23 | |||
24 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
25 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
27 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
28 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | */ | ||
35 | |||
36 | /** @file | ||
37 | ** @brief Maximally Stable Extremal Regions - MEX implementation | ||
38 | **/ | ||
39 | |||
40 | #include<mexutils.c> | ||
41 | #include<stdio.h> | ||
42 | #include<stdlib.h> | ||
43 | #include<math.h> | ||
44 | #include<string.h> | ||
45 | #include<assert.h> | ||
46 | |||
47 | #define MIN(x,y) (((x)<(y))?(x):(y)) | ||
48 | #define MAX(x,y) (((x)>(y))?(x):(y)) | ||
49 | |||
50 | typedef char unsigned val_t ; | ||
51 | typedef int unsigned idx_t ; | ||
52 | typedef long long int unsigned acc_t ; | ||
53 | |||
54 | /* advance N-dimensional subscript */ | ||
55 | void | ||
56 | adv(int const* dims, int ndims, int* subs_pt) | ||
57 | { | ||
58 | int d = 0 ; | ||
59 | while(d < ndims) { | ||
60 | if( ++subs_pt[d] < dims[d] ) return ; | ||
61 | subs_pt[d++] = 0 ; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /* driver */ | ||
66 | void | ||
67 | mexFunction(int nout, mxArray *out[], | ||
68 | int nin, const mxArray *in[]) | ||
69 | { | ||
70 | |||
71 | enum {IN_I=0, IN_ER} ; | ||
72 | enum {OUT_MEMBERS} ; | ||
73 | |||
74 | idx_t i ; | ||
75 | int k, nel, ndims ; | ||
76 | int const * dims ; | ||
77 | val_t const * I_pt ; | ||
78 | int last = 0 ; | ||
79 | int last_expanded = 0 ; | ||
80 | val_t value = 0 ; | ||
81 | |||
82 | double const * er_pt ; | ||
83 | |||
84 | int* subs_pt ; /* N-dimensional subscript */ | ||
85 | int* nsubs_pt ; /* diff-subscript to point to neigh. */ | ||
86 | idx_t* strides_pt ; /* strides to move in image array */ | ||
87 | val_t* visited_pt ; /* flag */ | ||
88 | idx_t* members_pt ; /* region members */ | ||
89 | |||
90 | /** ----------------------------------------------------------------- | ||
91 | ** Check the arguments | ||
92 | ** -------------------------------------------------------------- */ | ||
93 | if (nin != 2) { | ||
94 | mexErrMsgTxt("Two arguments required.") ; | ||
95 | } else if (nout > 4) { | ||
96 | mexErrMsgTxt("Too many output arguments."); | ||
97 | } | ||
98 | |||
99 | if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) { | ||
100 | mexErrMsgTxt("I must be of class UINT8.") ; | ||
101 | } | ||
102 | |||
103 | if(!uIsRealScalar(in[IN_ER])) { | ||
104 | mexErrMsgTxt("ER must be a DOUBLE scalar.") ; | ||
105 | } | ||
106 | |||
107 | /* get dimensions */ | ||
108 | nel = mxGetNumberOfElements(in[IN_I]) ; | ||
109 | ndims = mxGetNumberOfDimensions(in[IN_I]) ; | ||
110 | dims = mxGetDimensions(in[IN_I]) ; | ||
111 | I_pt = mxGetData(in[IN_I]) ; | ||
112 | |||
113 | /* allocate stuff */ | ||
114 | subs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
115 | nsubs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
116 | strides_pt = mxMalloc( sizeof(idx_t) * ndims ) ; | ||
117 | visited_pt = mxMalloc( sizeof(val_t) * nel ) ; | ||
118 | members_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
119 | |||
120 | er_pt = mxGetPr(in[IN_ER]) ; | ||
121 | |||
122 | /* compute strides to move into the N-dimensional image array */ | ||
123 | strides_pt [0] = 1 ; | ||
124 | for(k = 1 ; k < ndims ; ++k) { | ||
125 | strides_pt [k] = strides_pt [k-1] * dims [k-1] ; | ||
126 | } | ||
127 | |||
128 | /* load first pixel */ | ||
129 | memset(visited_pt, 0, sizeof(val_t) * nel) ; | ||
130 | { | ||
131 | idx_t idx = (idx_t) *er_pt ; | ||
132 | if( idx < 1 || idx > nel ) { | ||
133 | char buff[80] ; | ||
134 | snprintf(buff,80,"ER=%d out of range [1,%d]",idx,nel) ; | ||
135 | mexErrMsgTxt(buff) ; | ||
136 | } | ||
137 | members_pt [last++] = idx - 1 ; | ||
138 | } | ||
139 | value = I_pt[ members_pt[0] ] ; | ||
140 | |||
141 | /* ----------------------------------------------------------------- | ||
142 | * Fill region | ||
143 | * -------------------------------------------------------------- */ | ||
144 | while(last_expanded < last) { | ||
145 | |||
146 | /* pop next node xi */ | ||
147 | idx_t index = members_pt[last_expanded++] ; | ||
148 | |||
149 | /* convert index into a subscript sub; also initialize nsubs | ||
150 | to (-1,-1,...,-1) */ | ||
151 | { | ||
152 | idx_t temp = index ; | ||
153 | for(k = ndims-1 ; k >=0 ; --k) { | ||
154 | nsubs_pt [k] = -1 ; | ||
155 | subs_pt [k] = temp / strides_pt [k] ; | ||
156 | temp = temp % strides_pt [k] ; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /* process neighbors of xi */ | ||
161 | while( true ) { | ||
162 | int good = true ; | ||
163 | idx_t nindex = 0 ; | ||
164 | |||
165 | /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX | ||
166 | and check that the pixel is within image boundaries. */ | ||
167 | for(k = 0 ; k < ndims && good ; ++k) { | ||
168 | int temp = nsubs_pt [k] + subs_pt [k] ; | ||
169 | good &= 0 <= temp && temp < dims[k] ; | ||
170 | nindex += temp * strides_pt [k] ; | ||
171 | } | ||
172 | |||
173 | /* process neighbor | ||
174 | 1 - the pixel is within image boundaries; | ||
175 | 2 - the pixel is indeed different from the current node | ||
176 | (this happens when nsub=(0,0,...,0)); | ||
177 | 3 - the pixel has value not greather than val | ||
178 | is a pixel older than xi | ||
179 | 4 - the pixel has not been visited yet | ||
180 | */ | ||
181 | if(good | ||
182 | && nindex != index | ||
183 | && I_pt [nindex] <= value | ||
184 | && ! visited_pt [nindex] ) { | ||
185 | |||
186 | /* mark as visited */ | ||
187 | visited_pt [nindex] = 1 ; | ||
188 | |||
189 | /* add to list */ | ||
190 | members_pt [last++] = nindex ; | ||
191 | } | ||
192 | |||
193 | /* move to next neighbor */ | ||
194 | k = 0 ; | ||
195 | while(++ nsubs_pt [k] > 1) { | ||
196 | nsubs_pt [k++] = -1 ; | ||
197 | if(k == ndims) goto done_all_neighbors ; | ||
198 | } | ||
199 | } /* next neighbor */ | ||
200 | done_all_neighbors : ; | ||
201 | } /* goto pop next member */ | ||
202 | |||
203 | /* | ||
204 | * Save results | ||
205 | */ | ||
206 | { | ||
207 | int dims[2] ; | ||
208 | int unsigned * pt ; | ||
209 | dims[0] = last ; | ||
210 | out[OUT_MEMBERS] = mxCreateNumericArray(1,dims,mxUINT32_CLASS,mxREAL); | ||
211 | pt = mxGetData(out[OUT_MEMBERS]) ; | ||
212 | for (i = 0 ; i < last ; ++i) { | ||
213 | *pt++ = members_pt[i] + 1 ; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | /* free stuff */ | ||
218 | mxFree( members_pt ) ; | ||
219 | mxFree( visited_pt ) ; | ||
220 | mxFree( strides_pt ) ; | ||
221 | mxFree( nsubs_pt ) ; | ||
222 | mxFree( subs_pt ) ; | ||
223 | } | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/erfill.mexa64 b/SD-VBS/benchmarks/mser/src/matlab/erfill.mexa64 new file mode 100755 index 0000000..bc54d65 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/erfill.mexa64 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/erfill.mexglx b/SD-VBS/benchmarks/mser/src/matlab/erfill.mexglx new file mode 100755 index 0000000..8eec110 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/erfill.mexglx | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mexutils.c b/SD-VBS/benchmarks/mser/src/matlab/mexutils.c new file mode 100755 index 0000000..0fc664b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mexutils.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* file: mexutils.c | ||
2 | ** author: Andrea Vedaldi | ||
3 | ** description: Utility functions to write MEX files. | ||
4 | **/ | ||
5 | |||
6 | #include"mex.h" | ||
7 | |||
8 | #undef M_PI | ||
9 | #define M_PI 3.14159265358979 | ||
10 | |||
11 | /** @brief Is scalar? | ||
12 | ** | ||
13 | ** @return @c true if the array @a A is a scalar. | ||
14 | **/ | ||
15 | int | ||
16 | uIsScalar(const mxArray* A) | ||
17 | { | ||
18 | return | ||
19 | !mxIsComplex(A) && | ||
20 | mxGetNumberOfDimensions(A) == 2 && | ||
21 | mxGetM(A) == 1 && | ||
22 | mxGetN(A) == 1 ; | ||
23 | } | ||
24 | |||
25 | /** @brief Is real scalar? | ||
26 | ** | ||
27 | ** @return @c true if the array @a A is a real scalar. | ||
28 | **/ | ||
29 | int | ||
30 | uIsRealScalar(const mxArray* A) | ||
31 | { | ||
32 | return | ||
33 | mxIsDouble(A) && | ||
34 | !mxIsComplex(A) && | ||
35 | mxGetNumberOfDimensions(A) == 2 && | ||
36 | mxGetM(A) == 1 && | ||
37 | mxGetN(A) == 1 ; | ||
38 | } | ||
39 | |||
40 | /** @brief Is real matrix? | ||
41 | ** | ||
42 | ** The function checks wether the argument @a A is a real matrix. In | ||
43 | ** addition, if @a M >= 0, it checks wether the number of rows is | ||
44 | ** equal to @a M and, if @a N >= 0, if the number of columns is equal | ||
45 | ** to @a N. | ||
46 | ** | ||
47 | ** @param M number of rows. | ||
48 | ** @param N number of columns. | ||
49 | ** @return @c true if the array is a real matrix with the specified format. | ||
50 | **/ | ||
51 | int | ||
52 | uIsRealMatrix(const mxArray* A, int M, int N) | ||
53 | { | ||
54 | return | ||
55 | mxIsDouble(A) && | ||
56 | !mxIsComplex(A) && | ||
57 | mxGetNumberOfDimensions(A) == 2 && | ||
58 | ((M>=0)?(mxGetM(A) == M):1) && | ||
59 | ((N>=0)?(mxGetN(A) == N):1) ; | ||
60 | } | ||
61 | |||
62 | /** @brief Is real vector? | ||
63 | ** | ||
64 | ** The function checks wether the argument @a V is a real vector. By | ||
65 | ** definiton, a matrix is a vector if one of its dimension is one. | ||
66 | ** In addition, if @a D >= 0, it checks wether the dimension of the | ||
67 | ** vecotr is equal to @a D. | ||
68 | ** | ||
69 | ** @param D lenght of the vector. | ||
70 | ** @return @c true if the array is a real vector of the specified dimension. | ||
71 | **/ | ||
72 | int | ||
73 | uIsRealVector(const mxArray* V, int D) | ||
74 | { | ||
75 | int M = mxGetM(V) ; | ||
76 | int N = mxGetN(V) ; | ||
77 | int is_vector = (N == 1) || (M == 1) ; | ||
78 | |||
79 | return | ||
80 | mxIsDouble(V) && | ||
81 | !mxIsComplex(V) && | ||
82 | mxGetNumberOfDimensions(V) == 2 && | ||
83 | is_vector && | ||
84 | ( D < 0 || N == D || M == D) ; | ||
85 | } | ||
86 | |||
87 | |||
88 | /** @brief Is a string? | ||
89 | ** | ||
90 | ** The function checks wether the array @a S is a string. If | ||
91 | ** @a L is non-negative, it also check wether the strign has | ||
92 | ** length @a L. | ||
93 | ** | ||
94 | ** @return @a c true if S is a string of the specified length. | ||
95 | **/ | ||
96 | int | ||
97 | uIsString(const mxArray* S, int L) | ||
98 | { | ||
99 | int M = mxGetM(S) ; | ||
100 | int N = mxGetN(S) ; | ||
101 | |||
102 | return | ||
103 | mxIsChar(S) && | ||
104 | M == 1 && | ||
105 | (L < 0 || N == L) ; | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | ** | ||
110 | **/ | ||
111 | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser.mex.c b/SD-VBS/benchmarks/mser/src/matlab/mser.mex.c new file mode 100755 index 0000000..8473afe --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser.mex.c | |||
@@ -0,0 +1,815 @@ | |||
1 | /* file: mser.mex.c | ||
2 | ** description: Maximally Stable Extremal Regions | ||
3 | ** author: Andrea Vedaldi | ||
4 | **/ | ||
5 | |||
6 | /* AUTORIGHTS | ||
7 | Copyright (C) 2006 Regents of the University of California | ||
8 | All rights reserved | ||
9 | |||
10 | Written by Andrea Vedaldi (UCLA VisionLab). | ||
11 | |||
12 | Redistribution and use in source and binary forms, with or without | ||
13 | modification, are permitted provided that the following conditions are met | ||
14 | |||
15 | * Redistributions of source code must retain the above copyright | ||
16 | notice, this list of conditions and the following disclaimer. | ||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | * Neither the name of the University of California, Berkeley nor the | ||
21 | names of its contributors may be used to endorse or promote products | ||
22 | derived from this software without specific prior written permission. | ||
23 | |||
24 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
25 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
27 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
28 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | */ | ||
35 | |||
36 | /** @file | ||
37 | ** @brief Maximally Stable Extremal Regions - MEX implementation | ||
38 | **/ | ||
39 | |||
40 | #include<mexutils.c> | ||
41 | #include<stdio.h> | ||
42 | #include<stdlib.h> | ||
43 | #include<math.h> | ||
44 | #include<string.h> | ||
45 | #include<assert.h> | ||
46 | |||
47 | #define MIN(x,y) (((x)<(y))?(x):(y)) | ||
48 | #define MAX(x,y) (((x)>(y))?(x):(y)) | ||
49 | |||
50 | #define BUCKETS 256 | ||
51 | |||
52 | #define USE_BUCKET_SORT | ||
53 | /*#define USE_RANK_UNION | ||
54 | */ | ||
55 | |||
56 | typedef char unsigned val_t ; | ||
57 | typedef int unsigned idx_t ; | ||
58 | typedef long long int unsigned acc_t ; | ||
59 | |||
60 | /* pairs are used to sort the pixels */ | ||
61 | typedef struct | ||
62 | { | ||
63 | val_t value ; | ||
64 | idx_t index ; | ||
65 | } pair_t ; | ||
66 | |||
67 | /* forest node */ | ||
68 | typedef struct | ||
69 | { | ||
70 | idx_t parent ; /**< parent pixel */ | ||
71 | idx_t shortcut ; /**< shortcut to the root */ | ||
72 | idx_t region ; /**< index of the region */ | ||
73 | int area ; /**< area of the region */ | ||
74 | #ifdef USE_RANK_UNION | ||
75 | int height ; /**< node height */ | ||
76 | #endif | ||
77 | } node_t ; | ||
78 | |||
79 | /* extremal regions */ | ||
80 | typedef struct | ||
81 | { | ||
82 | idx_t parent ; /**< parent region */ | ||
83 | idx_t index ; /**< index of root pixel */ | ||
84 | val_t value ; /**< value of root pixel */ | ||
85 | int area ; /**< area of the region */ | ||
86 | int area_top ; /**< area of the region DELTA levels above */ | ||
87 | int area_bot ; /**< area of the region DELTA levels below */ | ||
88 | float variation ; /**< variation */ | ||
89 | int maxstable ; /**< max stable number (=0 if not maxstable) */ | ||
90 | } region_t ; | ||
91 | |||
92 | /* predicate used to sort pixels by increasing intensity */ | ||
93 | int | ||
94 | cmp_pair(void const* a, void const* b) | ||
95 | { | ||
96 | pair_t* pa = (pair_t*) a; | ||
97 | pair_t* pb = (pair_t*) b; | ||
98 | return pa->value - pb->value ; | ||
99 | } | ||
100 | |||
101 | /* advance N-dimensional subscript */ | ||
102 | void | ||
103 | adv(int const* dims, int ndims, int* subs_pt) | ||
104 | { | ||
105 | int d = 0 ; | ||
106 | while(d < ndims) { | ||
107 | if( ++subs_pt[d] < dims[d] ) return ; | ||
108 | subs_pt[d++] = 0 ; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | /* driver */ | ||
113 | void | ||
114 | mexFunction(int nout, mxArray *out[], | ||
115 | int nin, const mxArray *in[]) | ||
116 | { | ||
117 | enum {IN_I=0, IN_DELTA} ; | ||
118 | enum {OUT_REGIONS=0, OUT_ELL, OUT_PARENTS, OUT_AREA} ; | ||
119 | |||
120 | idx_t i ; | ||
121 | idx_t rindex = 0 ; | ||
122 | int k ; | ||
123 | |||
124 | /* configuration */ | ||
125 | int verbose = 0 ; /* be verbose */ | ||
126 | int small_cleanup= 1 ; /* remove very small regions */ | ||
127 | int big_cleanup = 1 ; /* remove very big regions */ | ||
128 | int bad_cleanup = 0 ; /* remove very bad regions */ | ||
129 | int dup_cleanup = 1 ; /* remove duplicates */ | ||
130 | val_t delta ; /* stability delta */ | ||
131 | |||
132 | /* node value denoting a void node */ | ||
133 | idx_t const node_is_void = 0xffffffff ; | ||
134 | |||
135 | int* subs_pt ; /* N-dimensional subscript */ | ||
136 | int* nsubs_pt ; /* diff-subscript to point to neigh. */ | ||
137 | idx_t* strides_pt ; /* strides to move in image array */ | ||
138 | idx_t* visited_pt ; /* flag */ | ||
139 | |||
140 | int nel ; /* number of image elements (pixels) */ | ||
141 | int ner = 0 ; /* number of extremal regions */ | ||
142 | int nmer = 0 ; /* number of maximally stable */ | ||
143 | int ndims ; /* number of dimensions */ | ||
144 | int const* dims ; /* dimensions */ | ||
145 | int njoins = 0 ; /* number of join ops */ | ||
146 | |||
147 | val_t const* I_pt ; /* source image */ | ||
148 | pair_t* pairs_pt ; /* scratch buffer to sort pixels */ | ||
149 | node_t* forest_pt ; /* the extremal regions forest */ | ||
150 | region_t* regions_pt ; /* list of extremal regions found */ | ||
151 | |||
152 | /* ellipses fitting */ | ||
153 | acc_t* acc_pt ; /* accumulator to integrate region moments */ | ||
154 | acc_t* ell_pt ; /* ellipses parameters */ | ||
155 | int gdl ; /* number of parameters of an ellipse */ | ||
156 | idx_t* joins_pt ; /* sequence of joins */ | ||
157 | |||
158 | /** ----------------------------------------------------------------- | ||
159 | ** Check the arguments | ||
160 | ** -------------------------------------------------------------- */ | ||
161 | if (nin != 2) { | ||
162 | mexErrMsgTxt("Two arguments required.") ; | ||
163 | } else if (nout > 4) { | ||
164 | mexErrMsgTxt("Too many output arguments."); | ||
165 | } | ||
166 | |||
167 | if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) { | ||
168 | mexErrMsgTxt("I must be of class UINT8") ; | ||
169 | } | ||
170 | |||
171 | if(!uIsScalar(in[IN_DELTA])) { | ||
172 | mexErrMsgTxt("DELTA must be scalar") ; | ||
173 | } | ||
174 | |||
175 | delta = 0 ; | ||
176 | switch(mxGetClassID(in[IN_DELTA])) { | ||
177 | case mxUINT8_CLASS : | ||
178 | delta = * (val_t*) mxGetData(in[IN_DELTA]) ; | ||
179 | break ; | ||
180 | |||
181 | case mxDOUBLE_CLASS : | ||
182 | { | ||
183 | double x = *mxGetPr(in[IN_DELTA]) ; | ||
184 | if(x < 0.0) { | ||
185 | mexErrMsgTxt("DELTA must be non-negative") ; | ||
186 | } | ||
187 | delta = (val_t) x ; | ||
188 | } | ||
189 | break ; | ||
190 | |||
191 | default : | ||
192 | mexErrMsgTxt("DELTA must be of class DOUBLE or UINT8") ; | ||
193 | } | ||
194 | |||
195 | /* get dimensions */ | ||
196 | nel = mxGetNumberOfElements(in[IN_I]) ; | ||
197 | ndims = mxGetNumberOfDimensions(in[IN_I]) ; | ||
198 | dims = mxGetDimensions(in[IN_I]) ; | ||
199 | I_pt = mxGetData(in[IN_I]) ; | ||
200 | |||
201 | /* allocate stuff */ | ||
202 | subs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
203 | nsubs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
204 | strides_pt = mxMalloc( sizeof(idx_t) * ndims ) ; | ||
205 | visited_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
206 | regions_pt = mxMalloc( sizeof(region_t) * nel ) ; | ||
207 | pairs_pt = mxMalloc( sizeof(pair_t) * nel ) ; | ||
208 | forest_pt = mxMalloc( sizeof(node_t) * nel ) ; | ||
209 | joins_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
210 | |||
211 | /* compute strides to move into the N-dimensional image array */ | ||
212 | strides_pt [0] = 1 ; | ||
213 | for(k = 1 ; k < ndims ; ++k) { | ||
214 | strides_pt [k] = strides_pt [k-1] * dims [k-1] ; | ||
215 | } | ||
216 | |||
217 | /* sort pixels by increasing intensity*/ | ||
218 | verbose && mexPrintf("Sorting pixels ... ") ; | ||
219 | |||
220 | #ifndef USE_BUCKET_SORT | ||
221 | for(i = 0 ; i < nel ; ++i) { | ||
222 | pairs_pt [i].value = I_pt [i] ; | ||
223 | pairs_pt [i].index = i ; | ||
224 | } | ||
225 | qsort(pairs_pt, nel, sizeof(pair_t), cmp_pair) ; | ||
226 | #else | ||
227 | { | ||
228 | int unsigned buckets [BUCKETS] ; | ||
229 | int unsigned v; | ||
230 | memset(buckets, 0, sizeof(int unsigned)*BUCKETS) ; | ||
231 | for(i = 0 ; i < nel ; ++i) { | ||
232 | v = (unsigned int)I_pt [i] ; | ||
233 | ++buckets[v] ; | ||
234 | } | ||
235 | for(i = 1 ; i < BUCKETS ; ++i) { | ||
236 | buckets[i] += buckets[i-1] ; | ||
237 | } | ||
238 | for(i = nel ; i >= 1 ; ) { | ||
239 | v = I_pt [--i] ; | ||
240 | idx_t j = --buckets [v] ; | ||
241 | pairs_pt [j].value = v ; | ||
242 | pairs_pt [j].index = i ; | ||
243 | } | ||
244 | } | ||
245 | #endif | ||
246 | verbose && mexPrintf("done\n") ; | ||
247 | |||
248 | /* initialize the forest with all void nodes */ | ||
249 | for(i = 0 ; i < nel ; ++i) { | ||
250 | forest_pt [i].parent = node_is_void ; | ||
251 | } | ||
252 | |||
253 | /* number of ellipse free parameters */ | ||
254 | gdl = ndims*(ndims+1)/2 + ndims ; | ||
255 | |||
256 | /* ----------------------------------------------------------------- | ||
257 | * Compute extremal regions tree | ||
258 | * -------------------------------------------------------------- */ | ||
259 | verbose && mexPrintf("Computing extremal regions ... ") ; | ||
260 | for(i = 0 ; i < nel ; ++i) { | ||
261 | |||
262 | /* pop next node xi */ | ||
263 | idx_t index = pairs_pt [i].index ; | ||
264 | val_t value = pairs_pt [i].value ; | ||
265 | |||
266 | |||
267 | /* this will be needed later */ | ||
268 | rindex = index ; | ||
269 | |||
270 | /* push it into the tree */ | ||
271 | forest_pt [index] .parent = index ; | ||
272 | forest_pt [index] .shortcut = index ; | ||
273 | forest_pt [index] .area = 1 ; | ||
274 | #ifdef USE_RANK_UNION | ||
275 | forest_pt [index] .height = 1 ; | ||
276 | #endif | ||
277 | |||
278 | /* convert index into a subscript sub; also initialize nsubs | ||
279 | to (-1,-1,...,-1) */ | ||
280 | { | ||
281 | idx_t temp = index ; | ||
282 | for(k = ndims-1 ; k >=0 ; --k) { | ||
283 | nsubs_pt [k] = -1 ; | ||
284 | subs_pt [k] = temp / strides_pt [k] ; | ||
285 | temp = temp % strides_pt [k] ; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* process neighbors of xi */ | ||
290 | while( true ) { | ||
291 | int good = true ; | ||
292 | idx_t nindex = 0 ; | ||
293 | |||
294 | /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX | ||
295 | and check that the pixel is within image boundaries. */ | ||
296 | for(k = 0 ; k < ndims && good ; ++k) { | ||
297 | int temp = nsubs_pt [k] + subs_pt [k] ; | ||
298 | good &= 0 <= temp && temp < dims[k] ; | ||
299 | nindex += temp * strides_pt [k] ; | ||
300 | } | ||
301 | |||
302 | /* keep going only if | ||
303 | 1 - the neighbor is within image boundaries; | ||
304 | 2 - the neighbor is indeed different from the current node | ||
305 | (this happens when nsub=(0,0,...,0)); | ||
306 | 3 - the nieghbor is already in the tree, meaning that | ||
307 | is a pixel older than xi. | ||
308 | */ | ||
309 | if(good && | ||
310 | nindex != index && | ||
311 | forest_pt[nindex].parent != node_is_void ) { | ||
312 | |||
313 | idx_t nrindex = 0, nvisited ; | ||
314 | val_t nrvalue = 0 ; | ||
315 | |||
316 | #ifdef USE_RANK_UNION | ||
317 | int height = forest_pt [ rindex] .height ; | ||
318 | int nheight = forest_pt [nrindex] .height ; | ||
319 | #endif | ||
320 | |||
321 | /* RINDEX = ROOT(INDEX) might change as we merge trees, so we | ||
322 | need to update it after each merge */ | ||
323 | |||
324 | /* find the root of the current node */ | ||
325 | /* also update the shortcuts */ | ||
326 | nvisited = 0 ; | ||
327 | while( forest_pt[rindex].shortcut != rindex ) { | ||
328 | visited_pt[ nvisited++ ] = rindex ; | ||
329 | rindex = forest_pt[rindex].shortcut ; | ||
330 | } | ||
331 | while( nvisited-- ) { | ||
332 | forest_pt [ visited_pt[nvisited] ] .shortcut = rindex ; | ||
333 | } | ||
334 | |||
335 | /* find the root of the neighbor */ | ||
336 | nrindex = nindex ; | ||
337 | nvisited = 0 ; | ||
338 | while( forest_pt[nrindex].shortcut != nrindex ) { | ||
339 | visited_pt[ nvisited++ ] = nrindex ; | ||
340 | nrindex = forest_pt[nrindex].shortcut ; | ||
341 | } | ||
342 | while( nvisited-- ) { | ||
343 | forest_pt [ visited_pt[nvisited] ] .shortcut = nrindex ; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | Now we join the two subtrees rooted at | ||
348 | |||
349 | RINDEX = ROOT(INDEX) and NRINDEX = ROOT(NINDEX). | ||
350 | |||
351 | Only three things can happen: | ||
352 | |||
353 | a - ROOT(INDEX) == ROOT(NRINDEX). In this case the two trees | ||
354 | have already been joined and we do not do anything. | ||
355 | |||
356 | b - I(ROOT(INDEX)) == I(ROOT(NRINDEX)). In this case index | ||
357 | is extending an extremal region with the same | ||
358 | value. Since ROOT(NRINDEX) will NOT be an extremal | ||
359 | region of the full image, ROOT(INDEX) can be safely | ||
360 | addedd as children of ROOT(NRINDEX) if this reduces | ||
361 | the height according to union rank. | ||
362 | |||
363 | c - I(ROOT(INDEX)) > I(ROOT(NRINDEX)) as index is extending | ||
364 | an extremal region, but increasing its level. In this | ||
365 | case ROOT(NRINDEX) WILL be an extremal region of the | ||
366 | final image and the only possibility is to add | ||
367 | ROOT(NRINDEX) as children of ROOT(INDEX). | ||
368 | */ | ||
369 | |||
370 | if( rindex != nrindex ) { | ||
371 | /* this is a genuine join */ | ||
372 | |||
373 | nrvalue = I_pt [nrindex] ; | ||
374 | if( nrvalue == value | ||
375 | #ifdef USE_RANK_UNION | ||
376 | && height < nheight | ||
377 | #endif | ||
378 | ) { | ||
379 | /* ROOT(INDEX) becomes the child */ | ||
380 | forest_pt[rindex] .parent = nrindex ; | ||
381 | forest_pt[rindex] .shortcut = nrindex ; | ||
382 | forest_pt[nrindex].area += forest_pt[rindex].area ; | ||
383 | |||
384 | #ifdef USE_RANK_UNION | ||
385 | forest_pt[nrindex].height = MAX(nheight, height+1) ; | ||
386 | #endif | ||
387 | |||
388 | joins_pt[njoins++] = rindex ; | ||
389 | |||
390 | } else { | ||
391 | /* ROOT(index) becomes parent */ | ||
392 | forest_pt[nrindex] .parent = rindex ; | ||
393 | forest_pt[nrindex] .shortcut = rindex ; | ||
394 | forest_pt[rindex] .area += forest_pt[nrindex].area ; | ||
395 | |||
396 | #ifdef USE_RANK_UNION | ||
397 | forest_pt[rindex].height = MAX(height, nheight+1) ; | ||
398 | #endif | ||
399 | if( nrvalue != value ) { | ||
400 | /* nrindex is extremal region: save for later */ | ||
401 | forest_pt[nrindex].region = ner ; | ||
402 | regions_pt [ner] .index = nrindex ; | ||
403 | regions_pt [ner] .parent = ner ; | ||
404 | regions_pt [ner] .value = nrvalue ; | ||
405 | regions_pt [ner] .area = forest_pt [nrindex].area ; | ||
406 | regions_pt [ner] .area_top = nel ; | ||
407 | regions_pt [ner] .area_bot = 0 ; | ||
408 | ++ner ; | ||
409 | } | ||
410 | |||
411 | /* annote join operation for post-processing */ | ||
412 | joins_pt[njoins++] = nrindex ; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | } /* neighbor done */ | ||
417 | |||
418 | /* move to next neighbor */ | ||
419 | k = 0 ; | ||
420 | while(++ nsubs_pt [k] > 1) { | ||
421 | nsubs_pt [k++] = -1 ; | ||
422 | if(k == ndims) goto done_all_neighbors ; | ||
423 | } | ||
424 | } /* next neighbor */ | ||
425 | done_all_neighbors : ; | ||
426 | } /* next pixel */ | ||
427 | |||
428 | |||
429 | /* the root of the last processed pixel must be a region */ | ||
430 | forest_pt [rindex].region = ner ; | ||
431 | regions_pt [ner] .index = rindex ; | ||
432 | regions_pt [ner] .parent = ner ; | ||
433 | regions_pt [ner] .value = I_pt [rindex] ; | ||
434 | regions_pt [ner] .area = forest_pt [rindex] .area ; | ||
435 | regions_pt [ner] .area_top = nel ; | ||
436 | regions_pt [ner] .area_bot = 0 ; | ||
437 | ++ner ; | ||
438 | |||
439 | verbose && mexPrintf("done\nExtremal regions: %d\n", ner) ; | ||
440 | |||
441 | /* ----------------------------------------------------------------- | ||
442 | * Compute region parents | ||
443 | * -------------------------------------------------------------- */ | ||
444 | for( i = 0 ; i < ner ; ++i) { | ||
445 | idx_t index = regions_pt [i].index ; | ||
446 | val_t value = regions_pt [i].value ; | ||
447 | idx_t j = i ; | ||
448 | |||
449 | while(j == i) { | ||
450 | idx_t pindex = forest_pt [index].parent ; | ||
451 | val_t pvalue = I_pt [pindex] ; | ||
452 | |||
453 | /* top of the tree */ | ||
454 | if(index == pindex) { | ||
455 | j = forest_pt[index].region ; | ||
456 | break ; | ||
457 | } | ||
458 | |||
459 | /* if index is the root of a region, either this is still | ||
460 | i, or it is the parent region we are looking for. */ | ||
461 | if(value < pvalue) { | ||
462 | j = forest_pt[index].region ; | ||
463 | } | ||
464 | |||
465 | index = pindex ; | ||
466 | value = pvalue ; | ||
467 | } | ||
468 | regions_pt[i]. parent = j ; | ||
469 | } | ||
470 | |||
471 | /* ----------------------------------------------------------------- | ||
472 | * Compute areas of tops and bottoms | ||
473 | * -------------------------------------------------------------- */ | ||
474 | |||
475 | /* We scan the list of regions from the bottom. Let x0 be the current | ||
476 | region and be x1 = PARENT(x0), x2 = PARENT(x1) and so on. | ||
477 | |||
478 | Here we do two things: | ||
479 | |||
480 | 1) Look for regions x for which x0 is the BOTTOM. This requires | ||
481 | VAL(x0) <= VAL(x) - DELTA < VAL(x1). | ||
482 | We update AREA_BOT(x) for each of such x found. | ||
483 | |||
484 | 2) Look for the region y which is the TOP of x0. This requires | ||
485 | VAL(y) <= VAL(x0) + DELTA < VAL(y+1) | ||
486 | We update AREA_TOP(x0) as soon as we find such y. | ||
487 | |||
488 | */ | ||
489 | |||
490 | for( i = 0 ; i < ner ; ++i) { | ||
491 | /* fix xi as the region, then xj are the parents */ | ||
492 | idx_t parent = regions_pt [i].parent ; | ||
493 | int val0 = regions_pt [i].value ; | ||
494 | int val1 = regions_pt [parent].value ; | ||
495 | int val = val0 ; | ||
496 | idx_t j = i ; | ||
497 | |||
498 | while(true) { | ||
499 | int valp = regions_pt [parent].value ; | ||
500 | |||
501 | /* i is the bottom of j */ | ||
502 | if(val0 <= val - delta && val - delta < val1) { | ||
503 | regions_pt [j].area_bot = | ||
504 | MAX(regions_pt [j].area_bot, regions_pt [i].area) ; | ||
505 | } | ||
506 | |||
507 | /* j is the top of i */ | ||
508 | if(val <= val0 + delta && val0 + delta < valp) { | ||
509 | regions_pt [i].area_top = regions_pt [j].area ; | ||
510 | } | ||
511 | |||
512 | /* stop if going on is useless */ | ||
513 | if(val1 <= val - delta && val0 + delta < val) | ||
514 | break ; | ||
515 | |||
516 | /* stop also if j is the root */ | ||
517 | if(j == parent) | ||
518 | break ; | ||
519 | |||
520 | /* next region upward */ | ||
521 | j = parent ; | ||
522 | parent = regions_pt [j].parent ; | ||
523 | val = valp ; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* ----------------------------------------------------------------- | ||
528 | * Compute variation | ||
529 | * -------------------------------------------------------------- */ | ||
530 | for(i = 0 ; i < ner ; ++i) { | ||
531 | int area = regions_pt [i].area ; | ||
532 | int area_top = regions_pt [i].area_top ; | ||
533 | int area_bot = regions_pt [i].area_bot ; | ||
534 | regions_pt [i].variation = | ||
535 | (float)(area_top - area_bot) / (float)area ; | ||
536 | |||
537 | /* initialize .mastable to 1 for all nodes */ | ||
538 | regions_pt [i].maxstable = 1 ; | ||
539 | } | ||
540 | |||
541 | /* ----------------------------------------------------------------- | ||
542 | * Remove regions which are NOT maximally stable | ||
543 | * -------------------------------------------------------------- */ | ||
544 | nmer = ner ; | ||
545 | for(i = 0 ; i < ner ; ++i) { | ||
546 | idx_t parent = regions_pt [i] .parent ; | ||
547 | float var = regions_pt [i] .variation ; | ||
548 | float pvar = regions_pt [parent] .variation ; | ||
549 | idx_t loser ; | ||
550 | |||
551 | /* decide which one to keep and put that in loser */ | ||
552 | if(var < pvar) loser = parent ; else loser = i ; | ||
553 | |||
554 | /* make loser NON maximally stable */ | ||
555 | if(regions_pt [loser].maxstable) --nmer ; | ||
556 | regions_pt [loser].maxstable = 0 ; | ||
557 | } | ||
558 | |||
559 | verbose && mexPrintf("Maximally stable regions: %d (%.1f%%)\n", | ||
560 | nmer, 100.0 * (double) nmer / ner) ; | ||
561 | |||
562 | /* ----------------------------------------------------------------- | ||
563 | * Remove more regions | ||
564 | * -------------------------------------------------------------- */ | ||
565 | |||
566 | /* it is critical for correct duplicate detection to remove regions | ||
567 | from the bottom (smallest one first) */ | ||
568 | |||
569 | if( big_cleanup || small_cleanup || bad_cleanup || dup_cleanup ) { | ||
570 | int nbig = 0 ; | ||
571 | int nsmall = 0 ; | ||
572 | int nbad = 0 ; | ||
573 | int ndup = 0 ; | ||
574 | |||
575 | /* scann all extremal regions */ | ||
576 | for(i = 0 ; i < ner ; ++i) { | ||
577 | |||
578 | /* process only maximally stable extremal regions */ | ||
579 | if(! regions_pt [i].maxstable) continue ; | ||
580 | |||
581 | if( bad_cleanup && regions_pt[i].variation >= 1.0f ) { | ||
582 | ++nbad ; | ||
583 | goto remove_this_region ; | ||
584 | } | ||
585 | |||
586 | if( big_cleanup && regions_pt[i].area > nel/2 ) { | ||
587 | ++nbig ; | ||
588 | goto remove_this_region ; | ||
589 | } | ||
590 | |||
591 | if( small_cleanup && regions_pt[i].area < 25 ) { | ||
592 | ++nsmall ; | ||
593 | goto remove_this_region ; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Remove duplicates | ||
598 | */ | ||
599 | if( dup_cleanup ) { | ||
600 | idx_t parent = regions_pt [i].parent ; | ||
601 | int area, parea ; | ||
602 | float change ; | ||
603 | |||
604 | /* the search does not apply to root regions */ | ||
605 | if(parent != i) { | ||
606 | |||
607 | /* search for the maximally stable parent region */ | ||
608 | while(! regions_pt[parent].maxstable) { | ||
609 | idx_t next = regions_pt[parent].parent ; | ||
610 | if(next == parent) break ; | ||
611 | parent = next ; | ||
612 | } | ||
613 | |||
614 | /* compare with the parent region; if the current and parent | ||
615 | regions are too similar, keep only the parent */ | ||
616 | area = regions_pt [i].area ; | ||
617 | parea = regions_pt [parent].area ; | ||
618 | change = (float)(parea - area)/area ; | ||
619 | |||
620 | if(change < 0.5) { | ||
621 | ++ndup ; | ||
622 | goto remove_this_region ; | ||
623 | } | ||
624 | |||
625 | } /* drop duplicates */ | ||
626 | } | ||
627 | continue ; | ||
628 | remove_this_region : | ||
629 | regions_pt[i].maxstable = false ; | ||
630 | --nmer ; | ||
631 | } /* next region to cleanup */ | ||
632 | |||
633 | if(verbose) { | ||
634 | mexPrintf(" Bad regions: %d\n", nbad ) ; | ||
635 | mexPrintf(" Small regions: %d\n", nsmall ) ; | ||
636 | mexPrintf(" Big regions: %d\n", nbig ) ; | ||
637 | mexPrintf(" Duplicated regions: %d\n", ndup ) ; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | verbose && mexPrintf("Cleaned-up regions: %d (%.1f%%)\n", | ||
642 | nmer, 100.0 * (double) nmer / ner) ; | ||
643 | |||
644 | /* ----------------------------------------------------------------- | ||
645 | * Fit ellipses | ||
646 | * -------------------------------------------------------------- */ | ||
647 | |||
648 | ell_pt = 0 ; | ||
649 | if (nout >= 1) { | ||
650 | int midx = 1 ; | ||
651 | int d, index, j ; | ||
652 | |||
653 | verbose && mexPrintf("Fitting ellipses...\n") ; | ||
654 | |||
655 | /* enumerate maxstable regions */ | ||
656 | for(i = 0 ; i < ner ; ++i) { | ||
657 | if(! regions_pt [i].maxstable) continue ; | ||
658 | regions_pt [i].maxstable = midx++ ; | ||
659 | } | ||
660 | |||
661 | /* allocate space */ | ||
662 | acc_pt = mxMalloc(sizeof(acc_t) * nel) ; | ||
663 | ell_pt = mxMalloc(sizeof(acc_t) * gdl * nmer) ; | ||
664 | |||
665 | /* clear accumulators */ | ||
666 | memset(ell_pt, 0, sizeof(int) * gdl * nmer) ; | ||
667 | |||
668 | /* for each gdl */ | ||
669 | for(d = 0 ; d < gdl ; ++d) { | ||
670 | /* initalize parameter */ | ||
671 | memset(subs_pt, 0, sizeof(int) * ndims) ; | ||
672 | |||
673 | if(d < ndims) { | ||
674 | verbose && mexPrintf(" mean %d\n",d) ; | ||
675 | for(index = 0 ; index < nel ; ++ index) { | ||
676 | acc_pt[index] = subs_pt[d] ; | ||
677 | adv(dims, ndims, subs_pt) ; | ||
678 | } | ||
679 | |||
680 | } else { | ||
681 | |||
682 | /* decode d-ndims into a (i,j) pair */ | ||
683 | i = d-ndims ; | ||
684 | j = 0 ; | ||
685 | while(i > j) { | ||
686 | i -= j + 1 ; | ||
687 | j ++ ; | ||
688 | } | ||
689 | |||
690 | verbose && mexPrintf(" corr (%d,%d)\n",i,j) ; | ||
691 | |||
692 | /* add x_i * x_j */ | ||
693 | for(index = 0 ; index < nel ; ++ index){ | ||
694 | acc_pt[index] = subs_pt[i]*subs_pt[j] ; | ||
695 | adv(dims, ndims, subs_pt) ; | ||
696 | } | ||
697 | } | ||
698 | |||
699 | /* integrate parameter */ | ||
700 | for(i = 0 ; i < njoins ; ++i) { | ||
701 | idx_t index = joins_pt[i] ; | ||
702 | idx_t parent = forest_pt [ index ].parent ; | ||
703 | acc_pt[parent] += acc_pt[index] ; | ||
704 | } | ||
705 | |||
706 | /* save back to ellpises */ | ||
707 | for(i = 0 ; i < ner ; ++i) { | ||
708 | idx_t region = regions_pt [i].maxstable ; | ||
709 | |||
710 | /* skip if not extremal region */ | ||
711 | if(region-- == 0) continue ; | ||
712 | ell_pt [d + gdl*region] = acc_pt [ regions_pt[i].index ] ; | ||
713 | } | ||
714 | |||
715 | /* next gdl */ | ||
716 | } | ||
717 | mxFree(acc_pt) ; | ||
718 | } | ||
719 | |||
720 | |||
721 | /* ----------------------------------------------------------------- | ||
722 | * Save back and exit | ||
723 | * -------------------------------------------------------------- */ | ||
724 | |||
725 | /* | ||
726 | * Save extremal regions | ||
727 | */ | ||
728 | { | ||
729 | int dims[2] ; | ||
730 | int unsigned * pt ; | ||
731 | dims[0] = nmer ; | ||
732 | out[OUT_REGIONS] = mxCreateNumericArray(1,dims,mxUINT32_CLASS,mxREAL); | ||
733 | pt = mxGetData(out[OUT_REGIONS]) ; | ||
734 | for (i = 0 ; i < ner ; ++i) { | ||
735 | if( regions_pt[i].maxstable ) { | ||
736 | /* adjust for MATLAB index compatibility */ | ||
737 | *pt++ = regions_pt[i].index + 1 ; | ||
738 | } | ||
739 | } | ||
740 | } | ||
741 | |||
742 | /* | ||
743 | * Save fitted ellipses | ||
744 | */ | ||
745 | if(nout >= 2) { | ||
746 | int dims[2], d, j, index ; | ||
747 | double * pt ; | ||
748 | dims[0] = gdl ; | ||
749 | dims[1] = nmer ; | ||
750 | |||
751 | out[OUT_ELL] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL) ; | ||
752 | pt = mxGetData(out[OUT_ELL]) ; | ||
753 | |||
754 | for(index = 0 ; index < nel ; ++index) { | ||
755 | |||
756 | idx_t region = regions_pt [index] .maxstable ; | ||
757 | int N = regions_pt [index] .area ; | ||
758 | |||
759 | if(region-- == 0) continue ; | ||
760 | |||
761 | for(d = 0 ; d < gdl ; ++d) { | ||
762 | |||
763 | pt[d] = (double) ell_pt[gdl*region + d] / N ; | ||
764 | |||
765 | if(d < ndims) { | ||
766 | /* adjust for MATLAB coordinate frame convention */ | ||
767 | pt[d] += 1 ; | ||
768 | } else { | ||
769 | /* remove squared mean from moment to get variance */ | ||
770 | i = d - ndims ; | ||
771 | j = 0 ; | ||
772 | while(i > j) { | ||
773 | i -= j + 1 ; | ||
774 | j ++ ; | ||
775 | } | ||
776 | pt[d] -= (pt[i]-1)*(pt[j]-1) ; | ||
777 | } | ||
778 | } | ||
779 | pt += gdl ; | ||
780 | } | ||
781 | mxFree(ell_pt) ; | ||
782 | } | ||
783 | |||
784 | if(nout >= 3) { | ||
785 | int unsigned * pt ; | ||
786 | out[OUT_PARENTS] = mxCreateNumericArray(ndims,dims,mxUINT32_CLASS,mxREAL) ; | ||
787 | pt = mxGetData(out[OUT_PARENTS]) ; | ||
788 | for(i = 0 ; i < nel ; ++i) { | ||
789 | *pt++ = forest_pt[i].parent ; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | if(nout >= 4) { | ||
794 | int dims[2] ; | ||
795 | int unsigned * pt ; | ||
796 | dims[0] = 3 ; | ||
797 | dims[1]= ner ; | ||
798 | out[OUT_AREA] = mxCreateNumericArray(2,dims,mxUINT32_CLASS,mxREAL); | ||
799 | pt = mxGetData(out[OUT_AREA]) ; | ||
800 | for( i = 0 ; i < ner ; ++i ) { | ||
801 | *pt++ = regions_pt [i]. area_bot ; | ||
802 | *pt++ = regions_pt [i]. area ; | ||
803 | *pt++ = regions_pt [i]. area_top ; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | /* free stuff */ | ||
808 | mxFree( forest_pt ) ; | ||
809 | mxFree( pairs_pt ) ; | ||
810 | mxFree( regions_pt ) ; | ||
811 | mxFree( visited_pt ) ; | ||
812 | mxFree( strides_pt ) ; | ||
813 | mxFree( nsubs_pt ) ; | ||
814 | mxFree( subs_pt ) ; | ||
815 | } | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser.mexa64 b/SD-VBS/benchmarks/mser/src/matlab/mser.mexa64 new file mode 100755 index 0000000..e3ca56b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser.mexa64 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser.mexglx b/SD-VBS/benchmarks/mser/src/matlab/mser.mexglx new file mode 100755 index 0000000..b69e1d2 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser.mexglx | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser_compile.m b/SD-VBS/benchmarks/mser/src/matlab/mser_compile.m new file mode 100755 index 0000000..5e3562b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser_compile.m | |||
@@ -0,0 +1,7 @@ | |||
1 | function mser_compile(type) | ||
2 | % MSER_COMPILE Compile MEX files | ||
3 | |||
4 | opts = { '-O', '-I.' } ; | ||
5 | |||
6 | mex('mser.mex.c','-output', 'mser',opts{:}) ; | ||
7 | mex('erfill.mex.c','-output', 'erfill',opts{:}) ; | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser_demo2.m b/SD-VBS/benchmarks/mser/src/matlab/mser_demo2.m new file mode 100755 index 0000000..37a4ed1 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser_demo2.m | |||
@@ -0,0 +1,62 @@ | |||
1 | % MSER_DEMO2 Demonstrate MSER code | ||
2 | |||
3 | % AUTORIGHTS | ||
4 | % Copyright (C) 2006 Regents of the University of California | ||
5 | % All rights reserved | ||
6 | % | ||
7 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
8 | % | ||
9 | % Redistribution and use in source and binary forms, with or without | ||
10 | % modification, are permitted provided that the following conditions are met | ||
11 | % | ||
12 | % * Redistributions of source code must retain the above copyright | ||
13 | % notice, this list of conditions and the following disclaimer. | ||
14 | % * Redistributions in binary form must reproduce the above copyright | ||
15 | % notice, this list of conditions and the following disclaimer in the | ||
16 | % documentation and/or other materials provided with the distribution. | ||
17 | % * Neither the name of the University of California, Berkeley nor the | ||
18 | % names of its contributors may be used to endorse or promote products | ||
19 | % derived from this software without specific prior written permission. | ||
20 | % | ||
21 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
22 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
23 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
25 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
26 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
27 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
28 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | I = load('clown') ; I = uint8(I.X) ; | ||
33 | figure(1) ; imagesc(I) ; colormap gray; hold on ; | ||
34 | |||
35 | [M,N] = size(I) ; | ||
36 | i = double(i) ; | ||
37 | j = double(j) ; | ||
38 | |||
39 | [r,ell] = mser(I,5) ; | ||
40 | |||
41 | r=double(r) ; | ||
42 | |||
43 | [i,j]=ind2sub(size(I),r) ; | ||
44 | plot(j,i,'r*') ; | ||
45 | |||
46 | ell = ell([2 1 5 4 3],:) ; | ||
47 | plotframe(ell); | ||
48 | |||
49 | figure(2) ; | ||
50 | |||
51 | clear MOV ; | ||
52 | K = size(ell,2) ; | ||
53 | for k=1:K | ||
54 | clf ; | ||
55 | sel = erfill(I,r(k)) ; | ||
56 | mask = zeros(M,N) ; mask(sel) =1 ; | ||
57 | imagesc(cat(3,I,255*uint8(mask),I)) ; colormap gray ; hold on ; | ||
58 | set(gca,'position',[0 0 1 1]) ; axis off ; axis equal ; | ||
59 | plot(j(k),i(k),'r*') ; | ||
60 | plotframe(ell(:,k),'color','r') ; | ||
61 | MOV(k) = getframe(gca) ; | ||
62 | end | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/mser_demo3.m b/SD-VBS/benchmarks/mser/src/matlab/mser_demo3.m new file mode 100755 index 0000000..4669437 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/mser_demo3.m | |||
@@ -0,0 +1,117 @@ | |||
1 | % MSER_DEMO3 Demonstrates MSER on a volumetric image | ||
2 | |||
3 | % AUTORIGHTS | ||
4 | % Copyright (C) 2006 Regents of the University of California | ||
5 | % All rights reserved | ||
6 | % | ||
7 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
8 | % | ||
9 | % Redistribution and use in source and binary forms, with or without | ||
10 | % modification, are permitted provided that the following conditions are met | ||
11 | % | ||
12 | % * Redistributions of source code must retain the above copyright | ||
13 | % notice, this list of conditions and the following disclaimer. | ||
14 | % * Redistributions in binary form must reproduce the above copyright | ||
15 | % notice, this list of conditions and the following disclaimer in the | ||
16 | % documentation and/or other materials provided with the distribution. | ||
17 | % * Neither the name of the University of California, Berkeley nor the | ||
18 | % names of its contributors may be used to endorse or promote products | ||
19 | % derived from this software without specific prior written permission. | ||
20 | % | ||
21 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
22 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
23 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
25 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
26 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
27 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
28 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | % -------------------------------------------------------------------- | ||
33 | % Create data | ||
34 | % -------------------------------------------------------------------- | ||
35 | |||
36 | % volumetric coordinate (x,y,z) | ||
37 | x = linspace(-1,1,50) ; | ||
38 | [x,y,z] = meshgrid(x,x,x) ; | ||
39 | |||
40 | % create funny volumetric image | ||
41 | I = sin(4*x).*cos(4*y).*sin(z) ; | ||
42 | I = I-min(I(:)) ; | ||
43 | I = I/max(I(:)) ; | ||
44 | |||
45 | % quantize the image in 10 levels | ||
46 | lev = 10 ; | ||
47 | I = lev*I ; | ||
48 | Ir = round(I) ; | ||
49 | |||
50 | % -------------------------------------------------------------------- | ||
51 | % Compute regions | ||
52 | % -------------------------------------------------------------------- | ||
53 | [idx,ell,p] = mser(uint8(Ir),1); | ||
54 | |||
55 | % -------------------------------------------------------------------- | ||
56 | % Plots | ||
57 | % -------------------------------------------------------------------- | ||
58 | |||
59 | % The image is quantized; store in LEV its range. | ||
60 | lev = unique(Ir(idx)) ; | ||
61 | |||
62 | figure(100); clf; | ||
63 | K=min(length(lev),4) ; | ||
64 | |||
65 | r=.99 ; | ||
66 | |||
67 | % one level per time | ||
68 | for k=1:K | ||
69 | tightsubplot(K,k) ; | ||
70 | [i,j,m] = ind2sub(size(I), idx(Ir(idx)==lev(k)) ) ; | ||
71 | |||
72 | % compute level set of level LEV(k) | ||
73 | Is = double(Ir<=lev(k)) ; | ||
74 | |||
75 | p1 = patch(isosurface(Is,r), ... | ||
76 | 'FaceColor','blue','EdgeColor','none') ; | ||
77 | p2 = patch(isocaps(Is,r),... | ||
78 | 'FaceColor','interp','EdgeColor','none') ; | ||
79 | isonormals(I,p1) | ||
80 | hold on ; | ||
81 | |||
82 | view(3); axis vis3d tight | ||
83 | camlight; lighting phong ; | ||
84 | |||
85 | % find regions that have this level | ||
86 | sel = find( Ir(idx) == lev(k) ) ; | ||
87 | |||
88 | % plot fitted ellipsoid | ||
89 | for r=sel' | ||
90 | E = ell(:,r) ; | ||
91 | c = E(1:3) ; | ||
92 | A = zeros(3) ; | ||
93 | A(1,1) = E(4) ; | ||
94 | A(1,2) = E(5) ; | ||
95 | A(2,2) = E(6) ; | ||
96 | A(1,3) = E(7) ; | ||
97 | A(2,3) = E(8) ; | ||
98 | A(3,3) = E(9) ; | ||
99 | |||
100 | A = A + A' - diag(diag(A)) ; | ||
101 | |||
102 | % correct var. order | ||
103 | perm = [0 1 0 ; 1 0 0 ; 0 0 1] ; | ||
104 | A = perm*A*perm ; | ||
105 | |||
106 | [V,D] = eig(A) ; | ||
107 | A = 2.5*V*sqrt(D) ; | ||
108 | |||
109 | [x,y,z]=sphere ; | ||
110 | [P,Q]=size(x) ; | ||
111 | X=A*[x(:)';y(:)';z(:)'] ; | ||
112 | x=reshape(X(1,:),P,Q)+c(2) ; | ||
113 | y=reshape(X(2,:),P,Q)+c(1) ; | ||
114 | z=reshape(X(3,:),P,Q)+c(3) ; | ||
115 | surf(x,y,z,'FaceAlpha',.5) ; | ||
116 | end | ||
117 | end | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/Makefile b/SD-VBS/benchmarks/mser/src/matlab/old/Makefile new file mode 100755 index 0000000..29c0982 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/Makefile | |||
@@ -0,0 +1,123 @@ | |||
1 | # file: Makefile | ||
2 | # author: Andrea Vedaldi | ||
3 | # description: Build mex files | ||
4 | |||
5 | # -------------------------------------------------------------------- | ||
6 | # | ||
7 | # -------------------------------------------------------------------- | ||
8 | |||
9 | # Determine on the flight the system we are running on | ||
10 | Darwin_ARCH := mac | ||
11 | Linux_ARCH := glx | ||
12 | ARCH := $($(shell uname)_ARCH) | ||
13 | |||
14 | mac_CFLAGS := -I. -pedantic -Wall -Wno-long-long | ||
15 | mac_MEX_CFLAGS := -g -O CFLAGS='$$CFLAGS $(mac_CFLAGS)' | ||
16 | mac_MEX_SUFFIX := mexmac | ||
17 | |||
18 | glx_CFLAGS := -I. -pedantic -Wall -Wno-long-long | ||
19 | glx_MEX_CFLAGS := -g -O CFLAGS='$$CFLAGS $(glx_CFLAGS)' | ||
20 | glx_MEX_SUFFIX := mexglx | ||
21 | |||
22 | MEX_SUFFIX := $($(ARCH)_MEX_SUFFIX) | ||
23 | MEX_CFLAGS := $($(ARCH)_MEX_CFLAGS) | ||
24 | |||
25 | VER := 0.4 | ||
26 | DIST := mser-$(VER) | ||
27 | BINDIST := $(DIST)-$(ARCH) | ||
28 | |||
29 | # -------------------------------------------------------------------- | ||
30 | # | ||
31 | # -------------------------------------------------------------------- | ||
32 | |||
33 | vpath %.mex.c . | ||
34 | |||
35 | src := $(wildcard *.mex.c) | ||
36 | msrc := $(wildcard *.m) | ||
37 | stem := $(notdir $(basename $(basename $(src)))) | ||
38 | tgt := $(addprefix ./, $(addsuffix .$(MEX_SUFFIX),$(stem))) | ||
39 | |||
40 | %.$(MEX_SUFFIX) : %.mex.c | ||
41 | mex -I. $(MEX_CFLAGS) $< -output $* | ||
42 | |||
43 | .PHONY: all | ||
44 | all: $(tgt) | ||
45 | |||
46 | .PHONY: info | ||
47 | info : | ||
48 | @echo src = $(src) | ||
49 | @echo stem = $(stem) | ||
50 | @echo tgt = $(tgt) | ||
51 | |||
52 | # PDF documentation | ||
53 | .PHONY: doc | ||
54 | doc: mser.html doc/mser.pdf | ||
55 | |||
56 | mser.html : $(msrc) | ||
57 | mdoc --output=mser.html . \ | ||
58 | --exclude='.*(_demo|_compile).*.m' | ||
59 | |||
60 | .PHONY: clean | ||
61 | clean: | ||
62 | rm -f $(tgt) | ||
63 | find . -name '.DS_Store' -exec rm -f \{\} \; | ||
64 | find . -name '.gdb_history' -exec rm -f \{\} \; | ||
65 | find . -name '*~' -exec rm -f \{\} \; | ||
66 | find . -name '*.bak' -exec rm -f \{\} \; | ||
67 | make -C doc/figures clean | ||
68 | |||
69 | .PHONY: distclean | ||
70 | distclean: clean | ||
71 | rm -f *.mexmac *.mexglx | ||
72 | rm -f mser.html | ||
73 | rm -f mser-*.tar.gz | ||
74 | rm -f doc/*.log | ||
75 | rm -f doc/*.aux | ||
76 | rm -f doc/*.toc | ||
77 | rm -f doc/*.bbl | ||
78 | rm -f doc/*.blg | ||
79 | rm -f doc/*.out | ||
80 | rm -f $(DIST).tar.gz | ||
81 | rm -f $(BINDIST).tar.gz | ||
82 | rm -rf $(BINDIST) | ||
83 | |||
84 | .PHONY: dist | ||
85 | dist: distclean | ||
86 | echo Version $(VER) >TIMESTAMP | ||
87 | echo Archive created on `date` >>TIMESTAMP | ||
88 | d=$(notdir $(CURDIR)) ; \ | ||
89 | tar chzvf $(DIST).tar.gz \ | ||
90 | --exclude mser_demo4.m \ | ||
91 | --exclude data/seq.avi \ | ||
92 | --exclude results \ | ||
93 | ../$${d} | ||
94 | |||
95 | .PHONY: bindist | ||
96 | bindist: all | ||
97 | test -e $(BINDIST) || mkdir $(BINDIST) | ||
98 | cp *.$(MEX_SUFFIX) $(BINDIST) | ||
99 | cd $(BINDIST) ; strip -S *.$(MEX_SUFFIX) | ||
100 | tar chzvf $(BINDIST).tar.gz $(BINDIST) | ||
101 | |||
102 | .PHONY: autorights | ||
103 | autorights: | ||
104 | autorights . \ | ||
105 | --verbose \ | ||
106 | --recursive \ | ||
107 | --template cal \ | ||
108 | --years 2006 \ | ||
109 | --authors "Andrea Vedaldi (UCLA VisionLab)" \ | ||
110 | --program "Video Extremal Regions" | ||
111 | |||
112 | doc/mser.pdf : doc/*.tex doc/*.bib doc/figures/*.fig | ||
113 | make -C doc/figures all | ||
114 | cd doc ; \ | ||
115 | for k in 1 2 3 ; \ | ||
116 | do \ | ||
117 | pdflatex -file-line-error-style -interaction batchmode \ | ||
118 | mser.tex ; \ | ||
119 | if test "$$k" = '1' ; \ | ||
120 | then \ | ||
121 | bibtex mser.aux ; \ | ||
122 | fi ; \ | ||
123 | done | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/TIMESTAMP b/SD-VBS/benchmarks/mser/src/matlab/old/TIMESTAMP new file mode 100755 index 0000000..1de1720 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/TIMESTAMP | |||
@@ -0,0 +1,2 @@ | |||
1 | Version 0.4 | ||
2 | Archive created on Wed Feb 7 11:08:47 PST 2007 | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/erfill.m b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.m new file mode 100755 index 0000000..6e11fc6 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.m | |||
@@ -0,0 +1,13 @@ | |||
1 | % ERFILL Fill extremal region | ||
2 | % MEMBERS=ERFILL(I,ER) returns the list MEMBERS of the pixels which | ||
3 | % belongs to the extremal region represented by the pixel ER. | ||
4 | % | ||
5 | % The selected region is the one that contains pixel ER and of | ||
6 | % inensity I(ER). | ||
7 | % | ||
8 | % I must be of class UINT8 and ER must be a (scalar) index of the | ||
9 | % region representative point. | ||
10 | % | ||
11 | % See also MSER(). | ||
12 | |||
13 | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mex.c b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mex.c new file mode 100755 index 0000000..893d346 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mex.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* file: erfill.mex.c | ||
2 | ** description: Extremal Regions filling | ||
3 | ** author: Andrea Vedaldi | ||
4 | **/ | ||
5 | |||
6 | /* AUTORIGHTS | ||
7 | Copyright (C) 2006 Regents of the University of California | ||
8 | All rights reserved | ||
9 | |||
10 | Written by Andrea Vedaldi (UCLA VisionLab). | ||
11 | |||
12 | Redistribution and use in source and binary forms, with or without | ||
13 | modification, are permitted provided that the following conditions are met | ||
14 | |||
15 | * Redistributions of source code must retain the above copyright | ||
16 | notice, this list of conditions and the following disclaimer. | ||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | * Neither the name of the University of California, Berkeley nor the | ||
21 | names of its contributors may be used to endorse or promote products | ||
22 | derived from this software without specific prior written permission. | ||
23 | |||
24 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
25 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
27 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
28 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | */ | ||
35 | |||
36 | /** @file | ||
37 | ** @brief Maximally Stable Extremal Regions - MEX implementation | ||
38 | **/ | ||
39 | |||
40 | #include<mexutils.c> | ||
41 | #include<stdio.h> | ||
42 | #include<stdlib.h> | ||
43 | #include<math.h> | ||
44 | #include<string.h> | ||
45 | #include<assert.h> | ||
46 | |||
47 | #define MIN(x,y) (((x)<(y))?(x):(y)) | ||
48 | #define MAX(x,y) (((x)>(y))?(x):(y)) | ||
49 | |||
50 | typedef char unsigned val_t ; | ||
51 | typedef int unsigned idx_t ; | ||
52 | typedef long long int unsigned acc_t ; | ||
53 | |||
54 | /* advance N-dimensional subscript */ | ||
55 | void | ||
56 | adv(int const* dims, int ndims, int* subs_pt) | ||
57 | { | ||
58 | int d = 0 ; | ||
59 | while(d < ndims) { | ||
60 | if( ++subs_pt[d] < dims[d] ) return ; | ||
61 | subs_pt[d++] = 0 ; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /* driver */ | ||
66 | void | ||
67 | mexFunction(int nout, mxArray *out[], | ||
68 | int nin, const mxArray *in[]) | ||
69 | { | ||
70 | |||
71 | enum {IN_I=0, IN_ER} ; | ||
72 | enum {OUT_MEMBERS} ; | ||
73 | |||
74 | idx_t i ; | ||
75 | int k, nel, ndims ; | ||
76 | int const * dims ; | ||
77 | val_t const * I_pt ; | ||
78 | int last = 0 ; | ||
79 | int last_expanded = 0 ; | ||
80 | val_t value = 0 ; | ||
81 | |||
82 | double const * er_pt ; | ||
83 | |||
84 | int* subs_pt ; /* N-dimensional subscript */ | ||
85 | int* nsubs_pt ; /* diff-subscript to point to neigh. */ | ||
86 | idx_t* strides_pt ; /* strides to move in image array */ | ||
87 | val_t* visited_pt ; /* flag */ | ||
88 | idx_t* members_pt ; /* region members */ | ||
89 | |||
90 | /** ----------------------------------------------------------------- | ||
91 | ** Check the arguments | ||
92 | ** -------------------------------------------------------------- */ | ||
93 | if (nin != 2) { | ||
94 | mexErrMsgTxt("Two arguments required.") ; | ||
95 | } else if (nout > 4) { | ||
96 | mexErrMsgTxt("Too many output arguments."); | ||
97 | } | ||
98 | |||
99 | if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) { | ||
100 | mexErrMsgTxt("I must be of class UINT8.") ; | ||
101 | } | ||
102 | |||
103 | if(!uIsRealScalar(in[IN_ER])) { | ||
104 | mexErrMsgTxt("ER must be a DOUBLE scalar.") ; | ||
105 | } | ||
106 | |||
107 | /* get dimensions */ | ||
108 | nel = mxGetNumberOfElements(in[IN_I]) ; | ||
109 | ndims = mxGetNumberOfDimensions(in[IN_I]) ; | ||
110 | dims = mxGetDimensions(in[IN_I]) ; | ||
111 | I_pt = mxGetData(in[IN_I]) ; | ||
112 | |||
113 | /* allocate stuff */ | ||
114 | subs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
115 | nsubs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
116 | strides_pt = mxMalloc( sizeof(idx_t) * ndims ) ; | ||
117 | visited_pt = mxMalloc( sizeof(val_t) * nel ) ; | ||
118 | members_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
119 | |||
120 | er_pt = mxGetPr(in[IN_ER]) ; | ||
121 | |||
122 | /* compute strides to move into the N-dimensional image array */ | ||
123 | strides_pt [0] = 1 ; | ||
124 | for(k = 1 ; k < ndims ; ++k) { | ||
125 | strides_pt [k] = strides_pt [k-1] * dims [k-1] ; | ||
126 | } | ||
127 | |||
128 | /* load first pixel */ | ||
129 | memset(visited_pt, 0, sizeof(val_t) * nel) ; | ||
130 | { | ||
131 | idx_t idx = (idx_t) *er_pt ; | ||
132 | if( idx < 1 || idx > nel ) { | ||
133 | char buff[80] ; | ||
134 | snprintf(buff,80,"ER=%d out of range [1,%d]",idx,nel) ; | ||
135 | mexErrMsgTxt(buff) ; | ||
136 | } | ||
137 | members_pt [last++] = idx - 1 ; | ||
138 | } | ||
139 | value = I_pt[ members_pt[0] ] ; | ||
140 | |||
141 | /* ----------------------------------------------------------------- | ||
142 | * Fill region | ||
143 | * -------------------------------------------------------------- */ | ||
144 | while(last_expanded < last) { | ||
145 | |||
146 | /* pop next node xi */ | ||
147 | idx_t index = members_pt[last_expanded++] ; | ||
148 | |||
149 | /* convert index into a subscript sub; also initialize nsubs | ||
150 | to (-1,-1,...,-1) */ | ||
151 | { | ||
152 | idx_t temp = index ; | ||
153 | for(k = ndims-1 ; k >=0 ; --k) { | ||
154 | nsubs_pt [k] = -1 ; | ||
155 | subs_pt [k] = temp / strides_pt [k] ; | ||
156 | temp = temp % strides_pt [k] ; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /* process neighbors of xi */ | ||
161 | while( true ) { | ||
162 | int good = true ; | ||
163 | idx_t nindex = 0 ; | ||
164 | |||
165 | /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX | ||
166 | and check that the pixel is within image boundaries. */ | ||
167 | for(k = 0 ; k < ndims && good ; ++k) { | ||
168 | int temp = nsubs_pt [k] + subs_pt [k] ; | ||
169 | good &= 0 <= temp && temp < dims[k] ; | ||
170 | nindex += temp * strides_pt [k] ; | ||
171 | } | ||
172 | |||
173 | /* process neighbor | ||
174 | 1 - the pixel is within image boundaries; | ||
175 | 2 - the pixel is indeed different from the current node | ||
176 | (this happens when nsub=(0,0,...,0)); | ||
177 | 3 - the pixel has value not greather than val | ||
178 | is a pixel older than xi | ||
179 | 4 - the pixel has not been visited yet | ||
180 | */ | ||
181 | if(good | ||
182 | && nindex != index | ||
183 | && I_pt [nindex] <= value | ||
184 | && ! visited_pt [nindex] ) { | ||
185 | |||
186 | /* mark as visited */ | ||
187 | visited_pt [nindex] = 1 ; | ||
188 | |||
189 | /* add to list */ | ||
190 | members_pt [last++] = nindex ; | ||
191 | } | ||
192 | |||
193 | /* move to next neighbor */ | ||
194 | k = 0 ; | ||
195 | while(++ nsubs_pt [k] > 1) { | ||
196 | nsubs_pt [k++] = -1 ; | ||
197 | if(k == ndims) goto done_all_neighbors ; | ||
198 | } | ||
199 | } /* next neighbor */ | ||
200 | done_all_neighbors : ; | ||
201 | } /* goto pop next member */ | ||
202 | |||
203 | /* | ||
204 | * Save results | ||
205 | */ | ||
206 | { | ||
207 | int dims[2] ; | ||
208 | int unsigned * pt ; | ||
209 | dims[0] = last ; | ||
210 | out[OUT_MEMBERS] = mxCreateNumericArray(1,dims,mxUINT32_CLASS,mxREAL); | ||
211 | pt = mxGetData(out[OUT_MEMBERS]) ; | ||
212 | for (i = 0 ; i < last ; ++i) { | ||
213 | *pt++ = members_pt[i] + 1 ; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | /* free stuff */ | ||
218 | mxFree( members_pt ) ; | ||
219 | mxFree( visited_pt ) ; | ||
220 | mxFree( strides_pt ) ; | ||
221 | mxFree( nsubs_pt ) ; | ||
222 | mxFree( subs_pt ) ; | ||
223 | } | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mexa64 b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mexa64 new file mode 100755 index 0000000..679e972 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/erfill.mexa64 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mexutils.c b/SD-VBS/benchmarks/mser/src/matlab/old/mexutils.c new file mode 100755 index 0000000..0fc664b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mexutils.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* file: mexutils.c | ||
2 | ** author: Andrea Vedaldi | ||
3 | ** description: Utility functions to write MEX files. | ||
4 | **/ | ||
5 | |||
6 | #include"mex.h" | ||
7 | |||
8 | #undef M_PI | ||
9 | #define M_PI 3.14159265358979 | ||
10 | |||
11 | /** @brief Is scalar? | ||
12 | ** | ||
13 | ** @return @c true if the array @a A is a scalar. | ||
14 | **/ | ||
15 | int | ||
16 | uIsScalar(const mxArray* A) | ||
17 | { | ||
18 | return | ||
19 | !mxIsComplex(A) && | ||
20 | mxGetNumberOfDimensions(A) == 2 && | ||
21 | mxGetM(A) == 1 && | ||
22 | mxGetN(A) == 1 ; | ||
23 | } | ||
24 | |||
25 | /** @brief Is real scalar? | ||
26 | ** | ||
27 | ** @return @c true if the array @a A is a real scalar. | ||
28 | **/ | ||
29 | int | ||
30 | uIsRealScalar(const mxArray* A) | ||
31 | { | ||
32 | return | ||
33 | mxIsDouble(A) && | ||
34 | !mxIsComplex(A) && | ||
35 | mxGetNumberOfDimensions(A) == 2 && | ||
36 | mxGetM(A) == 1 && | ||
37 | mxGetN(A) == 1 ; | ||
38 | } | ||
39 | |||
40 | /** @brief Is real matrix? | ||
41 | ** | ||
42 | ** The function checks wether the argument @a A is a real matrix. In | ||
43 | ** addition, if @a M >= 0, it checks wether the number of rows is | ||
44 | ** equal to @a M and, if @a N >= 0, if the number of columns is equal | ||
45 | ** to @a N. | ||
46 | ** | ||
47 | ** @param M number of rows. | ||
48 | ** @param N number of columns. | ||
49 | ** @return @c true if the array is a real matrix with the specified format. | ||
50 | **/ | ||
51 | int | ||
52 | uIsRealMatrix(const mxArray* A, int M, int N) | ||
53 | { | ||
54 | return | ||
55 | mxIsDouble(A) && | ||
56 | !mxIsComplex(A) && | ||
57 | mxGetNumberOfDimensions(A) == 2 && | ||
58 | ((M>=0)?(mxGetM(A) == M):1) && | ||
59 | ((N>=0)?(mxGetN(A) == N):1) ; | ||
60 | } | ||
61 | |||
62 | /** @brief Is real vector? | ||
63 | ** | ||
64 | ** The function checks wether the argument @a V is a real vector. By | ||
65 | ** definiton, a matrix is a vector if one of its dimension is one. | ||
66 | ** In addition, if @a D >= 0, it checks wether the dimension of the | ||
67 | ** vecotr is equal to @a D. | ||
68 | ** | ||
69 | ** @param D lenght of the vector. | ||
70 | ** @return @c true if the array is a real vector of the specified dimension. | ||
71 | **/ | ||
72 | int | ||
73 | uIsRealVector(const mxArray* V, int D) | ||
74 | { | ||
75 | int M = mxGetM(V) ; | ||
76 | int N = mxGetN(V) ; | ||
77 | int is_vector = (N == 1) || (M == 1) ; | ||
78 | |||
79 | return | ||
80 | mxIsDouble(V) && | ||
81 | !mxIsComplex(V) && | ||
82 | mxGetNumberOfDimensions(V) == 2 && | ||
83 | is_vector && | ||
84 | ( D < 0 || N == D || M == D) ; | ||
85 | } | ||
86 | |||
87 | |||
88 | /** @brief Is a string? | ||
89 | ** | ||
90 | ** The function checks wether the array @a S is a string. If | ||
91 | ** @a L is non-negative, it also check wether the strign has | ||
92 | ** length @a L. | ||
93 | ** | ||
94 | ** @return @a c true if S is a string of the specified length. | ||
95 | **/ | ||
96 | int | ||
97 | uIsString(const mxArray* S, int L) | ||
98 | { | ||
99 | int M = mxGetM(S) ; | ||
100 | int N = mxGetN(S) ; | ||
101 | |||
102 | return | ||
103 | mxIsChar(S) && | ||
104 | M == 1 && | ||
105 | (L < 0 || N == L) ; | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | ** | ||
110 | **/ | ||
111 | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mser.mex.c b/SD-VBS/benchmarks/mser/src/matlab/old/mser.mex.c new file mode 100755 index 0000000..48c788e --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mser.mex.c | |||
@@ -0,0 +1,809 @@ | |||
1 | /* file: mser.mex.c | ||
2 | ** description: Maximally Stable Extremal Regions | ||
3 | ** author: Andrea Vedaldi | ||
4 | **/ | ||
5 | |||
6 | /* AUTORIGHTS | ||
7 | Copyright (C) 2006 Regents of the University of California | ||
8 | All rights reserved | ||
9 | |||
10 | Written by Andrea Vedaldi (UCLA VisionLab). | ||
11 | |||
12 | Redistribution and use in source and binary forms, with or without | ||
13 | modification, are permitted provided that the following conditions are met | ||
14 | |||
15 | * Redistributions of source code must retain the above copyright | ||
16 | notice, this list of conditions and the following disclaimer. | ||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | * Neither the name of the University of California, Berkeley nor the | ||
21 | names of its contributors may be used to endorse or promote products | ||
22 | derived from this software without specific prior written permission. | ||
23 | |||
24 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
25 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
27 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
28 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | */ | ||
35 | |||
36 | /** @file | ||
37 | ** @brief Maximally Stable Extremal Regions - MEX implementation | ||
38 | **/ | ||
39 | |||
40 | #include<mexutils.c> | ||
41 | #include<stdio.h> | ||
42 | #include<stdlib.h> | ||
43 | #include<math.h> | ||
44 | #include<string.h> | ||
45 | #include<assert.h> | ||
46 | |||
47 | #define MIN(x,y) (((x)<(y))?(x):(y)) | ||
48 | #define MAX(x,y) (((x)>(y))?(x):(y)) | ||
49 | |||
50 | #define USE_BUCKET_SORT | ||
51 | /*#define USE_RANK_UNION | ||
52 | */ | ||
53 | |||
54 | typedef char unsigned val_t ; | ||
55 | typedef int unsigned idx_t ; | ||
56 | typedef long long int unsigned acc_t ; | ||
57 | |||
58 | /* pairs are used to sort the pixels */ | ||
59 | typedef struct | ||
60 | { | ||
61 | val_t value ; | ||
62 | idx_t index ; | ||
63 | } pair_t ; | ||
64 | |||
65 | /* forest node */ | ||
66 | typedef struct | ||
67 | { | ||
68 | idx_t parent ; /**< parent pixel */ | ||
69 | idx_t shortcut ; /**< shortcut to the root */ | ||
70 | idx_t region ; /**< index of the region */ | ||
71 | int area ; /**< area of the region */ | ||
72 | #ifdef USE_RANK_UNION | ||
73 | int height ; /**< node height */ | ||
74 | #endif | ||
75 | } node_t ; | ||
76 | |||
77 | /* extremal regions */ | ||
78 | typedef struct | ||
79 | { | ||
80 | idx_t parent ; /**< parent region */ | ||
81 | idx_t index ; /**< index of root pixel */ | ||
82 | val_t value ; /**< value of root pixel */ | ||
83 | int area ; /**< area of the region */ | ||
84 | int area_top ; /**< area of the region DELTA levels above */ | ||
85 | int area_bot ; /**< area of the region DELTA levels below */ | ||
86 | float variation ; /**< variation */ | ||
87 | int maxstable ; /**< max stable number (=0 if not maxstable) */ | ||
88 | } region_t ; | ||
89 | |||
90 | /* predicate used to sort pixels by increasing intensity */ | ||
91 | int | ||
92 | cmp_pair(void const* a, void const* b) | ||
93 | { | ||
94 | pair_t* pa = (pair_t*) a; | ||
95 | pair_t* pb = (pair_t*) b; | ||
96 | return pa->value - pb->value ; | ||
97 | } | ||
98 | |||
99 | /* advance N-dimensional subscript */ | ||
100 | void | ||
101 | adv(int const* dims, int ndims, int* subs_pt) | ||
102 | { | ||
103 | int d = 0 ; | ||
104 | while(d < ndims) { | ||
105 | if( ++subs_pt[d] < dims[d] ) return ; | ||
106 | subs_pt[d++] = 0 ; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* driver */ | ||
111 | void | ||
112 | mexFunction(int nout, mxArray *out[], | ||
113 | int nin, const mxArray *in[]) | ||
114 | { | ||
115 | enum {IN_I=0, IN_DELTA} ; | ||
116 | enum {OUT_REGIONS=0, OUT_ELL, OUT_PARENTS, OUT_AREA} ; | ||
117 | |||
118 | idx_t i ; | ||
119 | idx_t rindex = 0 ; | ||
120 | int k ; | ||
121 | |||
122 | /* configuration */ | ||
123 | int verbose = 1 ; /* be verbose */ | ||
124 | int small_cleanup= 1 ; /* remove very small regions */ | ||
125 | int big_cleanup = 1 ; /* remove very big regions */ | ||
126 | int bad_cleanup = 0 ; /* remove very bad regions */ | ||
127 | int dup_cleanup = 1 ; /* remove duplicates */ | ||
128 | val_t delta ; /* stability delta */ | ||
129 | |||
130 | /* node value denoting a void node */ | ||
131 | idx_t const node_is_void = 0xffffffff ; | ||
132 | |||
133 | int* subs_pt ; /* N-dimensional subscript */ | ||
134 | int* nsubs_pt ; /* diff-subscript to point to neigh. */ | ||
135 | idx_t* strides_pt ; /* strides to move in image array */ | ||
136 | idx_t* visited_pt ; /* flag */ | ||
137 | |||
138 | int nel ; /* number of image elements (pixels) */ | ||
139 | int ner = 0 ; /* number of extremal regions */ | ||
140 | int nmer = 0 ; /* number of maximally stable */ | ||
141 | int ndims ; /* number of dimensions */ | ||
142 | int const* dims ; /* dimensions */ | ||
143 | int njoins = 0 ; /* number of join ops */ | ||
144 | |||
145 | val_t const* I_pt ; /* source image */ | ||
146 | pair_t* pairs_pt ; /* scratch buffer to sort pixels */ | ||
147 | node_t* forest_pt ; /* the extremal regions forest */ | ||
148 | region_t* regions_pt ; /* list of extremal regions found */ | ||
149 | |||
150 | /* ellipses fitting */ | ||
151 | acc_t* acc_pt ; /* accumulator to integrate region moments */ | ||
152 | acc_t* ell_pt ; /* ellipses parameters */ | ||
153 | int gdl ; /* number of parameters of an ellipse */ | ||
154 | idx_t* joins_pt ; /* sequence of joins */ | ||
155 | |||
156 | /** ----------------------------------------------------------------- | ||
157 | ** Check the arguments | ||
158 | ** -------------------------------------------------------------- */ | ||
159 | if (nin != 2) { | ||
160 | mexErrMsgTxt("Two arguments required.") ; | ||
161 | } else if (nout > 4) { | ||
162 | mexErrMsgTxt("Too many output arguments."); | ||
163 | } | ||
164 | |||
165 | if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) { | ||
166 | mexErrMsgTxt("I must be of class UINT8") ; | ||
167 | } | ||
168 | |||
169 | if(!uIsScalar(in[IN_DELTA])) { | ||
170 | mexErrMsgTxt("DELTA must be scalar") ; | ||
171 | } | ||
172 | |||
173 | delta = 0 ; | ||
174 | switch(mxGetClassID(in[IN_DELTA])) { | ||
175 | case mxUINT8_CLASS : | ||
176 | delta = * (val_t*) mxGetData(in[IN_DELTA]) ; | ||
177 | break ; | ||
178 | |||
179 | case mxDOUBLE_CLASS : | ||
180 | { | ||
181 | double x = *mxGetPr(in[IN_DELTA]) ; | ||
182 | if(x < 0.0) { | ||
183 | mexErrMsgTxt("DELTA must be non-negative") ; | ||
184 | } | ||
185 | delta = (val_t) x ; | ||
186 | } | ||
187 | break ; | ||
188 | |||
189 | default : | ||
190 | mexErrMsgTxt("DELTA must be of class DOUBLE or UINT8") ; | ||
191 | } | ||
192 | |||
193 | /* get dimensions */ | ||
194 | nel = mxGetNumberOfElements(in[IN_I]) ; | ||
195 | ndims = mxGetNumberOfDimensions(in[IN_I]) ; | ||
196 | dims = mxGetDimensions(in[IN_I]) ; | ||
197 | I_pt = mxGetData(in[IN_I]) ; | ||
198 | |||
199 | /* allocate stuff */ | ||
200 | subs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
201 | nsubs_pt = mxMalloc( sizeof(int) * ndims ) ; | ||
202 | strides_pt = mxMalloc( sizeof(idx_t) * ndims ) ; | ||
203 | visited_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
204 | regions_pt = mxMalloc( sizeof(region_t) * nel ) ; | ||
205 | pairs_pt = mxMalloc( sizeof(pair_t) * nel ) ; | ||
206 | forest_pt = mxMalloc( sizeof(node_t) * nel ) ; | ||
207 | joins_pt = mxMalloc( sizeof(idx_t) * nel ) ; | ||
208 | |||
209 | /* compute strides to move into the N-dimensional image array */ | ||
210 | strides_pt [0] = 1 ; | ||
211 | for(k = 1 ; k < ndims ; ++k) { | ||
212 | strides_pt [k] = strides_pt [k-1] * dims [k-1] ; | ||
213 | } | ||
214 | |||
215 | /* sort pixels by increasing intensity*/ | ||
216 | verbose && mexPrintf("Sorting pixels ... ") ; | ||
217 | |||
218 | #ifndef USE_BUCKETSORT | ||
219 | for(i = 0 ; i < nel ; ++i) { | ||
220 | pairs_pt [i].value = I_pt [i] ; | ||
221 | pairs_pt [i].index = i ; | ||
222 | } | ||
223 | qsort(pairs_pt, nel, sizeof(pair_t), cmp_pair) ; | ||
224 | #else | ||
225 | { | ||
226 | int unsigned buckets [256] ; | ||
227 | memset(buckets, 0, sizeof(int unsigned)*256) ; | ||
228 | for(i = 0 ; i < nel ; ++i) { | ||
229 | val_t v = I_pt [i] ; | ||
230 | ++ buckets[v] ; | ||
231 | } | ||
232 | for(i = 1 ; i < 256 ; ++i) { | ||
233 | buckets[i] += buckets[i-1] ; | ||
234 | } | ||
235 | for(i = nel ; i >= 1 ; ) { | ||
236 | val_t v = I_pt [--i] ; | ||
237 | idx_t j = -- buckets [v] ; | ||
238 | pairs_pt [j].value = v ; | ||
239 | pairs_pt [j].index = i ; | ||
240 | } | ||
241 | } | ||
242 | #endif | ||
243 | verbose && mexPrintf("done\n") ; | ||
244 | |||
245 | /* initialize the forest with all void nodes */ | ||
246 | for(i = 0 ; i < nel ; ++i) { | ||
247 | forest_pt [i].parent = node_is_void ; | ||
248 | } | ||
249 | |||
250 | /* number of ellipse free parameters */ | ||
251 | gdl = ndims*(ndims+1)/2 + ndims ; | ||
252 | |||
253 | /* ----------------------------------------------------------------- | ||
254 | * Compute extremal regions tree | ||
255 | * -------------------------------------------------------------- */ | ||
256 | verbose && mexPrintf("Computing extremal regions ... ") ; | ||
257 | for(i = 0 ; i < nel ; ++i) { | ||
258 | |||
259 | /* pop next node xi */ | ||
260 | idx_t index = pairs_pt [i].index ; | ||
261 | val_t value = pairs_pt [i].value ; | ||
262 | |||
263 | /* this will be needed later */ | ||
264 | rindex = index ; | ||
265 | |||
266 | /* push it into the tree */ | ||
267 | forest_pt [index] .parent = index ; | ||
268 | forest_pt [index] .shortcut = index ; | ||
269 | forest_pt [index] .area = 1 ; | ||
270 | #ifdef USE_RANK_UNION | ||
271 | forest_pt [index] .height = 1 ; | ||
272 | #endif | ||
273 | |||
274 | /* convert index into a subscript sub; also initialize nsubs | ||
275 | to (-1,-1,...,-1) */ | ||
276 | { | ||
277 | idx_t temp = index ; | ||
278 | for(k = ndims-1 ; k >=0 ; --k) { | ||
279 | nsubs_pt [k] = -1 ; | ||
280 | subs_pt [k] = temp / strides_pt [k] ; | ||
281 | temp = temp % strides_pt [k] ; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | /* process neighbors of xi */ | ||
286 | while( true ) { | ||
287 | int good = true ; | ||
288 | idx_t nindex = 0 ; | ||
289 | |||
290 | /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX | ||
291 | and check that the pixel is within image boundaries. */ | ||
292 | for(k = 0 ; k < ndims && good ; ++k) { | ||
293 | int temp = nsubs_pt [k] + subs_pt [k] ; | ||
294 | good &= 0 <= temp && temp < dims[k] ; | ||
295 | nindex += temp * strides_pt [k] ; | ||
296 | } | ||
297 | |||
298 | /* keep going only if | ||
299 | 1 - the neighbor is within image boundaries; | ||
300 | 2 - the neighbor is indeed different from the current node | ||
301 | (this happens when nsub=(0,0,...,0)); | ||
302 | 3 - the nieghbor is already in the tree, meaning that | ||
303 | is a pixel older than xi. | ||
304 | */ | ||
305 | if(good && | ||
306 | nindex != index && | ||
307 | forest_pt[nindex].parent != node_is_void ) { | ||
308 | |||
309 | idx_t nrindex = 0, nvisited ; | ||
310 | val_t nrvalue = 0 ; | ||
311 | |||
312 | #ifdef USE_RANK_UNION | ||
313 | int height = forest_pt [ rindex] .height ; | ||
314 | int nheight = forest_pt [nrindex] .height ; | ||
315 | #endif | ||
316 | |||
317 | /* RINDEX = ROOT(INDEX) might change as we merge trees, so we | ||
318 | need to update it after each merge */ | ||
319 | |||
320 | /* find the root of the current node */ | ||
321 | /* also update the shortcuts */ | ||
322 | nvisited = 0 ; | ||
323 | while( forest_pt[rindex].shortcut != rindex ) { | ||
324 | visited_pt[ nvisited++ ] = rindex ; | ||
325 | rindex = forest_pt[rindex].shortcut ; | ||
326 | } | ||
327 | while( nvisited-- ) { | ||
328 | forest_pt [ visited_pt[nvisited] ] .shortcut = rindex ; | ||
329 | } | ||
330 | |||
331 | /* find the root of the neighbor */ | ||
332 | nrindex = nindex ; | ||
333 | nvisited = 0 ; | ||
334 | while( forest_pt[nrindex].shortcut != nrindex ) { | ||
335 | visited_pt[ nvisited++ ] = nrindex ; | ||
336 | nrindex = forest_pt[nrindex].shortcut ; | ||
337 | } | ||
338 | while( nvisited-- ) { | ||
339 | forest_pt [ visited_pt[nvisited] ] .shortcut = nrindex ; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | Now we join the two subtrees rooted at | ||
344 | |||
345 | RINDEX = ROOT(INDEX) and NRINDEX = ROOT(NINDEX). | ||
346 | |||
347 | Only three things can happen: | ||
348 | |||
349 | a - ROOT(INDEX) == ROOT(NRINDEX). In this case the two trees | ||
350 | have already been joined and we do not do anything. | ||
351 | |||
352 | b - I(ROOT(INDEX)) == I(ROOT(NRINDEX)). In this case index | ||
353 | is extending an extremal region with the same | ||
354 | value. Since ROOT(NRINDEX) will NOT be an extremal | ||
355 | region of the full image, ROOT(INDEX) can be safely | ||
356 | addedd as children of ROOT(NRINDEX) if this reduces | ||
357 | the height according to union rank. | ||
358 | |||
359 | c - I(ROOT(INDEX)) > I(ROOT(NRINDEX)) as index is extending | ||
360 | an extremal region, but increasing its level. In this | ||
361 | case ROOT(NRINDEX) WILL be an extremal region of the | ||
362 | final image and the only possibility is to add | ||
363 | ROOT(NRINDEX) as children of ROOT(INDEX). | ||
364 | */ | ||
365 | |||
366 | if( rindex != nrindex ) { | ||
367 | /* this is a genuine join */ | ||
368 | |||
369 | nrvalue = I_pt [nrindex] ; | ||
370 | if( nrvalue == value | ||
371 | #ifdef USE_RANK_UNION | ||
372 | && height < nheight | ||
373 | #endif | ||
374 | ) { | ||
375 | /* ROOT(INDEX) becomes the child */ | ||
376 | forest_pt[rindex] .parent = nrindex ; | ||
377 | forest_pt[rindex] .shortcut = nrindex ; | ||
378 | forest_pt[nrindex].area += forest_pt[rindex].area ; | ||
379 | |||
380 | #ifdef USE_RANK_UNION | ||
381 | forest_pt[nrindex].height = MAX(nheight, height+1) ; | ||
382 | #endif | ||
383 | |||
384 | joins_pt[njoins++] = rindex ; | ||
385 | |||
386 | } else { | ||
387 | /* ROOT(index) becomes parent */ | ||
388 | forest_pt[nrindex] .parent = rindex ; | ||
389 | forest_pt[nrindex] .shortcut = rindex ; | ||
390 | forest_pt[rindex] .area += forest_pt[nrindex].area ; | ||
391 | |||
392 | #ifdef USE_RANK_UNION | ||
393 | forest_pt[rindex].height = MAX(height, nheight+1) ; | ||
394 | #endif | ||
395 | if( nrvalue != value ) { | ||
396 | /* nrindex is extremal region: save for later */ | ||
397 | forest_pt[nrindex].region = ner ; | ||
398 | regions_pt [ner] .index = nrindex ; | ||
399 | regions_pt [ner] .parent = ner ; | ||
400 | regions_pt [ner] .value = nrvalue ; | ||
401 | regions_pt [ner] .area = forest_pt [nrindex].area ; | ||
402 | regions_pt [ner] .area_top = nel ; | ||
403 | regions_pt [ner] .area_bot = 0 ; | ||
404 | ++ner ; | ||
405 | /* printf("ner = %d\n", ner);*/ | ||
406 | } | ||
407 | |||
408 | /* annote join operation for post-processing */ | ||
409 | joins_pt[njoins++] = nrindex ; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | } /* neighbor done */ | ||
414 | |||
415 | /* move to next neighbor */ | ||
416 | k = 0 ; | ||
417 | while(++ nsubs_pt [k] > 1) { | ||
418 | nsubs_pt [k++] = -1 ; | ||
419 | if(k == ndims) goto done_all_neighbors ; | ||
420 | } | ||
421 | } /* next neighbor */ | ||
422 | done_all_neighbors : ; | ||
423 | } /* next pixel */ | ||
424 | |||
425 | /* the root of the last processed pixel must be a region */ | ||
426 | forest_pt [rindex].region = ner ; | ||
427 | regions_pt [ner] .index = rindex ; | ||
428 | regions_pt [ner] .parent = ner ; | ||
429 | regions_pt [ner] .value = I_pt [rindex] ; | ||
430 | regions_pt [ner] .area = forest_pt [rindex] .area ; | ||
431 | regions_pt [ner] .area_top = nel ; | ||
432 | regions_pt [ner] .area_bot = 0 ; | ||
433 | ++ner ; | ||
434 | |||
435 | verbose && mexPrintf("done\nExtremal regions: %d\n", ner) ; | ||
436 | |||
437 | /* ----------------------------------------------------------------- | ||
438 | * Compute region parents | ||
439 | * -------------------------------------------------------------- */ | ||
440 | for( i = 0 ; i < ner ; ++i) { | ||
441 | idx_t index = regions_pt [i].index ; | ||
442 | val_t value = regions_pt [i].value ; | ||
443 | idx_t j = i ; | ||
444 | |||
445 | while(j == i) { | ||
446 | idx_t pindex = forest_pt [index].parent ; | ||
447 | val_t pvalue = I_pt [pindex] ; | ||
448 | |||
449 | /* top of the tree */ | ||
450 | if(index == pindex) { | ||
451 | j = forest_pt[index].region ; | ||
452 | break ; | ||
453 | } | ||
454 | |||
455 | /* if index is the root of a region, either this is still | ||
456 | i, or it is the parent region we are looking for. */ | ||
457 | if(value < pvalue) { | ||
458 | j = forest_pt[index].region ; | ||
459 | } | ||
460 | |||
461 | index = pindex ; | ||
462 | value = pvalue ; | ||
463 | } | ||
464 | regions_pt[i]. parent = j ; | ||
465 | } | ||
466 | |||
467 | /* ----------------------------------------------------------------- | ||
468 | * Compute areas of tops and bottoms | ||
469 | * -------------------------------------------------------------- */ | ||
470 | |||
471 | /* We scan the list of regions from the bottom. Let x0 be the current | ||
472 | region and be x1 = PARENT(x0), x2 = PARENT(x1) and so on. | ||
473 | |||
474 | Here we do two things: | ||
475 | |||
476 | 1) Look for regions x for which x0 is the BOTTOM. This requires | ||
477 | VAL(x0) <= VAL(x) - DELTA < VAL(x1). | ||
478 | We update AREA_BOT(x) for each of such x found. | ||
479 | |||
480 | 2) Look for the region y which is the TOP of x0. This requires | ||
481 | VAL(y) <= VAL(x0) + DELTA < VAL(y+1) | ||
482 | We update AREA_TOP(x0) as soon as we find such y. | ||
483 | |||
484 | */ | ||
485 | |||
486 | for( i = 0 ; i < ner ; ++i) { | ||
487 | /* fix xi as the region, then xj are the parents */ | ||
488 | idx_t parent = regions_pt [i].parent ; | ||
489 | int val0 = regions_pt [i].value ; | ||
490 | int val1 = regions_pt [parent].value ; | ||
491 | int val = val0 ; | ||
492 | idx_t j = i ; | ||
493 | |||
494 | while(true) { | ||
495 | int valp = regions_pt [parent].value ; | ||
496 | |||
497 | /* i is the bottom of j */ | ||
498 | if(val0 <= val - delta && val - delta < val1) { | ||
499 | regions_pt [j].area_bot = | ||
500 | MAX(regions_pt [j].area_bot, regions_pt [i].area) ; | ||
501 | } | ||
502 | |||
503 | /* j is the top of i */ | ||
504 | if(val <= val0 + delta && val0 + delta < valp) { | ||
505 | regions_pt [i].area_top = regions_pt [j].area ; | ||
506 | } | ||
507 | |||
508 | /* stop if going on is useless */ | ||
509 | if(val1 <= val - delta && val0 + delta < val) | ||
510 | break ; | ||
511 | |||
512 | /* stop also if j is the root */ | ||
513 | if(j == parent) | ||
514 | break ; | ||
515 | |||
516 | /* next region upward */ | ||
517 | j = parent ; | ||
518 | parent = regions_pt [j].parent ; | ||
519 | val = valp ; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | /* ----------------------------------------------------------------- | ||
524 | * Compute variation | ||
525 | * -------------------------------------------------------------- */ | ||
526 | for(i = 0 ; i < ner ; ++i) { | ||
527 | int area = regions_pt [i].area ; | ||
528 | int area_top = regions_pt [i].area_top ; | ||
529 | int area_bot = regions_pt [i].area_bot ; | ||
530 | regions_pt [i].variation = | ||
531 | (float)(area_top - area_bot) / (float)area ; | ||
532 | |||
533 | /* initialize .mastable to 1 for all nodes */ | ||
534 | regions_pt [i].maxstable = 1 ; | ||
535 | } | ||
536 | |||
537 | /* ----------------------------------------------------------------- | ||
538 | * Remove regions which are NOT maximally stable | ||
539 | * -------------------------------------------------------------- */ | ||
540 | nmer = ner ; | ||
541 | for(i = 0 ; i < ner ; ++i) { | ||
542 | idx_t parent = regions_pt [i] .parent ; | ||
543 | float var = regions_pt [i] .variation ; | ||
544 | float pvar = regions_pt [parent] .variation ; | ||
545 | idx_t loser ; | ||
546 | |||
547 | /* decide which one to keep and put that in loser */ | ||
548 | if(var < pvar) loser = parent ; else loser = i ; | ||
549 | |||
550 | /* make loser NON maximally stable */ | ||
551 | if(regions_pt [loser].maxstable) --nmer ; | ||
552 | regions_pt [loser].maxstable = 0 ; | ||
553 | } | ||
554 | |||
555 | verbose && mexPrintf("Maximally stable regions: %d (%.1f%%)\n", | ||
556 | nmer, 100.0 * (double) nmer / ner) ; | ||
557 | |||
558 | /* ----------------------------------------------------------------- | ||
559 | * Remove more regions | ||
560 | * -------------------------------------------------------------- */ | ||
561 | |||
562 | /* it is critical for correct duplicate detection to remove regions | ||
563 | from the bottom (smallest one first) */ | ||
564 | |||
565 | if( big_cleanup || small_cleanup || bad_cleanup || dup_cleanup ) { | ||
566 | int nbig = 0 ; | ||
567 | int nsmall = 0 ; | ||
568 | int nbad = 0 ; | ||
569 | int ndup = 0 ; | ||
570 | |||
571 | /* scann all extremal regions */ | ||
572 | for(i = 0 ; i < ner ; ++i) { | ||
573 | |||
574 | /* process only maximally stable extremal regions */ | ||
575 | if(! regions_pt [i].maxstable) continue ; | ||
576 | |||
577 | if( bad_cleanup && regions_pt[i].variation >= 1.0f ) { | ||
578 | ++nbad ; | ||
579 | goto remove_this_region ; | ||
580 | } | ||
581 | |||
582 | if( big_cleanup && regions_pt[i].area > nel/2 ) { | ||
583 | ++nbig ; | ||
584 | goto remove_this_region ; | ||
585 | } | ||
586 | |||
587 | if( small_cleanup && regions_pt[i].area < 25 ) { | ||
588 | ++nsmall ; | ||
589 | goto remove_this_region ; | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * Remove duplicates | ||
594 | */ | ||
595 | if( dup_cleanup ) { | ||
596 | idx_t parent = regions_pt [i].parent ; | ||
597 | int area, parea ; | ||
598 | float change ; | ||
599 | |||
600 | /* the search does not apply to root regions */ | ||
601 | if(parent != i) { | ||
602 | |||
603 | /* search for the maximally stable parent region */ | ||
604 | while(! regions_pt[parent].maxstable) { | ||
605 | idx_t next = regions_pt[parent].parent ; | ||
606 | if(next == parent) break ; | ||
607 | parent = next ; | ||
608 | } | ||
609 | |||
610 | /* compare with the parent region; if the current and parent | ||
611 | regions are too similar, keep only the parent */ | ||
612 | area = regions_pt [i].area ; | ||
613 | parea = regions_pt [parent].area ; | ||
614 | change = (float)(parea - area)/area ; | ||
615 | |||
616 | if(change < 0.5) { | ||
617 | ++ndup ; | ||
618 | goto remove_this_region ; | ||
619 | } | ||
620 | |||
621 | } /* drop duplicates */ | ||
622 | } | ||
623 | continue ; | ||
624 | remove_this_region : | ||
625 | regions_pt[i].maxstable = false ; | ||
626 | --nmer ; | ||
627 | } /* next region to cleanup */ | ||
628 | |||
629 | if(verbose) { | ||
630 | mexPrintf(" Bad regions: %d\n", nbad ) ; | ||
631 | mexPrintf(" Small regions: %d\n", nsmall ) ; | ||
632 | mexPrintf(" Big regions: %d\n", nbig ) ; | ||
633 | mexPrintf(" Duplicated regions: %d\n", ndup ) ; | ||
634 | } | ||
635 | } | ||
636 | |||
637 | verbose && mexPrintf("Cleaned-up regions: %d (%.1f%%)\n", | ||
638 | nmer, 100.0 * (double) nmer / ner) ; | ||
639 | |||
640 | /* ----------------------------------------------------------------- | ||
641 | * Fit ellipses | ||
642 | * -------------------------------------------------------------- */ | ||
643 | ell_pt = 0 ; | ||
644 | if (nout >= 1) { | ||
645 | int midx = 1 ; | ||
646 | int d, index, j ; | ||
647 | |||
648 | verbose && mexPrintf("Fitting ellipses...\n") ; | ||
649 | |||
650 | /* enumerate maxstable regions */ | ||
651 | for(i = 0 ; i < ner ; ++i) { | ||
652 | if(! regions_pt [i].maxstable) continue ; | ||
653 | regions_pt [i].maxstable = midx++ ; | ||
654 | } | ||
655 | |||
656 | /* allocate space */ | ||
657 | acc_pt = mxMalloc(sizeof(acc_t) * nel) ; | ||
658 | ell_pt = mxMalloc(sizeof(acc_t) * gdl * nmer) ; | ||
659 | |||
660 | /* clear accumulators */ | ||
661 | memset(ell_pt, 0, sizeof(int) * gdl * nmer) ; | ||
662 | |||
663 | /* for each gdl */ | ||
664 | for(d = 0 ; d < gdl ; ++d) { | ||
665 | /* initalize parameter */ | ||
666 | memset(subs_pt, 0, sizeof(int) * ndims) ; | ||
667 | |||
668 | if(d < ndims) { | ||
669 | verbose && mexPrintf(" mean %d\n",d) ; | ||
670 | for(index = 0 ; index < nel ; ++ index) { | ||
671 | acc_pt[index] = subs_pt[d] ; | ||
672 | adv(dims, ndims, subs_pt) ; | ||
673 | } | ||
674 | |||
675 | } else { | ||
676 | |||
677 | /* decode d-ndims into a (i,j) pair */ | ||
678 | i = d-ndims ; | ||
679 | j = 0 ; | ||
680 | while(i > j) { | ||
681 | i -= j + 1 ; | ||
682 | j ++ ; | ||
683 | } | ||
684 | |||
685 | verbose && mexPrintf(" corr (%d,%d)\n",i,j) ; | ||
686 | |||
687 | /* add x_i * x_j */ | ||
688 | for(index = 0 ; index < nel ; ++ index){ | ||
689 | acc_pt[index] = subs_pt[i]*subs_pt[j] ; | ||
690 | adv(dims, ndims, subs_pt) ; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | /* integrate parameter */ | ||
695 | for(i = 0 ; i < njoins ; ++i) { | ||
696 | idx_t index = joins_pt[i] ; | ||
697 | idx_t parent = forest_pt [ index ].parent ; | ||
698 | acc_pt[parent] += acc_pt[index] ; | ||
699 | } | ||
700 | |||
701 | /* save back to ellpises */ | ||
702 | for(i = 0 ; i < ner ; ++i) { | ||
703 | idx_t region = regions_pt [i].maxstable ; | ||
704 | |||
705 | /* skip if not extremal region */ | ||
706 | if(region-- == 0) continue ; | ||
707 | ell_pt [d + gdl*region] = acc_pt [ regions_pt[i].index ] ; | ||
708 | } | ||
709 | |||
710 | /* next gdl */ | ||
711 | } | ||
712 | mxFree(acc_pt) ; | ||
713 | } | ||
714 | |||
715 | /* ----------------------------------------------------------------- | ||
716 | * Save back and exit | ||
717 | * -------------------------------------------------------------- */ | ||
718 | |||
719 | /* | ||
720 | * Save extremal regions | ||
721 | */ | ||
722 | { | ||
723 | int dims[2] ; | ||
724 | int unsigned * pt ; | ||
725 | dims[0] = nmer ; | ||
726 | out[OUT_REGIONS] = mxCreateNumericArray(1,dims,mxUINT32_CLASS,mxREAL); | ||
727 | pt = mxGetData(out[OUT_REGIONS]) ; | ||
728 | for (i = 0 ; i < ner ; ++i) { | ||
729 | if( regions_pt[i].maxstable ) { | ||
730 | /* adjust for MATLAB index compatibility */ | ||
731 | *pt++ = regions_pt[i].index + 1 ; | ||
732 | } | ||
733 | } | ||
734 | } | ||
735 | |||
736 | /* | ||
737 | * Save fitted ellipses | ||
738 | */ | ||
739 | if(nout >= 2) { | ||
740 | int dims[2], d, j, index ; | ||
741 | double * pt ; | ||
742 | dims[0] = gdl ; | ||
743 | dims[1] = nmer ; | ||
744 | |||
745 | out[OUT_ELL] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL) ; | ||
746 | pt = mxGetData(out[OUT_ELL]) ; | ||
747 | |||
748 | for(index = 0 ; index < nel ; ++index) { | ||
749 | |||
750 | idx_t region = regions_pt [index] .maxstable ; | ||
751 | int N = regions_pt [index] .area ; | ||
752 | |||
753 | if(region-- == 0) continue ; | ||
754 | |||
755 | for(d = 0 ; d < gdl ; ++d) { | ||
756 | |||
757 | pt[d] = (double) ell_pt[gdl*region + d] / N ; | ||
758 | |||
759 | if(d < ndims) { | ||
760 | /* adjust for MATLAB coordinate frame convention */ | ||
761 | pt[d] += 1 ; | ||
762 | } else { | ||
763 | /* remove squared mean from moment to get variance */ | ||
764 | i = d - ndims ; | ||
765 | j = 0 ; | ||
766 | while(i > j) { | ||
767 | i -= j + 1 ; | ||
768 | j ++ ; | ||
769 | } | ||
770 | pt[d] -= (pt[i]-1)*(pt[j]-1) ; | ||
771 | } | ||
772 | } | ||
773 | pt += gdl ; | ||
774 | } | ||
775 | mxFree(ell_pt) ; | ||
776 | } | ||
777 | |||
778 | if(nout >= 3) { | ||
779 | int unsigned * pt ; | ||
780 | out[OUT_PARENTS] = mxCreateNumericArray(ndims,dims,mxUINT32_CLASS,mxREAL) ; | ||
781 | pt = mxGetData(out[OUT_PARENTS]) ; | ||
782 | for(i = 0 ; i < nel ; ++i) { | ||
783 | *pt++ = forest_pt[i].parent ; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | if(nout >= 4) { | ||
788 | int dims[2] ; | ||
789 | int unsigned * pt ; | ||
790 | dims[0] = 3 ; | ||
791 | dims[1]= ner ; | ||
792 | out[OUT_AREA] = mxCreateNumericArray(2,dims,mxUINT32_CLASS,mxREAL); | ||
793 | pt = mxGetData(out[OUT_AREA]) ; | ||
794 | for( i = 0 ; i < ner ; ++i ) { | ||
795 | *pt++ = regions_pt [i]. area_bot ; | ||
796 | *pt++ = regions_pt [i]. area ; | ||
797 | *pt++ = regions_pt [i]. area_top ; | ||
798 | } | ||
799 | } | ||
800 | |||
801 | /* free stuff */ | ||
802 | mxFree( forest_pt ) ; | ||
803 | mxFree( pairs_pt ) ; | ||
804 | mxFree( regions_pt ) ; | ||
805 | mxFree( visited_pt ) ; | ||
806 | mxFree( strides_pt ) ; | ||
807 | mxFree( nsubs_pt ) ; | ||
808 | mxFree( subs_pt ) ; | ||
809 | } | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mser.mexa64 b/SD-VBS/benchmarks/mser/src/matlab/old/mser.mexa64 new file mode 100755 index 0000000..fb9fb0b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mser.mexa64 | |||
Binary files differ | |||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mser_compile.m b/SD-VBS/benchmarks/mser/src/matlab/old/mser_compile.m new file mode 100755 index 0000000..5e3562b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mser_compile.m | |||
@@ -0,0 +1,7 @@ | |||
1 | function mser_compile(type) | ||
2 | % MSER_COMPILE Compile MEX files | ||
3 | |||
4 | opts = { '-O', '-I.' } ; | ||
5 | |||
6 | mex('mser.mex.c','-output', 'mser',opts{:}) ; | ||
7 | mex('erfill.mex.c','-output', 'erfill',opts{:}) ; | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo2.m b/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo2.m new file mode 100755 index 0000000..37a4ed1 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo2.m | |||
@@ -0,0 +1,62 @@ | |||
1 | % MSER_DEMO2 Demonstrate MSER code | ||
2 | |||
3 | % AUTORIGHTS | ||
4 | % Copyright (C) 2006 Regents of the University of California | ||
5 | % All rights reserved | ||
6 | % | ||
7 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
8 | % | ||
9 | % Redistribution and use in source and binary forms, with or without | ||
10 | % modification, are permitted provided that the following conditions are met | ||
11 | % | ||
12 | % * Redistributions of source code must retain the above copyright | ||
13 | % notice, this list of conditions and the following disclaimer. | ||
14 | % * Redistributions in binary form must reproduce the above copyright | ||
15 | % notice, this list of conditions and the following disclaimer in the | ||
16 | % documentation and/or other materials provided with the distribution. | ||
17 | % * Neither the name of the University of California, Berkeley nor the | ||
18 | % names of its contributors may be used to endorse or promote products | ||
19 | % derived from this software without specific prior written permission. | ||
20 | % | ||
21 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
22 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
23 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
25 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
26 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
27 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
28 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | I = load('clown') ; I = uint8(I.X) ; | ||
33 | figure(1) ; imagesc(I) ; colormap gray; hold on ; | ||
34 | |||
35 | [M,N] = size(I) ; | ||
36 | i = double(i) ; | ||
37 | j = double(j) ; | ||
38 | |||
39 | [r,ell] = mser(I,5) ; | ||
40 | |||
41 | r=double(r) ; | ||
42 | |||
43 | [i,j]=ind2sub(size(I),r) ; | ||
44 | plot(j,i,'r*') ; | ||
45 | |||
46 | ell = ell([2 1 5 4 3],:) ; | ||
47 | plotframe(ell); | ||
48 | |||
49 | figure(2) ; | ||
50 | |||
51 | clear MOV ; | ||
52 | K = size(ell,2) ; | ||
53 | for k=1:K | ||
54 | clf ; | ||
55 | sel = erfill(I,r(k)) ; | ||
56 | mask = zeros(M,N) ; mask(sel) =1 ; | ||
57 | imagesc(cat(3,I,255*uint8(mask),I)) ; colormap gray ; hold on ; | ||
58 | set(gca,'position',[0 0 1 1]) ; axis off ; axis equal ; | ||
59 | plot(j(k),i(k),'r*') ; | ||
60 | plotframe(ell(:,k),'color','r') ; | ||
61 | MOV(k) = getframe(gca) ; | ||
62 | end | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo3.m b/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo3.m new file mode 100755 index 0000000..4669437 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/mser_demo3.m | |||
@@ -0,0 +1,117 @@ | |||
1 | % MSER_DEMO3 Demonstrates MSER on a volumetric image | ||
2 | |||
3 | % AUTORIGHTS | ||
4 | % Copyright (C) 2006 Regents of the University of California | ||
5 | % All rights reserved | ||
6 | % | ||
7 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
8 | % | ||
9 | % Redistribution and use in source and binary forms, with or without | ||
10 | % modification, are permitted provided that the following conditions are met | ||
11 | % | ||
12 | % * Redistributions of source code must retain the above copyright | ||
13 | % notice, this list of conditions and the following disclaimer. | ||
14 | % * Redistributions in binary form must reproduce the above copyright | ||
15 | % notice, this list of conditions and the following disclaimer in the | ||
16 | % documentation and/or other materials provided with the distribution. | ||
17 | % * Neither the name of the University of California, Berkeley nor the | ||
18 | % names of its contributors may be used to endorse or promote products | ||
19 | % derived from this software without specific prior written permission. | ||
20 | % | ||
21 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
22 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
23 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
25 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
26 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
27 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
28 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | % -------------------------------------------------------------------- | ||
33 | % Create data | ||
34 | % -------------------------------------------------------------------- | ||
35 | |||
36 | % volumetric coordinate (x,y,z) | ||
37 | x = linspace(-1,1,50) ; | ||
38 | [x,y,z] = meshgrid(x,x,x) ; | ||
39 | |||
40 | % create funny volumetric image | ||
41 | I = sin(4*x).*cos(4*y).*sin(z) ; | ||
42 | I = I-min(I(:)) ; | ||
43 | I = I/max(I(:)) ; | ||
44 | |||
45 | % quantize the image in 10 levels | ||
46 | lev = 10 ; | ||
47 | I = lev*I ; | ||
48 | Ir = round(I) ; | ||
49 | |||
50 | % -------------------------------------------------------------------- | ||
51 | % Compute regions | ||
52 | % -------------------------------------------------------------------- | ||
53 | [idx,ell,p] = mser(uint8(Ir),1); | ||
54 | |||
55 | % -------------------------------------------------------------------- | ||
56 | % Plots | ||
57 | % -------------------------------------------------------------------- | ||
58 | |||
59 | % The image is quantized; store in LEV its range. | ||
60 | lev = unique(Ir(idx)) ; | ||
61 | |||
62 | figure(100); clf; | ||
63 | K=min(length(lev),4) ; | ||
64 | |||
65 | r=.99 ; | ||
66 | |||
67 | % one level per time | ||
68 | for k=1:K | ||
69 | tightsubplot(K,k) ; | ||
70 | [i,j,m] = ind2sub(size(I), idx(Ir(idx)==lev(k)) ) ; | ||
71 | |||
72 | % compute level set of level LEV(k) | ||
73 | Is = double(Ir<=lev(k)) ; | ||
74 | |||
75 | p1 = patch(isosurface(Is,r), ... | ||
76 | 'FaceColor','blue','EdgeColor','none') ; | ||
77 | p2 = patch(isocaps(Is,r),... | ||
78 | 'FaceColor','interp','EdgeColor','none') ; | ||
79 | isonormals(I,p1) | ||
80 | hold on ; | ||
81 | |||
82 | view(3); axis vis3d tight | ||
83 | camlight; lighting phong ; | ||
84 | |||
85 | % find regions that have this level | ||
86 | sel = find( Ir(idx) == lev(k) ) ; | ||
87 | |||
88 | % plot fitted ellipsoid | ||
89 | for r=sel' | ||
90 | E = ell(:,r) ; | ||
91 | c = E(1:3) ; | ||
92 | A = zeros(3) ; | ||
93 | A(1,1) = E(4) ; | ||
94 | A(1,2) = E(5) ; | ||
95 | A(2,2) = E(6) ; | ||
96 | A(1,3) = E(7) ; | ||
97 | A(2,3) = E(8) ; | ||
98 | A(3,3) = E(9) ; | ||
99 | |||
100 | A = A + A' - diag(diag(A)) ; | ||
101 | |||
102 | % correct var. order | ||
103 | perm = [0 1 0 ; 1 0 0 ; 0 0 1] ; | ||
104 | A = perm*A*perm ; | ||
105 | |||
106 | [V,D] = eig(A) ; | ||
107 | A = 2.5*V*sqrt(D) ; | ||
108 | |||
109 | [x,y,z]=sphere ; | ||
110 | [P,Q]=size(x) ; | ||
111 | X=A*[x(:)';y(:)';z(:)'] ; | ||
112 | x=reshape(X(1,:),P,Q)+c(2) ; | ||
113 | y=reshape(X(2,:),P,Q)+c(1) ; | ||
114 | z=reshape(X(3,:),P,Q)+c(3) ; | ||
115 | surf(x,y,z,'FaceAlpha',.5) ; | ||
116 | end | ||
117 | end | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/overview_mser.m b/SD-VBS/benchmarks/mser/src/matlab/old/overview_mser.m new file mode 100755 index 0000000..b7fcf2b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/overview_mser.m | |||
@@ -0,0 +1,8 @@ | |||
1 | % OVERVIEW_MSER Maximally Stable Extremal Regions | ||
2 | % This is a MATLAB/MEX implementation of Maximally Stable Extremal | ||
3 | % Regions (MSER). You can: | ||
4 | % | ||
5 | % * Use MSER() to extract the maximally stable extremal regions from | ||
6 | % a given image. | ||
7 | % | ||
8 | % For practical coding example, see MSER_DEMO() and MSER_DEMO3(). | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/old/script_run_profile.m b/SD-VBS/benchmarks/mser/src/matlab/old/script_run_profile.m new file mode 100755 index 0000000..bdb2c04 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/old/script_run_profile.m | |||
@@ -0,0 +1,137 @@ | |||
1 | function script_run_profile(dataDir, resultDir, type, common,toolDir) | ||
2 | |||
3 | path(path, common); | ||
4 | |||
5 | % MSER_DEMO Demonstrates MSER | ||
6 | |||
7 | % AUTORIGHTS | ||
8 | % Copyright (C) 2006 Regents of the University of California | ||
9 | % All rights reserved | ||
10 | % | ||
11 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
12 | % | ||
13 | % Redistribution and use in source and binary forms, with or without | ||
14 | % modification, are permitted provided that the following conditions are met | ||
15 | % | ||
16 | % * Redistributions of source code must retain the above copyright | ||
17 | % notice, this list of conditions and the following disclaimer. | ||
18 | % * Redistributions in binary form must reproduce the above copyright | ||
19 | % notice, this list of conditions and the following disclaimer in the | ||
20 | % documentation and/or other materials provided with the distribution. | ||
21 | % * Neither the name of the University of California, Berkeley nor the | ||
22 | % names of its contributors may be used to endorse or promote products | ||
23 | % derived from this software without specific prior written permission. | ||
24 | % | ||
25 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
26 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
27 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
28 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
29 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
30 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
31 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
32 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
33 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
34 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | |||
36 | which_image = 3 ; | ||
37 | |||
38 | % -------------------------------------------------------------------- | ||
39 | % Create data | ||
40 | % -------------------------------------------------------------------- | ||
41 | switch which_image | ||
42 | case 1 | ||
43 | I = rand(200,200) ; | ||
44 | I = imsmooth(I,10) ; | ||
45 | I = I-min(I(:)) ; | ||
46 | I = I/max(I(:)) ; | ||
47 | lev = 10 ; | ||
48 | I = uint8(round(I*lev)) ; | ||
49 | |||
50 | case 2 | ||
51 | I = zeros(200,200) ; | ||
52 | I(50:150,50:150)=5 ; | ||
53 | I = imsmooth(I,10) ; | ||
54 | I = uint8(round(I)) ; | ||
55 | |||
56 | case 3 | ||
57 | Files = dir([dataDir,'/1.bmp']); | ||
58 | I=readImage(fullfile(dataDir,Files(1).name)); | ||
59 | |||
60 | % if(ndims(Image) > 2) | ||
61 | % | ||
62 | % for i=1:size(Image,1) | ||
63 | % for j=1:size(Image,2) | ||
64 | % I(i,j) = (Image(i,j,1) + Image(i,j,2)*6 + Image(i,j,3)*3)/10; | ||
65 | % end | ||
66 | % end | ||
67 | % | ||
68 | % else | ||
69 | % I = Image; | ||
70 | % end | ||
71 | disp(size(I)); | ||
72 | end | ||
73 | |||
74 | % -------------------------------------------------------------------- | ||
75 | % Compute MSERs | ||
76 | % -------------------------------------------------------------------- | ||
77 | |||
78 | %% Self check params | ||
79 | tol = 0.1; | ||
80 | elapsed = zeros(1,2); | ||
81 | |||
82 | %% Timing | ||
83 | start = photonStartTiming; | ||
84 | |||
85 | [idx,ell,p,a] = mser(uint8(I), 2) ; | ||
86 | |||
87 | %% Timing | ||
88 | stop = photonEndTiming; | ||
89 | |||
90 | temp = photonReportTiming(start, stop); | ||
91 | elapsed(1) = elapsed(1) + temp(1); | ||
92 | elapsed(2) = elapsed(2) + temp(2); | ||
93 | |||
94 | %% Self checking | ||
95 | writeMatrix(idx, dataDir); | ||
96 | ret = selfCheck(idx, dataDir, tol); | ||
97 | if(ret == -1) | ||
98 | disp('Error in MSER'); | ||
99 | end | ||
100 | |||
101 | %% Timing | ||
102 | photonPrintTiming(elapsed); | ||
103 | |||
104 | %% -------------------------------------------------------------------- | ||
105 | %% Plots | ||
106 | %% -------------------------------------------------------------------- | ||
107 | %[i,j] = ind2sub(size(I),idx) ; | ||
108 | % | ||
109 | %figure(100) ; clf ; imagesc(I) ; hold on ; | ||
110 | %set(gca,'Position',[0 0 1 1]) ; | ||
111 | %plot(j,i,'g*') ; colormap gray ; | ||
112 | % | ||
113 | %% swap x with y | ||
114 | %ell = ell([2 1 5 4 3],:) ; | ||
115 | % | ||
116 | %for k=1:size(ell,2) | ||
117 | % E = ell(:,k) ; | ||
118 | % c = E(1:2) ; | ||
119 | % A = zeros(2) ; | ||
120 | % A(1,1) = E(3) ; | ||
121 | % A(1,2) = E(4) ; | ||
122 | % A(2,2) = E(5) ; | ||
123 | % A = A + A' - diag(diag(A)) ; | ||
124 | % | ||
125 | % [V,D] = eig(A) ; | ||
126 | % A = 2.5*V*sqrt(D) ; | ||
127 | % | ||
128 | % X = A*[cos(linspace(0,2*pi,30)) ; sin(linspace(0,2*pi,30)) ;] ; | ||
129 | % X(1,:) = X(1,:) + c(1) ; | ||
130 | % X(2,:) = X(2,:) + c(2) ; | ||
131 | % | ||
132 | % plot(X(1,:),X(2,:),'r-','LineWidth',2) ; | ||
133 | % plot(c(1),c(2),'r.') ; | ||
134 | % plot(j(k),i(k),'g*') ; | ||
135 | %end | ||
136 | % | ||
137 | %line([j'; ell(1,:)],[i'; ell(2,:)],'color','b') ; | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/overview_mser.m b/SD-VBS/benchmarks/mser/src/matlab/overview_mser.m new file mode 100755 index 0000000..b7fcf2b --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/overview_mser.m | |||
@@ -0,0 +1,8 @@ | |||
1 | % OVERVIEW_MSER Maximally Stable Extremal Regions | ||
2 | % This is a MATLAB/MEX implementation of Maximally Stable Extremal | ||
3 | % Regions (MSER). You can: | ||
4 | % | ||
5 | % * Use MSER() to extract the maximally stable extremal regions from | ||
6 | % a given image. | ||
7 | % | ||
8 | % For practical coding example, see MSER_DEMO() and MSER_DEMO3(). | ||
diff --git a/SD-VBS/benchmarks/mser/src/matlab/script_run_profile.m b/SD-VBS/benchmarks/mser/src/matlab/script_run_profile.m new file mode 100755 index 0000000..ec06539 --- /dev/null +++ b/SD-VBS/benchmarks/mser/src/matlab/script_run_profile.m | |||
@@ -0,0 +1,126 @@ | |||
1 | function script_run_profile(dataDir, resultDir, type, common,toolDir) | ||
2 | |||
3 | mser_compile; | ||
4 | path(path, common); | ||
5 | |||
6 | % MSER_DEMO Demonstrates MSER | ||
7 | |||
8 | % AUTORIGHTS | ||
9 | % Copyright (C) 2006 Regents of the University of California | ||
10 | % All rights reserved | ||
11 | % | ||
12 | % Written by Andrea Vedaldi (UCLA VisionLab). | ||
13 | % | ||
14 | % Redistribution and use in source and binary forms, with or without | ||
15 | % modification, are permitted provided that the following conditions are met | ||
16 | % | ||
17 | % * Redistributions of source code must retain the above copyright | ||
18 | % notice, this list of conditions and the following disclaimer. | ||
19 | % * Redistributions in binary form must reproduce the above copyright | ||
20 | % notice, this list of conditions and the following disclaimer in the | ||
21 | % documentation and/or other materials provided with the distribution. | ||
22 | % * Neither the name of the University of California, Berkeley nor the | ||
23 | % names of its contributors may be used to endorse or promote products | ||
24 | % derived from this software without specific prior written permission. | ||
25 | % | ||
26 | % THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | ||
27 | % EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
28 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
29 | % DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
30 | % DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
31 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
32 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
33 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
35 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | |||
37 | which_image = 3 ; | ||
38 | |||
39 | % -------------------------------------------------------------------- | ||
40 | % Create data | ||
41 | % -------------------------------------------------------------------- | ||
42 | switch which_image | ||
43 | case 1 | ||
44 | I = rand(200,200) ; | ||
45 | I = imsmooth(I,10) ; | ||
46 | I = I-min(I(:)) ; | ||
47 | I = I/max(I(:)) ; | ||
48 | lev = 10 ; | ||
49 | I = uint8(round(I*lev)) ; | ||
50 | |||
51 | case 2 | ||
52 | I = zeros(200,200) ; | ||
53 | I(50:150,50:150)=5 ; | ||
54 | I = imsmooth(I,10) ; | ||
55 | I = uint8(round(I)) ; | ||
56 | |||
57 | case 3 | ||
58 | Files = dir([dataDir,'/1.bmp']); | ||
59 | I=readImage(fullfile(dataDir,Files(1).name)); | ||
60 | end | ||
61 | |||
62 | % -------------------------------------------------------------------- | ||
63 | % Compute MSERs | ||
64 | % -------------------------------------------------------------------- | ||
65 | |||
66 | %% Self check params | ||
67 | tol = 0.1; | ||
68 | elapsed = zeros(1,2); | ||
69 | |||
70 | rows = size(I,1); | ||
71 | cols = size(I,2); | ||
72 | |||
73 | fprintf(1,'Input size\t\t- (%dx%d)\n', rows, cols); | ||
74 | |||
75 | %% Timing | ||
76 | start = photonStartTiming; | ||
77 | |||
78 | [idx] = mser(uint8(I), 2) ; | ||
79 | |||
80 | %% Timing | ||
81 | stop = photonEndTiming; | ||
82 | |||
83 | temp = photonReportTiming(start, stop); | ||
84 | elapsed(1) = elapsed(1) + temp(1); | ||
85 | elapsed(2) = elapsed(2) + temp(2); | ||
86 | |||
87 | %% Self checking | ||
88 | writeMatrix(idx, dataDir); | ||
89 | |||
90 | %% Timing | ||
91 | photonPrintTiming(elapsed); | ||
92 | |||
93 | %% -------------------------------------------------------------------- | ||
94 | %% Plots | ||
95 | %% -------------------------------------------------------------------- | ||
96 | %[i,j] = ind2sub(size(I),idx) ; | ||
97 | % | ||
98 | %figure(100) ; clf ; imagesc(I) ; hold on ; | ||
99 | %set(gca,'Position',[0 0 1 1]) ; | ||
100 | %plot(j,i,'g*') ; colormap gray ; | ||
101 | % | ||
102 | %% swap x with y | ||
103 | %ell = ell([2 1 5 4 3],:) ; | ||
104 | % | ||
105 | %for k=1:size(ell,2) | ||
106 | % E = ell(:,k) ; | ||
107 | % c = E(1:2) ; | ||
108 | % A = zeros(2) ; | ||
109 | % A(1,1) = E(3) ; | ||
110 | % A(1,2) = E(4) ; | ||
111 | % A(2,2) = E(5) ; | ||
112 | % A = A + A' - diag(diag(A)) ; | ||
113 | % | ||
114 | % [V,D] = eig(A) ; | ||
115 | % A = 2.5*V*sqrt(D) ; | ||
116 | % | ||
117 | % X = A*[cos(linspace(0,2*pi,30)) ; sin(linspace(0,2*pi,30)) ;] ; | ||
118 | % X(1,:) = X(1,:) + c(1) ; | ||
119 | % X(2,:) = X(2,:) + c(2) ; | ||
120 | % | ||
121 | % plot(X(1,:),X(2,:),'r-','LineWidth',2) ; | ||
122 | % plot(c(1),c(2),'r.') ; | ||
123 | % plot(j(k),i(k),'g*') ; | ||
124 | %end | ||
125 | % | ||
126 | %line([j'; ell(1,:)],[i'; ell(2,:)],'color','b') ; | ||