Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
                                      })

#%%
# 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,
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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,