İki ses dosyasının benzer olduğunu kanıtlamak için çapraz korelasyonu nasıl uygularım?


58

Benzer olduklarını kanıtlamak için iki ses dosyasının çapraz korelasyonunu yapmalıyım. İki ses dosyasının FFT'sini aldım ve güç spektrum değerlerini ayrı dizilerde aldım.

Onları çapraz ilişkilendirip benzer olduklarını kanıtlamak için daha fazla nasıl ilerlemeliyim? Bunu yapmanın daha iyi bir yolu var mı? Herhangi bir temel fikir öğrenmem ve uygulamam için yardımcı olacaktır.


İki rastgele sinyal vektörünün çapraz korelasyonu göz önüne alındığında. İki vektörü MATLAB'de elde etmek için tersini nasıl uygularsınız. John Muhehe

Yanıtlar:


56

Çapraz korelasyon ve evrişim yakından ilişkilidir. Kısacası, FFT’lerle evrişim yapmak için

  1. giriş sinyallerini sıfırlayın (dalganın en az yarısı "boş" olacak şekilde sonuna sıfır ekleyin)
  2. her iki sinyalin FFT'sini alın
  3. sonuçları bir araya getirin (element-bilge çarpma)
  4. ters FFT yapmak

conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))

Sıfırlama işlemini yapmanız gerekir, çünkü FFT metodu aslında dairesel çapraz korelasyondur, yani sinyal uçlarda sarılır. Öyleyse, üst üste binmekten kurtulmak, sonsuza kadar sıfır bir sinyali simüle etmek için yeterince sıfır eklersiniz.

Evrişim yerine çapraz korelasyon elde etmek için , ya FFT yapmadan önce sinyallerden birini zamana tersine çevirmeniz ya da FFT'den sonra sinyallerden birinin karmaşık konjugatını almanız gerekir:

  • corr(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros[reversed]))
  • corr(a, b) = ifft(fft(a_and_zeros) * conj(fft(b_and_zeros)))

hangisi donanım / yazılımınızla daha kolaydır? Otokorelasyon için (bir sinyalin kendisiyle çapraz korelasyonu), karmaşık konjugatı yapmak daha iyidir, çünkü o zaman sadece bir kez FFT'yi hesaplamanız gerekir.

Sinyaller gerçekse, gerçek FFT'leri (RFFT / IRFFT) kullanabilir ve hesaplama zamanınızın yarısından fazlasını yalnızca spektrumun yarısını hesaplayarak kazanabilirsiniz.

Ayrıca , FFT'nin optimize ettiği daha büyük bir boyuta dolgulu olarak hesaplama süresinden tasarruf edebilirsiniz ( FFTPACK için 5 pürüzsüz bir sayı , FFTW için ~ pürüzsüz bir sayı veya basit bir donanım uygulaması için 2 gücü gibi).

İşte kaba kuvvet korelasyonuna kıyasla Python of FFT korelasyonuna bir örnek: https://stackoverflow.com/a/1768140/125507

Bu size ofset ve benzerlik ölçüsü olan çapraz korelasyon fonksiyonunu verecektir. Dalgaların birbirleriyle "sıralandığı" dengeyi sağlamak için, korelasyon fonksiyonunda bir tepe noktası olacaktır:

korelasyon fonksiyonunda zirve

Zirvenin x değeri, negatif veya pozitif olabilen uzaklıktır.

Bunu yalnızca iki dalga arasındaki dengeyi bulmak için kullandım. Zirvede parabolik / kuadratik enterpolasyon kullanarak ofsetin daha kesin bir tahminini (örneklerin çözünürlüğünden daha iyi) alabilirsiniz .

-1 ile 1 arasında bir benzerlik değeri elde etmek için (sinyallerden birini diğerinin arttıkça azaldığını gösteren negatif bir değer), girişlerin uzunluğuna, FFT'nin uzunluğuna, özel FFT uygulamanıza göre genliği ölçeklendirmeniz gerekir. ölçekleme, vb. Bir dalganın kendisiyle özdeşleşmesi size mümkün olan maksimum eşleşmenin değerini verecektir.

Bunun sadece aynı şekle sahip dalgalar üzerinde çalışacağını unutmayın. Farklı bir donanımda örneklenmişlerse veya biraz gürültü eklenmişlerse, ancak yine de aynı şekle sahiplerse, bu karşılaştırma işe yarayacaktır, ancak dalga şekli filtreleme veya faz kaymalarıyla değiştirilmişse, aynı şekilde ses çıkarabilir ancak kazanabilir aynı zamanda korelasyon yok.


3
Sıfır dolgusu en az N = beden (a) + beden (b) -1, tercihen 2 değerine yuvarlanmış olmalıdır. -1 ile 1 arasında bir değer elde etmek için, norm (a) * normuna (b) bölün. bu, belirli bir gecikme için N-uzayda iki vektör arasındaki açının kosinüsünü verir (yani dairesel kayma modulo N). Aşırı gecikmelerde, birbiriyle örtüşen pek fazla örnek yoktur (sadece en uçta bir tane), bu nedenle norm (a) * normuna (b) bölünmek, bu korelasyonları 0'a doğru yönlendirecektir (yani, N-uzayında bağıl dikliklerini gösterir). .
Eryk Sun

1
Açıklamasında bir hata olabileceğini düşünüyorum. Bir FFT vermek terimi ile terimini FFTs araya çarparak olmamalı konvolüsyon sinyalleri, değil FFT çapraz korelasyon ? Anladığım kadarıyla çapraz korelasyonun FFT'sini almak için, iFFT'yi almadan önce FFT vektörlerinden birinin kompleks konjugatını terim-çarpımlarında kullanmak gerekir.
Dilip Sarwate

@DilipSarwate: Evet, haklısın. Ayrıca bir yanıtı eklediğim zaman yönünde bir sinyal geri alabilirsiniz.
Endolith

1
"Neden donanım zaman aşımına uğramak zor?" Durumlarda çok da, veri hesaplamaları olduklarını beklenti içinde sistolik dizilerde saklanır yerel yani , saklanan -inci hücrenin, sadece en yakın komşuları ile etkileşim . Gönderme hücre # için ve gönderme hücre # için ve tüm için yapıyorum kablolama maliyetlerini, kablolama gecikmeleri artan ayrıca (ve dolayısıyla maksimum elde saat hızını azaltır) ve tüm çünkü Teller birbirinin üzerinden geçmeli, yönlendirme problemleri yaratır. Mümkünse Bu kaçınılmalıdır, ve bu durumda, bu ise önlenebilir.i x [ ± i ] x [ i ] ( N - i ) x [ N - i ] i ix[i]ix[±i]x[i](Ni)x[Ni]ii
Dilip Sarwate

1
@ Leo element-bilge çarpma. n-by-1 dizi x n-by-1 dizi = n-by-1 dizi Ben cevap olarak bu "örnek-örnek" denir.
endolith

17

Korelasyon , iki zaman diliminin (sizin durumunuzdaki ses örnekleri) benzerliğini bir sayıyla ifade etmenin bir yoludur. Aşağıdaki şekilde uygulanan bir kovaryans uyarlamasıdır :

period = 1/sampleFrequency;
covariance=0;

for (iSample = 0; iSample<nSamples; iSample++)
    covariance += (timeSeries_1(iSample)*timeSeries_2(iSample))/period;
    //Dividing by `period` might not even be necessary

Korelasyon, her iki zaman serisinin standart sapmalarının çarpımına bölünen kovaryans olan normalleştirilmiş kovaryans versiyonudur. Korelasyon, hiçbir korelasyon olmadığında (tamamen benzer değil) 0 değerini ve toplam korelasyon için 1 değerini (tamamen benzer şekilde) verecektir.

İki ses örneğinin benzer olabileceğini ancak senkronize edilmediğini hayal edebilirsiniz. Yani nerede çapraz korelasyon . Gelir Sen onlardan biri bir örnek tarafından değiştirdi zaman serileri arasındaki korelasyonu hesaplamak:

for (iShift=0; iShift<nSamples; iShift++)
    xcorr(iShift) = corr(timeSeries_1, timeSeries_2_shifted_one_sample);

Ardından corrserideki maksimum değeri arayın ve bitirdiniz. (veya yeterli bir ilişki bulursanız durun) Elbette biraz daha fazlası var. Standart sapmayı uygulamanız ve biraz hafıza yönetimi yapmanız ve zaman kaydırma işlemlerini uygulamanız gerekir. Tüm ses numunelerinizin uzunluğu eşit ise, kovaryansı normalleştirmeden yapabilir ve devam edip çapraz kovaryansı hesaplayabilirsiniz.

Önceki sorunuza güzel bir ilişki : Fourier analizi sadece çapraz kovaryansın bir uyarlamasıdır. Bir zaman serisini kaydırmak ve diğer sinyal ile kovaryansları hesaplamak yerine, bir sinyal ile farklı frekanslardaki bir dizi (ko) sinüs dalgası arasındaki kovaryansları hesaplarsınız. Hepsi aynı prensibe dayanıyor.


1
0'ın korelasyon olmadığını ve 1'in toplam korelasyon olduğunu söylemiştiniz. Sadece -1 ile negatif korelasyonun tamamlandığını not etmek istiyorum. Olduğu gibi, -1, örnek 1'in örnek 2'nin zıttı olduğunu belirtir. Eğer bir X, Y grafiği üzerinde düşünürseniz, negatif eğime sahip bir çizgiye karşı pozitif eğimli bir çizgidir. 0'a yaklaştıkça çizgi "şişman" olur.
Kellenjb

@kellenjb, Evet, ama muhtemelen şunu söyleyebilirim, muhtemelen ilgilendiğiniz korelasyonun büyüklüğü. 1 veya -1, sinyallerin birbirlerini doğrudan etkilediği anlamına gelir.
Kortuk

13

Sinyal işlemede çapraz korelasyon (MATLAB'da xcorr) ters çevrilmiş iki sekanstan biriyle bir evrişim işlemidir. Zaman tersine dönme, frekans alanındaki karmaşık eşlenmeye karşılık geldiğinden, çapraz korelasyonu aşağıdaki gibi hesaplamak için DFT'yi kullanabilirsiniz:

R_xy = ifft(fft(x,N) * conj(fft(y,N)))

burada N = beden (x) + beden (y) - 1 (tercihen 2 kuvvete yuvarlanmış) DFT'nin uzunluğudur.

DFT'lerin çarpımı, zaman içindeki dairesel evrişime eşdeğerdir . Her iki vektörün de N uzunluğuna sıfır olarak döşenmesi, y'nin dairesel olarak kaydırılan bileşenlerinin x ile üst üste binmesini önler; bu da sonucu, x'in ve zamanının ters çevrilmiş y ile aynı olmasını sağlar.

1'lik bir gecikme, y'nin sağdaki dairesel bir kayması, -1'lik bir gecikme ise bir soldaki dairesel kaymadır. Çapraz korelasyon, tüm gecikmeler için basit bir nokta ürün dizisidir. Standart fft sıralamasına göre, bunlar aşağıdaki gibi erişilebilir bir dizide olacaktır. 0 ile boy (x) -1 arasındaki endeksler pozitif gecikmelerdir. N-boy (y) +1 ila N-1 arasındaki endeksler ters sıradaki negatif gecikmelerdir. (Python'da negatif gecikmelere R_xy [-1] gibi negatif endekslerle kolayca erişilebilir.)

Sıfırdan doldurulmuş x ve y'yi N boyutlu vektörler olarak düşünebilirsiniz. Belirli bir gecikme için x ve y nin nokta çarpımıdır |x|*|y|*cos(theta). X ve y normları dairesel kaymalar için sabittir, bu nedenle onları ayırmak, açı tetanın sadece değişen kosinüsünü bırakır. Eğer x ve y (belirli bir gecikme için) N uzayda dikse, korelasyon 0'dır (yani teta = 90 derece). Eş-doğrusal ise, değer 1 (pozitif korelasyonlu) veya -1 (negatif korelasyonlu, yani teta = 180 derece) olur. Bu, birliğe normalize edilmiş çapraz korelasyona yol açar:

R_xy = ifft(fft(x,N) * conj(fft(y,N))) / (norm(x) * norm(y))

Bu, yalnızca örtüşen kısımlar için normları yeniden hesaplayarak tarafsız yapılabilir, ancak daha sonra zaman alanındaki tüm hesaplamayı da yapabilirsiniz. Ayrıca, farklı normalleştirme sürümleri göreceksiniz. Birliğe normalize olmak yerine, bazen çapraz korelasyon M (önyargılı) tarafından normalleştirilir, burada M = maks (boyut (x), boyut (y)) veya M- | m | (4. gecikmenin tarafsız bir tahmini).

Maksimum istatistiksel önem için, korelasyonu hesaplamadan önce ortalama (DC önyargı) kaldırılmalıdır. Buna çapraz kovaryans (MATLAB'da xcov) denir:

x2 = x - mean(x)
y2 = y - mean(y)
phi_xy = ifft(fft(x2,N) * conj(fft(y2,N))) / (norm(x2) * norm(y2))

Bu dizinin son boyutta olmalıdır demek 2*size (a) + size(b) - 1ya 2*size (b) + size (a) - 1? Ancak her iki durumda da iki yastıklı dizi farklı boyutlardadır. Çok fazla sıfırla doldurmanın sonucu nedir?

@RobertK Çapraz korelasyon dizisinin en azından eryksun cevabında dediği gibi a ve b (eksi bir) uzunluklarının toplamının uzunluğu olması gerekir. Basit olması için, uzunluk genellikle uzun vektörün uzunluğunun iki katı olarak alınır (bazen verimli bir FFT kullanmak için bir sonraki büyük güce yuvarlanır ). Seçim, müşteri gecikmeden karar verdiğinde daha uzun bir vektörün kendi kendine korelasyonunu istediğini belirlediğinde yardımcı olur. Çok fazla sıfırla doldurmanın bir sonucu ilave hesaplamadır, ancak bu daha verimli FFT uygulamaları ile iyileştirilebilir. 2
Dilip Sarwate

@RobertKJ: Vardiya başına bir çıktı, bir örnek minimum örtüşme ile bilerliyorsunuz a. Bu size(a)olumlu ve size(b) - 1olumsuz gecikmelere neden olur. Ters, N-nokta DFTS ürünü dönüşümü kullanılarak, indisleri 0ile size(a)-1pozitif gecikme vardır ve endeksleri N-size(b)+1üzerinden N-1ters negatif gecikme bulunmaktadır.
Eryk Sun

3

Eğer Matlab kullanıyorsanız cross correlate işlevini deneyin:

c= xcorr(x,y)

İşte Matlab belgeleri:

xcorrrastgele bir sürecin çapraz korelasyon dizisini tahmin eder. Otokorelasyon özel bir durum olarak ele alınır.

...

c = xcorr(x,y)uzunluk vektörleri ( ) olan xve uzunluk 2 * N-1 vektöründe çapraz korelasyon dizisini döndürür . Eğer ve aynı uzunlukta değildir, daha kısa vektör daha da vektörün uzunluğuna sıfır getirilmiş olup. yNN > 1xy

korelasyon http://www.mathworks.com/help/toolbox/signal/ref/eqn1263487323.gif


Bağlantı kopmuş gibi görünüyor.
Danijel

2

Ses dosyalarını karşılaştırmanın hızlı ve basit bir yolu. Ses dosyasını alın, bir kopyasını alın, bir basamağa, yan yana yapıştırın, 2 stereo kanalda, stereo parçalardan birinin üzerine fazı ters çevirin, her iki dosyayı da yakınlaştırma modunda hizalayın. her iki dosyanın başında aynı genliğe sahip, sonra oynat, eğer tam bir sessizlik varsa, o zaman her iki dosya da aynıdır, eğer bir fark varsa, oldukça açık bir şekilde duyacaksınız!


1

Burada en çok yazdığı gibi korelasyon kullanmalısınız.

Sadece 2 faktörü göz önünde bulundurun:

  1. Hacim farklı ölçeklenirse, korelasyonu normalleştirmelisiniz.
  2. Zamanın ölçeklenmesi varsa, Dinamik Zaman Çözme özelliğini kullanabilirsiniz.

0

Farkı bulmanın en kolay yolu IMO, zaman alanındaki iki ses sinyalini çıkarmaktır. Eşitlerse, her zaman noktasındaki sonuç sıfır olur. Eşit değilse, aralarındaki fark çıkarıldıktan sonra bırakılır ve doğrudan dinleyebilirsiniz. Ne kadar benzer olduklarının hızlı bir şekilde ölçülmesi, bu farkın RMS değeri olacaktır. Bu genellikle örneğin MP3 veya WAV dosyasının MP3 farkını duymak için ses karıştırma ve mastering işleminde yapılır. (Bir sinyalin fazını ters çevirmek ve bunları eklemek, çıkartma ile aynıdır. Bu, DAW yazılımında yapıldığında kullanılan yöntemdir.) Bunun çalışması için mükemmel zaman ayarlı olmaları gerekir. Eğer değilseniz, onları ilk on tepe noktasını tespit etmek, tepe noktalarının ortalama ofsetini hesaplamak ve bir sinyali kaydırmak gibi hizalamak için bir algoritma geliştirebilirsiniz.

Frekans alanına dönüşmek ve teklif ettiğiniz sinyallerin güç spektrumlarını karşılaştırmak, bazı zaman alanı bilgisini görmezden geliyor. Örneğin, geriye oynatılan ses, ileri oynatıldığında aynı spektruma sahip olur. Böylece, iki çok farklı ses sinyali aynı spektruma sahip olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.