annotate SegEval.py @ 10:6d1c6639f5db

notebook
author mitian
date Thu, 14 May 2015 18:01:00 +0100
parents 294f66d285af
children 6dae41887406
rev   line source
mi@0 1 #!/usr/bin/env python
mi@0 2 # encoding: utf-8
mi@0 3 """
mi@0 4 SegEval.py
mi@0 5
mi@0 6 The main segmentation program.
mi@0 7
mi@0 8 Created by mi tian on 2015-04-02.
mi@0 9 Copyright (c) 2015 __MyCompanyName__. All rights reserved.
mi@0 10 """
mi@0 11
mi@0 12 # Load starndard python libs
mi@0 13 import sys, os, optparse, csv
mi@0 14 from itertools import combinations
mi@0 15 from os.path import join, isdir, isfile, abspath, dirname, basename, split, splitext
mi@0 16 from copy import copy
mi@0 17
mi@0 18 import matplotlib
mi@0 19 # matplotlib.use('Agg')
mi@0 20 import matplotlib.pyplot as plt
mi@0 21 import matplotlib.gridspec as gridspec
mi@0 22 import numpy as np
mi@0 23 import scipy as sp
mi@0 24 from scipy.signal import correlate2d, convolve2d, filtfilt, resample
mi@0 25 from scipy.ndimage.filters import *
mi@0 26 from sklearn.decomposition import PCA
mi@0 27 from sklearn.mixture import GMM
mi@0 28 from sklearn.cluster import KMeans
mi@0 29 from sklearn.preprocessing import normalize
mi@0 30 from sklearn.metrics.pairwise import pairwise_distances
mi@0 31
mi@0 32 # Load dependencies
mi@0 33 from utils.SegUtil import getMean, getStd, getDelta, getSSM, reduceSSM, upSample, normaliseFeature
mi@0 34 from utils.PeakPickerUtil import PeakPicker
mi@0 35 from utils.gmmdist import *
mi@0 36 from utils.GmmMetrics import GmmDistance
mi@0 37 from utils.RankClustering import rClustering
mi@0 38 from utils.kmeans import Kmeans
mi@0 39 from utils.PathTracker import PathTracker
mitian@10 40 from utils.OnsetPlotProc import onset_plot, plot_on
mi@0 41
mi@0 42 # Load bourdary retrieval utilities
mi@0 43 import cnmf as cnmf_S
mi@0 44 import foote as foote_S
mi@0 45 import sf as sf_S
mi@0 46 import fmc2d as fmc2d_S
mitian@1 47 import novelty as novelty_S
mitian@1 48
mitian@1 49 # Algorithm params
mitian@1 50 h = 8 # Size of median filter for features in C-NMF
mitian@1 51 R = 15 # Size of the median filter for the activation matrix C-NMF
mitian@4 52 rank = 4 # Rank of decomposition for the boundaries
mitian@1 53 rank_labels = 6 # Rank of decomposition for the labels
mitian@1 54 R_labels = 6 # Size of the median filter for the labels
mitian@1 55 # Foote
mitian@1 56 M = 2 # Median filter for the audio features (in beats)
mitian@1 57 Mg = 32 # Gaussian kernel size
mitian@1 58 L = 16 # Size of the median filter for the adaptive threshold
mitian@1 59 # 2D-FMC
mitian@1 60 N = 8 # Size of the fixed length segments (for 2D-FMC)
mitian@1 61
mi@0 62
mi@0 63 # Define arg parser
mi@0 64 def parse_args():
mi@0 65 op = optparse.OptionParser()
mi@0 66 # IO options
mi@0 67 op.add_option('-g', '--gammatonegram-features', action="store", dest="GF", default='/Volumes/c4dm-03/people/mit/features/gammatonegram/qupujicheng/2048', type="str", help="Loading gammatone features from.." )
mi@0 68 op.add_option('-s', '--spectrogram-features', action="store", dest="SF", default='/Volumes/c4dm-03/people/mit/features/spectrogram/qupujicheng/2048', type="str", help="Loading spectral features from.." )
mi@0 69 op.add_option('-t', '--tempogram-features', action="store", dest="TF", default='/Volumes/c4dm-03/people/mit/features/tempogram/qupujicheng/tempo_features_6s', type="str", help="Loading tempogram features from.." )
mi@0 70 op.add_option('-f', '--featureset', action="store", dest="FEATURES", default='[0, 1, 2, 3]', type="str", help="Choose feature subsets (input a list of integers) used for segmentation -- gammtone, chroma, timbre, tempo -- 0, 1, 2, 3." )
mi@0 71 op.add_option('-a', '--annotations', action="store", dest="GT", default='/Volumes/c4dm-03/people/mit/annotation/qupujicheng/lowercase', type="str", help="Loading annotation files from.. ")
mi@0 72 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 ")
mi@0 73
mi@0 74 # boundary retrieval options
mitian@1 75 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')." )
mitian@1 76 op.add_option('-l', '--labeling-method', action="store", dest="LABEL", type='choice', choices=['cnmf', 'fmc2d'], default='cnmf', help="Choose boundary labeling algorithm ('cnmf', 'fmc2d')." )
mi@0 77
mi@0 78 # Plot/print/mode options
mi@0 79 op.add_option('-p', '--plot', action="store_true", dest="PLOT", default=False, help="Save plots")
mi@0 80 op.add_option('-e', '--test-mode', action="store_true", dest="TEST", default=False, help="Test mode")
mi@0 81 op.add_option('-v', '--verbose-mode', action="store_true", dest="VERBOSE", default=False, help="Print results in verbose mode.")
mi@0 82
mi@0 83 return op.parse_args()
mi@0 84 options, args = parse_args()
mi@0 85
mi@0 86 class FeatureObj() :
mi@0 87 __slots__ = ['key', 'audio', 'timestamps', 'gammatone_features', 'tempo_features', 'timbre_features', 'harmonic_features', 'gammatone_ssm', 'tempo_ssm', 'timbre_features', 'harmonic_ssm', 'ssm_timestamps']
mi@0 88
mi@0 89 class AudioObj():
mi@0 90 __slots__ = ['name', 'feature_list', 'gt', 'label', 'gammatone_features', 'tempo_features', 'timbre_features', 'harmonic_features', 'combined_features',\
mi@0 91 'gammatone_ssm', 'tempo_ssm', 'timbre_ssm', 'harmonic_ssm', 'combined_ssm', 'ssm', 'ssm_timestamps', 'tempo_timestamps']
mi@0 92
mi@0 93 class EvalObj():
mi@0 94 __slots__ = ['TP', 'FP', 'FN', 'P', 'R', 'F', 'AD', 'DA']
mi@0 95
mi@0 96
mi@0 97 class SSMseg(object):
mi@0 98 '''The main segmentation object'''
mi@0 99 def __init__(self):
mi@0 100 self.SampleRate = 44100
mi@0 101 self.NqHz = self.SampleRate/2
mi@0 102 self.timestamp = []
mi@0 103 self.previousSample = 0.0
mi@0 104 self.featureWindow = 6.0
mi@0 105 self.featureStep = 3.0
mi@0 106 self.kernel_size = 64 # Adjust this param according to the feature resolution.pq
mi@0 107 self.blockSize = 2048
mi@0 108 self.stepSize = 1024
mi@0 109
mi@0 110 '''NOTE: Match the following params with those used for feature extraction!'''
mi@0 111
mi@0 112 '''NOTE: Unlike spectrogram ones, Gammatone features are extracted without taking an FFT. The windowing is done under the purpose of chunking
mi@0 113 the audio to facilitate the gammatone filtering with the specified blockSize and stepSize. The resulting gammatonegram is aggregated every
mi@0 114 gammatoneLen without overlap.'''
mi@0 115 self.gammatoneLen = 2048
mi@0 116 self.gammatoneBandGroups = [0, 2, 6, 10, 13, 17, 20]
mi@0 117 self.nGammatoneBands = 20
mi@0 118 self.lowFreq = 100
mi@0 119 self.highFreq = self.SampleRate / 4
mi@0 120
mi@0 121 '''Settings for extracting tempogram features.'''
mi@0 122 self.tempoWindow = 6.0
mi@0 123 self.bpmBands = [30, 45, 60, 80, 100, 120, 180, 240, 400, 600]
mi@0 124
mitian@3 125 '''Peak picking settings for novelty based method'''
mitian@4 126 self.threshold = 30
mi@0 127 self.confidence_threshold = 0.5
mi@0 128 self.delta_threshold = 0.0
mi@0 129 self.backtracking_threshold = 1.9
mi@0 130 self.polyfitting_on = True
mi@0 131 self.medfilter_on = True
mi@0 132 self.LPfilter_on = True
mi@0 133 self.whitening_on = False
mi@0 134 self.aCoeffs = [1.0000, -0.5949, 0.2348]
mi@0 135 self.bCoeffs = [0.1600, 0.3200, 0.1600]
mi@0 136 self.cutoff = 0.34
mi@0 137 self.medianWin = 7
mi@0 138
mitian@10 139 if plot_on : onset_plot.reset()
mi@0 140
mitian@3 141 def pairwiseF(self, annotation, detection, tolerance=3.0, combine=1.0, idx2time=None):
mi@0 142 '''Pairwise F measure evaluation of detection rates.'''
mitian@3 143
mitian@5 144 res = EvalObj()
mitian@5 145 res.TP, res.FP, res.FN = 0, 0, 0
mitian@5 146 res.P, res.R, res.F = 0.0, 0.0, 0.0
mitian@5 147 res.AD, res.DA = 0.0, 0.0
mitian@5 148
mitian@5 149 if len(detection) == 0:
mitian@5 150 return res
mitian@5 151
mitian@5 152 gt = len(annotation) # Total number of ground truth data points
mitian@5 153 dt = len(detection) # Total number of experimental data points
mitian@5 154 foundIdx = []
mitian@5 155 D_AD = np.zeros(gt)
mitian@5 156 D_DA = np.zeros(dt)
mitian@5 157
mitian@4 158 if idx2time != None:
mitian@3 159 # Map detected idxs to real time
mitian@4 160 detection = [idx2time[int(np.rint(i))] for i in detection] + [annotation[-1]]
mi@0 161 # print 'detection', detection
mi@0 162 detection = np.append(detection, annotation[-1])
mitian@5 163
mi@0 164 for dtIdx in xrange(dt):
mi@0 165 D_DA[dtIdx] = np.min(abs(detection[dtIdx] - annotation))
mi@0 166 for gtIdx in xrange(gt):
mi@0 167 D_AD[gtIdx] = np.min(abs(annotation[gtIdx] - detection))
mi@0 168 for dtIdx in xrange(dt):
mi@0 169 if (annotation[gtIdx] >= detection[dtIdx] - tolerance/2.0) and (annotation[gtIdx] <= detection[dtIdx] + tolerance/2.0):
mi@0 170 res.TP = res.TP + 1.0
mi@0 171 foundIdx.append(gtIdx)
mi@0 172 foundIdx = list(set(foundIdx))
mi@0 173 res.TP = len(foundIdx)
mi@0 174 res.FP = max(0, dt - res.TP)
mi@0 175 res.FN = max(0, gt - res.TP)
mi@0 176
mi@0 177 res.AD = np.mean(D_AD)
mi@0 178 res.DA = np.mean(D_DA)
mi@0 179
mi@0 180
mi@0 181 if res.TP == 0:
mi@0 182 return res
mi@0 183
mi@0 184 res.P = res.TP / float(dt)
mi@0 185 res.R = res.TP / float(gt)
mi@0 186 res.F = 2 * res.P * res.R / (res.P + res.R)
mi@0 187 return res
mi@0 188
mitian@4 189 def writeIndividualHeader(self, filename):
mitian@3 190 '''Write header of output files for individual features.'''
mitian@3 191
mitian@3 192 with open(filename, 'a') as f:
mitian@3 193 csvwriter = csv.writer(f, delimiter=',')
mitian@3 194 csvwriter.writerow(['audio', 'gammatone_tp_05', 'gammatone_fp_05', 'gammatone_fn_05', 'gammatone_P_05', 'gammatone_R_05', 'gammatone_F_05', 'gammatone_AD_05', 'gammatone_DA_05', 'gammatone_tp_3', \
mitian@3 195 'gammatone_fp_3', 'gammatone_fn_3', 'gammatone_P_3', 'gammatone_R_3', 'gammatone_F_3', 'gammatone_AD_3', 'gammatone_DA_3', 'harmonic_tp_05', 'harmonic_fp_05', 'harmonic_fn_05', 'harmonic_P_05', \
mitian@3 196 'harmonic_R_05', 'harmonic_F_05', 'harmonic_AD_05', 'harmonic_DA_05', 'harmonic_tp_3', 'harmonic_fp_3', 'harmonic_fn_3', 'harmonic_P_3', 'harmonic_R_3', 'harmonic_F_3', 'harmonic_AD_3', 'harmonic_DA_3', \
mitian@3 197 'timbre_tp_05', 'timbre_fp_05', 'timbre_fn_05', 'timbre_P_05', 'timbre_R_05', 'timbre_F_05', 'timbre_AD_05', 'timbre_DA_05', 'timbre_tp_3', 'timbre_fp_3', 'timbre_fn_3', 'timbre_P_3', 'timbre_R_3', \
mitian@3 198 'timbre_F_3', 'timbre_AD_3', 'timbre_DA_3', 'tempo_tp_05', 'tempo_fp_05', 'tempo_fn_05', 'tempo_P_05', 'tempo_R_05', 'tempo_F_05', 'tempo_AD_05', 'tempo_DA_05', \
mitian@3 199 'tempo_tp_3', 'tempo_fp_3', 'tempo_fn_3', 'tempo_P_3', 'tempo_R_3', 'tempo_F_3', 'tempo_AD_3', 'tempo_DA_3'])
mitian@3 200
mitian@4 201 def writeIndividualRes(self, filename, ao_name, gt_res_05, gt_res_3, harmonic_res_05, harmonic_res_3, timbre_res_05, timbre_res_3, tempo_res_05, tempo_res_3):
mitian@3 202 '''Write result of single detection for individual features.'''
mitian@3 203
mitian@3 204 with open(filename, 'a') as f:
mitian@3 205 csvwriter = csv.writer(f, delimiter=',')
mitian@3 206 csvwriter.writerow([ao_name, gt_res_05.TP, gt_res_05.FP, gt_res_05.FN, gt_res_05.P, gt_res_05.R, gt_res_05.F, gt_res_05.AD, gt_res_05.DA, gt_res_3.TP, gt_res_3.FP, gt_res_3.FN, gt_res_3.P, \
mitian@3 207 gt_res_3.R, gt_res_3.F, gt_res_3.AD, gt_res_3.DA, harmonic_res_05.TP, harmonic_res_05.FP, harmonic_res_05.FN, harmonic_res_05.P, harmonic_res_05.R, harmonic_res_05.F, harmonic_res_05.AD, harmonic_res_05.DA, \
mitian@3 208 harmonic_res_3.TP, harmonic_res_3.FP, harmonic_res_3.FN, harmonic_res_3.P, harmonic_res_3.R, harmonic_res_3.F, harmonic_res_3.AD, harmonic_res_3.DA, timbre_res_05.TP, timbre_res_05.FP, \
mitian@3 209 timbre_res_05.FN, timbre_res_05.P, timbre_res_05.R, timbre_res_05.F, timbre_res_05.AD, timbre_res_05.DA, timbre_res_3.TP, timbre_res_3.FP, timbre_res_3.FN, timbre_res_3.P, timbre_res_3.R, timbre_res_3.F, \
mitian@3 210 timbre_res_3.AD, timbre_res_3.DA, tempo_res_05.TP, tempo_res_05.FP, tempo_res_05.FN, tempo_res_05.P, tempo_res_05.R, tempo_res_05.F, tempo_res_05.AD, tempo_res_05.DA, tempo_res_3.TP, tempo_res_3.FP, \
mitian@3 211 tempo_res_3.FN, tempo_res_3.P, tempo_res_3.R, tempo_res_3.F, tempo_res_3.AD, tempo_res_3.DA])
mitian@3 212
mitian@3 213 def writeCombinedHeader(self, filename):
mitian@3 214 '''Write header of output files for combined features.'''
mitian@3 215
mitian@3 216 with open(filename, 'a') as f:
mitian@3 217 csvwriter = csv.writer(f, delimiter=',')
mitian@3 218 csvwriter.writerow(['audio', 'gt_tb_P_0.5', 'gt_tb_R_0.5', 'gt_tb_F_0.5', 'gt_tb_P_3', 'gt_tb_R_3', 'gt_tb_F_3', 'gt_tp_P_0.5', 'gt_tp_R_0.5', 'gt_tp_F_0.5', 'gt_tp_P_3', 'gt_tp_R_3', 'gt_tp_F_3',\
mitian@4 219 'gt_hm_P_0.5', 'gt_hm_R_0.5', 'gt_hm_F_0.5', 'gt_hm_P_3', 'gt_hm_R_3', 'gt_hm_F_3', 'tb_tp_P_0.5', 'tb_tp_R_0.5', 'tb_tp_F_0.5', 'tb_tp_P_3', 'tb_tp_R_3', 'tb_tp_F_3', 'hm_tb_P_0.5', 'hm_tb_R_0.5', 'hm_tb_F_0.5', \
mitian@4 220 'hm_tb_P_3', 'hm_tb_R_3', 'hm_tb_F_3', 'hm_tp_P_0.5', 'hm_tp_R_0.5', 'hm_tp_F_0.5', 'hm_tp_P_3', 'hm_tp_R_3', 'hm_tp_F_3', 'gt_tb_tp_P_0.5', 'gt_tb_tp_R_0.5', 'gt_tb_tp_F_0.5', 'gt_tb_tp_P_3', 'gt_tb_tp_R_3', \
mitian@4 221 'gt_tb_tp_F_3', 'gt_hm_tb_P_0.5', 'gt_hm_tb_R_0.5', 'gt_hm_tb_F_0.5', 'gt_hm_tb_P_3', 'gt_hm_tb_R_3', 'gt_hm_tb_F_3', 'gt_hm_tp_P_0.5', 'gt_hm_tp_R_0.5', 'gt_hm_tp_F_0.5', 'gt_hm_tp_P_3', 'gt_hm_tp_R_3', 'gt_hm_tp_F_3', \
mitian@4 222 'hm_tb_tp_P_0.5', 'hm_tb_tp_R_0.5', 'hm_tb_tp_F_0.5', 'hm_tb_tp_P_3', 'hm_tb_tp_R_3', 'hm_tb_tp_F_3', 'gt_hm_tb_tp_P_0.5', 'gt_hm_tb_tp_R_0.5', 'gt_hm_tb_tp_F_0.5', 'gt_hm_tb_tp_P_3', 'gt_hm_tb_tp_R_3', 'gt_hm_tb_tp_F_3'])
mitian@3 223
mitian@4 224 def writeCombinedRes(self, filename, ao_name, gt_hm_res_05, gt_hm_res_3, gt_tb_res_05, gt_tb_res_3, gt_tp_res_05, gt_tp_res_3, hm_tb_res_05, hm_tb_res_3, hm_tp_res_05, hm_tp_res_3, \
mitian@4 225 tb_tp_res_05, tb_tp_res_3, gt_hm_tb_res_05, gt_hm_tb_res_3, gt_hm_tp_res_05, gt_hm_tp_res_3, gt_tb_tp_res_05, gt_tb_tp_res_3, hm_tb_tp_res_05, hm_tb_tp_res_3, gt_hm_tb_tp_res_05, gt_hm_tb_tp_res_3):
mitian@3 226 '''Write result of single detection for combined features.'''
mitian@3 227
mitian@3 228 with open(filename, 'a') as f:
mitian@3 229 csvwriter = csv.writer(f, delimiter=',')
mitian@3 230 csvwriter.writerow([ao_name, gt_tb_res_05.P, gt_tb_res_05.R, gt_tb_res_05.F, gt_tb_res_3.P, gt_tb_res_3.R, gt_tb_res_3.F, gt_tp_res_05.P, gt_tp_res_05.R, gt_tp_res_05.F, gt_tp_res_3.P, gt_tp_res_3.R, gt_tp_res_3.F, \
mitian@3 231 gt_hm_res_05.P, gt_hm_res_05.R, gt_hm_res_05.F, gt_hm_res_3.P, gt_hm_res_3.R, gt_hm_res_3.F, tb_tp_res_05.P, tb_tp_res_05.R, tb_tp_res_05.F, tb_tp_res_3.P, tb_tp_res_3.R, tb_tp_res_3.F, \
mitian@4 232 hm_tb_res_05.P, hm_tb_res_05.R, hm_tb_res_05.F, hm_tb_res_3.P, hm_tb_res_3.R, hm_tb_res_3.F, hm_tp_res_05.P, hm_tp_res_05.R, hm_tp_res_05.F, hm_tp_res_3.P, hm_tp_res_3.R, hm_tp_res_3.F, \
mitian@4 233 gt_tb_tp_res_05.P, gt_tb_tp_res_05.R, gt_tb_tp_res_05.F, gt_tb_tp_res_3.P, gt_tb_tp_res_3.R, gt_tb_tp_res_3.F, gt_hm_tb_res_05.P, gt_hm_tb_res_05.R, gt_hm_tb_res_05.F, gt_hm_tb_res_3.P, gt_hm_tb_res_3.R, gt_hm_tb_res_3.F, \
mitian@4 234 gt_hm_tp_res_05.P, gt_hm_tp_res_05.R, gt_hm_tp_res_05.F, gt_hm_tp_res_3.P, gt_hm_tp_res_3.R, gt_hm_tp_res_3.F, hm_tb_tp_res_05.P, hm_tb_tp_res_05.R, hm_tb_tp_res_05.F, hm_tb_tp_res_3.P, hm_tb_tp_res_3.R, hm_tb_tp_res_3.F, \
mitian@4 235 gt_hm_tb_tp_res_05.P, gt_hm_tb_tp_res_05.R, gt_hm_tb_tp_res_05.F, gt_hm_tb_tp_res_3.P, gt_hm_tb_tp_res_3.R, gt_hm_tb_tp_res_3.F])
mitian@3 236
mitian@4 237 def writeMergedHeader(self, filename):
mitian@4 238 '''Write header of output files merging individual detections.'''
mitian@4 239 with open(filename, 'a') as f:
mitian@4 240 csvwriter = csv.writer(f, delimiter=',')
mitian@4 241 csvwriter.writerow(['audio', 'merged_tp_05', 'merged_fp_05', 'merged_fn_05', 'merged_P_05', 'merged_R_05', 'merged_F_05', 'merged_AD_05', 'merged_DA_05', 'merged_tp_3', \
mitian@4 242 'merged_fp_3', 'merged_fn_3', 'merged_P_3', 'merged_R_3', 'merged_F_3', 'merged_AD_3', 'merged_DA_3'])
mitian@4 243
mitian@4 244 def writeMergedRes(self, filename, ao_name, merged_res_05, merged_res_3):
mitian@4 245 '''Write results by merging individual detections.'''
mitian@4 246 with open(filename, 'a') as f:
mitian@4 247 csvwriter = csv.writer(f, delimiter=',')
mitian@4 248 csvwriter.writerow([ao_name, merged_res_05.TP, merged_res_05.FP, merged_res_05.FN, merged_res_05.P, merged_res_05.R, merged_res_05.F, merged_res_05.AD, merged_res_05.DA, \
mitian@4 249 merged_res_3.TP, merged_res_3.FP, merged_res_3.FN, merged_res_3.P, merged_res_3.R, merged_res_3.F, merged_res_3.AD, merged_res_3.DA])
mitian@4 250
mitian@4 251
mi@0 252 def process(self):
mi@0 253 '''For the aggregated input features, discard a propertion each time as the pairwise distances within the feature space descending.
mi@0 254 In the meanwhile evaluate the segmentation result and track the trend of perfomance changing by measuring the feature selection
mi@0 255 threshold - segmentation f measure curve.
mi@0 256 '''
mi@0 257
mi@0 258 peak_picker = PeakPicker()
mi@0 259 peak_picker.params.alpha = 9.0 # Alpha norm
mi@0 260 peak_picker.params.delta = self.delta_threshold # Adaptive thresholding delta
mi@0 261 peak_picker.params.QuadThresh_a = (100 - self.threshold) / 1000.0
mi@0 262 peak_picker.params.QuadThresh_b = 0.0
mi@0 263 peak_picker.params.QuadThresh_c = (100 - self.threshold) / 1500.0
mi@0 264 peak_picker.params.rawSensitivity = 20
mi@0 265 peak_picker.params.aCoeffs = self.aCoeffs
mi@0 266 peak_picker.params.bCoeffs = self.bCoeffs
mi@0 267 peak_picker.params.preWin = self.medianWin
mi@0 268 peak_picker.params.postWin = self.medianWin + 1
mi@0 269 peak_picker.params.LP_on = self.LPfilter_on
mi@0 270 peak_picker.params.Medfilt_on = self.medfilter_on
mi@0 271 peak_picker.params.Polyfit_on = self.polyfitting_on
mi@0 272 peak_picker.params.isMedianPositive = False
mi@0 273
mi@0 274 # Settings used for feature extraction
mi@0 275 feature_window_frame = int(self.SampleRate / self.gammatoneLen * self.featureWindow)
mi@0 276 feature_step_frame = int(0.5 * self.SampleRate / self.gammatoneLen * self.featureStep)
mi@0 277 aggregation_window, aggregation_step = 100, 50
mi@0 278 featureRate = float(self.SampleRate) / self.stepSize
mi@0 279
mi@0 280 audio_files = [x for x in os.listdir(options.GT) if not x.startswith(".") ]
mitian@4 281 if options.TEST:
mitian@4 282 audio_files = audio_files[:1]
mi@0 283 audio_files.sort()
mi@0 284 audio_list = []
mi@0 285
mi@0 286 gammatone_feature_list = [i for i in os.listdir(options.GF) if not i.startswith('.')]
mitian@4 287 gammatone_feature_list = ['contrast6', 'rolloff4', 'dct']
mi@0 288 tempo_feature_list = [i for i in os.listdir(options.TF) if not i.startswith('.')]
mitian@4 289 tempo_feature_list = ['ti', 'tir']
mitian@4 290 timbre_feature_list = ['mfcc_harmonic']
mitian@4 291 harmonic_feature_list = ['chromagram']
mi@0 292
mi@0 293 gammatone_feature_list = [join(options.GF, f) for f in gammatone_feature_list]
mi@0 294 timbre_feature_list = [join(options.SF, f) for f in timbre_feature_list]
mi@0 295 tempo_feature_list = [join(options.TF, f) for f in tempo_feature_list]
mi@0 296 harmonic_feature_list = [join(options.SF, f) for f in harmonic_feature_list]
mi@0 297
mi@0 298 fobj_list = []
mi@0 299
mi@0 300 # For each audio file, load specific features
mi@0 301 for audio in audio_files:
mi@0 302 ao = AudioObj()
mi@0 303 ao.name = splitext(audio)[0]
mitian@5 304 annotation_file = join(options.GT, ao.name+'.txt') # iso, salami
mitian@5 305 ao.gt = np.genfromtxt(annotation_file, usecols=0)
mitian@5 306 ao.label = np.genfromtxt(annotation_file, usecols=1, dtype=str)
mitian@5 307 # annotation_file = join(options.GT, ao.name+'.csv') # qupujicheng
mitian@5 308 # ao.gt = np.genfromtxt(annotation_file, usecols=0, delimiter=',')
mitian@5 309 # ao.label = np.genfromtxt(annotation_file, usecols=1, delimiter=',', dtype=str)
mi@0 310
mi@0 311 gammatone_featureset, timbre_featureset, tempo_featureset, harmonic_featureset = [], [], [], []
mi@0 312 for feature in gammatone_feature_list:
mi@0 313 for f in os.listdir(feature):
mi@0 314 if f[:f.find('_vamp')]==ao.name:
mi@0 315 gammatone_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
mi@0 316 break
mi@0 317 if len(gammatone_feature_list) > 1:
mi@0 318 n_frame = np.min([x.shape[0] for x in gammatone_featureset])
mi@0 319 gammatone_featureset = [x[:n_frame,:] for x in gammatone_featureset]
mi@0 320 ao.gammatone_features = np.hstack((gammatone_featureset))
mi@0 321 else:
mi@0 322 ao.gammatone_features = gammatone_featureset[0]
mi@0 323
mi@0 324 for feature in timbre_feature_list:
mi@0 325 for f in os.listdir(feature):
mi@0 326 if f[:f.find('_vamp')]==ao.name:
mi@0 327 timbre_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
mi@0 328 break
mi@0 329 if len(timbre_feature_list) > 1:
mi@0 330 n_frame = np.min([x.shape[0] for x in timbre_featureset])
mi@0 331 timbre_featureset = [x[:n_frame,:] for x in timbre_featureset]
mi@0 332 ao.timbre_features = np.hstack((timbre_featureset))
mi@0 333 else:
mi@0 334 ao.timbre_features = timbre_featureset[0]
mi@0 335 for feature in tempo_feature_list:
mi@0 336 for f in os.listdir(feature):
mi@0 337 if f[:f.find('_vamp')]==ao.name:
mi@0 338 tempo_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,1:])
mi@0 339 ao.tempo_timestamps = np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,0]
mi@0 340 break
mi@0 341 if len(tempo_feature_list) > 1:
mi@0 342 n_frame = np.min([x.shape[0] for x in tempo_featureset])
mi@0 343 tempo_featureset = [x[:n_frame,:] for x in tempo_featureset]
mi@0 344 ao.tempo_features = np.hstack((tempo_featureset))
mi@0 345 else:
mi@0 346 ao.tempo_features = tempo_featureset[0]
mi@0 347 for feature in harmonic_feature_list:
mi@0 348 for f in os.listdir(feature):
mi@0 349 if f[:f.find('_vamp')]==ao.name:
mi@0 350 harmonic_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
mi@0 351 break
mi@0 352 if len(harmonic_feature_list) > 1:
mi@0 353 n_frame = np.min([x.shape[0] for x in harmonic_featureset])
mi@0 354 harmonic_featureset = [x[:n_frame,:] for x in harmonic_featureset]
mi@0 355 ao.harmonic_features = np.hstack((harmonic_featureset))
mi@0 356 else:
mi@0 357 ao.harmonic_features = harmonic_featureset[0]
mi@0 358
mi@0 359 # Get aggregated features for computing ssm
mi@0 360 aggregation_window, aggregation_step = 1,1
mi@0 361 featureRate = float(self.SampleRate) /self.stepSize
mi@0 362 pca = PCA(n_components=5)
mi@0 363
mi@0 364 # Resample and normalise features
mitian@4 365 step = ao.tempo_features.shape[0]
mi@0 366 ao.gammatone_features = resample(ao.gammatone_features, step)
mi@0 367 ao.gammatone_features = normaliseFeature(ao.gammatone_features)
mi@0 368 ao.timbre_features = resample(ao.timbre_features, step)
mi@0 369 ao.timbre_features = normaliseFeature(ao.timbre_features)
mi@0 370 ao.harmonic_features = resample(ao.harmonic_features, step)
mi@0 371 ao.harmonic_features = normaliseFeature(ao.harmonic_features)
mitian@4 372 ao.tempo_features = normaliseFeature(ao.tempo_features)
mi@0 373
mi@0 374 pca.fit(ao.gammatone_features)
mi@0 375 ao.gammatone_features = pca.transform(ao.gammatone_features)
mi@0 376 ao.gammatone_ssm = getSSM(ao.gammatone_features)
mi@0 377
mi@0 378 pca.fit(ao.tempo_features)
mi@0 379 ao.tempo_features = pca.transform(ao.tempo_features)
mi@0 380 ao.tempo_ssm = getSSM(ao.tempo_features)
mi@0 381
mi@0 382 pca.fit(ao.timbre_features)
mi@0 383 ao.timbre_features = pca.transform(ao.timbre_features)
mi@0 384 ao.timbre_ssm = getSSM(ao.timbre_features)
mi@0 385
mi@0 386 pca.fit(ao.harmonic_features)
mi@0 387 ao.harmonic_features = pca.transform(ao.harmonic_features)
mi@0 388 ao.harmonic_ssm = getSSM(ao.harmonic_features)
mi@0 389
mi@0 390 ao.ssm_timestamps = np.array(map(lambda x: ao.tempo_timestamps[aggregation_step*x], np.arange(0, ao.gammatone_ssm.shape[0])))
mi@0 391
mi@0 392 audio_list.append(ao)
mi@0 393
mitian@3 394 # Prepare output files.
mitian@3 395 outfile1 = join(options.OUTPUT, 'individual_novelty.csv')
mitian@3 396 outfile2 = join(options.OUTPUT, 'individual_foote.csv')
mitian@3 397 outfile3 = join(options.OUTPUT, 'individual_sf.csv')
mitian@3 398 outfile4 = join(options.OUTPUT, 'individual_cnmf.csv')
mitian@3 399
mitian@3 400 outfile5 = join(options.OUTPUT, 'combined_novelty.csv')
mitian@3 401 outfile6 = join(options.OUTPUT, 'combined_foote.csv')
mitian@3 402 outfile7 = join(options.OUTPUT, 'combined_sf.csv')
mitian@3 403 outfile8 = join(options.OUTPUT, 'combined_cnmf.csv')
mitian@3 404
mitian@4 405 outfile9 = join(options.OUTPUT, 'individual_merged.csv')
mitian@4 406
mitian@4 407 self.writeIndividualHeader(outfile1)
mitian@4 408 self.writeIndividualHeader(outfile2)
mitian@4 409 self.writeIndividualHeader(outfile3)
mitian@4 410 self.writeIndividualHeader(outfile4)
mitian@3 411
mitian@4 412 # self.writeCombinedHeader(outfile5)
mitian@4 413 # self.writeCombinedHeader(outfile6)
mitian@4 414 self.writeCombinedHeader(outfile7)
mitian@4 415 self.writeCombinedHeader(outfile8)
mitian@4 416
mitian@4 417 self.writeMergedHeader(outfile9)
mitian@3 418
mi@0 419 print 'Segmenting using %s method' %options.BOUNDARY
mi@0 420 for i,ao in enumerate(audio_list):
mi@0 421 print 'processing: %s' %ao.name
mitian@3 422
mitian@3 423 ############################################################################################################################################
mitian@3 424 # Experiment 1: segmentation using individual features.
mitian@3 425
mitian@3 426 gammatone_novelty, smoothed_gammatone_novelty, gammatone_novelty_idxs = novelty_S.process(ao.gammatone_ssm, self.kernel_size, peak_picker)
mitian@3 427 timbre_novelty, smoothed_timbre_novelty, timbre_novelty_idxs = novelty_S.process(ao.timbre_ssm, self.kernel_size, peak_picker)
mitian@7 428 tempo_novelty, smoothed_tempo_novelty, tempo_novelty_idxs = novelty_S.process(ao.tempo_ssm, self.kernel_size, peak_picker)
mitian@7 429 harmonic_novelty, smoothed_harmonic_novelty, harmonic_novelty_idxs = novelty_S.process(ao.harmonic_ssm, self.kernel_size, peak_picker)
mitian@3 430
mitian@3 431 gammatone_cnmf_idxs = cnmf_S.segmentation(ao.gammatone_features, rank=rank, R=R, h=h, niter=300)
mitian@3 432 timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)
mitian@3 433 tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)
mitian@3 434 harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)
mitian@3 435
mitian@3 436 gammatone_foote_idxs = foote_S.segmentation(ao.gammatone_features, M=M, Mg=Mg, L=L)
mitian@3 437 timbre_foote_idxs = foote_S.segmentation(ao.timbre_features, M=M, Mg=Mg, L=L)
mitian@3 438 tempo_foote_idxs = foote_S.segmentation(ao.tempo_features, M=M, Mg=Mg, L=L)
mitian@3 439 harmonic_foote_idxs = foote_S.segmentation(ao.harmonic_features, M=M, Mg=Mg, L=L)
mitian@3 440
mitian@3 441 gammatone_sf_idxs = sf_S.segmentation(ao.gammatone_features)
mitian@3 442 timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
mitian@3 443 tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
mitian@3 444 harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
mitian@1 445
mitian@3 446 # Evaluate and write results.
mitian@3 447 gt_novelty_05 = self.pairwiseF(ao.gt, gammatone_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 448 gt_novelty_3 = self.pairwiseF(ao.gt, gammatone_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 449 harmonic_novelty_05 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 450 harmonic_novelty_3 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 451 tempo_novelty_05 = self.pairwiseF(ao.gt, tempo_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 452 tempo_novelty_3 = self.pairwiseF(ao.gt, tempo_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 453 timbre_novelty_05 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 454 timbre_novelty_3 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mi@0 455
mitian@3 456 gt_cnmf_05 = self.pairwiseF(ao.gt, gammatone_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 457 gt_cnmf_3 = self.pairwiseF(ao.gt, gammatone_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 458 harmonic_cnmf_05 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 459 harmonic_cnmf_3 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 460 tempo_cnmf_05 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 461 tempo_cnmf_3 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 462 timbre_cnmf_05 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 463 timbre_cnmf_3 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 464
mitian@3 465 gt_sf_05 = self.pairwiseF(ao.gt, gammatone_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 466 gt_sf_3 = self.pairwiseF(ao.gt, gammatone_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 467 harmonic_sf_05 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 468 harmonic_sf_3 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 469 tempo_sf_05 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 470 tempo_sf_3 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 471 timbre_sf_05 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 472 timbre_sf_3 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 473
mitian@3 474 gt_foote_05 = self.pairwiseF(ao.gt, gammatone_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 475 gt_foote_3 = self.pairwiseF(ao.gt, gammatone_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 476 harmonic_foote_05 = self.pairwiseF(ao.gt, harmonic_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 477 harmonic_foote_3 = self.pairwiseF(ao.gt, harmonic_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 478 tempo_foote_05 = self.pairwiseF(ao.gt, tempo_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 479 tempo_foote_3 = self.pairwiseF(ao.gt, tempo_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 480 timbre_foote_05 = self.pairwiseF(ao.gt, timbre_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 481 timbre_foote_3 = self.pairwiseF(ao.gt, timbre_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@1 482
mitian@5 483 self.writeIndividualRes(outfile1, ao.name, gt_novelty_05, gt_novelty_3, harmonic_novelty_05, harmonic_novelty_3, tempo_novelty_05, tempo_novelty_3, timbre_novelty_05, timbre_novelty_3)
mitian@5 484 self.writeIndividualRes(outfile2, ao.name, gt_cnmf_05, gt_cnmf_3, harmonic_cnmf_05, harmonic_cnmf_3, tempo_cnmf_05, tempo_cnmf_3, timbre_cnmf_05, timbre_cnmf_3)
mitian@5 485 self.writeIndividualRes(outfile3, ao.name, gt_sf_05, gt_sf_3, harmonic_sf_05, harmonic_sf_3, tempo_sf_05, tempo_sf_3, timbre_sf_05, timbre_sf_3)
mitian@5 486 self.writeIndividualRes(outfile4, ao.name, gt_foote_05, gt_foote_3, harmonic_foote_05, harmonic_foote_3, tempo_foote_05, tempo_foote_3, timbre_foote_05, timbre_foote_3)
mitian@1 487
mitian@1 488
mitian@3 489 ############################################################################################################################################
mitian@3 490 # Experiment 2: segmentation using combined features.
mi@2 491
mitian@3 492 # Dumping features.
mitian@3 493 gt_hm = np.hstack([ao.gammatone_features, ao.harmonic_features])
mitian@3 494 gt_tb = np.hstack([ao.gammatone_features, ao.timbre_features])
mitian@3 495 gt_tp = np.hstack([ao.gammatone_features, ao.tempo_features])
mitian@3 496 hm_tb = np.hstack([ao.harmonic_features, ao.timbre_features])
mitian@3 497 hm_tp = np.hstack([ao.harmonic_features, ao.tempo_features])
mitian@3 498 tb_tp = np.hstack([ao.timbre_features, ao.tempo_features])
mitian@4 499 gt_hm_tb = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.timbre_features])
mitian@3 500 gt_hm_tp = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.tempo_features])
mitian@3 501 gt_tb_tp = np.hstack([ao.gammatone_features, ao.timbre_features, ao.tempo_features])
mitian@3 502 hm_tb_tp = np.hstack([ao.harmonic_features, ao.timbre_features, ao.tempo_features])
mitian@3 503 gt_hm_tb_tp = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.timbre_features, ao.tempo_features])
mitian@3 504
mitian@4 505 # Evaluting and writing results.
mitian@3 506 gt_hm_sf_idxs = sf_S.segmentation(gt_hm)
mitian@3 507 gt_tb_sf_idxs = sf_S.segmentation(gt_tb)
mitian@3 508 gt_tp_sf_idxs = sf_S.segmentation(gt_tp)
mitian@3 509 hm_tb_sf_idxs = sf_S.segmentation(hm_tb)
mitian@3 510 hm_tp_sf_idxs = sf_S.segmentation(hm_tp)
mitian@3 511 tb_tp_sf_idxs = sf_S.segmentation(tb_tp)
mitian@3 512 gt_hm_tb_sf_idxs = sf_S.segmentation(gt_hm_tb)
mitian@3 513 gt_hm_tp_sf_idxs = sf_S.segmentation(gt_hm_tp)
mitian@3 514 gt_tb_tp_sf_idxs = sf_S.segmentation(gt_tb_tp)
mitian@3 515 hm_tb_tp_sf_idxs = sf_S.segmentation(hm_tb_tp)
mitian@3 516 gt_hm_tb_tp_sf_idxs = sf_S.segmentation(gt_hm_tb_tp)
mitian@3 517
mitian@4 518 gt_hm_cnmf_idxs = cnmf_S.segmentation(gt_hm, rank=4, R=R, h=h, niter=300)
mitian@4 519 gt_tb_cnmf_idxs = cnmf_S.segmentation(gt_tb, rank=4, R=R, h=h, niter=300)
mitian@4 520 gt_tp_cnmf_idxs = cnmf_S.segmentation(gt_tp, rank=4, R=R, h=h, niter=300)
mitian@4 521 hm_tb_cnmf_idxs = cnmf_S.segmentation(hm_tb, rank=4, R=R, h=h, niter=300)
mitian@4 522 hm_tp_cnmf_idxs = cnmf_S.segmentation(hm_tp, rank=4, R=R, h=h, niter=300)
mitian@4 523 tb_tp_cnmf_idxs = cnmf_S.segmentation(tb_tp, rank=4, R=R, h=h, niter=300)
mitian@4 524 gt_hm_tb_cnmf_idxs = cnmf_S.segmentation(gt_hm_tb, rank=6, R=R, h=h, niter=300)
mitian@4 525 gt_hm_tp_cnmf_idxs = cnmf_S.segmentation(gt_hm_tp, rank=6, R=R, h=h, niter=300)
mitian@4 526 gt_tb_tp_cnmf_idxs = cnmf_S.segmentation(gt_tb_tp, rank=6, R=R, h=h, niter=300)
mitian@4 527 hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(hm_tb_tp, rank=6, R=R, h=h, niter=300)
mitian@4 528 gt_hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(gt_hm_tb_tp, rank=8, R=R, h=h, niter=300)
mitian@3 529
mitian@4 530 gt_hm_sf_05 = self.pairwiseF(ao.gt, gt_hm_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 531 gt_tb_sf_05 = self.pairwiseF(ao.gt, gt_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 532 gt_tp_sf_05 = self.pairwiseF(ao.gt, gt_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 533 hm_tb_sf_05 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 534 hm_tp_sf_05 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 535 tb_tp_sf_05 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 536 gt_hm_tb_sf_05 = self.pairwiseF(ao.gt, gt_hm_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 537 gt_hm_tp_sf_05 = self.pairwiseF(ao.gt, gt_hm_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 538 gt_tb_tp_sf_05 = self.pairwiseF(ao.gt, gt_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 539 hm_tb_tp_sf_05 = self.pairwiseF(ao.gt, hm_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 540 gt_hm_tb_tp_sf_05 = self.pairwiseF(ao.gt, gt_hm_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 541
mitian@4 542 gt_hm_sf_3 = self.pairwiseF(ao.gt, gt_hm_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 543 gt_tb_sf_3 = self.pairwiseF(ao.gt, gt_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 544 gt_tp_sf_3 = self.pairwiseF(ao.gt, gt_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 545 hm_tb_sf_3 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 546 hm_tp_sf_3 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 547 tb_tp_sf_3 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 548 gt_hm_tb_sf_3 = self.pairwiseF(ao.gt, gt_hm_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 549 gt_hm_tp_sf_3 = self.pairwiseF(ao.gt, gt_hm_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 550 gt_tb_tp_sf_3 = self.pairwiseF(ao.gt, gt_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 551 hm_tb_tp_sf_3 = self.pairwiseF(ao.gt, hm_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 552 gt_hm_tb_tp_sf_3 = self.pairwiseF(ao.gt, gt_hm_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 553
mitian@4 554 gt_hm_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 555 gt_tb_cnmf_05 = self.pairwiseF(ao.gt, gt_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 556 gt_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 557 hm_tb_cnmf_05 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 558 hm_tp_cnmf_05 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 559 tb_tp_cnmf_05 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 560 gt_hm_tb_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 561 gt_hm_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 562 gt_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 563 hm_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, hm_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 564 gt_hm_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 565
mitian@4 566 gt_hm_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 567 gt_tb_cnmf_3 = self.pairwiseF(ao.gt, gt_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 568 gt_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 569 hm_tb_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 570 hm_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 571 tb_tp_cnmf_3 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 572 gt_hm_tb_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 573 gt_hm_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 574 gt_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 575 hm_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 576 gt_hm_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@3 577
mitian@4 578 self.writeCombinedRes(outfile7, ao.name, gt_hm_sf_05, gt_hm_sf_3, gt_tb_sf_05, gt_tb_sf_3, gt_tp_sf_05, gt_tp_sf_3, hm_tb_sf_05, hm_tb_sf_3, hm_tp_sf_05, hm_tp_sf_3, tb_tp_sf_05, tb_tp_sf_3,\
mitian@4 579 gt_hm_tb_sf_05, gt_hm_tb_sf_3, gt_hm_tp_sf_05, gt_hm_tp_sf_3, gt_tb_tp_sf_05, gt_tb_tp_sf_3, hm_tb_tp_sf_05, hm_tb_tp_sf_3, gt_hm_tb_tp_sf_05, gt_hm_tb_tp_sf_3)
mitian@4 580
mitian@4 581 self.writeCombinedRes(outfile8, ao.name, gt_hm_cnmf_05, gt_hm_cnmf_3, gt_tb_cnmf_05, gt_tb_cnmf_3, gt_tp_cnmf_05, gt_tp_cnmf_3, hm_tb_cnmf_05, hm_tb_cnmf_3, hm_tp_cnmf_05, hm_tp_cnmf_3, tb_tp_cnmf_05, tb_tp_cnmf_3,\
mitian@4 582 gt_hm_tb_cnmf_05, gt_hm_tb_cnmf_3, gt_hm_tp_cnmf_05, gt_hm_tp_cnmf_3, gt_tb_tp_cnmf_05, gt_tb_tp_cnmf_3, hm_tb_tp_cnmf_05, hm_tb_tp_cnmf_3, gt_hm_tb_tp_cnmf_05, gt_hm_tb_tp_cnmf_3)
mitian@3 583
mitian@3 584 ############################################################################################################################################
mitian@3 585 # Experiment 3: Pruning boundaries detected by individual boundary algorithms.
mitian@3 586
mitian@4 587 # Use different boundary methods for different features
mitian@4 588 gammatone_idxs, harmonic_idxs, timbre_idxs, tempo_idxs = gammatone_sf_idxs, harmonic_sf_idxs, timbre_sf_idxs, tempo_sf_idxs
mitian@4 589 bound_candidates = list(gammatone_idxs) + list(harmonic_idxs) + list(timbre_idxs) + list(tempo_idxs)
mitian@4 590 bound_candidates.sort()
mitian@4 591
mitian@4 592 nBounds = len(bound_candidates)
mitian@4 593 final_idxs = []
mitian@4 594 idx = 0
mitian@4 595 tol = 10 # tolerance window of merging boundary scores
mitian@4 596 while idx < nBounds:
mitian@4 597 temp = [bound_candidates[idx]]
mitian@4 598 pos = [idx]
mitian@4 599 idx += 1
mitian@4 600 while (idx + tol < nBounds and np.max(bound_candidates[idx: idx+tol]) > 0):
mitian@4 601 temp += [bound_candidates[idx+delta] for delta in xrange(tol) if (bound_candidates[idx]+delta in bound_candidates)]
mitian@4 602 pos += [idx+delta for delta in xrange(tol) if (bound_candidates[idx]+delta in bound_candidates)]
mitian@4 603 idx += tol
mitian@4 604 if len(temp) == 1:
mitian@4 605 final_idxs.append(temp[0])
mitian@4 606 else:
mitian@4 607 final_idxs.append(int(np.rint(np.mean(temp))))
mitian@4 608
mitian@4 609 merged_05 = self.pairwiseF(ao.gt, final_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 610 merged_3 = self.pairwiseF(ao.gt, final_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
mitian@4 611
mitian@4 612 self.writeMergedRes(outfile9, ao.name, merged_05, merged_3)
mitian@4 613
mitian@3 614 # if options.BOUNDARY == 'novelty':
mitian@3 615 # gammatone_novelty, smoothed_gammatone_novelty, gammatone_bound_idxs = novelty_S.process(ao.gammatone_ssm, self.kernel_size, peak_picker)
mitian@3 616 # timbre_novelty, smoothed_timbre_novelty, timbre_bound_idxs = novelty_S.process(ao.timbre_ssm, self.kernel_size, peak_picker)
mitian@3 617 # tempo_novelty, smoothed_harmonic_novelty, tempo_bound_idxs = novelty_S.process(ao.tempo_ssm, self.kernel_size, peak_picker)
mitian@3 618 # harmonic_novelty, smoothed_tempo_novelty, harmonic_bound_idxs = novelty_S.process(ao.harmonic_ssm, self.kernel_size, peak_picker)
mitian@3 619 #
mitian@3 620 # if options.BOUNDARY == 'cnmf':
mitian@3 621 # gammatone_cnmf_idxs = cnmf_S.segmentation(ao.gammatone_features, rank=rank, R=R, h=8, niter=300)
mitian@3 622 # timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)
mitian@3 623 # tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)
mitian@3 624 # harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)
mitian@3 625 #
mitian@3 626 # if options.BOUNDARY == 'foote':
mitian@3 627 # gammatone_foote_idxs = foote_S.segmentation(ao.gammatone_features, M=M, Mg=Mg, L=L)
mitian@3 628 # timbre_foote_idxs = foote_S.segmentation(ao.timbre_features, M=M, Mg=Mg, L=L)
mitian@3 629 # tempo_foote_idxs = foote_S.segmentation(ao.tempo_features, M=M, Mg=Mg, L=L)
mitian@3 630 # harmonic_foote_idxs = foote_S.segmentation(ao.harmonic_features, M=M, Mg=Mg, L=L)
mitian@3 631 #
mitian@3 632 # if options.BOUNDARY == 'sf':
mitian@3 633 # gammatone_sf_idxs = sf_S.segmentation(ao.gammatone_features)
mitian@3 634 # timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
mitian@3 635 # tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
mitian@3 636 # harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
mitian@3 637 #
mitian@3 638 # gammatone_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_novelty_peaks]
mitian@3 639 # timbre_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_novelty_peaks]
mitian@3 640 # harmonic_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_novelty_peaks]
mitian@3 641 # tempo_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_novelty_peaks]
mitian@3 642 #
mitian@3 643 # gammatone_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_cnmf_peaks]
mitian@3 644 # timbre_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_cnmf_peaks]
mitian@3 645 # harmonic_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_cnmf_peaks]
mitian@3 646 # tempo_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_cnmf_peaks]
mitian@3 647 #
mitian@3 648 # gammatone_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_sf_peaks]
mitian@3 649 # timbre_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_sf_peaks]
mitian@3 650 # harmonic_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_sf_peaks]
mitian@3 651 # tempo_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_sf_peaks]
mitian@3 652 #
mitian@3 653 # gammatone_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_foote_peaks]
mitian@3 654 # timbre_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_foote_peaks]
mitian@3 655 # harmonic_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_foote_peaks]
mitian@3 656 # tempo_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_foote_peaks]
mitian@3 657 #
mitian@3 658 # # Experiment 2: Trying combined features using the best boundary retrieval method
mitian@3 659 # ao_featureset = [ao.gammatone_features, ao.harmonic_features, ao.timbre_features, ao.tempo_features]
mitian@3 660 # feature_sel = [int(x) for x in options.FEATURES if x.isdigit()]
mitian@3 661 # fused_featureset = [ao_featureset[i] for i in feature_sel]
mitian@3 662
mitian@3 663 # if options.LABEL == 'fmc2d':
mitian@3 664 # gammatone_fmc2d_labels = fmc2d_S.compute_similarity(gammatone_bound_idxs, xmeans=True, N=N)
mitian@3 665 # timbre_fmc2d_labels = fmc2d_S.compute_similarity(timbre_bound_idxs, xmeans=True, N=N)
mitian@3 666 # tempo_fmc2d_labels = fmc2d_S.compute_similarity(tempo_bound_idxs, xmeans=True, N=N)
mitian@3 667 # harmonic_fmc2d_labels = fmc2d_S.compute_similarity(harmonic_bound_idxs, xmeans=True, N=N)
mitian@3 668 #
mitian@3 669 # if options.LABEL == 'cnmf':
mitian@3 670 # gammatone_cnmf_labels = cnmf_S.compute_labels(gammatone_bound_idxs, est_bound_idxs, nFrames)
mitian@3 671 # timbre_cnmf_labels = cnmf_S.compute_labels(timbre_bound_idxs, est_bound_idxs, nFrames)
mitian@3 672 # tempo_cnmf_labels = cnmf_S.compute_labels(tempo_bound_idxs, est_bound_idxs, nFrames)
mitian@3 673 # harmonic_cnmf_labels = cnmf_S.compute_labels(harmonic_bound_idxs, est_bound_idxs, nFrames)
mitian@3 674 #
mitian@3 675 #
mitian@3 676
mi@0 677
mi@0 678
mi@0 679 def main():
mi@0 680
mi@0 681 segmenter = SSMseg()
mi@0 682 segmenter.process()
mi@0 683
mi@0 684
mi@0 685 if __name__ == '__main__':
mi@0 686 main()
mi@0 687