오디오 녹음에서 피크 수 감지


12

오디오 녹음 모음에서 음절 수를 감지하는 방법을 찾으려고합니다. 웨이브 파일에서 좋은 프록시가 최고라고 생각합니다.

다음은 영어로 말하는 파일로 시도한 것입니다 (실제 사용 사례는 Kiswahili입니다). 이 예제 녹음의 대본은 "이것은 타이머 기능을 사용하려고합니다. 나는 일시 정지, 발성 중입니다." 이 구절에는 총 22 개의 음절이 있습니다.

wav 파일 : https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0

seewaveR 의 패키지는 훌륭하고 여러 가지 잠재적 기능이 있습니다. 먼저 웨이브 파일을 가져옵니다.

library(seewave)
library(tuneR)
w <- readWave("YOURPATHHERE/test.wav")  
w
# Wave Object
# Number of Samples:      278528
# Duration (seconds):     6.32
# Samplingrate (Hertz):   44100
# Channels (Mono/Stereo): Stereo
# PCM (integer format):   TRUE
# Bit (8/16/24/32/64):    16

내가 시도한 첫 번째 것은 timer()기능이었습니다. 그것이 반환하는 것 중 하나는 각 발성 기간입니다. 이 기능은 7 음절을 식별하는데 22 음절보다 훨씬 짧습니다. 음모를 간략히 살펴보면, 발성 음이 음절과 같지 않다는 것을 알 수 있습니다.

t <- timer(w, threshold=2, msmooth=c(400,90), dmin=0.1)
length(t$s)
# [1] 7

여기에 이미지 설명을 입력하십시오

또한 임계 값을 설정하지 않고 fpeaks 기능을 시도했습니다. 54 개의 피크를 반환했습니다.

ms <- meanspec(w)
peaks <- fpeaks(ms)

여기에 이미지 설명을 입력하십시오

이것은 시간이 아닌 주파수로 진폭을 플로팅합니다. 0.005에 해당하는 임계 값 매개 변수를 추가하면 노이즈가 필터링되고 카운트가 23 개로 줄어 실제 음절 수와 거의 비슷합니다 (22).

여기에 이미지 설명을 입력하십시오

이것이 최선의 방법인지 잘 모르겠습니다. 결과는 threshold 매개 변수의 값에 민감하므로 많은 파일을 처리해야합니다. 음절을 나타내는 피크를 감지하기 위해 이것을 코딩하는 방법에 대한 더 나은 아이디어가 있습니까?


2
이것은 매우 흥미로운 질문이지만 Stack Exchange Signal Processing Q & A 사이트 에서 메소드에 대한 더 나은 도움을받을 수 있습니다 .
eipi10

알았어 고마워. 아무도 응답하지 않으면 확인합니다. 매우 감사.
Eric Green

아이디어 일 뿐이지 만 변경점 분석을 수행하는 것이 좋습니다 . 패키지 를 사용 하여 R 에서 쉽게 분석을 수행 할 수 있습니다 changepoint. 간단히 말해, 변화 점 분석은 변화감지하는 데 중점을 두며, 연결된 예제는 거래 데이터와 관련이 있지만이 기술을 사운드 데이터에 적용하는 것은 흥미로울 수 있습니다.
Konrad

나는 가장 많은 표를 얻은 답변을 받아 들일 것입니다. 이것은 다른 CV 아이디어를 구현하려는 시도입니다. 그러나 핵심 질문은 여전히 ​​남아 있습니다. 녹음의 기능을 사용하여 말하는 음절 수에 해당하는 여러 피크를 정확하게 감지하는 방법입니다. 모든 아이디어에 감사드립니다. 해결책이 있으면 여기에 다시 게시하겠습니다.
Eric Green

답변:


5

다음은 최고의 솔루션이라고 생각하지 않지만 @ eipi10은 CrossValidated 에서이 답변 을 확인하는 것이 좋습니다 . 그래서 나는했다.

일반적인 접근 방식은 데이터를 평활화 한 다음 로컬 최대 필터를 평활화하여 피크를 찾는 것입니다.

첫 번째 단계는 argmax함수 를 작성하는 것입니다.

argmax <- function(x, y, w=1, ...) {
  require(zoo)
  n <- length(y)
  y.smooth <- loess(y ~ x, ...)$fitted
  y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
  delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
  i.max <- which(delta <= 0) + w
  list(x=x[i.max], i=i.max, y.hat=y.smooth)
}

반환 값에는 질문에 답하는 로컬 최대 값 (x)의 인수와 해당 로컬 최대 값이 발생하는 x 및 y 배열의 인덱스가 포함됩니다 (i).

test(a) x와 y를 명시 적으로 정의하고 (b) 피크 수를 표시 하기 위해 플로팅 기능 을 약간 수정했습니다 .

test <- function(x, y, w, span) {
  peaks <- argmax(x, y, w=w, span=span)

  plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", 
                                              span, ", peaks = ", 
                                              length(peaks$x), sep=""))
  lines(x, peaks$y.hat,  lwd=2) #$
  y.min <- min(y)
  sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
                                    col="Red", lty=2))
  points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}

fpeaks원래 질문에서 언급 한 접근 방식 과 마찬가지로이 접근 방식에도 많은 조정이 필요합니다. 나는 이것에 들어가는 "올바른"대답 (즉, 음절 / 피크 ​​수)을 알지 못하므로 결정 규칙을 정의하는 방법을 잘 모르겠습니다.

par(mfrow=c(3,1))
test(ms[,1], ms[,2], 2, 0.01)
test(ms[,1], ms[,2], 2, 0.045)
test(ms[,1], ms[,2], 2, 0.05)

여기에 이미지 설명을 입력하십시오

이 시점 fpeaks에서 조금 덜 복잡해 보이지만 여전히 만족 스럽지는 않습니다.


황토 매개 변수가 충분한 스무딩을 수행하지 않아 만족스럽지 않을 수 있습니다. 더 부드러운 선택은 데이터의 성격과 목표에 따라 안내되어야합니다. 그것은 컴퓨팅 플랫폼이 제공하는 모든 것과 그것이 제공하는 기본값에 남겨질 것이 아닙니다.
whuber

이것은 기본값이 아닙니다. 단지 예입니다. 이 경우 감독되지 않은 학습의 더 큰 도전에 당황합니다. 녹음의 음절 수를 모르므로 파일 배치를 조정하는 방법을 잘 모르겠습니다. 상수 매개 변수는 아마도 의미가 없지만 다른 결정 규칙 (예 : 이러한 매개 변수에 대한 최적의 값을 결정하는 데 사용할 수있는 다른 웨이브 메트릭)을 설정하는 방법을 잘 모르겠습니다. 알고리즘이 이러한 매개 변수를 설정하는 데 도움이되는 훈련 세트를 만들어야한다고 생각합니다. 그래도 확실하지 않습니다.
Eric Green

에 대한 명령에서 loess스무딩 정도에 대해 명시 적으로 제공된 인수가 없습니다. 실제로 움직이는 창에서 황토를 달리는 데는 아무런 소용이 없습니다. 이미 내부적으로 수행하고 있습니다.
whuber

너의 의도를 알 겠어. 나는 그것이 w스무딩의 논거 라고 생각했다 . 이것은 원래 솔루션의 저자가 다음과 같은 기능을 설명하는 방법입니다. "환경에 따라 조정될 두 매개 변수가 있습니다. 코드는 황토의 스팬 주장이 더 부드럽습니다. "
Eric Green

그 저자 w는 매끄럽게 잃어 버릴 수는 없지만 일반적으로 창 중앙값 또는 Hanning 또는 데이터의 통계적 행동에 적합한 것으로 간주되는 매우 일반적인 접근 방식을 염두에두고 매개 변수 중 하나를 포함 했습니다. 분석가의 목표. 많은 스무더의 속성은 창의 너비에 따라 다릅니다.
whuber

1

단백질 전기 영동 프로파일을 분석하는 데 비슷한 문제가있었습니다. 프로파일의 두 번째 파생물에 msprocess R 패키지의 일부 기능을 적용하여 문제를 해결했습니다 ( https://fr.wikipedia.org/wiki/D%C3%A9pouillement_d 'une_courbe # Position_et_hauteur_du_pic 참조). http://onlinelibrary.wiley.com/doi/10.1111/1755-0998.12389/abstract;jsessionid=8EE0B64238728C0979FF71C576884771.f02t03 에 게시되었습니다.

비슷한 솔루션이 당신을 위해 일할 수 있는지 모르겠습니다. 행운을 빕니다


감사합니다, @ user17493.bis. 보충 자료로 출판 해 주셔서 감사합니다. 이 아이디어를 시도하기가 훨씬 쉬워집니다!
Eric Green

0

다음 은 자기 상관 함수에서 피크를 찾아 주기성을 추정하는 동안 이전에 사용했던 Python의 라이브러리입니다.

피크 검출을 위해 1 차 차이 / 이산 도함수를 사용하며 임계 값 및 최소 거리 (연속 피크 간) 매개 변수에 의한 튜닝을 지원합니다. 가우스 밀도 추정 및 보간을 사용하여 피크 분해능을 향상시킬 수도 있습니다 (링크 참조).

시끄러운 데이터조차도 많은 조정없이 나에게 아주 잘 작동했습니다. 시도 해봐.


감사합니다, @ tool.ish. 내가 인용 한 R 방법의 좋은 대안처럼 보입니다. 그러나 여전히 튜닝 문제가 있다고 생각합니다.
Eric Green

0

changepoint패키지를 활용하는 솔루션을 제안하고 싶습니다 . 아래의 간단한 예 는 사용 가능한 데이터에서 하나의 채널을보고 변경점으로 정의 된 피크를 식별하려고 시도합니다 .

데이터 소싱

# Libs
library(seewave)
library(tuneR)

# Download
tmpWav <- tempfile(fileext = ".wav")
download.file(url = "https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0",
              destfile = tmpWav)

# Read
w <- readWave(filename = tmpWav)

데이터 준비

# Libs
require(changepoint)

# Create time series data for one channel as an example
leftTS <- ts(data = w@left)

## Preview
plot.ts(leftTS)

plot.ts호출을 통해 생성 된 차트 : 시계열로서의 채널

변화 점 분석

changepoint패키지를 식별하기위한 옵션을 제공합니다 변경 / 피크를 데이터에. 아래 코드는 BinSeg 방법을 사용하여 3 개의 피크를 찾는 간단한 예제 만 제공합니다 .

# BinSeg method (example)
leftTSpelt <- cpt.var(data = leftTS, method = "BinSeg", penalty = "BIC", Q = 3)
## Preview
plot(leftTSpelt, cpt.width = 3)

획득 한 차트 : 일부 변경점 값을 얻을 수도 있습니다.

cpts(leftTSpelt)
[1]  89582 165572 181053

사이드 노트

제공된 예제는 주로 변경점 분석이 제공된 데이터에 적용되는 방법을 보여줍니다. cp.var함수에 전달 된 매개 변수와 관련하여주의해야합니다 . 패키지 및 사용 가능한 기능에 대한 자세한 설명은 다음 백서에 나와 있습니다.

Killick, Rebecca and Eckley, Idris (2014) changepoint : 변경점 분석을위한 R 패키지. 통계 소프트웨어 저널, 58 (3). 1-19 쪽.

ecp

ecpR 패키지를 언급 할 가치가 있습니다. 이를 ecp통해 비모수 다변량 변화 점 분석을 수행 할 수 있으며, 이는 여러 채널에서 발생하는 변화 점을 식별하려는 경우 유용 할 수 있습니다.


감사합니다, @konrad. 어느 패키지에 대해서도 몰랐으므로 데모에 시간을 내 주셔서 감사합니다. 필자는이 모든 패키지에서 근본적인 문제로 몇 개의 피크를 찾을 지 모르므로 매개 변수를 조정하는 방법을 모르겠습니다. 이것은 여전히 ​​정확한 수의 피크 (즉, 음절)를 정확하게 식별하기 위해 매개 변수를 설정하는 방법을 결정하기 위해 일부 알고리즘을 사용해야하는 상황처럼 보입니다.
Eric Green

@EricGreen 원칙적으로 변경점 분석을 통해 분포를 보면 피크를 식별 할 수 있습니다. 적절한 방법, 위약금 등을 적용하는 것입니다. 프로세스에 대해 자세히 설명하면서 이전 주석에 링크 된 웹 사이트를 살펴 보는 것이 좋습니다.
Konrad

문자 그대로 분포를 시선으로 볼 것인지 확실하지 않습니다. 2000 개의 파일이 있으며이를 자동화 할 방법이 필요합니다. 각 파일을 검사 할 수 있어도 음절 수를 피크로보기가 어렵습니다. 어쩌면 나는 조밀하고 있으며이 접근법의 장점을 보러 올 것입니다. 나는 여전히 각 파일의 매개 변수를 자동 조정하는 방법이 필요하므로 감지 된 피크 수는 음절 수의 정확한 프록시입니다.
Eric Green

@EricGreen 아니오, 물론 문학은 아닙니다. cpt 함수 중 하나에 전달되어야하는 적절한 매개 변수를 찾으면 여러 오브젝트에서 실행할 수 있습니다. 언어학에 대한 전문 지식이 없기 때문에 음절이 시계열 데이터에서 관찰 된 일반적인 피크에 해당하는지 알 수 없습니다.
Konrad

잡았다. 이 특정 사용 사례에 대해 "적절한 매개 변수를 추출"단계를 방해하고 있다고 생각합니다. 그러나 나는 모든 아이디어를 고맙게 생각했고 내가 시도한 것의 좋은 대안이 될 수있는 몇 가지 새로운 패키지에 대해 배웠습니다.
Eric Green
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.