Mercurial > hg > segmentation
diff novelty.py @ 0:26838b1f560f
initial commit of a segmenter project
author | mi tian |
---|---|
date | Thu, 02 Apr 2015 18:09:27 +0100 |
parents | |
children | c11ea9e0357f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/novelty.py Thu Apr 02 18:09:27 2015 +0100 @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +novelty.py + +Created by mi tian on 2015-04-02. +Copyright (c) 2015 __MyCompanyName__. All rights reserved. +""" + +import sys, os +import numpy as np +from scipy.signal import correlate2d, convolve2d + +# from utils.PeakPickerUtil import PeakPicker + +def getNoveltyCurve(ssm, kernel_size, normalise=False): + '''Return novelty score from ssm.''' + + kernel_size = int(np.floor(kernel_size/2.0) + 1) + stripe = getDiagonalSlice(ssm, kernel_size) + kernel = gaussian_kernel(kernel_size) + xc = convolve2d(stripe,kernel,mode='same') + xc[abs(xc)>1e+10]=0.00001 + + novelty = xc[int(np.floor(xc.shape[0]/2.0)),:] + novelty = [0.0 if (np.isnan(x) or np.isinf(x) or x > 1e+100) else x for x in novelty] + + if normalise: + novelty = (novelty - np.min(novelty)) / (np.max(novelty) - np.min(novelty)) + return novelty + +def getDiagonalSlice(ssm, width): + ''' Return a diagonal stripe of the ssm given its width, with 45 degrees rotation. + Note: requres 45 degrees rotated kernel also.''' + w = int(np.floor(width/2.0)) + length = len(np.diagonal(ssm)) + stripe = np.zeros((2*w+1,length)) + # print 'diagonal', length, w, stripe.shape + for i in xrange(-w, w+1) : + stripe[w+i,:] = np.hstack(( np.zeros(int(np.floor(abs(i)/2.0))), np.diagonal(ssm,i), np.zeros(int(np.ceil(abs(i)/2.0))) )) + return stripe + +def gaussian_kernel(size): + '''Create a gaussian tapered 45 degrees rotated checkerboard kernel. + TODO: Unit testing: Should produce this with kernel size 3: + 0.1353 -0.3679 0.1353 + 0.3679 1.0000 0.3679 + 0.1353 -0.3679 0.1353 + ''' + n = float(np.ceil(size / 2.0)) + kernel = np.zeros((size,size)) + for i in xrange(1,size+1) : + for j in xrange(1,size+1) : + gauss = np.exp( -4.0 * (np.square( (i-n)/n ) + np.square( (j-n)/n )) ) + # gauss = 1 + if np.logical_xor( j - n > np.floor((i-n) / 2.0), j - n > np.floor((n-i) / 2.0) ) : + kernel[i-1,j-1] = -gauss + else: + kernel[i-1,j-1] = gauss + + return kernel + +def getNoveltyPeaks(ssm, kernel_size, peak_picker, normalise=False): + '''Detect segment boundaries in the ssm.''' + novelty = getNoveltyCurve(ssm, kernel_size, normalise=False) + smoothed_novelty, novelty_peaks = peak_picker.process(novelty) + + return novelty, smoothed_novelty, novelty_peaks \ No newline at end of file