가변 속도에서 고정 속도로 다시 샘플링하는 알고리즘은 무엇입니까?


27

타임 스탬프와 값으로 판독 값을보고하는 센서가 있습니다. 그러나 고정 속도로 판독 값을 생성하지 않습니다.

변동율 데이터를 다루기가 어렵다는 것을 알았습니다. 대부분의 필터는 고정 샘플링 속도를 기대합니다. 고정 샘플 속도로 그래프를 그리기가 더 쉽습니다.

가변 샘플링 속도에서 고정 샘플링 속도로 리샘플링하는 알고리즘이 있습니까?


프로그래머의 크로스 포스트입니다. 나는 이것이 더 좋은 곳이라고 들었다. programmers.stackexchange.com/questions/193795/…
FigBug

센서가 판독 값을보고 할시기는 무엇입니까? 판독 값이 변경 될 때만 판독 값을 보내나요? 간단한 접근 방식은 생성 된 판독 값 사이의 최단 시간보다 짧은 "가상 샘플 간격"(T)을 선택하는 것입니다. 알고리즘 입력시 마지막으로보고 된 판독 값 (CurrentReading) 만 저장하십시오. 알고리즘 출력에서 ​​CurrentReading을 T 초마다 "새 샘플"로보고하여 필터 또는 그래프 서비스가 일정한 속도 (매 T 초)로 판독 값을 수신하도록합니다. 이것이 귀하의 경우에 적합한 지 전혀 모릅니다.
user2718

5ms 또는 10ms마다 샘플링을 시도합니다. 그러나 우선 순위가 낮은 작업이므로 놓치거나 지연 될 수 있습니다. 1ms 정확한 타이밍이 있습니다. 처리는 실시간이 아닌 PC에서 수행되므로 구현이 더 쉬운 경우 느린 알고리즘이 좋습니다.
FigBug

1
푸리에 재구성을 살펴 보셨습니까? 불균일하게 샘플링 된 데이터를 기반으로 푸리에 변환이 있습니다. 일반적인 aoproach는 푸리에 이미지를 고르게 샘플링 된 시간 도메인으로 다시 변환하는 것입니다.
mbaitoff

3
샘플링중인 기본 신호의 특성을 알고 있습니까? 불규칙한 간격의 데이터가 측정중인 신호의 대역폭과 비교하여 여전히 샘플링 속도가 상당히 높으면 균일 한 간격의 타임 그리드에 대한 다항식 보간과 같은 간단한 것이 잘 작동 할 수 있습니다.
Jason R

답변:


21

가장 간단한 방법은 Jim Clay가 제안한 것과 같은 일종의 스플라인 보간 (선형 또는 기타)을 수행하는 것입니다. 그러나 배치 처리의 고급 스러움이 있고 특히 불균일 한 샘플 세트가 과도하게 결정된 경우 매우 완벽한 "완벽한 재구성"알고리즘이 있습니다. 수치적인 이유로 모든 경우에 실용적이지는 않지만 적어도 개념적으로는 알아볼 가치가 있습니다. 나는 먼저이 논문 에서 그것에 대해 읽었다 .

요령은 비 균일 샘플 세트가 이미 sinc 보간을 통해 균일 한 샘플에서 재구성 된 것으로 간주하는 것입니다 . 논문의 표기법에 따라 :

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

이것은 각각의 비 균일 샘플 마다 하나씩 선형 방정식 세트를 제공합니다. 여기서 미지수는 같은 간격의 샘플 ., 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)].

위의 방정식에서, 은 알려지지 않은 균일 한 샘플 수, 는 균일 한 샘플 속도의 역수, 은 비 균일 샘플의 수 ( 보다 클 수 있음 )입니다. 해당 시스템 의 최소 제곱 솔루션을 계산하여 균일 한 샘플을 재구성 할 수 있습니다. 기술적으로, 비 균일 샘플 만이 필요하지만, 얼마나 "비산"되어 있는지에 따라, 보간 행렬은 심하게 조절되지 않을 수 있습니다 . 이 경우 더 많은 비 균일 샘플을 사용하면 도움이됩니다.nTmn

장난감 예제로, 위의 방법과 약간의 지터 그리드에서 3 차 스플라인 보간을 비교 한 ( numpy 사용 )는 다음과 같습니다.

비 균일 샘플의 Sinc vs Cubic Spline 재구성

(위의 줄거리를 재현하는 코드는이 답변의 끝에 포함되어 있습니다)

다음 문서 중 하나에서 시작하여 고품질의 강력한 방법을 사용하는 것이 더 적합 할 것입니다.

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()

tj=jT

내가 이해하는 것처럼 OP의 질문은 샘플이 떨어지거나 지연되는 것입니다. 이 방법은 기본적으로 과도하게 결정된 방정식 시스템이므로, 손실 된 샘플은 알 수없는 값으로 만 표시됩니다 (값이 0 인 데이터 포인트가 아님). 아니면 당신이 원하는 것이 아닐까요?
datageist

tjj,yjjJy0=0yj

샘플 속도가 정확히 동일하면 (누락 된 포인트 포함) 보간 행렬은 희소합니다 (각 출력이 하나의 입력에만 의존하기 때문에). 일반적으로, 불균일 한 샘플의 평균 샘플링 속도는 균일 한 재구성 속도보다 커야합니다. 다시 말해, "갭을 채우려면"(예를 들어 T> 1) 더 낮은 속도로 재구성해야합니다. 그래도 요점을 참조하십시오.
datageist

2
이와 같은 답변은 순금입니다.
Ahmed Fasih 2016 년

6

이것은 비동기 샘플 속도 변환의 문제처럼 들립니다. 한 샘플 속도에서 다른 샘플 속도로 변환하기 위해 sinc 보간을 수행하여 신호의 연속 시간 표현을 계산 한 다음 새로운 샘플 속도로 다시 샘플링 할 수 있습니다. 당신이하고있는 일은별로 다르지 않습니다. 샘플 시간이 고정되도록 신호를 다시 샘플링해야합니다.

연속 시간 신호는 각 샘플을 sinc 함수로 변환하여 계산할 수 있습니다. sinc 함수는 무한정 계속되므로 실제 유한 한 길이의 윈도우 형 sinc와 같은보다 실용적인 것을 사용합니다. 까다로운 부분은 샘플이 제 시간에 움직이기 때문에 리샘플링 할 때 각 샘플마다 다른 위상 오프셋을 가진 sinc를 사용해야한다는 것입니다.

샘플링 된 신호의 연속 시간 신호 :

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

Ts

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

여기에서 신호를 다시 샘플링 할 수 있습니다.

y[n]=x(nTns

Tns

종합하면 다음과 같은 이점이 있습니다.

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

이것은 인과 관계가 아니기 때문에 sinc 함수를 유한지지 함수로 대체 할 수 있으며 그에 따라 합산 한계를 조정할 수 있습니다.

kernel (t)를 windowed sinc 또는 길이 2k의 다른 유사한 함수로 설정하십시오.

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

이것이 도움이되기를 바랍니다 ...하지만 길을 따라 실수를했을 수 있으며 약간의 수학 집약적 일 수 있습니다. 자세한 내용은 샘플링 속도 변환을 조사하는 것이 좋습니다. 여기 다른 누군가가 더 나은 설명이나 해결책을 줄 수 있습니다.


sinc 함수를 사용하여 신호의 연속 버전을 재구성하려면 샘플의 간격이 동일해야하므로 sinc 함수는 중재 샘플 간격에 맞게 조정해야합니다. 구현하기가 다소 어려울 수 있습니다.
user2718

예, 여기에 표시된대로 정확하게 수행하는 것은 그리 효율적이지 않습니다. 서로 다른 샘플 시간마다 새로운 커널 계수를 계산해야합니다. 그러나 여러 커널 모음을 계산할 수 있었으며 시간 중 하나에 시간이 양자화되었습니다. 양자화 오류와 관련하여 성능이 저하 될 수 있습니다.
Jacob

단일 sinc 룩업 테이블을 미리 계산하고 해당 룩업 테이블의 포인트 사이를 보간 할 수도 있습니다.
jms

5

나는 야곱의 대답이 매우 효과적이라고 생각합니다.

왜곡 도입 측면에서 그리 좋지 않은 쉬운 방법은 다항식 보간을 수행하는 것입니다. 임의의 시간 샘플에서 원하는 시간에 샘플을 생성하기 위해 선형 보간 (쉽고, 신호 성능이 좋지 않은) 또는 입방 스플라인 (여전히 어렵지 않고 더 나은 신호 성능)을 사용합니다.


1
대답은 Jacob보다 구현하기가 훨씬 쉬워 보이므로 먼저 사용했습니다. 작동하는 것 같지만 아직 전체 테스트를 실행하지 않았습니다.
FigBug

1
@FigBug-시간이 있다면, 최종 해결책으로 의견을 추가하십시오.
user2718

2


Nnear

Nnear
y1y1
y0(y1+y1)/2
[xi,yi]xi=0
y0yi
[xi,yi]
a+bxy0a
같은 방법으로 2 차, 입체, 사인 코사인에 맞출 수 있습니다.



2πftf


4 개 또는 6 개 또는 8 개 이웃과의 선형 교차는 데이터에 충분할 수 있습니다.
스플라인으로 뛰어 들기 전에 철저히 이해하는 방법부터 시작하는 것이 좋습니다.


또 다른 매우 다른 방법은 역 거리 가중치 입니다. 구현하기 쉽고 ( SOW에서 idw-interpolation-with-python 참조 ) 2d 3d 이상에서도 작동하지만 이론적으로 분석하기는 어렵습니다.

(물론, 어떠한 단일 보간법 가능한 조합의 엄청나게 맞 없다
. 실제로 발생 [노이즈 신호, 에러 메트릭 테스트 기능]
테스트 기능보다 세계에서, 방법은 더 노브있다.
그럼에도 불구하고 갤러리 방법 및 테스트 기능이 유용 할 수 있습니다.)


1

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

0

이국적인 처리를 시작하기 전에 다음과 같이 간단한 시도를 시도 할 수 있습니다 (의사 코드-보간은 없지만 추가 가능).

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의 답변은 정확하지만 Jacob의 답변은 정확하지 않습니다. 이를 확인하는 쉬운 방법은 datageist가 제안한 알고리즘이 원래의 샘플을 통해 보간되도록 보장하는 반면 (무한 수치 정밀도를 가정) Jacob의 대답은 그렇지 않습니다.

  • 균일 한 샘플링의 경우, sinc 함수 세트는 직교합니다. 각 시프트 된 sinc 함수가 입력 샘플에 대해 이산화되면 무한 동일성 행렬을 형성합니다. n = 0을 제외한 모든 n에 대해 sin (n pi) / (n pi)가 0이기 때문입니다.
  • 그러나이 특성은 단순히 비 균일 한 경우에 외삽 될 수는 없습니다. 입력 샘플에 대해 이산화 된 유사한 sinc 함수 세트가 중요하지 않은 행렬을 생성합니다. 따라서 주변 샘플의 기여도는 0이 아니며 재구성은 더 이상 입력 샘플을 통해 보간되지 않습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.