Mercurial > hg > camir-aes2014
comparison core/magnatagatune/MTTTagFeatureGenreBasic.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 classdef MTTTagFeatureGenreBasic < MTTAudioFeature & handle | |
2 | |
3 | |
4 properties(Constant = true) | |
5 | |
6 my_revision = str2double(substr('$Rev: 99 $', 5, -1)); | |
7 end | |
8 | |
9 % --- | |
10 % here come the internal clip properties. | |
11 % the database is stored as a global variable | |
12 % --- | |
13 properties | |
14 | |
15 my_params = struct(... | |
16 ... % --- | |
17 ... % these are GenreBasic parameters | |
18 ... % --- | |
19 'pct_genres', 1, ... % 1/100 percentile genre tags used | |
20 'empty_genres', 0 ... % allow empty genres to persist | |
21 ); | |
22 end | |
23 | |
24 methods | |
25 | |
26 % --- | |
27 % constructor: pointer to feature in database | |
28 % --- | |
29 function feature = MTTTagFeatureGenreBasic(varargin) | |
30 | |
31 feature = feature@MTTAudioFeature(varargin{:}); | |
32 end | |
33 | |
34 function data = extract(feature, clip) | |
35 % process tag information and build the tag vector | |
36 | |
37 % --- | |
38 % get total number of tags. | |
39 % | |
40 % NOTE: the highest tag id should match the size of the | |
41 % tagdb lexicon | |
42 % --- | |
43 % num_tags = clip.my_db.genredb.size(); | |
44 | |
45 if feature.my_params.pct_genres ~= 0 | |
46 % no tags, f.e. for parameter experiments in | |
47 % higher level features | |
48 [tagids, score] = clip.my_db.genredb.annotids_for_owner(clip.id); | |
49 | |
50 % save lexicon | |
51 data.lexicon = clip.my_db.genredb.lexicon; | |
52 | |
53 % save to data structure | |
54 data.tags.ids = tagids; | |
55 data.tags.scores = score; | |
56 end | |
57 | |
58 % save info data | |
59 data.info.type = 'MTTTagFeatureGenreBasic'; | |
60 data.info.owner = clip; | |
61 data.info.owner_id = clip.id; | |
62 data.info.creatorrev = feature.my_revision; | |
63 | |
64 % save parameters | |
65 data.info.params = feature.my_params; | |
66 | |
67 data.final.vector = []; | |
68 data.final.vector_info = struct(); | |
69 data.final.dim = 0; | |
70 end | |
71 | |
72 | |
73 % --- | |
74 % NOTE: the following transforms are just stated fro | |
75 % future use by now | |
76 % --- | |
77 function define_global_transform(features) | |
78 % --- | |
79 % compute the relevant tags, and save | |
80 % them in the commom place | |
81 % --- | |
82 | |
83 % compute extreme cases | |
84 if features(1).my_params.pct_genres == 1 && features(1).my_params.empty_genres | |
85 % all tags allowed | |
86 | |
87 common.rel_dimensions.tags.ids = 1:numel(features(1).data.lexicon); | |
88 common.rel_dimensions.tags.id_pos = 1:numel(features(1).data.lexicon); | |
89 | |
90 % set common feature values | |
91 features(1).my_db.set_common(common); | |
92 return; | |
93 | |
94 elseif features(1).my_params.pct_genres == 0 | |
95 % no tags, f.e. for parameter experiments in | |
96 % higher level features | |
97 | |
98 common.rel_dimensions.tags.ids = []; | |
99 common.rel_dimensions.tags.id_pos = []; | |
100 | |
101 % set common feature values | |
102 features(1).my_db.set_common(common); | |
103 return; | |
104 end | |
105 | |
106 | |
107 allids = sparse(numel(features), numel(features(1).data.lexicon)); | |
108 for i = 1:numel(features) | |
109 | |
110 allids(i,features(i).data.tags.ids) = ... | |
111 allids(i,features(i).data.tags.ids) + features(i).data.tags.scores; | |
112 end | |
113 | |
114 % --- | |
115 % get usage of tags and filter not-used tags | |
116 % --- | |
117 tagsum = sum(allids, 1); | |
118 nonzero = tagsum > 0; | |
119 | |
120 % --- | |
121 % NOTE: We remove the empty genres, then | |
122 % sort by weight / number of appearance and cut off | |
123 ids = find(nonzero); | |
124 [null, idx] = sort(tagsum(ids),'descend'); | |
125 ids = ids(idx); | |
126 | |
127 % cutoff | |
128 num_tags = ceil( features(1).my_params.pct_genres * numel(ids)); | |
129 valid_ids = ids(1:min(end, num_tags)); | |
130 | |
131 % --- | |
132 % NOTE: make sure that the positions for the tags | |
133 % stay correctly assigned / consistent | |
134 % --- | |
135 id_pos = sparse(size(valid_ids)); | |
136 id_pos(valid_ids) = 1:num_tags; | |
137 | |
138 % save to common data structure | |
139 common.rel_dimensions.tags.ids = valid_ids; | |
140 common.rel_dimensions.tags.id_pos = id_pos; | |
141 | |
142 % set common feature values | |
143 features(1).my_db.set_common(common); | |
144 end | |
145 | |
146 function finalise(features) | |
147 | |
148 for i = 1:numel(features) | |
149 | |
150 % check for neccesary parameters | |
151 if isempty(features(i).my_db.commondb) | |
152 | |
153 error('Define the global transformation first') | |
154 return; | |
155 end | |
156 | |
157 if features(i).my_params.pct_genres == 0 | |
158 vector_info.labels = {}; | |
159 | |
160 % save into feature struct | |
161 features(i).data.final.dim = 0; | |
162 features(i).data.final.vector = []; | |
163 features(i).data.final.vector_info = vector_info; | |
164 return; | |
165 end | |
166 % get valid tag ids | |
167 valid_ids = features(i).common.rel_dimensions.tags.ids; | |
168 num_tags = numel(valid_ids); | |
169 | |
170 % --- | |
171 % get vector positions for contined ids, | |
172 % and sort out the non_allowed id's | |
173 % --- | |
174 id_pos = features(i).common.rel_dimensions.tags.id_pos; | |
175 | |
176 [has_ids, has_pos] = intersect(features(i).data.tags.ids, valid_ids); | |
177 | |
178 score = features(i).data.tags.scores; | |
179 | |
180 % create feature vector | |
181 vector = zeros(num_tags,1); | |
182 vector(id_pos(has_ids)) = score(has_pos); | |
183 | |
184 % --- | |
185 % NOTE: this labelling costs to much space | |
186 % --- | |
187 vector_info.labels = features(i).data.lexicon(valid_ids); | |
188 | |
189 % save into feature struct | |
190 features(i).data.final.dim = num_tags; | |
191 features(i).data.final.vector = vector; | |
192 features(i).data.final.vector_info = vector_info; | |
193 end | |
194 end | |
195 | |
196 function [a1] = visualise(feature) | |
197 | |
198 % get tag descriptions form first clip | |
199 tags = MTTClip(feature(1).owner_id()).my_db.genres; | |
200 | |
201 % works for multiple feature instances | |
202 for i = 1:numel(feature) | |
203 | |
204 clip = MTTClip(feature(i).owner_id()); | |
205 | |
206 % plot feature data | |
207 h = bar(feature(i).data.final.vector); | |
208 a1 = gca; | |
209 | |
210 set(a1,'XTick', 1:feature(i).data.final.dim,... | |
211 'XTickLabel', tags); | |
212 title(sprintf('clip %d: %s by %s, genres', ... | |
213 clip.id, clip.title(),clip.artist())); | |
214 end | |
215 end | |
216 | |
217 end | |
218 end |