wolffd@0: % --- wolffd@0: % The DistMeasureMahal class states a wrapper for wolffd@0: % special Mahalanobis similarity distance, and is compatible with the wolffd@0: % DistMeasure class wolffd@0: % --- wolffd@0: classdef DistMeasureNNet < handle wolffd@0: wolffd@0: properties (SetAccess = private) wolffd@0: wolffd@0: net; wolffd@0: wolffd@0: featX; wolffd@0: wolffd@0: ids; wolffd@0: ret_ids; wolffd@0: end wolffd@0: wolffd@0: methods wolffd@0: wolffd@0: % --- wolffd@0: % constructor wolffd@0: % --- wolffd@0: function m = DistMeasureNNet(clips, net, featX) wolffd@0: wolffd@0: if size(featX, 2) ~= numel(clips) wolffd@0: error 'wrong input format' wolffd@0: end wolffd@0: wolffd@0: % fill index and generate matrix; wolffd@0: m.ids = [clips.id]; wolffd@0: wolffd@0: % reverse index wolffd@0: m.ret_ids = sparse(numel(m.ids),1); wolffd@0: m.ret_ids(m.ids) = 1:numel(m.ids); wolffd@0: wolffd@0: % --- wolffd@0: % save neural net and lazy-copy features wolffd@0: % --- wolffd@0: m.net = net; wolffd@0: wolffd@0: m.featX = featX; wolffd@0: wolffd@0: end wolffd@0: wolffd@0: wolffd@0: % --- wolffd@0: % this function returns the wolffd@0: % similarity of two clip indices wolffd@0: % --- wolffd@0: function out = mat(m, idxa, idxb) wolffd@0: wolffd@0: if nargin == 1 wolffd@0: idxa = 1:numel(m.ids); wolffd@0: idxb = 1:numel(m.ids); wolffd@0: end wolffd@0: wolffd@0: % cycle through all index combinations wolffd@0: out = zeros(numel(idxa), numel(idxb)); wolffd@0: for i = 1:numel(idxa) wolffd@0: for j = 1:numel(idxb) wolffd@0: wolffd@0: % calculate distance vector wolffd@0: deltas = m.featX(:,idxa(i)) - m.featX(:,idxb(j)); wolffd@0: wolffd@0: % return distance from net wolffd@0: out(i,j) = m.net.calcValue(deltas); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: end wolffd@0: wolffd@0: % --- wolffd@0: % returns the distance for the two input clips wolffd@0: % --- wolffd@0: function out = distance(m, clipa, clipb) wolffd@0: posa = m.get_clip_pos(clipa); wolffd@0: posb = m.get_clip_pos(clipb); wolffd@0: wolffd@0: out = m.mat(posa, posb); wolffd@0: end wolffd@0: wolffd@0: % --- wolffd@0: % returns a list of n (default = 10) clips most wolffd@0: % similar to the input wolffd@0: % --- wolffd@0: function [clips, dist] = get_nearest(m, clip, n) wolffd@0: % list = get_nearest(m, clip, n) wolffd@0: % wolffd@0: % returns a list of n (default = 10) clips most wolffd@0: % similar to the input wolffd@0: wolffd@0: % default number of results wolffd@0: if nargin == 2 wolffd@0: wolffd@0: n = 10; wolffd@0: end wolffd@0: wolffd@0: % return all clips in case n = 0 wolffd@0: if n == 0; n = numel(m.ids); end wolffd@0: wolffd@0: % get clip positions wolffd@0: pos = m.get_clip_pos(clip); wolffd@0: wolffd@0: % sort according to distance wolffd@0: [sc, idx] = sort( m.mat(pos, 1:numel(m.ids)), 'ascend'); wolffd@0: wolffd@0: % we only output relevant data wolffd@0: idx = idx(sc < inf); wolffd@0: wolffd@0: if numel(idx) > 0 wolffd@0: % create clips form best ids wolffd@0: clips = MTTClip( m.ids( idx(1:min(n, end)))); wolffd@0: dist = m.mat(pos, idx(1:min(n, end))); wolffd@0: wolffd@0: else wolffd@0: clips = []; wolffd@0: dist = []; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: wolffd@0: wolffd@0: function [clips, dist] = present_nearest(m, clip, n) wolffd@0: % plays and shows the n best hits for a given clip wolffd@0: wolffd@0: % default number of results wolffd@0: if nargin == 2 wolffd@0: wolffd@0: n = 3; wolffd@0: end wolffd@0: wolffd@0: % get best list wolffd@0: [clips, dist] = get_nearest(m, clip, n); wolffd@0: wolffd@0: clip.audio_features_basicsm.visualise(); wolffd@0: for i = 1:numel(clips) wolffd@0: fprintf('\n\n\n- Rank %d, distance: %1.4f \n\n',i, dist(i)); wolffd@0: wolffd@0: clips(i).audio_features_basicsm.visualise(); wolffd@0: h = gcf(); wolffd@0: t = clips(i).play(20); wolffd@0: pause(t); wolffd@0: close(h); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: function a = visualise(m) wolffd@0: wolffd@0: figure; wolffd@0: wolffd@0: % plot data wolffd@0: wolffd@0: imagesc(m.mat); wolffd@0: wolffd@0: a = gca; wolffd@0: set(a,'YTick',[1:numel(m.ids)], 'YTickLabel',m.ids); wolffd@0: set(a,'XTick',[1:numel(m.ids)], 'XTickLabel', m.ids); wolffd@0: wolffd@0: axis xy; wolffd@0: colormap(hot); wolffd@0: end wolffd@0: wolffd@0: % end methods wolffd@0: end wolffd@0: wolffd@0: % --- wolffd@0: % private methods wolffd@0: % --- wolffd@0: methods(Access = private) wolffd@0: wolffd@0: function out = get_clip_pos(m, clip) wolffd@0: % returns position in mat for given clip wolffd@0: wolffd@0: out = m.ret_ids(clip.id); wolffd@0: end wolffd@0: wolffd@0: end wolffd@0: wolffd@0: end