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
|
mitian@18
|
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 sklearn.decomposition import PCA
|
mi@0
|
26 from sklearn.mixture import GMM
|
mi@0
|
27 from sklearn.cluster import KMeans
|
mi@0
|
28 from sklearn.preprocessing import normalize
|
mi@0
|
29 from sklearn.metrics.pairwise import pairwise_distances
|
mi@0
|
30
|
mi@0
|
31 # Load dependencies
|
mitian@18
|
32 from utils.SegUtil import getMean, getStd, getDelta, getSSM, reduceSSM, upSample, normaliseFeature, normaliseArray
|
mi@0
|
33 from utils.PeakPickerUtil import PeakPicker
|
mi@0
|
34 from utils.gmmdist import *
|
mi@0
|
35 from utils.GmmMetrics import GmmDistance
|
mi@0
|
36 from utils.RankClustering import rClustering
|
mi@0
|
37 from utils.kmeans import Kmeans
|
mitian@18
|
38 # from utils.PathTracker import PathTracker
|
mitian@10
|
39 from utils.OnsetPlotProc import onset_plot, plot_on
|
mi@0
|
40
|
mi@0
|
41 # Load bourdary retrieval utilities
|
mi@0
|
42 import cnmf as cnmf_S
|
mi@0
|
43 import foote as foote_S
|
mi@0
|
44 import sf as sf_S
|
mi@0
|
45 import fmc2d as fmc2d_S
|
mitian@1
|
46 import novelty as novelty_S
|
mitian@1
|
47
|
mitian@1
|
48 # Algorithm params
|
mitian@18
|
49 # cnmf
|
mitian@1
|
50 h = 8 # Size of median filter for features in C-NMF
|
mitian@18
|
51 R = 12 # Size of the median filter for the activation matrix C-NMF
|
mitian@18
|
52 rank = 4 # Rank of decomposition for the boundaries
|
mitian@14
|
53 rank_labels = 16 # Rank of decomposition for the labels
|
mitian@14
|
54 R_labels = 4 # 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('-a', '--annotations', action="store", dest="GT", default='/Volumes/c4dm-03/people/mit/annotation/qupujicheng/lowercase', type="str", help="Loading annotation files from.. ")
|
mi@0
|
71 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 ")
|
mitian@18
|
72 op.add_option('-d', '--dataset', action="store", dest="DATASET", default='qupujicheng', type="str", help="Specify datasets")
|
mi@0
|
73
|
mitian@18
|
74 # parameterization 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')." )
|
mitian@18
|
77 op.add_option('-x', '--experiment', action="store", dest="EXPERIMENT", type='choice', choices=['all', 'individual', 'fuse_feature', 'fuse_ssm', 'fuse_novelty', 'fuse_bounds'], default='all', help="Specify experiment to execute." )
|
mi@0
|
78
|
mi@0
|
79 # Plot/print/mode options
|
mi@0
|
80 op.add_option('-p', '--plot', action="store_true", dest="PLOT", default=False, help="Save plots")
|
mi@0
|
81 op.add_option('-e', '--test-mode', action="store_true", dest="TEST", default=False, help="Test mode")
|
mi@0
|
82 op.add_option('-v', '--verbose-mode', action="store_true", dest="VERBOSE", default=False, help="Print results in verbose mode.")
|
mitian@18
|
83
|
mi@0
|
84 return op.parse_args()
|
mi@0
|
85 options, args = parse_args()
|
mi@0
|
86
|
mi@0
|
87 class FeatureObj() :
|
mi@0
|
88 __slots__ = ['key', 'audio', 'timestamps', 'gammatone_features', 'tempo_features', 'timbre_features', 'harmonic_features', 'gammatone_ssm', 'tempo_ssm', 'timbre_features', 'harmonic_ssm', 'ssm_timestamps']
|
mi@0
|
89
|
mi@0
|
90 class AudioObj():
|
mi@0
|
91 __slots__ = ['name', 'feature_list', 'gt', 'label', 'gammatone_features', 'tempo_features', 'timbre_features', 'harmonic_features', 'combined_features',\
|
mitian@18
|
92 'gammatone_ssm', 'tempo_ssm', 'timbre_ssm', 'harmonic_ssm', 'combined_ssm', 'ssm', 'ssm_timestamps', 'timestamps']
|
mi@0
|
93
|
mi@0
|
94 class EvalObj():
|
mitian@18
|
95 __slots__ = ['TP', 'FP', 'FN', 'P', 'R', 'F', 'AD', 'DA', 'detection']
|
mi@0
|
96
|
mi@0
|
97
|
mi@0
|
98 class SSMseg(object):
|
mi@0
|
99 '''The main segmentation object'''
|
mi@0
|
100 def __init__(self):
|
mitian@18
|
101 self.SampleRate = 44100.0
|
mi@0
|
102 self.NqHz = self.SampleRate/2
|
mi@0
|
103 self.previousSample = 0.0
|
mi@0
|
104 self.featureWindow = 6.0
|
mi@0
|
105 self.featureStep = 3.0
|
mitian@18
|
106 self.kernel_size = 100 # Adjust this param according to the feature resolution.pq
|
mitian@18
|
107 self.blockSize = 2048.0
|
mitian@18
|
108 self.stepSize = 1024.0
|
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@18
|
126 self.threshold = 10
|
mitian@18
|
127 self.confidence_threshold = 0.4
|
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
|
mitian@18
|
133 self.whitening_on = True
|
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
|
mitian@18
|
137 self.medianWin = 10
|
mitian@18
|
138 self.lin = 0.5
|
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@18
|
152 if idx2time != None:
|
mitian@18
|
153 # Map detected idxs to real time
|
mitian@18
|
154 detection.sort()
|
mitian@18
|
155 if detection[-1] >= len(idx2time):
|
mitian@18
|
156 detection = detection[:-len(np.array(detection)[np.array(detection)-len(idx2time)>=0])]
|
mitian@18
|
157 detection = [idx2time[int(i)] for i in detection]
|
mitian@18
|
158 detection = np.append(detection, annotation[-1])
|
mitian@18
|
159 res.detection = detection
|
mitian@18
|
160
|
mitian@5
|
161 gt = len(annotation) # Total number of ground truth data points
|
mitian@5
|
162 dt = len(detection) # Total number of experimental data points
|
mitian@5
|
163 foundIdx = []
|
mitian@5
|
164 D_AD = np.zeros(gt)
|
mitian@5
|
165 D_DA = np.zeros(dt)
|
mitian@5
|
166
|
mi@0
|
167 for dtIdx in xrange(dt):
|
mi@0
|
168 D_DA[dtIdx] = np.min(abs(detection[dtIdx] - annotation))
|
mitian@18
|
169
|
mi@0
|
170 for gtIdx in xrange(gt):
|
mi@0
|
171 D_AD[gtIdx] = np.min(abs(annotation[gtIdx] - detection))
|
mi@0
|
172 for dtIdx in xrange(dt):
|
mi@0
|
173 if (annotation[gtIdx] >= detection[dtIdx] - tolerance/2.0) and (annotation[gtIdx] <= detection[dtIdx] + tolerance/2.0):
|
mi@0
|
174 foundIdx.append(gtIdx)
|
mitian@18
|
175 continue
|
mi@0
|
176 foundIdx = list(set(foundIdx))
|
mi@0
|
177 res.TP = len(foundIdx)
|
mitian@18
|
178 # res.FP = dt - res.TP
|
mi@0
|
179 res.FP = max(0, dt - res.TP)
|
mitian@18
|
180 res.FN = gt - res.TP
|
mi@0
|
181
|
mi@0
|
182 res.AD = np.mean(D_AD)
|
mitian@18
|
183 res.DA = np.mean(D_DA)
|
mi@0
|
184
|
mi@0
|
185 if res.TP == 0:
|
mi@0
|
186 return res
|
mi@0
|
187
|
mitian@18
|
188 res.P = res.TP / float(res.TP+res.FP)
|
mitian@18
|
189 res.R = res.TP / float(res.TP+res.FN)
|
mi@0
|
190 res.F = 2 * res.P * res.R / (res.P + res.R)
|
mi@0
|
191 return res
|
mi@0
|
192
|
mitian@4
|
193 def writeIndividualHeader(self, filename):
|
mitian@3
|
194 '''Write header of output files for individual features.'''
|
mitian@3
|
195
|
mitian@3
|
196 with open(filename, 'a') as f:
|
mitian@3
|
197 csvwriter = csv.writer(f, delimiter=',')
|
mitian@18
|
198 csvwriter.writerow(['audio', 'harmonic_tp_05', 'harmonic_fp_05', 'harmonic_fn_05', 'harmonic_P_05', \
|
mitian@3
|
199 '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
|
200 '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
|
201 '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
|
202 '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
|
203
|
mitian@18
|
204 def writeIndividualRes(self, filename, ao_name, harmonic_res_05, harmonic_res_3, timbre_res_05, timbre_res_3, tempo_res_05, tempo_res_3):
|
mitian@3
|
205 '''Write result of single detection for individual features.'''
|
mitian@3
|
206
|
mitian@3
|
207 with open(filename, 'a') as f:
|
mitian@3
|
208 csvwriter = csv.writer(f, delimiter=',')
|
mitian@18
|
209 csvwriter.writerow([ao_name, 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
|
210 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
|
211 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
|
212 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
|
213 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
|
214
|
mitian@3
|
215 def writeCombinedHeader(self, filename):
|
mitian@3
|
216 '''Write header of output files for combined features.'''
|
mitian@3
|
217
|
mitian@3
|
218 with open(filename, 'a') as f:
|
mitian@3
|
219 csvwriter = csv.writer(f, delimiter=',')
|
mitian@18
|
220 csvwriter.writerow(['audio', 'hm_tb_P_0.5', 'hm_tb_R_0.5', 'hm_tb_F_0.5', 'hm_tb_P_3', 'hm_tb_R_3', 'hm_tb_F_3', 'hm_tp_P_0.5', 'hm_tp_R_0.5',\
|
mitian@18
|
221 'hm_tp_F_0.5', 'hm_tp_P_3', 'hm_tp_R_3', 'hm_tp_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',\
|
mitian@18
|
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'])
|
mitian@3
|
223
|
mitian@18
|
224 def writeCombinedRes(self, filename, ao_name, hm_tb_res_05, hm_tb_res_3, hm_tp_res_05, hm_tp_res_3, tb_tp_res_05, tb_tp_res_3, hm_tb_tp_res_05, hm_tb_tp_res_3):
|
mitian@3
|
225 '''Write result of single detection for combined features.'''
|
mitian@3
|
226
|
mitian@3
|
227 with open(filename, 'a') as f:
|
mitian@3
|
228 csvwriter = csv.writer(f, delimiter=',')
|
mitian@18
|
229 csvwriter.writerow([ao_name, 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,\
|
mitian@18
|
230 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, 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@18
|
231 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@18
|
232
|
mitian@18
|
233 def removeDuplicates(self, bounds, tol=1.0):
|
mitian@18
|
234 '''Remove duplicates by averaging boundaries located in the tolerance window.'''
|
mitian@18
|
235 new_bounds = []
|
mitian@18
|
236 bounds = list(set(bounds))
|
mitian@18
|
237 bounds.sort()
|
mitian@18
|
238 tol_win = int(tol * self.SampleRate / self.stepSize)
|
mitian@3
|
239
|
mitian@18
|
240 bound_idx = 0
|
mitian@18
|
241 nBounds = len(bounds)
|
mitian@18
|
242
|
mitian@18
|
243 while bound_idx < nBounds:
|
mitian@18
|
244 start = bounds[bound_idx]
|
mitian@18
|
245 cnt = 1
|
mitian@18
|
246 temp = [start]
|
mitian@18
|
247 while (bound_idx+cnt < nBounds and (bounds[bound_idx+cnt] - start <= tol_win)):
|
mitian@18
|
248 temp.append(bounds[bound_idx+cnt])
|
mitian@18
|
249 cnt += 1
|
mitian@4
|
250
|
mitian@18
|
251 new_bounds.append(int(np.mean(temp)))
|
mitian@18
|
252 bound_idx += cnt
|
mitian@18
|
253
|
mitian@18
|
254 # print 'new_bounds', nBounds, len(new_bounds)
|
mitian@18
|
255 return new_bounds
|
mitian@18
|
256
|
mitian@18
|
257 def selectBounds(self, nc, bounds, thresh=0.5):
|
mitian@18
|
258 '''Select bounds with nc value above thresh.'''
|
mitian@18
|
259 # return list(np.array(bounds)[np.where(np.array(nc)>thresh)[0]])
|
mitian@18
|
260 bounds_keep = []
|
mitian@18
|
261 nc = normaliseArray(nc)
|
mitian@18
|
262 for i, x in enumerate(bounds):
|
mitian@18
|
263 if nc[x] >= thresh:
|
mitian@18
|
264 bounds_keep.append(x)
|
mitian@18
|
265 # print 'bounds_keep', len(bounds), len(bounds_keep)
|
mitian@18
|
266 return bounds_keep
|
mitian@4
|
267
|
mi@0
|
268 def process(self):
|
mi@0
|
269 '''For the aggregated input features, discard a propertion each time as the pairwise distances within the feature space descending.
|
mi@0
|
270 In the meanwhile evaluate the segmentation result and track the trend of perfomance changing by measuring the feature selection
|
mi@0
|
271 threshold - segmentation f measure curve.
|
mi@0
|
272 '''
|
mi@0
|
273
|
mi@0
|
274 peak_picker = PeakPicker()
|
mi@0
|
275 peak_picker.params.alpha = 9.0 # Alpha norm
|
mi@0
|
276 peak_picker.params.delta = self.delta_threshold # Adaptive thresholding delta
|
mi@0
|
277 peak_picker.params.QuadThresh_a = (100 - self.threshold) / 1000.0
|
mi@0
|
278 peak_picker.params.QuadThresh_b = 0.0
|
mi@0
|
279 peak_picker.params.QuadThresh_c = (100 - self.threshold) / 1500.0
|
mi@0
|
280 peak_picker.params.rawSensitivity = 20
|
mi@0
|
281 peak_picker.params.aCoeffs = self.aCoeffs
|
mi@0
|
282 peak_picker.params.bCoeffs = self.bCoeffs
|
mi@0
|
283 peak_picker.params.preWin = self.medianWin
|
mi@0
|
284 peak_picker.params.postWin = self.medianWin + 1
|
mi@0
|
285 peak_picker.params.LP_on = self.LPfilter_on
|
mi@0
|
286 peak_picker.params.Medfilt_on = self.medfilter_on
|
mi@0
|
287 peak_picker.params.Polyfit_on = self.polyfitting_on
|
mi@0
|
288 peak_picker.params.isMedianPositive = False
|
mi@0
|
289
|
mi@0
|
290 # Settings used for feature extraction
|
mi@0
|
291 feature_window_frame = int(self.SampleRate / self.gammatoneLen * self.featureWindow)
|
mi@0
|
292 feature_step_frame = int(0.5 * self.SampleRate / self.gammatoneLen * self.featureStep)
|
mi@0
|
293 aggregation_window, aggregation_step = 100, 50
|
mi@0
|
294 featureRate = float(self.SampleRate) / self.stepSize
|
mi@0
|
295
|
mi@0
|
296 audio_files = [x for x in os.listdir(options.GT) if not x.startswith(".") ]
|
mitian@4
|
297 if options.TEST:
|
mitian@4
|
298 audio_files = audio_files[:1]
|
mi@0
|
299 audio_files.sort()
|
mi@0
|
300 audio_list = []
|
mi@0
|
301
|
mi@0
|
302 gammatone_feature_list = [i for i in os.listdir(options.GF) if not i.startswith('.')]
|
mitian@4
|
303 gammatone_feature_list = ['contrast6', 'rolloff4', 'dct']
|
mi@0
|
304 tempo_feature_list = [i for i in os.listdir(options.TF) if not i.startswith('.')]
|
mitian@4
|
305 tempo_feature_list = ['ti', 'tir']
|
mitian@4
|
306 timbre_feature_list = ['mfcc_harmonic']
|
mitian@18
|
307 harmonic_feature_list = ['chromagram_harmonic']
|
mi@0
|
308
|
mi@0
|
309 gammatone_feature_list = [join(options.GF, f) for f in gammatone_feature_list]
|
mi@0
|
310 timbre_feature_list = [join(options.SF, f) for f in timbre_feature_list]
|
mi@0
|
311 tempo_feature_list = [join(options.TF, f) for f in tempo_feature_list]
|
mi@0
|
312 harmonic_feature_list = [join(options.SF, f) for f in harmonic_feature_list]
|
mi@0
|
313
|
mitian@18
|
314
|
mitian@18
|
315 # Prepare output files.
|
mitian@18
|
316 outfile1 = join(options.OUTPUT, 'individual_novelty.csv')
|
mitian@18
|
317 outfile2 = join(options.OUTPUT, 'individual_cnmf.csv')
|
mitian@18
|
318 outfile3 = join(options.OUTPUT, 'individual_sf.csv')
|
mitian@18
|
319
|
mitian@18
|
320 outfile4 = join(options.OUTPUT, 'combinedFeatures_novelty.csv')
|
mitian@18
|
321 outfile5 = join(options.OUTPUT, 'combinedFeatures_cnmf.csv')
|
mitian@18
|
322 outfile6 = join(options.OUTPUT, 'combinedFeatures_sf.csv')
|
mi@0
|
323
|
mitian@18
|
324 # outfile7 = join(options.OUTPUT, 'combinedSSM_novelty.csv')
|
mitian@18
|
325 #
|
mitian@18
|
326 # outfile8 = join(options.OUTPUT, 'combinedBounds_novelty.csv')
|
mitian@18
|
327 # outfile9 = join(options.OUTPUT, 'combinedBounds_sf.csv')
|
mitian@18
|
328
|
mitian@18
|
329 # self.writeIndividualHeader(outfile1)
|
mitian@18
|
330 # self.writeIndividualHeader(outfile2)
|
mitian@18
|
331 # self.writeIndividualHeader(outfile3)
|
mitian@18
|
332 #
|
mitian@18
|
333 self.writeCombinedHeader(outfile4)
|
mitian@18
|
334 self.writeCombinedHeader(outfile5)
|
mitian@18
|
335 self.writeCombinedHeader(outfile6)
|
mitian@18
|
336 # self.writeCombinedHeader(outfile7)
|
mitian@18
|
337 # self.writeCombinedHeader(outfile8)
|
mitian@18
|
338 # self.writeCombinedHeader(outfile9)
|
mitian@18
|
339
|
mi@0
|
340 # For each audio file, load specific features
|
mi@0
|
341 for audio in audio_files:
|
mi@0
|
342 ao = AudioObj()
|
mi@0
|
343 ao.name = splitext(audio)[0]
|
mitian@18
|
344
|
mitian@18
|
345 # Load annotations for specified audio collection.
|
mitian@18
|
346 if options.DATASET == 'qupujicheng':
|
mitian@18
|
347 annotation_file = join(options.GT, ao.name+'.csv') # qupujicheng
|
mitian@18
|
348 ao.gt = np.genfromtxt(annotation_file, usecols=0, delimiter=',')
|
mitian@18
|
349 ao.label = np.genfromtxt(annotation_file, usecols=1, delimiter=',', dtype=str)
|
mitian@18
|
350 elif options.DATASET == 'salami':
|
mitian@18
|
351 annotation_file = join(options.GT, ao.name+'.txt') # iso, salami
|
mitian@18
|
352 ao.gt = np.genfromtxt(annotation_file, usecols=0)
|
mitian@18
|
353 ao.label = np.genfromtxt(annotation_file, usecols=1, dtype=str)
|
mitian@18
|
354 else:
|
mitian@18
|
355 annotation_file = join(options.GT, ao.name+'.lab') # beatles
|
mitian@18
|
356 ao.gt = np.genfromtxt(annotation_file, usecols=(0,1))
|
mitian@18
|
357 ao.gt = np.unique(np.ndarray.flatten(ao.gt))
|
mitian@18
|
358 ao.label = np.genfromtxt(annotation_file, usecols=2, dtype=str)
|
mi@0
|
359
|
mi@0
|
360 gammatone_featureset, timbre_featureset, tempo_featureset, harmonic_featureset = [], [], [], []
|
mi@0
|
361
|
mi@0
|
362 for feature in timbre_feature_list:
|
mi@0
|
363 for f in os.listdir(feature):
|
mi@0
|
364 if f[:f.find('_vamp')]==ao.name:
|
mitian@18
|
365 timbre_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,0:14])
|
mi@0
|
366 break
|
mi@0
|
367 if len(timbre_feature_list) > 1:
|
mi@0
|
368 n_frame = np.min([x.shape[0] for x in timbre_featureset])
|
mi@0
|
369 timbre_featureset = [x[:n_frame,:] for x in timbre_featureset]
|
mi@0
|
370 ao.timbre_features = np.hstack((timbre_featureset))
|
mi@0
|
371 else:
|
mi@0
|
372 ao.timbre_features = timbre_featureset[0]
|
mi@0
|
373 for feature in tempo_feature_list:
|
mi@0
|
374 for f in os.listdir(feature):
|
mi@0
|
375 if f[:f.find('_vamp')]==ao.name:
|
mi@0
|
376 tempo_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,1:])
|
mi@0
|
377 ao.tempo_timestamps = np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,0]
|
mi@0
|
378 break
|
mi@0
|
379 if len(tempo_feature_list) > 1:
|
mi@0
|
380 n_frame = np.min([x.shape[0] for x in tempo_featureset])
|
mi@0
|
381 tempo_featureset = [x[:n_frame,:] for x in tempo_featureset]
|
mi@0
|
382 ao.tempo_features = np.hstack((tempo_featureset))
|
mi@0
|
383 else:
|
mi@0
|
384 ao.tempo_features = tempo_featureset[0]
|
mi@0
|
385 for feature in harmonic_feature_list:
|
mi@0
|
386 for f in os.listdir(feature):
|
mi@0
|
387 if f[:f.find('_vamp')]==ao.name:
|
mi@0
|
388 harmonic_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
|
mi@0
|
389 break
|
mi@0
|
390 if len(harmonic_feature_list) > 1:
|
mi@0
|
391 n_frame = np.min([x.shape[0] for x in harmonic_featureset])
|
mi@0
|
392 harmonic_featureset = [x[:n_frame,:] for x in harmonic_featureset]
|
mi@0
|
393 ao.harmonic_features = np.hstack((harmonic_featureset))
|
mi@0
|
394 else:
|
mi@0
|
395 ao.harmonic_features = harmonic_featureset[0]
|
mi@0
|
396
|
mi@0
|
397 # Get aggregated features for computing ssm
|
mitian@18
|
398 aggregation_window, aggregation_step = 20,10
|
mitian@18
|
399 featureRate = float(self.SampleRate) / self.stepSize
|
mitian@18
|
400 pca = PCA(n_components=6)
|
mi@0
|
401
|
mi@0
|
402 # Resample and normalise features
|
mitian@18
|
403 # step = ao.tempo_features.shape[0]
|
mitian@18
|
404 # ao.timbre_features = resample(ao.timbre_features, step)
|
mitian@18
|
405 ao.timbre_features = normaliseFeature(ao.timbre_features)
|
mitian@18
|
406 # ao.harmonic_features = resample(ao.harmonic_features, step)
|
mitian@18
|
407 ao.harmonic_features = normaliseFeature(ao.harmonic_features)
|
mitian@18
|
408 nFrames = np.min([ao.timbre_features.shapes[0], ao.harmonic_features.shapes[0]])
|
mitian@18
|
409 ao.timbre_features = ao.timbre_features[:nFrames, :]
|
mitian@18
|
410 ao.harmonic_features = ao.harmonic_features[:nFrames, :]
|
mitian@18
|
411 ao.tempo_features = normaliseFeature(ao.tempo_features)
|
mitian@18
|
412 ao.tempo_features = upSample(ao.tempo_features, nFrames)
|
mitian@18
|
413 ao.timestamps = np.array(map(lambda x: x / featureRate, np.arange(0, nFrames)))
|
mitian@18
|
414
|
mitian@18
|
415 step = nFrames / 10
|
mi@0
|
416 ao.timbre_features = resample(ao.timbre_features, step)
|
mi@0
|
417 ao.harmonic_features = resample(ao.harmonic_features, step)
|
mitian@18
|
418 ao.tempo_features = resample(ao.tempo_features, step)
|
mi@0
|
419
|
mi@0
|
420 pca.fit(ao.tempo_features)
|
mi@0
|
421 ao.tempo_features = pca.transform(ao.tempo_features)
|
mi@0
|
422 ao.tempo_ssm = getSSM(ao.tempo_features)
|
mi@0
|
423
|
mi@0
|
424 pca.fit(ao.timbre_features)
|
mi@0
|
425 ao.timbre_features = pca.transform(ao.timbre_features)
|
mi@0
|
426 ao.timbre_ssm = getSSM(ao.timbre_features)
|
mi@0
|
427
|
mi@0
|
428 pca.fit(ao.harmonic_features)
|
mi@0
|
429 ao.harmonic_features = pca.transform(ao.harmonic_features)
|
mi@0
|
430 ao.harmonic_ssm = getSSM(ao.harmonic_features)
|
mi@0
|
431
|
mitian@18
|
432
|
mitian@3
|
433
|
mitian@3
|
434 ############################################################################################################################################
|
mitian@3
|
435 # Experiment 1: segmentation using individual features.
|
mitian@18
|
436
|
mitian@18
|
437 timbre_novelty, smoothed_timbre_novelty, timbre_novelty_idxs = novelty_S.process(ao.timbre_ssm, peak_picker, self.kernel_size)
|
mitian@18
|
438 tempo_novelty, smoothed_tempo_novelty, tempo_novelty_idxs = novelty_S.process(ao.tempo_ssm, peak_picker, self.kernel_size)
|
mitian@18
|
439 harmonic_novelty, smoothed_harmonic_novelty, harmonic_novelty_idxs = novelty_S.process(ao.harmonic_ssm, peak_picker, self.kernel_size)
|
mitian@3
|
440
|
mitian@18
|
441 timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)[-1]
|
mitian@18
|
442 tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)[-1]
|
mitian@18
|
443 harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)[-1]
|
mitian@3
|
444
|
mitian@18
|
445 timbre_sf_nc, timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
|
mitian@18
|
446 tempo_sf_nc, tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
|
mitian@18
|
447 harmonic_sf_nc, harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
|
mitian@1
|
448
|
mitian@3
|
449 # Evaluate and write results.
|
mitian@3
|
450 harmonic_novelty_05 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
451 harmonic_novelty_3 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
452 tempo_novelty_05 = self.pairwiseF(ao.gt, tempo_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
453 tempo_novelty_3 = self.pairwiseF(ao.gt, tempo_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
454 timbre_novelty_05 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
455 timbre_novelty_3 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mi@0
|
456
|
mitian@3
|
457 harmonic_cnmf_05 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
458 harmonic_cnmf_3 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
459 tempo_cnmf_05 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
460 tempo_cnmf_3 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
461 timbre_cnmf_05 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
462 timbre_cnmf_3 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
463
|
mitian@3
|
464 harmonic_sf_05 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
465 harmonic_sf_3 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
466 tempo_sf_05 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
467 tempo_sf_3 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
468 timbre_sf_05 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
469 timbre_sf_3 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@1
|
470
|
mitian@18
|
471 self.writeIndividualRes(outfile1, ao.name, harmonic_novelty_05, harmonic_novelty_3, tempo_novelty_05, tempo_novelty_3, timbre_novelty_05, timbre_novelty_3)
|
mitian@18
|
472 self.writeIndividualRes(outfile2, ao.name, harmonic_cnmf_05, harmonic_cnmf_3, tempo_cnmf_05, tempo_cnmf_3, timbre_cnmf_05, timbre_cnmf_3)
|
mitian@18
|
473 self.writeIndividualRes(outfile3, ao.name, harmonic_sf_05, harmonic_sf_3, tempo_sf_05, tempo_sf_3, timbre_sf_05, timbre_sf_3)
|
mitian@1
|
474
|
mitian@1
|
475
|
mitian@3
|
476 ############################################################################################################################################
|
mitian@3
|
477 # Experiment 2: segmentation using combined features.
|
mi@2
|
478
|
mitian@3
|
479 # Dumping features.
|
mitian@3
|
480 hm_tb = np.hstack([ao.harmonic_features, ao.timbre_features])
|
mitian@3
|
481 hm_tp = np.hstack([ao.harmonic_features, ao.tempo_features])
|
mitian@3
|
482 tb_tp = np.hstack([ao.timbre_features, ao.tempo_features])
|
mitian@3
|
483 hm_tb_tp = np.hstack([ao.harmonic_features, ao.timbre_features, ao.tempo_features])
|
mitian@18
|
484
|
mitian@18
|
485 hm_tb_feature_ssm = getSSM(hm_tb)
|
mitian@18
|
486 hm_tp_feature_ssm = getSSM(hm_tp)
|
mitian@18
|
487 tb_tp_feature_ssm = getSSM(tb_tp)
|
mitian@18
|
488 hm_tb_tp_feature_ssm = getSSM(hm_tb_tp)
|
mitian@3
|
489
|
mitian@4
|
490 # Evaluting and writing results.
|
mitian@18
|
491 hm_tb_novelty_idxs = novelty_S.process(hm_tb_feature_ssm)[-1]
|
mitian@18
|
492 hm_tp_novelty_idxs = novelty_S.process(hm_tp_feature_ssm)[-1]
|
mitian@18
|
493 tb_tp_novelty_idxs = novelty_S.process(tb_tp_feature_ssm)[-1]
|
mitian@18
|
494 hm_tb_tp_novelty_idxs = novelty_S.process(hm_tb_tp_feature_ssm)[-1]
|
mitian@3
|
495
|
mitian@18
|
496 hm_tb_sf_idxs = sf_S.segmentation(hm_tb)[-1]
|
mitian@18
|
497 hm_tp_sf_idxs = sf_S.segmentation(hm_tp)[-1]
|
mitian@18
|
498 tb_tp_sf_idxs = sf_S.segmentation(tb_tp)[-1]
|
mitian@18
|
499 hm_tb_tp_sf_idxs = sf_S.segmentation(hm_tb_tp)[-1]
|
mitian@3
|
500
|
mitian@18
|
501 hm_tb_cnmf_idxs = cnmf_S.segmentation(hm_tb, rank=4, R=R, h=h, niter=300)[-1]
|
mitian@18
|
502 hm_tp_cnmf_idxs = cnmf_S.segmentation(hm_tp, rank=4, R=R, h=h, niter=300)[-1]
|
mitian@18
|
503 tb_tp_cnmf_idxs = cnmf_S.segmentation(tb_tp, rank=4, R=R, h=h, niter=300)[-1]
|
mitian@18
|
504 hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(hm_tb_tp, rank=6, R=R, h=h, niter=300)[-1]
|
mitian@18
|
505
|
mitian@18
|
506 hm_tb_novelty_05 = self.pairwiseF(ao.gt, hm_tb_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
507 hm_tp_novelty_05 = self.pairwiseF(ao.gt, hm_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
508 tb_tp_novelty_05 = self.pairwiseF(ao.gt, tb_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
509 hm_tb_tp_novelty_05 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
510
|
mitian@18
|
511 hm_tb_novelty_3 = self.pairwiseF(ao.gt, hm_tb_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
512 hm_tp_novelty_3 = self.pairwiseF(ao.gt, hm_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
513 tb_tp_novelty_3 = self.pairwiseF(ao.gt, tb_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
514 hm_tb_tp_novelty_3 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
515
|
mitian@4
|
516 hm_tb_sf_05 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
517 hm_tp_sf_05 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
518 tb_tp_sf_05 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
519 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
|
520
|
mitian@4
|
521 hm_tb_sf_3 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
522 hm_tp_sf_3 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
523 tb_tp_sf_3 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
524 hm_tb_tp_sf_3 = self.pairwiseF(ao.gt, hm_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
525
|
mitian@4
|
526 hm_tb_cnmf_05 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
527 hm_tp_cnmf_05 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
528 tb_tp_cnmf_05 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
529 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
|
530
|
mitian@4
|
531 hm_tb_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
532 hm_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
533 tb_tp_cnmf_3 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@4
|
534 hm_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@3
|
535
|
mitian@3
|
536
|
mitian@18
|
537 self.writeCombinedRes(outfile4, ao.name, hm_tb_novelty_05, hm_tb_novelty_3, hm_tp_novelty_05, hm_tp_novelty_3, tb_tp_novelty_05, tb_tp_novelty_3, hm_tb_tp_novelty_05, hm_tb_tp_novelty_3)
|
mitian@18
|
538 self.writeCombinedRes(outfile5, ao.name, hm_tb_cnmf_05, hm_tb_cnmf_3, hm_tp_cnmf_05, hm_tp_cnmf_3, tb_tp_cnmf_05, tb_tp_cnmf_3, hm_tb_tp_cnmf_05, hm_tb_tp_cnmf_3)
|
mitian@18
|
539 self.writeCombinedRes(outfile6, ao.name, hm_tb_sf_05, hm_tb_sf_3, hm_tp_sf_05, hm_tp_sf_3, tb_tp_sf_05, tb_tp_sf_3, hm_tb_tp_sf_05, hm_tb_tp_sf_3)
|
mitian@3
|
540
|
mitian@4
|
541
|
mitian@18
|
542 # ############################################################################################################################################
|
mitian@18
|
543 # # Experiment 3: late fusion -- segmentation using combined ssms.
|
mitian@18
|
544 #
|
mitian@18
|
545 # hm_tb_ssm = self.lin * ao.harmonic_ssm + (1-self.lin) * ao.timbre_ssm
|
mitian@18
|
546 # hm_tp_ssm = self.lin * ao.harmonic_ssm + (1-self.lin) * ao.tempo_ssm
|
mitian@18
|
547 # tb_tp_ssm = self.lin * ao.timbre_ssm + (1-self.lin) * ao.tempo_ssm
|
mitian@18
|
548 # hm_tb_tp_ssm = (ao.harmonic_ssm + ao.timbre_ssm + ao.tempo_ssm) / 3.0
|
mitian@18
|
549 #
|
mitian@18
|
550 # hm_tb_ssm_novelty_idxs = novelty_S.process(hm_tb_ssm)[-1]
|
mitian@18
|
551 # hm_tp_ssm_novelty_idxs = novelty_S.process(hm_tp_ssm)[-1]
|
mitian@18
|
552 # tb_tp_ssm_novelty_idxs = novelty_S.process(tb_tp_ssm)[-1]
|
mitian@18
|
553 # hm_tb_tp_ssm_novelty_idxs = novelty_S.process(hm_tb_tp_ssm)[-1]
|
mitian@18
|
554 #
|
mitian@18
|
555 # hm_tb_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tb_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
556 # hm_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
557 # tb_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, tb_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
558 # hm_tb_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tb_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
559 #
|
mitian@18
|
560 # hm_tb_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tb_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
561 # hm_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
562 # tb_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, tb_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
563 # hm_tb_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tb_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
564 #
|
mitian@18
|
565 # self.writeCombinedRes(outfile7, ao.name, hm_tb_ssm_novelty_05, hm_tb_ssm_novelty_3, hm_tp_ssm_novelty_05, hm_tp_ssm_novelty_3, tb_tp_ssm_novelty_05, tb_tp_ssm_novelty_3, hm_tb_tp_ssm_novelty_05, hm_tb_tp_ssm_novelty_3)
|
mitian@4
|
566
|
mitian@18
|
567 # ############################################################################################################################################
|
mitian@18
|
568 # # Experiment 4: late fusion -- segmentation using combined boundaries.
|
mitian@18
|
569 # hm_novelty_bounds = self.selectBounds(smoothed_harmonic_novelty, harmonic_novelty_idxs, self.confidence_threshold)
|
mitian@18
|
570 # tb_novelty_bounds = self.selectBounds(smoothed_timbre_novelty, timbre_novelty_idxs, self.confidence_threshold)
|
mitian@18
|
571 # tp_novelty_bounds = self.selectBounds(smoothed_tempo_novelty, timbre_novelty_idxs, self.confidence_threshold)
|
mitian@18
|
572 #
|
mitian@18
|
573 # hm_tb_novelty_bounds = hm_novelty_bounds + tb_novelty_bounds
|
mitian@18
|
574 # hm_tp_novelty_bounds = hm_novelty_bounds + tp_novelty_bounds
|
mitian@18
|
575 # tb_tp_novelty_bounds = tb_novelty_bounds + tp_novelty_bounds
|
mitian@18
|
576 # hm_tb_tp_novelty_bounds = hm_novelty_bounds + tb_novelty_bounds + tp_novelty_bounds
|
mitian@18
|
577 #
|
mitian@18
|
578 # hm_tb_novelty_bounds = self.removeDuplicates(hm_tb_novelty_bounds, tol=1.0)
|
mitian@18
|
579 # hm_tp_novelty_bounds = self.removeDuplicates(hm_tp_novelty_bounds, tol=1.0)
|
mitian@18
|
580 # tb_tp_novelty_bounds = self.removeDuplicates(tb_tp_novelty_bounds, tol=1.0)
|
mitian@18
|
581 # hm_tb_tp_novelty_bounds = self.removeDuplicates(hm_tb_tp_novelty_bounds, tol=1.0)
|
mitian@18
|
582 #
|
mitian@18
|
583 # hm_sf_bounds = self.selectBounds(harmonic_sf_nc, harmonic_sf_idxs, self.confidence_threshold)
|
mitian@18
|
584 # tb_sf_bounds = self.selectBounds(timbre_sf_nc, timbre_sf_idxs, self.confidence_threshold)
|
mitian@18
|
585 # tp_sf_bounds = self.selectBounds(tempo_sf_nc, tempo_sf_idxs, self.confidence_threshold)
|
mitian@18
|
586 #
|
mitian@18
|
587 # hm_tb_sf_bounds = hm_sf_bounds + tb_sf_bounds
|
mitian@18
|
588 # hm_tp_sf_bounds = hm_sf_bounds + tp_sf_bounds
|
mitian@18
|
589 # tb_tp_sf_bounds = tb_sf_bounds + tp_sf_bounds
|
mitian@18
|
590 # hm_tb_tp_sf_bounds = hm_sf_bounds + tb_sf_bounds + tp_sf_bounds
|
mitian@18
|
591 #
|
mitian@18
|
592 # hm_tb_sf_bounds = self.removeDuplicates(hm_tb_sf_bounds, tol=1.0)
|
mitian@18
|
593 # hm_tp_sf_bounds = self.removeDuplicates(hm_tp_sf_bounds, tol=1.0)
|
mitian@18
|
594 # tb_tp_sf_bounds = self.removeDuplicates(tb_tp_sf_bounds, tol=1.0)
|
mitian@18
|
595 # hm_tb_tp_sf_bounds = self.removeDuplicates(hm_tb_tp_sf_bounds, tol=1.0)
|
mitian@18
|
596 #
|
mitian@18
|
597 #
|
mitian@18
|
598 # hm_tb_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tb_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
599 # hm_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
600 # tb_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, tb_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
601 # hm_tb_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
602 #
|
mitian@18
|
603 # hm_tb_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tb_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
604 # hm_tp_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
605 # tb_tp_sf_bounds_05 = self.pairwiseF(ao.gt, tb_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
606 # hm_tb_tp_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tb_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
607 #
|
mitian@18
|
608 # hm_tb_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tb_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
609 # hm_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
610 # tb_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, tb_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
611 # hm_tb_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
612 #
|
mitian@18
|
613 # hm_tb_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tb_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
614 # hm_tp_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
615 # tb_tp_sf_bounds_3 = self.pairwiseF(ao.gt, tb_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
616 # hm_tb_tp_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tb_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
|
mitian@18
|
617 #
|
mitian@18
|
618 # self.writeCombinedRes(outfile8, ao.name, hm_tb_novelty_bounds_05, hm_tb_novelty_bounds_3, hm_tp_novelty_bounds_05, hm_tp_novelty_bounds_3, tb_tp_novelty_bounds_05, tb_tp_novelty_bounds_3, hm_tb_tp_novelty_bounds_05, hm_tb_tp_novelty_bounds_3)
|
mitian@18
|
619 # self.writeCombinedRes(outfile9, ao.name, hm_tb_sf_bounds_05, hm_tb_sf_bounds_3, hm_tp_sf_bounds_05, hm_tp_sf_bounds_3, tb_tp_sf_bounds_05, tb_tp_sf_bounds_3, hm_tb_tp_sf_bounds_05, hm_tb_tp_sf_bounds_3)
|
mitian@4
|
620
|
mi@0
|
621
|
mi@0
|
622
|
mi@0
|
623 def main():
|
mi@0
|
624
|
mi@0
|
625 segmenter = SSMseg()
|
mi@0
|
626 segmenter.process()
|
mi@0
|
627
|
mi@0
|
628
|
mi@0
|
629 if __name__ == '__main__':
|
mi@0
|
630 main()
|
mi@0
|
631
|