def batch_find_rois(flist, params_detections, path_audio): """ Exports features saved as joblib into a csv file readable by R and other programs. The joblib file should be computed using the Parameters: ---------- params_detection: dict Dictionary with the basic parameters to feed find_rois: 'flims', 'tlen', and 'th'. path_flist : str Path to a *.txt file with the list of audio filenames to process path_audio : str Path to the place were the dataset of audio files are stored Returns: ------- Saves a joblib file to disk. Does not return any variable """ # load parameters flims = params_detections['flims'] tlen = params_detections['tlen'] th = params_detections['th'] detections = list() for idx, fname in enumerate(flist['fname']): print(idx + 1, '/', len(flist), fname) s, fs = sound.load(path_audio + fname) rois = find_rois_cwt(s, fs, flims, tlen, th) if not rois.empty: # filter rois shorter than 25% of tlen idx_rm = (rois.max_t - rois.min_t) < tlen * 0.25 rois.drop(index=np.where(idx_rm)[0], inplace=True) rois.reset_index(inplace=True, drop=True) else: pass # save to list detections.append({'fname': fname, 'rois': rois}) info_detections = { 'detections': detections, 'parameters': params_detections } return info_detections
}) #%% # It is possible to extract Rois directly from the audio waveform without # computing the spectrogram. This works well if there is no big overlap between # each acoustic signature and you # First, we have to define the frequency bandwidth where to find acoustic events # In our example, there are clearly 3 frequency bandwidths (low : l, medium:m # and high : h). # We know that we have mostly short (ie. s) acoustic events in low, med and high # frequency bandwidths but also a long (ie l) acoustic events in med. # To extract df_rois_sh = rois.find_rois_cwt(s, fs, flims=[7000, 8000], tlen=0.2, th=0.000001) df_rois_sm = rois.find_rois_cwt(s, fs, flims=[3500, 5500], tlen=0.2, th=0.000001) df_rois_lm = rois.find_rois_cwt(s, fs, flims=[2000, 7500], tlen=2, th=0.0001) df_rois_sl = rois.find_rois_cwt(s, fs, flims=[1800, 3000], tlen=0.2, th=0.000001) ## concat df
centroid = format_features(centroid, tn, fn) overlay_centroid(Sxx, ext, centroid, savefig=None, vmin=-120, vmax=20, color='blue', fig=fig, ax=ax) # merge dataframes containing different features into a single dataframe (drop duplicate columns) features = pd.concat([shape, centroid], axis=0, sort=False).fillna(0) ###=============== Find ROI 1D ================= rois_cr = find_rois_cwt(s, fs, flims=[3000, 8000], tlen=3, th=0.003) rois_sp = find_rois_cwt(s, fs, flims=[6000, 12000], tlen=0.2, th=0.001) rois = pd.concat([rois_sp, rois_cr], ignore_index=True) rois = format_features(rois, tn, fn) # view bbox ax, fig = overlay_rois(Sxx, ext, rois, vmin=-120, vmax=20) # get features: shape, center frequency shape, params = shape_features(Sxx, resolution='low', rois=rois) plot_shape(shape.mean(), params) centroid = centroid_features(Sxx, rois) centroid = format_features(centroid, tn, fn)
from maad.util import power2dB, plot2D s, fs = sound.load('../../data/spinetail.wav') Sxx, tn, fn, ext = sound.spectrogram(s, fs, nperseg=1024, noverlap=512) Sxx_db = power2dB(Sxx, db_range=100) + 100 plot2D(Sxx_db, **{'extent': ext}) #%% # Detect the accelerating trill # ----------------------------- # The accelerating trill is the song of a small neotropical bird, Cranioleuca erythrops. This song can be detected on the recording using the function find_rois_cwt and setting frequency limits flims=(4500,8000) and temporal length of signal tlen=2. _ = find_rois_cwt(s, fs, flims=(4500, 8000), tlen=2, th=0, display=True, figsize=(13, 6)) #%% # Detect the fast descending chirp # -------------------------------- # Alternatively, the fast descending chirp (unknown species) can be segmented in the recording by changing the detection parameters. df = find_rois_cwt(s, fs, flims=(8000, 12000), tlen=0.1, th=0.001, display=True,
def batch_predict_rois(flist, tuned_clfs, params, path_audio_db='./'): """ Predict the labels of rois in a list of audio files. Parameters ---------- flist: pandas DataFrame list of audio filenames to be analysed. Column name must be 'fname' tuned_clfs: dict data structure with tuned classifiers by grid search or random search params: dict data structure with the same parameters used to train the classifiers. Keys to be included: 'sample_rate_wav', 'flims', 'tlen', 'th', 'opt_spec', 'opt_shape_str' path_audio_db: str, default current directory path pointing to the directory where the audio files are located. Note that all files in flist must be in the same directory Returns ------- predictions: dict data structure with name of audio files as keys. Each element in the dictionary has a DataFrame with predictions for every region interest found. Predictions are given as probabilities for three different classifiers, namely Random Forest ('rf'), Adaboost ('adb') and Support Vector Machines ('svm'). """ t_start = time.time() # compute processing time # Load params and variables clf_svm = tuned_clfs['svm'].best_estimator_ clf_rf = tuned_clfs['rf'].best_estimator_ clf_adb = tuned_clfs['adb'].best_estimator_ flims = params['flims'] tlen = params['tlen'] th = params['th'] opt_spec = params['opt_spec'] opt_shape = opt_shape_presets(params['opt_shape_str']) sample_rate_std = params['sample_rate_wav'] # Batch: compute rois, features and predict through files predictions = dict() for idx, fname in enumerate(flist['fname']): print(idx+1, '/', len(flist), fname) # fname = flist['fname'][0] s, fs = sound.load(path_audio_db+fname) # Check sampling frequency on file if fs==sample_rate_std: pass else: print('Warning: sample rate mismatch, resampling audio file to standard', sample_rate_std, 'Hz') s = resample(s, fs, sample_rate_std, res_type='kaiser_fast') fs = sample_rate_std rois = find_rois_cwt(s, fs, flims, tlen, th) if rois.empty: #print('< No detection on file >') predictions[fname] = -1 else: # filter rois shorter than 25% of tlen idx_rm = (rois.max_t - rois.min_t) < tlen*0.25 rois.drop(index=np.where(idx_rm)[0], inplace=True) rois.reset_index(inplace=True, drop=True) if rois.empty: print('< No detection on file >') predictions[fname] = -1 else: # compute features rois_features = compute_rois_features(s, fs, rois, opt_spec, opt_shape, flims) # predict X = rois_features.loc[:,rois_features.columns.str.startswith('shp')] #X['frequency'] = preprocessing.scale(X['frequency']) # new! scale frequency pred_rf = pd.DataFrame(data=clf_rf.predict_proba(X), columns=[s + '_rf' for s in clf_rf.classes_.astype('str')]) pred_adb = pd.DataFrame(data=clf_adb.predict_proba(X), columns=[s + '_adb' for s in clf_adb.classes_.astype('str')]) pred_svm = pd.DataFrame(data=clf_svm.predict_proba(X), columns=[s + '_svm' for s in clf_svm.classes_.astype('str')]) # save to variable pred_proba_file = pd.concat([rois, pred_rf, pred_adb, pred_svm], axis=1) predictions[fname] = pred_proba_file t_stop = time.time() # compute processing time print('Batch process completed. Processing time: ', np.round(t_stop - t_start,2),'s') return predictions
from maad.rois import find_rois_cwt from maad.util import plot_spectrogram s, fs = sound.load('../../data/spinetail.wav') Sxx, tn, fn, ext = sound.spectrogram(s, fs, nperseg=1024, noverlap=512) plot_spectrogram(Sxx, extent=ext, db_range=60, gain=20, figsize=(4, 10)) #%% # Detect the bouncy trill # ----------------------- # The accelerating trill is the song of a small neotropical bird, the Red-faced Spinetail *Cranioleuca erythrops*. This song can be detected on the recording using the function ``find_rois_cwt`` and setting frequency limits ``flims=(4500,8000)`` and temporal length of signal ``tlen=2``. The segmentation results are returned as a dataframe with temporal segmentation given by the function and using the frequency limits defined by the user. df_trill = find_rois_cwt(s, fs, flims=(4500, 8000), tlen=2, th=0, display=True, figsize=(10, 6)) print(df_trill) #%% # Detect the fast descending chirp # -------------------------------- # Alternatively, the fast descending chirp (unknown species) can be segmented in the recording by changing the detection parameters, ``flims`` and ``tlen``. df_chirp = find_rois_cwt(s, fs, flims=(8000, 12000), tlen=0.1, th=0.001,