diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirnovelty.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirnovelty.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,208 @@
+function varargout = mirnovelty(orig,varargin)
+%   n = mirnovelty(m) evaluates the novelty score from a similarity matrix.
+%   [n,m] = mirnovelty(m) also return the similarity matrix.
+%   Optional argument: 
+%       mirnovelty(...,'Distance',f) specifies the name of a dissimilarity
+%           distance function, from those proposed in the Statistics Toolbox
+%               (help pdist).
+%           default value: f = 'cosine'
+%       mirnovelty(...,'Similarity',f) specifies the name of a similarity
+%           measure function. This function is applied to the result of the
+%           distance function. cf. mirsimatrix 
+%           default value: f = 'exponential'
+%               corresponding to f(x) = exp(-x)
+%       mirnovelty(...,'KernelSize',s) or more simply mirnovelty(...,s) 
+%           specifies the length of the gaussian kernel, in samples.
+%           default value: s = 64.
+%       mirnovelty(...,'Normal',0) does not normalize the novelty curve
+%           between the values 0 and 1.
+%
+%   Foote, J. & Cooper, M. (2003). Media Segmentation using Self-Similarity
+% Decomposition,. In Proc. SPIE Storage and Retrieval for Multimedia
+% Databases, Vol. 5021, pp. 167-75.
+
+        dist.key = 'Distance';
+        dist.type = 'String';
+        dist.default = 'cosine';
+    option.dist = dist;
+
+        sm.key = {'Measure','Similarity'};
+        sm.type = 'String';
+        sm.default = 'exponential';
+    option.sm = sm;
+
+        K.key = {'KernelSize','Width'};
+        K.type = 'Integer';
+        K.default = 64;
+    option.K = K;
+    
+        transf.type = 'String';
+        transf.default = 'TimeLag';
+        transf.choice = {'Horizontal','TimeLag'};
+    option.transf = transf;
+
+        normal.key = 'Normal';
+        normal.type = 'Boolean';
+        normal.default = 1;
+        normal.when = 'After';
+    option.normal = normal;
+    
+specif.option = option;
+specif.combineframes = @combineframes;
+specif.nochunk = 1;
+varargout = mirfunction(@mirnovelty,orig,varargin,nargout,specif,@init,@main);
+    
+
+function [x type] = init(x,option)
+type = 'mirscalar';
+if not(isamir(x,'mirscalar') && strcmp(get(x,'Title'),'Novelty'))
+    x = mirsimatrix(x,'Distance',option.dist,'Similarity',option.sm,...
+                      'Width',option.K,option.transf);
+end
+if isa(x,'mirdesign')
+    x = set(x,'Overlap',ceil(option.K));
+end
+
+
+function y = main(orig,option,postoption)
+if iscell(orig)
+    orig = orig{1};
+end
+if not(isa(orig,'mirscalar'))
+    s = get(orig,'Data');
+    dw = get(orig,'DiagWidth');
+    for k = 1:length(s)
+        if isnumeric(dw)
+            dwk = dw;
+        else
+            dwk = dw{k};
+        end
+        if option.K
+            cgs = min(option.K,dwk);
+        else
+            cgs = dwk;
+        end
+        cg = checkergauss(cgs,option.transf);
+        disp('Computing convolution, please wait...')
+        for z = 1:length(s{k})
+            sz = s{k}{z};
+            szm = max(max(sz));
+            for i = find(isnan(sz))
+                sz(i) = szm;
+            end
+            cv = convolve2(sz,cg,'same');
+            nl = size(cv,1);
+            nc = size(cv,2);
+            if nl == 0
+                warning('WARNING IN NOVELTY: No frame decomposition. The novelty score cannot be computed.');
+                score{k}{z} = [];
+            else
+                sco = cv(floor(size(cv,1)/2),:);
+                incr = find(diff(sco)>=0);
+                if not(isempty(incr))
+                    decr = find(diff(sco)<=0);
+                    sco(1:incr(1)-1) = NaN(1,incr(1)-1);
+                    if not(isempty(decr))
+                        sco(decr(end)+1:end) = NaN(1,length(sco)-decr(end));
+                    end
+                    incr = find(diff(sco)>=0);
+                    sco2 = sco;
+                    if not(isempty(incr))
+                        sco2 = sco2(1:incr(end)+1);
+                    end
+                    decr = find(diff(sco)<=0);
+                    if not(isempty(decr)) && decr(1)>2
+                        sco2 = sco2(decr(1)-1:end);
+                    end
+                    mins = min(sco2);
+                    rang = find(sco>= mins);
+                    if not(isempty(rang))
+                        sco(1:rang(1)-1) = NaN(1,rang(1)-1);
+                        sco(rang(end)+1:end) = NaN(1,length(sco)-rang(end));
+                    end
+                end
+                score{k}{z} = sco;
+            end
+        end
+    end
+else
+    score = get(orig,'Data');
+end
+if not(isempty(postoption)) && postoption.normal
+    for k = 1:length(score)
+        for l = 1:length(score{k})
+            sco = score{k}{l};
+            sco = (sco-min(sco))/(max(sco)-min(sco));
+            score{k}{l} = sco;
+        end
+    end
+end
+n = mirscalar(orig,'Data',score,'Title','Novelty'); 
+y = {n orig};
+
+
+function old = combineframes(old,new)
+if not(iscell(old))
+    old = {old};
+end
+if not(iscell(new))
+    new = {new};
+end
+for var = 1:length(new)
+    ov = old{var};
+    nv = new{var};
+    ofp = get(ov,'FramePos');
+    ofp = ofp{1}{1};
+    nfp = get(nv,'FramePos');
+    nfp = nfp{1}{1};
+    od = get(ov,'Data');
+    od = od{1}{1};
+    onan = find(isnan(od));
+    od(onan) = [];
+    ofp(:,onan) = [];
+    nd = get(nv,'Data');
+    nd = nd{1}{1};
+    nnan = find(isnan(nd));
+    nd(nnan) = [];
+    nfp(:,nnan) = [];
+    [unused omatch nmatch] = intersect(ofp(1,:),nfp(1,:));
+    if isempty(omatch)
+        ov = set(ov,'FramePos',{{[ofp nfp]}},'Data',{{[od nd]}});
+    else
+        lm = length(omatch);
+        ov = set(ov,'FramePos',{{[ofp(:,1:omatch(1)-1) nfp]}},...
+            'Data',{{[od(1:omatch(1)-1),...
+                      (od(omatch).*(lm:-1:1) + nd(nmatch).*(1:lm))/(lm+1),...
+                      nd(nmatch(end)+1:end)]}});
+    end
+    old{var} = ov;
+end
+
+
+function y = checkergauss(N,transf)
+hN = ceil(N/2);
+if strcmpi(transf,'TimeLag')
+    y = zeros(hN,N);
+    for j = 1:N
+        for i = 1:hN
+            g = exp(-((i/hN)^2 + (((j-hN)/hN)^2))*4);
+            if j>hN && j<hN+i
+                y(hN-i+1,j) = -g;
+            else
+                y(hN-i+1,j) = g;
+            end
+        end
+    end
+else
+    y = zeros(N);
+    for i = 1:N
+        for j = 1:N
+            g = exp(-(((i-hN)/hN)^2 + (((j-hN)/hN)^2))*4);
+            if xor(j>i,j>N-i)
+                y(i,j) = -g;
+            else
+                y(i,j) = g;
+            end
+        end
+    end
+end
\ No newline at end of file