Deteccion temporal con filtros de amplitud y tiempo

Las distribuciones de amplitud en tiempo y frecuencia en archivos de audio donde las señales de interés presentan una mayor proporción señal-ruido pueden ser usadas para detectar la posición de las señales (i.e. anotar los archivos de audio) automáticamente.

Usaremos como ejemplo una grabación Phaethornis longirostris que se encuentra en la carpeta “./ejemplos/deteccion”. Un espectrograma largo ayudará a tener una idea de la estructura del canto en esta especie:

# cargar warbleR 
library(warbleR)

# parametros globales
warbleR_options(wl = 200, ovlp = 90, wav.path = "PONER RUTA A 'ejemplos/deteccion' AQUI", flim = c(2, 11))

# spectrograma largo
full_spec(ovlp = 50, sxrow = 26.5 / 12, rows = 12)

La función auto_detec() utiliza umbrales aplicados a marcos de amplitud (“envelopes”) así como filtros de rango de frecuencia y de duración para detectar la posición temporal. EL siguiente código aplica los siguientes parámetros para detectar los elementos del canto:

  • Un umbral de 14 %
  • Un filtro de duración mínima de 0.1 s
  • Un filtro de duración máxima de 0.17 s ’ Un alisado (‘ssmooth’) de 400 muestras
ad <- autodetec(threshold = 14, mindur= 0.1, maxdur = 0.17, bp = c(2, 11), ssmooth = 400, ls = TRUE, sxrow = 26.5 / 12, rows = 12)

 

La deteccion se ve así:

Deteccion temporal con correlación-cruzada

Se pueden detectar señales con correlación cruzada utilizando el paquete monitoR. Este paquete tiene como objetivo facilitar la detección de plantillas (‘templates’) acústicas. El código aquí es similar pero mucho menos detallado que la viñeta de monitoR, por lo que recomiendo mirar la viñeta si desea obtener más información.

monitoR ejecuta una correlación-cruzada entre los archivos de sonido para buscar las señales utilizando plantillas previamente definidas. Por lo tanto, las plantillas deben ser ejemplos de las señales que queremos detectar. Acá se muestra cómo funciona el paquete usando la misma grabación del ejemplo anterior.

Primero necesitamos crear la plantilla. Solo tenemos que proporcionar el nombre del archivo de sonido donde se encuentra la plantilla, el inicio y el final, y el rango de frecuencia (una anotación). Cargaremos el primer canto detectado en el código anterior:

library(monitoR)

pl1 <- makeCorTemplate("./ejemplos/deteccion/LBH.374.SUR-2.wav", t.lim = c(ad$start[1], ad$end[1]), wl = 300, ovlp = 90, frq.lim = c(1, 11), dens = 1, name = "pl1")

## 
## Automatic point selection.
## 
## Done.

Ahora podemos correr la correlación sobre el archivo completo:

cscores <- corMatch(survey = "./ejemplos/deteccion/LBH.374.SUR-2.wav", templates = pl1, parallel = FALSE, show.prog = FALSE, time.source = "fileinfo", cor.method = "pearson", warn = FALSE)
## 
## Starting  pl1 . . .
##  Fourier transform on survey . . .
##  Continuing. . .
## 
##  Done.

Los picos de deteccion se pueden extraer con la función findPeaks() y graficarlos así:

cdetects <- findPeaks(cscores)
## 
## Done with  pl1
## Done
# graficar
plot(cdetects, hit.marker="points")

Sin embargo esa visualización no es útil para archivos largos. Alternativamente podemos extraer los valores de las detecciones y usar warbleR para visualizarlas. Las detecciones se pueden extraer así:

dtcs <- cdetects@detections

 

  • Convierta las detecciones producidas con monitoR a un cuadro de selección con el formato de warbleR

  • Utilice la función full_spec() para visualizar las detecciones

 

Detectar rango de frecuencias

Para definir el rango de frecuencia en una anotación normalmente involucra “dibujar” manualmente los cuadros de selección en Raven/Audacity/Syrinx. Una forma alternativa, y potencialmente menos subjetiva, es inferir el rango usando la distribución de energía en el dominio de la frecuencia aplicando umbrales de amplitud en los espectros. Hay 2 funciones de warbleR que hacen exactamente eso:

  • freq_range_detec(): detecta el rango de frecuencia de las señales en los objetos ‘wave’ (como una función sewave). Puede producir imágenes en la ventana gráfica si plot = TRUE.

  • freq_range(): aplicafreq_range_detec() de forma iterativa en las señales que figuran en un cuadro de selección (como la mayoría de las funciones de warbleR). Se producen archivos de imagen si img = TRUE los cuales incluyen un espectrograma y un espectro de frecuencia para cada selección.

freq_range_detec

freq_range_detec funciona en objetos ‘wave’. En este ejemplo, lo usamos para detectar el rango de frecuencia en la primer nota de ‘tico’:

w2 <- readWave("./ejemplos/deteccion/LBH.374.SUR-2.wav", from = ad$start[1], 
               to = ad$end[1], units = "seconds")

data(tico)

tico1 <- cutw(tico, from = 0, to =  0.5, output = "Wave")

freq_range_detec(tico1, bp = c(2, 9.6), fsmooth = 1, threshold = 8)

##   bottom.freq top.freq
## 1     2.49165  4.91715

freq_range

Como se mencionó anteriormente, el rango de frecuencia se puede calcular para toda la selección en un cuadro de selección usando freq_range:

fr_ad <- freq_range(X = ad, bp = c(2, 12), fsmooth = 0.001, ovlp = 95, 
                          wl = 200, threshold = 10, img = FALSE)

head(fr_ad)
##         sound.files selec     start       end bottom.freq top.freq
## 1 LBH.374.SUR-2.wav     1 0.3325400 0.4673247     2.97675  8.70975
## 2 LBH.374.SUR-2.wav     2 0.8496606 0.9728126     2.97675  8.70975
## 3 LBH.374.SUR-2.wav     3 1.3889354 1.5192757     3.19725  8.48925
## 4 LBH.374.SUR-2.wav     4 1.9285731 2.0534712     3.19725  8.70975
## 5 LBH.374.SUR-2.wav     5 2.4643559 2.5838571          NA  8.70975
## 6 LBH.374.SUR-2.wav     6 2.9814085 3.1123383     2.97675  8.48925

 

Ahora tenemos un cuadro de selección con las “coordenadas” de tiempo y frecuencia para cada canto en el archivo de audio.

 

  • Utilice la función full_spec() para visualizar las selecciones en el cuadro de selección “fr_ad”

  • Convierta el cuadro de selección “fr_ad” a un cuadro de selección extendido

 

Información de la sesión

## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.2 LTS
## 
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=es_CR.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=es_CR.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=es_CR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] monitoR_1.0.7      kableExtra_1.1.0   warbleR_1.1.16    
## [4] NatureSounds_1.0.1 seewave_2.1.3      tuneR_1.3.3       
## [7] maps_3.3.0        
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.1        pracma_2.2.5      highr_0.8        
##  [4] pillar_1.3.1      compiler_3.5.3    bitops_1.0-6     
##  [7] iterators_1.0.10  tools_3.5.3       Sim.DiffProc_4.3 
## [10] digest_0.6.18     viridisLite_0.3.0 evaluate_0.13    
## [13] tibble_2.1.1      fftw_1.0-5        pkgconfig_2.0.2  
## [16] rlang_0.3.4       rstudioapi_0.10   yaml_2.2.0       
## [19] parallel_3.5.3    xfun_0.6          xml2_1.2.0       
## [22] httr_1.4.0        stringr_1.4.0     knitr_1.22       
## [25] hms_0.4.2         webshot_0.5.1     glue_1.3.1       
## [28] R6_2.4.0          dtw_1.20-1        jpeg_0.1-8       
## [31] pbapply_1.4-0     rmarkdown_1.12    soundgen_1.4.0   
## [34] readr_1.3.1       magrittr_1.5      scales_1.0.0     
## [37] htmltools_0.3.6   MASS_7.3-51.1     rvest_0.3.3      
## [40] colorspace_1.4-1  Deriv_3.8.5       stringi_1.4.3    
## [43] proxy_0.4-23      munsell_0.5.0     signal_0.7-6     
## [46] RCurl_1.95-4.12   crayon_1.3.4      rjson_0.2.20