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