Değişken orandan sabit orana yeniden örnekleme algoritması nedir?


27

Değerlerini zaman damgası ve değeri ile rapor eden bir sensörüm var. Ancak, sabit bir oranda okumalar üretmez.

Değişken oranlı verileri başa çıkmada zor buluyorum. Çoğu filtre sabit bir örnekleme oranı bekliyor. Grafik çizmek de sabit bir örnekleme oranıyla daha kolaydır.

Değişken bir örnekleme oranından sabit bir örnekleme oranına yeniden örnekleme için bir algoritma var mı?


Bu programcıların çapraz gönderisi. Bana sorulacak daha iyi bir yer olduğu söylendi. programmers.stackexchange.com/questions/193795/…
FigBug

Sensörün bir okumayı ne zaman raporlayacağını ne belirler? Sadece okuma değiştiğinde bir okuma gönderir mi? Basit bir yaklaşım, oluşturulan okumalar arasındaki en kısa süreden sadece daha küçük bir "sanal örnekleme aralığı" (T) seçmek olacaktır. Algoritma girişinde, yalnızca en son bildirilen okumayı (CurrentReading) saklayın. Algoritma çıktısında, CurrentReading'i her T saniyede bir "yeni örnek" olarak raporlayın, böylece filtre veya grafik hizmeti okumaları sabit bir hızda (her T saniyede) alır. Bu durumda sizin için yeterli olup olmadığını hiç bir fikrim yok.
user2718

Her 5 veya 10ms'de bir örneklemeye çalışır. Ancak bu düşük öncelikli bir görevdir, bu yüzden kaçırılabilir veya gecikebilir. Zamanlamanın 1 msn doğru olduğunu düşünüyorum. PC'de işlem yapılır, gerçek zamanlı değil, bu nedenle uygulanması daha kolaysa yavaş bir algoritma olur.
FigBug

1
Fourier yeniden yapılanmasına baktınız mı? Düzensiz örneklenmiş verilere dayanan bir fourier dönüşümü vardır. Olağan aoproach, dörtlü bir görüntüyü eşit örneklenmiş zaman alanına geri döndürmektir.
mbaitoff

3
Örneklemekte olduğunuz altta yatan sinyalin özelliklerini biliyor musunuz? Düzensiz aralıklı veriler, ölçülen sinyalin bant genişliğine kıyasla hala oldukça yüksek bir örnekleme hızındaysa, eşit aralıklı bir zaman ızgarasına polinom enterpolasyonu gibi basit bir şey düzgün çalışabilir.
Jason R,

Yanıtlar:


21

En basit yaklaşım, Jim Clay'in önerdiği gibi bir çeşit spline enterpolasyonu yapmaktır (doğrusal veya başka şekilde). Bununla birlikte, toplu işleme lüksüne sahipseniz ve özellikle önceden tanımlanmış düzensiz örneklere sahipseniz, son derece zarif "mükemmel bir yeniden yapılandırma" algoritması vardır. Sayısal nedenlerle, her durumda pratik olmayabilir, ancak en azından kavramsal olarak bilmeye değer. İlk önce bu makalede okudum .

İşin püf noktası, üniform olmayan örnekler kümenizi , sinc interpolasyonu yoluyla muntazam örneklerden yeniden yapılmış olduğunu düşünmektir . Makaledeki notaları takip ederek:

y(t)=k=1Ny(kT)sin(π(tkT)/T)π(tkT)/T=k=1Ny(kT)sinc(tkTT).

Bunun , bilinmeyenlerin eşit aralıklı örnekler olan olduğu her bir tek tip olmayan örnek için bir doğrusal denklem kümesi sağladığını unutmayın :y ( k, T )y(t)y(kT)

[y(t0)y(t1)y(tm)]=[sinc(t0TT)sinc(t02TT)sinc(t0nTT)sinc(t1TT)sinc(t12TT)sinc(t1nTT)sinc(tmTT)sinc(tm2TT)sinc(tmnTT)][y(T)y(2T)y(nT)].

Yukarıdaki denklemde, , bilinmeyen üniform örneklerin sayısıdır, , üniform örnek oranının tersidir ve , üniform olmayan örneklerin sayısıdır (ki, büyük olabilir ). Bu sistemin en küçük kareler çözümünü hesaplayarak, homojen örnekler yeniden yapılandırılabilir. Teknik olarak, sadece biçimli olmayan örnekleri gereklidir, ama "dağılmış" şekline bağlı olarak, zaman içinde, interpolasyon matris korkunç olabilir edilir kötü durumdaki . Bu durumda, daha fazla düzgün olmayan örneklerin kullanılması genellikle yardımcı olur.T m nnTmnn

Bir oyuncak örneği olarak, yukarıdaki yöntem ile hafif sarsıntılı bir ızgarada kübik spline enterpolasyonu arasında bir karşılaştırma ( numpy kullanarak ):

Sinc ve Cubic Spline Üniform Olmayan Örneklerin Yeniden İnşası

(Yukarıdaki taslağı yeniden oluşturma kodu bu cevabın sonuna eklenmiştir)

Söylenenlerin tümü, yüksek kaliteli, sağlam yöntemler için, aşağıdaki belgelerden birinde bir şeyle başlamak muhtemelen daha uygun olacaktır:

A. Aldroubi ve Karlheinz Grochenig, Değişmeyen Değişken Alanlarda Düzgün Olmayan Örnekleme ve Yeniden Yapılanma , SIAM Rev., 2001, no. 4, 585-620. ( pdf bağlantısı ).

K. Grochenig ve H. Schwab, Değişmeyen Değişen Alanlarda Tekdüzen Örneklemede Hızlı Lokal Yeniden Yapılanma Yöntemleri , SIAM J. Matrix Anal. Appl., 24 (2003), 899-913.

-

import numpy as np
import pylab as py

import scipy.interpolate as spi
import numpy.random as npr
import numpy.linalg as npl

npr.seed(0)

class Signal(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def plot(self, title):
        self._plot(title)
        py.plot(self.x, self.y ,'bo-')
        py.ylim([-1.8,1.8])
        py.plot(hires.x,hires.y, 'k-', alpha=.5)

    def _plot(self, title):
        py.grid()
        py.title(title)
        py.xlim([0.0,1.0])

    def sinc_resample(self, xnew):
        m,n = (len(self.x), len(xnew))
        T = 1./n
        A = np.zeros((m,n))

        for i in range(0,m):
            A[i,:] = np.sinc((self.x[i] - xnew)/T)

        return Signal(xnew, npl.lstsq(A,self.y)[0])

    def spline_resample(self, xnew):
        s = spi.splrep(self.x, self.y)
        return Signal(xnew, spi.splev(xnew, s))

class Error(Signal):

    def __init__(self, a, b):
        self.x = a.x
        self.y = np.abs(a.y - b.y)

    def plot(self, title):
        self._plot(title)
        py.plot(self.x, self.y, 'bo-')
        py.ylim([0.0,.5])

def grid(n): return np.linspace(0.0,1.0,n)
def sample(f, x): return Signal(x, f(x))

def random_offsets(n, amt=.5):
    return (amt/n) * (npr.random(n) - .5)

def jittered_grid(n, amt=.5):
    return np.sort(grid(n) + random_offsets(n,amt))

def f(x):
    t = np.pi * 2.0 * x
    return np.sin(t) + .5 * np.sin(14.0*t)

n = 30
m = n + 1

# Signals
even   = sample(f, np.r_[1:n+1] / float(n))
uneven = sample(f, jittered_grid(m))
hires  = sample(f, grid(10*n))

sinc   = uneven.sinc_resample(even.x)
spline = uneven.spline_resample(even.x)

sinc_err   = Error(sinc, even)
spline_err = Error(spline, even)

# Plot Labels
sn = lambda x,n: "%sly Sampled (%s points)" % (x,n)
r  = lambda x: "%s Reconstruction" % x
re = lambda x: "%s Error" % r(x)

plots = [
    [even,       sn("Even", n)],
    [uneven,     sn("Uneven", m)],
    [sinc,       r("Sinc")],
    [sinc_err,   re("Sinc")],
    [spline,     r("Cubic Spline")],
    [spline_err, re("Cubic Spline")]
]

for i in range(0,len(plots)):
    py.subplot(3, 2, i+1)
    p = plots[i]
    p[0].plot(p[1])

py.show()

Güzel yöntem ve kod. Fakat OP'lerin sorusu olduğunu düşündüğüm ile birkaç (örneğin [0 1 - 3 4 5 - 7 8] T), 0 matrisindeki sinc değil mi? Tabii bunu düzeltmenin bir yolu var, ama. tj=jT
denis

Anladığım kadarıyla, OP'nin sorusu düşmüş ve / veya gecikmiş örnekler hakkındadır. Bu yöntem temel olarak sadece önceden tanımlanmış bir denklem sistemidir, bu nedenle bırakılan örnekler yalnızca bilinmeyenler olarak görünür (0 değeri olan veri noktaları olarak değil). Ya da belki de istediğin bu değil?
datageist

tümü tam sayı ise (T = 1) ne olur ? Diyelim ki için veri noktaları [ ] , sıfır olmayan bir tamsayı kümesi var; örneğin {-1 1} veya {-2 -1 1 2}; enterpolasyonlu , bağımsız değil - yoksa bir şeyi mi kaçırdım? j , y j j J y 0 = 0 y jtjj,yjjJy0=0yj
denis

Örnekleme oranları tam olarak aynıysa (eksik / puan), enterpolasyon matrisi seyrek olacaktır (çünkü her çıktı yalnızca bir girişe bağlıdır). Genel olarak, tek tip olmayan örneklerin ortalama örnek oranı tek tip yeniden yapılanma oranından daha büyük olmalıdır. Başka bir deyişle, "boşlukları doldurmak" için daha düşük bir oranda yeniden yapılandırmanız gerekir (örneğin T> 1). Ama amacını anlıyorum.
datageist

2
Bunun gibi cevaplar saf altın.
Ahmed Fasih

6

Bu, zaman uyumsuz bir örnekleme hızı dönüştürme sorunu gibi geliyor. Bir örnekleme oranından diğerine dönüştürmek için, sinincin sürekli zaman gösterimini sinc enterpolasyonu yaparak hesaplayabiliriz, sonra yeni örnekleme hızımızda yeniden örnekleyebiliriz. Yaptıkların pek farklı değil. Sabit olan örnekleme zamanları için sinyalinizi yeniden örneklemeniz gerekir.

Sürekli zaman sinyali, her numunenin bir sinc işlevi ile sarılmasıyla hesaplanabilir. Sinc işlevi sürekli olarak devam ettiğinden, pratik sonlu uzunlukta pencereli bir sincap gibi daha pratik bir şey kullanıyoruz. İşin zor yanı, numunelerinizin zaman içinde hareket etmesi nedeniyle, yeniden örnekleme yapılırken her numune için farklı bir faz kaymasına sahip bir sincap kullanılması gerekebilir.

Örneklenen sinyalden sürekli zaman sinyali:

x(t)=n=x[n]sinc(tnTsTs)

burada örnek zamanınızdır. Ancak, sizin durumunuzda, örnekleme zamanınız sabit değildir. Bu yüzden, o numunedeki numune zamanı ile değiştirmeniz gerektiğini düşünüyorum.Ts

x(t)=n=x[n]sinc(tnTs[n]Ts[n])

Bundan, sinyali yeniden örnekleyebilirsiniz:

y[n]=x(nTns )

burada istenen örnekleme zamanıdır.Tns

Hepsini bir araya getirerek:

y[m]=n=x[n]sinc(mTnsnTs[n]Ts[n])

Bu nedensel veya izlenebilir olmadığından, sinc işlevi sonlu destek işleviyle ve buna göre ayarlanan toplama sınırlarıyla değiştirilebilir.

Çekirdeğin (t) pencereli bir sinc ya da 2k uzunluğundaki benzer bir işlevi olmasına izin verin:

y[m]=n=kkx[n]kernel(mTnsnTs[n]Ts[n])

Umarım bu yardımcı olur ... ama yol boyunca bir hata yapmış olabilirim ve biraz matematik yoğun olabilir. Daha fazla bilgi için örneklem oranı dönüşümünü araştırmanızı tavsiye ederim. Belki buradaki bir başkası da daha iyi bir açıklama ya da çözüm sağlayabilir.


Bir sinyalin sürekli bir versiyonunu yeniden oluşturmak için bir sinc işlevi kullanmak, örneklerin eşit aralıklarla yerleştirilmesini gerektirir, bu nedenle sinc işlevi, örnek boşluğuna arbitray uyarlaması yapmak zorunda kalacaktır. Uygulaması oldukça zor olabilir.
user2718

evet, bu tam olarak burada görüldüğü gibi yapmak için çok etkili olmaz. Her farklı örnekleme zamanı için yeni çekirdek katsayılarının hesaplanmasını gerektirir. Bununla birlikte, birkaç çekirdekten oluşan bir toplama hesaplanabilir ve zaman bunlardan birine ölçülür. Kantitatif hataya göre bir performans düşmesi olur.
Jacob,

Ayrıca, tek bir iç arama masasını önceden hesaplayabilir ve arama masasının noktaları arasında enterpolasyon yapabilirsiniz.
jms,

5

Bence Jacob'ın cevabı çok işe yarar.

Distorsiyon açısından muhtemelen pek iyi olmayan daha kolay bir yöntem polinom interpolasyonu yapmaktır. İsteğe bağlı zaman örneklerinden istediğiniz zaman numune üretmek için doğrusal enterpolasyonu (kolay, iyi sinyal performansı kadar iyi değil) veya kübik çizgi (hala çok zor değil, daha iyi sinyal performansı) kullanırdım.


1
Yanıtınız Jacob'ın uygulamasından çok daha kolay görünüyor, bu yüzden önce ben geldim. Çalışıyor gibi gözüküyor, ancak henüz tam bir test yapmadım.
FigBug

1
@FBBug -Zamanınız varsa, son çözümünüzle ilgili bir yorum ekleyin.
user2718

2

(Bir ay sonra) herhangi bir enterpolasyon yöntemi için iki ana seçenek vardır:
1) kullanılacak eksik noktaya en yakın veri noktası sayısı, 2 4 6 ... 2) kullanılacak temel fonksiyonların sınıfı: doğrusal, polinom, sinüs-kosinüs (Fourier), parça parça kübik (B-spline veya enterpolasyon spline), sinc-like ... (Seçenek 0, başkasının yöntemini ve kodunu kullanıp kullanmama veya kendin yap).Nnear

noktalarına düz bir çizgi koymak kolaydır: 2 puan [-1, ], [1, ]: tahmini puan ortalama ile : ortalama general : bkz. örneğin Nümerik Tarifler p. 781: bir çizgi ve tahmin . Kişi aynı şekilde kuadratik, kübik, sinüs-kosinüs sığdırabilir.y - 1 y 1Nnear
y1y1
[ x i , y i ] x i = 0y0(y1+y1)/2
[xi,yi]xi=0
y i [ x i , y i ]y0yi
[xi,yi]
y 0aa+bxy0a

Anladığım kadarıyla eşit olmayan aralıklarda, birkaç noktanın eksik olduğu bir veri var.
Doğrusal enterpolasyon bu durum için ne kadar işe yarıyor?
Eh, hadi cos deneyin ile = 0.25: 1 0 -1 0 1 0 -1 0 ... herhangi bir nokta ortalamasının 2 komşuları 0'a korkunç. 4 komşu: ortalama [1 0 (eksik -1) 0 1] = 1/2, korkunç. (Bununla ilgili 4-komşu filtreyi [-1 3 3 -1] / 4 deneyin.)f2πftf


4 ya da 6 ya da 8 komşuyla doğrusal yorum, verileriniz için yeterince iyi çalışabilir.
Spinclere dalmadan önce iyice anladığınız bir yöntemle başlamak isterim, içten benzeri ... bunlar da eğlenceli olabilir.


Bir başka oldukça farklı yöntem Ters mesafe ağırlıklandırmadır . Uygulaması kolaydır (bkz . SO üzerinde python ile idw-enterpolasyonu ), 2d 3d ve üzeriyle de çalışır, ancak teorik olarak analiz edilmesi zor bir iştir.

(Açıkçası, NO tek bir enterpolasyon yöntemi,
gerçekte meydana gelen [sinyal, gürültü, hata ölçümü, test fonksiyonu] kombinasyonlarının zilyonlarına uyabilir .
Dünyada, test fonksiyonlarından daha fazla düğmeyle daha fazla yöntem vardır.
Bununla birlikte, bir galeri yöntemlerin ve test işlevlerinin kullanımı yararlı olabilir.)


1

Matlab ile çalışıyorsanız, zaman çizelgeleriyle çalışarak yapabilirsiniz.

time  % is your starting vector of time

data % vector of data you want to resample 

data_TS = timeseries(data,time); % define the data as a timeseries 

new_time = time(0):dt:time(end); % new vector of time with fixed dt=1/fs

data_res = resample(data_TS,new_time); % data resampled at constant fs

0

Egzotik bir işlem yapmadan önce, bunun gibi basit bir şeyi deneyebilirsiniz (sözde kod - enterpolasyon yok, ancak bu eklenebilir).

TimeStamp[]  //Array of Sensor TimeStamps -NULL terminated – TimeStamp[i] corresponds to Reading[i]
Reading[]      //Array of Sensor Readings       -NULL terminated

AlgorithmOut   //Delimited file of of readings in fixed sample time (5ms) 
CurrentSavedReading = Reading[0]

SampleTime=TimeStamp[0] //ms virtual sample time, 5ms fixed samples

i = 0 // loop index
While(TimeStamp[i] != NULL)
{
   FileWrite (CurrentSavedReading, AlgorithmOut)//write value to file
   SampleTime = SampleTime + 5//ms
   if(SampleTime > TimeStamp[i])
   {
      i++
      CurrentSavedReading = Reading[i]
   }
}

0

IMHO Datageist'in cevabı doğru, Jacob'ın cevabı doğru değil. Bunu doğrulamanın kolay bir yolu, datageistin önerdiği algoritmanın, orijinal örneklerle (sonsuz sayısal hassasiyet varsayarak) enterpolasyon yapmasının garantilenmiş olmasıdır, oysa Jacob'ın cevabı yoktur.

  • Düzgün örnekleme durumu için, sinc fonksiyonlarının kümesi diktir: eğer her bir sinc fonksiyonu giriş örnekleri üzerinde ayrıştırılırsa, sonsuz bir kimlik matrisi oluştururlar. Bunun sebebi sin (n pi) / (n pi), n = 0 dışındaki herkes için sıfır olmasıdır.
  • Bununla birlikte, bu özellik tek tip olmayan duruma ilave edilemez: giriş numuneleri üzerinde ayrılan benzer bir sinc işlevi seti önemsiz bir matris verir. Bu nedenle, çevreleyen örneklerden gelen katkılar sıfır olmayacak ve yeniden yapılanma artık giriş numuneleri arasında enterpolasyon yapmayacaktır.
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.