Mercurial > hg > segmentation
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) |