comparison utils/SegUtil.py @ 17:c01fcb752221

new annotations
author mitian
date Fri, 21 Aug 2015 10:15:29 +0100
parents 8b814fe5781d
children
comparison
equal deleted inserted replaced
16:8b814fe5781d 17:c01fcb752221
18 import scipy 18 import scipy
19 from scipy.spatial import distance 19 from scipy.spatial import distance
20 from scipy.ndimage import filters, zoom 20 from scipy.ndimage import filters, zoom
21 from scipy import signal 21 from scipy import signal
22 from scipy.signal import correlate2d, convolve2d, filtfilt, resample, butter 22 from scipy.signal import correlate2d, convolve2d, filtfilt, resample, butter
23 import pylab as plt 23 # import pylab as plt
24 from scipy.spatial.distance import squareform, pdist 24 from scipy.spatial.distance import squareform, pdist
25 from scipy.ndimage.filters import maximum_filter, minimum_filter, percentile_filter, uniform_filter 25 from scipy.ndimage.filters import maximum_filter, minimum_filter, percentile_filter, uniform_filter
26 from scipy.ndimage.filters import median_filter as med_filter 26 from scipy.ndimage.filters import median_filter as med_filter # median_filter is a user defined function in this script
27 from sklearn.metrics.pairwise import pairwise_distances 27 from sklearn.metrics.pairwise import pairwise_distances
28 28
29 from GmmMetrics import GmmDistance
29 30
30 def lognormalize_chroma(C): 31 def lognormalize_chroma(C):
31 """Log-normalizes chroma such that each vector is between -80 to 0.""" 32 """Log-normalizes chroma such that each vector is between -80 to 0."""
32 C += np.abs(C.min()) + 0.1 33 C += np.abs(C.min()) + 0.1
33 C = C/C.max(axis=0) 34 C = C/C.max(axis=0)
44 45
45 def ensure_dir(directory): 46 def ensure_dir(directory):
46 """Makes sure that the given directory exists.""" 47 """Makes sure that the given directory exists."""
47 if not os.path.exists(directory): 48 if not os.path.exists(directory):
48 os.makedirs(directory) 49 os.makedirs(directory)
50
49 51
50 def median_filter(X, M=8): 52 def median_filter(X, M=8):
51 """Median filter along the first axis of the feature matrix X.""" 53 """Median filter along the first axis of the feature matrix X."""
52 for i in xrange(X.shape[1]): 54 for i in xrange(X.shape[1]):
53 X[:, i] = filters.median_filter(X[:, i], size=M) 55 X[:, i] = filters.median_filter(X[:, i], size=M)
277 if sym: 279 if sym:
278 rec = rec * rec.T 280 rec = rec * rec.T
279 281
280 return rec 282 return rec
281 283
282 def finiteMax(X):
283 '''Return the smallest finite value in the array'''
284 if not (np.isnan(X).any() or np.isposinf(X).any()):
285 return np.max(X)
286 data = np.sort(np.ndarray.flatten(X))
287 pos = np.where(data == np.inf)[0]
288 fMax = 0
289 return fMax
290
291 def finiteMin(feature):
292 '''Return the smallest finite value in the array'''
293 if not (np.isnan(X).any() or np.isinf(X).any()):
294 return np.min(X)
295 fMin = 0
296 return fMin
297
298 def lp(signal, fc=0.34, axis=-1): 284 def lp(signal, fc=0.34, axis=-1):
299 '''Low pass filter function 285 '''Low pass filter function
300 signal: Raw signal to be smoothed. 286 signal: Raw signal to be smoothed.
301 fc: Cutoff frequency of the butterworth filter. Normalized from 0 to 1, where 1 is the Nyquist frequency. 287 fc: Cutoff frequency of the butterworth filter. Normalized from 0 to 1, where 1 is the Nyquist frequency.
302 axis: The axis of x to which the filter is applied. Default is -1.''' 288 axis: The axis of x to which the filter is applied. Default is -1.'''
303 bCoeffs, aCoeffs = butter(2, fc) 289 bCoeffs, aCoeffs = butter(2, fc)
304 lp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis) 290 lp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis)
305 return lp_smoothed_signal 291 return lp_smoothed_signal
306 292
293
307 def hp(signal, fc=0.34, axis=-1): 294 def hp(signal, fc=0.34, axis=-1):
308 '''Low pass filter function 295 '''Low pass filter function
309 signal: Raw signal to be smoothed. 296 signal: Raw signal to be smoothed.
310 fc: Cutoff frequency of the butterworth filter. 297 fc: Cutoff frequency of the butterworth filter.
311 axis: The axis of x to which the filter is applied. Default is -1.''' 298 axis: The axis of x to which the filter is applied. Default is -1.'''
312 bCoeffs, aCoeffs = butter(2, fc, 'highpass') 299 bCoeffs, aCoeffs = butter(2, fc, 'highpass')
313 hp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis) 300 hp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis)
314 return hp_smoothed_signal 301 return hp_smoothed_signal
315 302
303
316 def getMean(feature, winlen, stepsize): 304 def getMean(feature, winlen, stepsize):
317 means = [] 305 means = []
318 steps = int((feature.shape[0] - winlen + stepsize) / stepsize) 306 steps = int((feature.shape[0] - winlen + stepsize) / stepsize)
319 for i in xrange(steps): 307 for i in xrange(steps):
320 means.append(np.mean(feature[i*stepsize:(i*stepsize+winlen), :], axis=0)) 308 means.append(np.mean(feature[i*stepsize:(i*stepsize+winlen), :], axis=0))
341 dm = pairwise_distances(feature_array, metric=metric) 329 dm = pairwise_distances(feature_array, metric=metric)
342 dm = np.nan_to_num(dm) 330 dm = np.nan_to_num(dm)
343 if norm == 'simple': 331 if norm == 'simple':
344 ssm = 1 - (dm - np.min(dm)) / (np.max(dm) - np.min(dm)) 332 ssm = 1 - (dm - np.min(dm)) / (np.max(dm) - np.min(dm))
345 if norm == 'exp': # Use with cosine metric only 333 if norm == 'exp': # Use with cosine metric only
346 ssm = np.exp(dm - 1) 334 ssm = 1 - np.exp(dm - 1)
347 if reduce: 335 if reduce:
348 ssm = reduceSSM(ssm) 336 ssm = reduceSSM(ssm)
349 return ssm 337 return ssm
338
350 339
351 def enhanceSSM(ssm, fc=0.34, med_size=(5,5), max_size=(5,5), min_size=(5,5), filter_type='min', axis=-1): 340 def enhanceSSM(ssm, fc=0.34, med_size=(5,5), max_size=(5,5), min_size=(5,5), filter_type='min', axis=-1):
352 '''A series of filtering for SSM enhancement 341 '''A series of filtering for SSM enhancement
353 fc: cutoff frequency for LP filtering. 342 fc: cutoff frequency for LP filtering.
354 med_size: Median filter window size. 343 med_size: Median filter window size.
355 int or tuple. If using an integer for a 2d input, axis must be specified. 344 int or tuple. If using an integer for a 2d input, axis must be specified.
356 filter_type: Select either to use maximum filter or minimum filter. 345 filter_type: Select either to use maximum filter or minimum filter according to the distance metric with which the SSM was computed.
357 float ['min', 'max', None] 346 float ['min', 'max', None]
358 max_size: Maximum filter window size. 347 max_size: Maximum filter window size.
359 int or tuple. If using an integer for a 2d input, axis must be specified. 348 int or tuple. If using an integer for a 2d input, axis must be specified.
360 Use this when homogeneity in the SSM is expressed by LARGE value. 349 Use this when homogeneity in the SSM is expressed by LARGE value.
361 min_size: Mininum filter window size. 350 min_size: Mininum filter window size.
373 elif filter_type == 'max': 362 elif filter_type == 'max':
374 enhanced_ssm = maximum_filter(ssm_med, size=max_size) 363 enhanced_ssm = maximum_filter(ssm_med, size=max_size)
375 else: 364 else:
376 enhanced_ssm = ssm_med 365 enhanced_ssm = ssm_med
377 return enhanced_ssm 366 return enhanced_ssm
378 367
368
379 def reduceSSM(ssm, maxfilter_size = 2, remove_size=50): 369 def reduceSSM(ssm, maxfilter_size = 2, remove_size=50):
380 '''Adaptive thresholding using OTSU method 370 '''Adaptive thresholding using OTSU method
381 Required package: skimage (0.10+)''' 371 Required package: skimage (0.10+) -- NOT installed on ignis, do NOT call this function!'''
382 372
383 from skimage.morphology import disk 373 from skimage.morphology import disk
384 # from skimage.filters import threshold_otsu, rank #skimage 0.12 374 # from skimage.filters import threshold_otsu, rank #skimage 0.12
385 from skimage.filter.rank import otsu #skimage 0.10 375 from skimage.filter.rank import otsu #skimage 0.10
386 from skimage.filter import threshold_otsu 376 from skimage.filter import threshold_otsu
387 377
388 reduced_ssm = copy(ssm) 378 reduced_ssm = copy(ssm)
389 reduced_ssm[reduced_ssm<0.75] = 0 379 reduced_ssm[reduced_ssm<0.75] = 0
390 # # reduced_ssm = maximum_filter(reduced_ssm,size=maxfilter_size) 380 # # reduced_ssm = maximum_filter(reduced_ssm,size=maxfilter_size)
391 # # reduced_ssm = morphology.remove_small_objects(reduced_ssm.astype(bool), min_size=remove_size) 381 # # reduced_ssm = morphology.remove_small_objects(reduced_ssm.astype(bool), min_size=remove_size)
392 local_otsu = otsu(reduced_ssm, disk(5)) 382 local_otsu = otsu(reduced_ssm, disk(5))
414 feature_array[np.isnan(feature_array)] = 0.0 404 feature_array[np.isnan(feature_array)] = 0.0
415 feature_array[np.isinf(feature_array)] = 0.0 405 feature_array[np.isinf(feature_array)] = 0.0
416 406
417 return feature_array 407 return feature_array
418 408
409 def normaliseArray(X):
410 '''Normalise 1d array.'''
411 if np.max(X) == np.min(X):
412 return None
413 return (X - np.min(X)) / (np.max(X) - np.min(X))
414
415 def pairwiseSKL(self, gmm_list):
416 '''Compute pairwise symmetrised KL divergence of a list of GMMs.'''
417 n_GMMs = len(gmm_list)
418 distance_matrix = np.zeros((n_GMMs, n_GMMs))
419 for i in xrange(n_GMMs):
420 for j in xrange(i, n_GMMs):
421 distance_matrix[i][j] = gmm_list[i].skl_distance_full(gmm_list[j])
422 distance_matrix[j][i] = distance_matrix[i][j]
423
424 np.fill_diagonal(distance_matrix, 0.0)
425 distance_matrix[np.isinf(distance_matrix)] = np.finfo(np.float64).max
426
427 return distance_matrix
419 428
420 def getRolloff(data, tpower, filterbank, thresh=0.9): 429 def getRolloff(data, tpower, filterbank, thresh=0.9):
421 nFrames = data.shape[0] 430 nFrames = data.shape[0]
422 nFilters = len(filterbank) 431 nFilters = len(filterbank)
423 rolloff = np.zeros(nFrames) 432 rolloff = np.zeros(nFrames)