타임 스탬프와 값으로 판독 값을보고하는 센서가 있습니다. 그러나 고정 속도로 판독 값을 생성하지 않습니다.
변동율 데이터를 다루기가 어렵다는 것을 알았습니다. 대부분의 필터는 고정 샘플링 속도를 기대합니다. 고정 샘플 속도로 그래프를 그리기가 더 쉽습니다.
가변 샘플링 속도에서 고정 샘플링 속도로 리샘플링하는 알고리즘이 있습니까?
타임 스탬프와 값으로 판독 값을보고하는 센서가 있습니다. 그러나 고정 속도로 판독 값을 생성하지 않습니다.
변동율 데이터를 다루기가 어렵다는 것을 알았습니다. 대부분의 필터는 고정 샘플링 속도를 기대합니다. 고정 샘플 속도로 그래프를 그리기가 더 쉽습니다.
가변 샘플링 속도에서 고정 샘플링 속도로 리샘플링하는 알고리즘이 있습니까?
답변:
가장 간단한 방법은 Jim Clay가 제안한 것과 같은 일종의 스플라인 보간 (선형 또는 기타)을 수행하는 것입니다. 그러나 배치 처리의 고급 스러움이 있고 특히 불균일 한 샘플 세트가 과도하게 결정된 경우 매우 완벽한 "완벽한 재구성"알고리즘이 있습니다. 수치적인 이유로 모든 경우에 실용적이지는 않지만 적어도 개념적으로는 알아볼 가치가 있습니다. 나는 먼저이 논문 에서 그것에 대해 읽었다 .
요령은 비 균일 샘플 세트가 이미 sinc 보간을 통해 균일 한 샘플에서 재구성 된 것으로 간주하는 것입니다 . 논문의 표기법에 따라 :
이것은 각각의 비 균일 샘플 마다 하나씩 선형 방정식 세트를 제공합니다. 여기서 미지수는 같은 간격의 샘플 ., Y ( k 개의 T )
위의 방정식에서, 은 알려지지 않은 균일 한 샘플 수, 는 균일 한 샘플 속도의 역수, 은 비 균일 샘플의 수 ( 보다 클 수 있음 )입니다. 해당 시스템 의 최소 제곱 솔루션을 계산하여 균일 한 샘플을 재구성 할 수 있습니다. 기술적으로, 비 균일 샘플 만이 필요하지만, 얼마나 "비산"되어 있는지에 따라, 보간 행렬은 심하게 조절되지 않을 수 있습니다 . 이 경우 더 많은 비 균일 샘플을 사용하면 도움이됩니다.
장난감 예제로, 위의 방법과 약간의 지터 그리드에서 3 차 스플라인 보간을 비교 한 ( numpy 사용 )는 다음과 같습니다.
(위의 줄거리를 재현하는 코드는이 답변의 끝에 포함되어 있습니다)
다음 문서 중 하나에서 시작하여 고품질의 강력한 방법을 사용하는 것이 더 적합 할 것입니다.
A. Aldroubi와 Karlheinz Grochenig, 시프트 불변 공간에서의 비 균일 샘플링 및 재구성 , SIAM Rev., 2001, no. 4, 585-620. ( pdf 링크 ).
K. Grochenig 및 H. Schwab, SINA 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()
이것은 비동기 샘플 속도 변환의 문제처럼 들립니다. 한 샘플 속도에서 다른 샘플 속도로 변환하기 위해 sinc 보간을 수행하여 신호의 연속 시간 표현을 계산 한 다음 새로운 샘플 속도로 다시 샘플링 할 수 있습니다. 당신이하고있는 일은별로 다르지 않습니다. 샘플 시간이 고정되도록 신호를 다시 샘플링해야합니다.
연속 시간 신호는 각 샘플을 sinc 함수로 변환하여 계산할 수 있습니다. sinc 함수는 무한정 계속되므로 실제 유한 한 길이의 윈도우 형 sinc와 같은보다 실용적인 것을 사용합니다. 까다로운 부분은 샘플이 제 시간에 움직이기 때문에 리샘플링 할 때 각 샘플마다 다른 위상 오프셋을 가진 sinc를 사용해야한다는 것입니다.
샘플링 된 신호의 연속 시간 신호 :
여기에서 신호를 다시 샘플링 할 수 있습니다.
종합하면 다음과 같은 이점이 있습니다.
이것은 인과 관계가 아니기 때문에 sinc 함수를 유한지지 함수로 대체 할 수 있으며 그에 따라 합산 한계를 조정할 수 있습니다.
kernel (t)를 windowed sinc 또는 길이 2k의 다른 유사한 함수로 설정하십시오.
이것이 도움이되기를 바랍니다 ...하지만 길을 따라 실수를했을 수 있으며 약간의 수학 집약적 일 수 있습니다. 자세한 내용은 샘플링 속도 변환을 조사하는 것이 좋습니다. 여기 다른 누군가가 더 나은 설명이나 해결책을 줄 수 있습니다.
나는 야곱의 대답이 매우 효과적이라고 생각합니다.
왜곡 도입 측면에서 그리 좋지 않은 쉬운 방법은 다항식 보간을 수행하는 것입니다. 임의의 시간 샘플에서 원하는 시간에 샘플을 생성하기 위해 선형 보간 (쉽고, 신호 성능이 좋지 않은) 또는 입방 스플라인 (여전히 어렵지 않고 더 나은 신호 성능)을 사용합니다.
같은 방법으로 2 차, 입체, 사인 코사인에 맞출 수 있습니다.
4 개 또는 6 개 또는 8 개 이웃과의 선형 교차는 데이터에 충분할 수 있습니다.
스플라인으로 뛰어 들기 전에 철저히 이해하는 방법부터 시작하는 것이 좋습니다.
(물론, 어떠한 단일 보간법 가능한 조합의 엄청나게 맞 없다
. 실제로 발생 [노이즈 신호, 에러 메트릭 테스트 기능]
테스트 기능보다 세계에서, 방법은 더 노브있다.
그럼에도 불구하고 갤러리 방법 및 테스트 기능이 유용 할 수 있습니다.)
matlab으로 작업하는 경우 시계열로 작업하여 수행 할 수 있습니다.
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
이국적인 처리를 시작하기 전에 다음과 같이 간단한 시도를 시도 할 수 있습니다 (의사 코드-보간은 없지만 추가 가능).
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]
}
}
IMHO Datageist의 답변은 정확하지만 Jacob의 답변은 정확하지 않습니다. 이를 확인하는 쉬운 방법은 datageist가 제안한 알고리즘이 원래의 샘플을 통해 보간되도록 보장하는 반면 (무한 수치 정밀도를 가정) Jacob의 대답은 그렇지 않습니다.