본문 바로가기
Brain Engineering/MNE

Signal Processing : Acquiring Data

by goatlab 2022. 4. 5.
728x90
반응형
SMALL

What is a signal

 

신경 과학에서 대부분의 신호는 시간에 따라 변하는 전압이다. ECG, EEG, EMG 등과 같은 많은 생체 신호는 증폭되고 필터링된 전위 (ex. 전압)이다. 다른 것들은 변환기의 결과일 수 있으며, 다른 물리적 측정값 (ex. 거리, 압력)이 (일반적으로 전압) 될 수 있다. 주목할만한 예외는 시선 추적과 같은 모든 비디오 기반 신호이다. 이들은 일반적으로 디지털 형식으로 직접 임의의 단위로 기록된다.

 

Analog to Digital

 

대부분의 신호는 아날로그 신호로 측정된다. 이는 시간이 지남에 따라 연속적임을 의미한다. 컴퓨터는 아날로그 신호를 저장하거나 처리할 수 없다. 따라서 주석에 표시된 대로 수행 하는 아날로그-디지털 변환기 (ADC)를 사용한다. 이 단계를 이산화라고 한다. 이제부터 연속 및 아날로그는 물론 이산 및 디지털도 서로 바꿔서 사용할 수 있다. 다음은 다른 샘플링 속도로 이산화된 순수 사인파의 예이다.

 

import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate


# We'll use this interpolation to rebuild an analogue signal from digital samples
# credit for this implementation goes to endolith: https://gist.github.com/endolith
def sinc_interp(x, s, u):
    """
    Interpolates x, sampled at "s" instants
    Output y is sampled at "u" instants ("u" for "upsampled")
    
    from Matlab:
    http://phaseportrait.blogspot.com/2008/06/sinc-interpolation-in-matlab.html        
    """
    # Validate arguments
    if len(x) != len(s):
        raise(Exception, 'x and s must be the same length')
    
    # Find the period    
    T = s[1] - s[0]    
    
    transposed = np.transpose(np.tile(np.arange(len(s)), (len(u),1))) * T    
    
    sincM = np.tile(u, (len(s), 1)) - transposed
    y = np.dot(x, np.sinc(sincM / T))
    
    return y
        

#Set up figure
fig, axes = plt.subplots(3,4,figsize=(12,4),sharex='col',sharey='row')

# The signal will be a pure sinusoidal, at a frequency of 3 Hz (Hertz, Hz = 1/s)
frequency = 3;
# A high sampling rate (number of recorded data points per time unit) will give the
# illusion of an analog signal, you will not be able to see the time steps.
# At a lower sampling rate, you can clearly see when a point was sampled
# If the sampling rate is at or below the Nyquist frequency, the acquired signal will be erroneous.

# Now lets discretize this with a sampling rate of 10 Hz

# We'll look at a dozen frequencies
sampling_rates = [50,25,12,7,6.2,6,5.8,5,4.5,4,3,2.9];#np.logspace(np.log10(96),np.log10(1.5),num=8);

# Compare all signals to a sampling rate of 50 Hz. Used by the interpolation
reference_sampling_rate = 50;
reference_time = np.arange(-10,10,1/reference_sampling_rate);
reference_time = np.append(reference_time,1);
reference_voltage = np.sin(2*np.pi*frequency*reference_time)

# Iterate over axes and sampling rates
for (axe,sampling_rate) in zip(axes.reshape(-1),sampling_rates):
    # Create the time vector.
    time = np.arange(-10.01,10,1/sampling_rate);
    
    # Compute the sinusoidal (x = Amplitude*sin(angular_frequency * time))
    # Where angular_frequency = 2 * pi * frequency
    voltage  =  np.sin(2*np.pi*frequency*time);
    
    # In order to get a better idea of the signal represented by the samples it is interpolated
    # and plotted on top of the discretized signal. this step is not part of discretization.
    # interpolate the signal using Whittaker-Shannon Interpolation
    interpolated_voltage = sinc_interp(voltage,time,reference_time);
    
    axe.stem(time,voltage,use_line_collection=True);
    axe.plot(reference_time,interpolated_voltage,'r');
    axe.plot(reference_time,reference_voltage,'g.')
    axe.set_title('Sampling Rate = {:05.2f} Hz'.format(sampling_rate))
    axe.set_xlim(0,1)
    

plt.tight_layout()

 

플롯은 샘플링 속도가 6Hz 아래로 떨어질 때 보간된 신호에 정성적 변화가 있음을 보여준다. 6Hz에서 신호는 여전히 원본과 거의 비슷하게 보이지만 5.8에서 보간된 신호는 갑자기 역위상이 된다. 훨씬 더 낮은 주파수의 완전히 새로운 신호가 나타난다. 특히, 3Hz (원래 신호의 기본 주파수)에서 신호는 DC (직류) 신호로 완전히 평평해진다. 샘플을 채취할 때마다 신호가 정확히 동일한 진폭을 갖기 때문에 이는 의미가 있다.

 

The Nyquist-Shanon Theorem

 

이러한 효과를 앨리어싱이라고 하며 Whittaker-Nyquist-Kotelnikov-Shannon 이론을 준수하지 않는 샘플링 속도로 인해 발생한다. 이 정리에 대한 여러 독립적인 발견이 있었다. Nyquist 또는 Nyquist-Shannon 정리로 가장 일반적으로 알려져 있다.

 

함수 x(t)에 B 헤르츠보다 높은 주파수가 포함되어 있지 않으면 1/(2B)초 간격으로 떨어진 일련의 점에 세로 좌표를 지정하여 완전히 결정된다.

 

다시 말해, 샘플링 속도가 신호에 존재하는 가장 높은 주파수 성분의 두 배 이상인 경우 신호가 완전히 결정된다 (즉, 정보 손실이 없음).  2B 의 주파수를 나이퀴스트 속도 (또는 주파수)라고 한다. 이 예에서는 가장 높은 주파수 (유일한) 구성 요소가 3Hz에 있으므로 6Hz이다.

 

플롯을 보면 몇 가지 문제가 있음을 알 수 있다. 정리를 준수하지만 나이퀴스트 속도에 가까운 주파수는 여전히 상당히 왜곡되어 있다. 가능한 최고의 보간 방법인 sinc 보간법 (위에서 설명한 sinc 함수의 이름을 따서 명명됨)을 사용한다. 그러나 제한된 시간 동안만 샘플링했다. 그것을 확장 할 것인가 ±신호를 완벽하게 재구성할 수 있어야 한다. (이론에 의하면) 

 

이러한 샘플링 정리의 요점은 정보 손실을 방지하는 것만이 아니다. 6 및 3Hz에서 신호가 평평해지면 샘플링 속도가 신호 주파수의 두 배나 되기 때문이다. 이 경우 신호가 0을 통과할 때마다 샘플링했다. 따라서 정리를 무시하면 완전히 비정상적인 결과가 나올 수 있다.

 

다음은 청각적 예이다.

 

경고: 사운드 볼륨을 확인하시오 : 고음

 

C7 (2093Hz) - F8 (2794Hz) 및 C8 (4186Hz) - F8 (5588Hz)의 두 옥타브에서 완벽한 5번째 하모니를 사용한다.

먼저 44100Hz에서 샘플링한다. 이것은 음악에 사용되는 일반적인 샘플 레이트이다.

 

import numpy as np
import simpleaudio as sa

# define a playback duration
note_length = 1
# define sampling rate
sr = 44100
# compute the frequencies of notes
f = [pow(2,(96-69)/12)*440,pow(2,(101-69)/12)*440,
    pow(2,(108-69)/12)*440,pow(2,(113-69)/12)*440]
# define some variable amplitudes for the notes
amplitudes = np.array([1,1,0.8,0.8])/len(f);
# compute time vector
t = np.arange(0,note_length,1/sr)
# compute audio signal
signal = np.sum(np.array([a*np.sin(2*np.pi*ff*t) for a in amplitudes for ff in f]),0)/len(f)
audio = signal * (2**15 -1)
audio = np.int16(audio)
play_obj = sa.play_buffer(audio,1,2,sr)
play_obj.wait_done()

 

지금까지 특별한 것은 없다. 이제 샘플링 속도를 11025Hz로 낮춘다. 이것은 일반적으로 전화 회선에서 들을 수 있는 것이다.

 

# define sampling rate
sr = 11025
# compute time vector
t = np.arange(0,note_length,1/sr)
# compute audio signal
signal = np.sum(np.array([np.sin(2*np.pi*ff*t) for ff in f]),0)/len(f)
audio = signal * (2**15 -1)
audio = np.int16(audio)
play_obj = sa.play_buffer(audio,1,2,sr)
play_obj.wait_done()

 

큰 문제는 없었지만 고음에 문제가 있다. 거기에 독특한 전자 감각이 있다. 이것은 앨리어싱이다. 부적절한 샘플링 속도로 인해 완전히 새로운 주파수가 신호에 도입된다.

 

이제 8000Hz까지 내려간다. 워키토키에서 이 문제가 발생할 수 있다.

 

https://neuro.inf.unibe.ch/AlgorithmsNeuroscience/Tutorial_files/AcquiringData.html

 

Acquiring Data

Acquiring Data ## load librariesimport matplotlib.pyplot as pltimport matplotlib.animationimport numpy as npimport cmath as cmfrom scipy impor...

neuro.inf.unibe.ch

 

728x90
반응형
LIST