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