changeset 1:c11ea9e0357f

adding funcs
author mitian
date Thu, 02 Apr 2015 22:16:38 +0100
parents 26838b1f560f
children ef1fd8b0f3c4
files SegEval.py cnmf.py foote.py novelty.py sf.py utils/SegProperties.py utils/SegUtil.py
diffstat 7 files changed, 84 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/SegEval.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/SegEval.py	Thu Apr 02 22:16:38 2015 +0100
@@ -43,6 +43,21 @@
 import foote as foote_S
 import sf as sf_S
 import fmc2d as fmc2d_S
+import novelty as novelty_S
+
+# Algorithm params
+h = 8               # Size of median filter for features in C-NMF
+R = 15              # Size of the median filter for the activation matrix C-NMF
+rank = 4            # Rank of decomposition for the boundaries
+rank_labels = 6     # Rank of decomposition for the labels
+R_labels = 6        # Size of the median filter for the labels
+# Foote
+M = 2           # Median filter for the audio features (in beats)
+Mg = 32         # Gaussian kernel size
+L = 16          # Size of the median filter for the adaptive threshold
+# 2D-FMC
+N = 8          # Size of the fixed length segments (for 2D-FMC)
+
 
 # Define arg parser
 def parse_args():
@@ -56,7 +71,8 @@
 	op.add_option('-o', '--ouput', action="store", dest="OUTPUT", default='/Volumes/c4dm-03/people/mit/segmentation/gammatone/qupujicheng', type="str", help="Write segmentation results to ")
 
 	# boundary retrieval options
-	op.add_option('-b', '--bounrary-method', action="store", dest="BOUNDARY", default=['novelty', 'cnmf', 'sf', 'fmc2d'], help="Choose boundary retrieval algorithm ('novelty', 'cnmf', 'sf', 'fmc2d')." )
+	op.add_option('-b', '--bounrary-method', action="store", dest="BOUNDARY", type='choice', choices=['novelty', 'cnmf', 'foote', 'sf'], default='novelty', help="Choose boundary retrieval algorithm ('novelty', 'cnmf', 'sf', 'fmc2d')." )
+	op.add_option('-l', '--labeling-method', action="store", dest="LABEL", type='choice', choices=['cnmf', 'fmc2d'], default='cnmf', help="Choose boundary labeling algorithm ('cnmf', 'fmc2d')." )
 	
 	# Plot/print/mode options
 	op.add_option('-p', '--plot', action="store_true", dest="PLOT", default=False, help="Save plots")
@@ -305,38 +321,55 @@
 		print 'Segmenting using %s method' %options.BOUNDARY
 		for i,ao in enumerate(audio_list):
 			print 'processing: %s' %ao.name
-						
-
-
+				
+			# Experiment 1: segmentation using individual features.
+			if options.BOUNDARY == 'novelty':
+				# Peak picking from the novelty curve
+				gammatone_novelty, smoothed_gammatone_novelty, gammatone_bound_idxs = novelty_S.process(ao.gammatone_ssm, self.kernel_size, peak_picker)
+				timbre_novelty, smoothed_timbre_novelty, timbre_bound_idxs = novelty_S.process(ao.timbre_ssm, self.kernel_size, peak_picker)
+				tempo_novelty, smoothed_harmonic_novelty, tempo_bound_idxs = novelty_S.process(ao.tempo_ssm, self.kernel_size, peak_picker)
+				harmonic_novelty, smoothed_tempo_novelty, harmonic_bound_idxs = novelty_S.process(ao.harmonic_ssm, self.kernel_size, peak_picker)
+							
+			if options.BOUNDARY == 'cnmf':
+				gammatone_bound_idxs = cnmf_S.segmentation(ao.gammatone_features, rank=rank, R=R, h=8, niter=300)
+				timbre_bound_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)
+				tempo_bound_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)
+				harmonic_bound_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)
+				
+			if options.BOUNDARY == 'foote':
+				gammatone_bound_idxs = foote_S.segmentation(ao.gammatone_features, M=M, Mg=Mg, L=L)
+				timbre_bound_idxs = foote_S.segmentation(ao.timbre_features, M=M, Mg=Mg, L=L)
+				tempo_bound_idxs = foote_S.segmentation(ao.tempo_features, M=M, Mg=Mg, L=L)
+				harmonic_bound_idxs = foote_S.segmentation(ao.harmonic_features, M=M, Mg=Mg, L=L)
 			
+			if options.BOUNDARY == 'sf':
+				gammatone_bound_idxs = sf_S.segmentation(ao.gammatone_features)
+				timbre_bound_idxs = sf_S.segmentation(ao.timbre_features)
+				tempo_bound_idxs = sf_S.segmentation(ao.tempo_features)
+				harmonic_bound_idxs = sf_S.segmentation(ao.harmonic_features)
+			
+			if options.LABEL == 'fmc2d':
+				gammatone_bound_labels = fmc2d_S.compute_similarity(gammatone_bound_idxs, xmeans=True, N=N)
+				timbre_bound_labels = fmc2d_S.compute_similarity(timbre_bound_idxs, xmeans=True, N=N)
+				tempo_bound_labels = fmc2d_S.compute_similarity(tempo_bound_idxs, xmeans=True, N=N)
+				harmonic_bound_labels = fmc2d_S.compute_similarity(harmonic_bound_idxs, xmeans=True, N=N)
+			
+			if options.LABEL == 'cnmf':	
+				gammatone_bound_labels = cnmf_S.compute_labels(gammatone_bound_idxs, est_bound_idxs, nFrames)
+				timbre_bound_labels = cnmf_S.compute_labels(timbre_bound_idxs, est_bound_idxs, nFrames)
+				tempo_bound_labels = cnmf_S.compute_labels(tempo_bound_idxs, est_bound_idxs, nFrames)
+				harmonic_bound_labels = cnmf_S.compute_labels(harmonic_bound_idxs, est_bound_idxs, nFrames)
+				
+			gammatone_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_novelty_peaks]
+			timbre_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_novelty_peaks]
+			harmonic_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_novelty_peaks]
+			tempo_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_novelty_peaks]
+			
+			# Experiment 2: Trying combined features using the best boundary retrieval method
 			ao_featureset = [ao.gammatone_features, ao.harmonic_features, ao.timbre_features, ao.tempo_features]
 			feature_sel = [int(x) for x in options.FEATURES if x.isdigit()]
 			ao_featureset = [ao_featureset[i] for i in feature_sel]
 		
-			gammatone_novelty, smoothed_gammatone_novelty, gammatone_novelty_peaks = getNoveltyPeaks(ao.gammatone_ssm, self.kernel_size, peak_picker)
-			timbre_novelty, smoothed_timbre_novelty, timbre_novelty_peaks = getNoveltyPeaks(ao.timbre_ssm, self.kernel_size, peak_picker)
-			tempo_novelty, smoothed_harmonic_novelty, harmonic_novelty_peaks = getNoveltyPeaks(ao.tempo_ssm, self.kernel_size, peak_picker)
-			harmonic_novelty, smoothed_tempo_novelty, tempo_novelty_peaks = getNoveltyPeaks(ao.harmonic_ssm, self.kernel_size, peak_picker)
-							
-			# Peak picking from the novelty curve
-			smoothed_gammatone_novelty, gammatone_novelty_peaks = peak_picker.process(gammatone_novelty)
-			gammatone_detection = [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_novelty_peaks]
-			smoothed_timbre_novelty, timbre_novelty_peaks = peak_picker.process(timbre_novelty)
-			timbre_detection = [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_novelty_peaks]
-			smoothed_harmonic_novelty, harmonic_novelty_peaks = peak_picker.process(harmonic_novelty)
-			harmonic_detection = [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_novelty_peaks]
-			smoothed_tempo_novelty, tempo_novelty_peaks = peak_picker.process(tempo_novelty)
-			tempo_detection = [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_novelty_peaks]
-			
-			if (len(gammatone_novelty_peaks) == 0 or len(harmonic_novelty_peaks)== 0 or len(timbre_novelty_peaks) == 0 or len(tempo_novelty_peaks) == 0):
-				print ao.name, len(gammatone_novelty_peaks), len(harmonic_novelty_peaks), len(timbre_novelty_peaks), len(tempo_novelty_peaks) 
-				
-			smoothed_gammatone_novelty -= np.min(smoothed_gammatone_novelty)
-			smoothed_harmonic_novelty -= np.min(smoothed_harmonic_novelty)
-			smoothed_timbre_novelty -= np.min(smoothed_timbre_novelty)
-			smoothed_tempo_novelty -= np.min(smoothed_tempo_novelty)
-			combined_sdf = (np.array(smoothed_gammatone_novelty) + np.array(smoothed_harmonic_novelty) + np.array(smoothed_timbre_novelty) + np.array(smoothed_tempo_novelty))
-			
 
 
 def main():
--- a/cnmf.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/cnmf.py	Thu Apr 02 22:16:38 2015 +0100
@@ -115,7 +115,7 @@
     """
 
     # Filter
-    X = utils.median_filter(X, M=h)
+    X = SegUtil.median_filter(X, M=h)
     X = X.T
 
     # Find non filtered boundaries
--- a/foote.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/foote.py	Thu Apr 02 22:16:38 2015 +0100
@@ -36,16 +36,16 @@
         Array containing the indices of the boundaries.
     """
     # Filter
-    F = utils.median_filter(F, M=M)
+    F = SegUtil.median_filter(F, M=M)
 
     # Self Similarity Matrix
-    S = utils.compute_ssm(F)
+    S = SegUtil.compute_ssm(F)
 
     # Compute gaussian kernel
-    G = utils.compute_gaussian_krnl(Mg)
+    G = SegUtil.compute_gaussian_krnl(Mg)
 
     # Compute the novelty curve
-    nc = utils.compute_nc(S, G)
+    nc = SegUtil.compute_nc(S, G)
 
     # Find peaks in the novelty curve
-    return utils.pick_peaks(nc, L=L, plot=plot)
+    return SegUtil.pick_peaks(nc, L=L, plot=plot)
--- a/novelty.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/novelty.py	Thu Apr 02 22:16:38 2015 +0100
@@ -10,6 +10,7 @@
 import sys, os
 import numpy as np
 from scipy.signal import correlate2d, convolve2d
+import matplotlib.pyplot as plt
 
 # from utils.PeakPickerUtil import PeakPicker
 
@@ -60,9 +61,14 @@
 				
 	return kernel	
 	
-def getNoveltyPeaks(ssm, kernel_size, peak_picker, normalise=False):
+def process(ssm, kernel_size, peak_picker, normalise=False, plot=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
+	if plot:
+		plot_detection(smoothed_novelty, novelty_peaks)
+	return novelty, smoothed_novelty, novelty_peaks
+	
+def plot_detection(smoothed_novelty, novelty_peaks):
+	pass
\ No newline at end of file
--- a/sf.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/sf.py	Thu Apr 02 22:16:38 2015 +0100
@@ -28,7 +28,6 @@
 # Local stuff
 from utils import SegUtil
 
-
 def median_filter(X, M=8):
     """Median filter along the first axis of the feature matrix X."""
     for i in xrange(X.shape[1]):
@@ -125,7 +124,7 @@
     E = embedded_space(F, m)
 
     # Recurrence matrix
-    R = utils.recurrence_matrix(E.T, k=k * int(F.shape[0]),
+    R = SegUtil.recurrence_matrix(E.T, k=k * int(F.shape[0]),
                                 width=0,  # zeros from the diagonal
                                 metric="seuclidean",
                                 sym=True).astype(np.float32)
--- a/utils/SegProperties.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/utils/SegProperties.py	Thu Apr 02 22:16:38 2015 +0100
@@ -7,8 +7,11 @@
 Copyright (c) 2015 __MyCompanyName__. All rights reserved.
 """
 
-import sys
-import os
+import sys, os
+import numpy as np
+from sklearn.metrics.pairwise import pairwise_distances
+from gmmdist import *
+from GmmMetrics import GmmDistance
 
 class FeatureGMM(object):
 	'''Represent segment candidates using single GMMs and compute pairwise distances.'''
@@ -39,7 +42,7 @@
 			gf=GaussianFeature(feature[int(num * stepsize) : int((num * stepsize) + win_len), :],2)
 			# f.write("\n%s" %str(gf))
 			gaussian_list.append(gf)
-			tsi = int(floor( num * stepsize + 1)) 
+			tsi = int(np.floor( num * stepsize + 1)) 
 			gaussian_timestamps.append(self.timestamp[tsi])
 
 		# f.close()
--- a/utils/SegUtil.py	Thu Apr 02 18:09:27 2015 +0100
+++ b/utils/SegUtil.py	Thu Apr 02 22:16:38 2015 +0100
@@ -14,13 +14,14 @@
 
 import copy
 import numpy as np
-import os
+import os, sys
 import scipy
 from scipy.spatial import distance
 from scipy.ndimage import filters, zoom
 from scipy import signal
 import pylab as plt
 from scipy.spatial.distance import squareform, pdist
+from scipy.ndimage.filters import *
 
 
 def lognormalize_chroma(C):