2013-11-20 2 views
2

FFT와 역 FFT (IFFT)를 사용하여 Matlab에서 (실제) 신호를 필터링하려고합니다. IIR 필터 (계수 'b'및 'a')가 있습니다. 나는 (약?) 기대하고있어 같은 결과를 단순히이했던 것처럼 :MATLAB : IIR 필터로 FFT/IFFT를 사용하여 주파수 영역에서 필터링

filteredSignal = filter(b,a,signal); 

그래서 내가 무슨 짓을 : 여기

NFFT = length(signal); 
FFTsignal = fft(signal, NFFT); 
FilterFreqResponse = freqz(b,a,NFFT); 
FFTfilteredSignal = FFTsignal .* FilterFreqResponse; 
filteredSignal = ifft(FFTfilteredSignal, NFFT); 

그리고 문제입니다 결과 신호 (filteredSignal)는 복잡합니다. 그리고 실제 신호 (내 입력 신호)를 원합니다. filter 함수는 또한 실제 신호를 반환합니다. 그래서 ... 내가 뭘 잘못하고 있니? IIR 필터로 FFT 기반 필터링을 사용할 수 있습니까? 내 필터의 주파수 응답이 원점을 기준으로 대칭이 아니므로 필터링 된 신호의 스펙트럼이 대칭 적이 지 않습니다 ... 따라서 시간 영역의 필터링 된 신호는 실제 일 수 없습니다 ...?

PS : 거기 IFFT 기능에 "대칭"옵션 : 나는이 작업을 수행 할 경우, filteredSignal 이제 진짜 ...하지만 하나 (진폭과 위상에) 분명히 다른

filteredSignal = ifft(FFTfilteredSignal, NFFT, 'symmetric'); 

"필터"기능을 직접 사용합니다. 그리고이 "대칭"옵션은 분명히 허수 부나 그와 비슷한 것을 버려서 아마 그것을 사용하는 것은 좋지 않을 것입니다 ...

미리 감사드립니다. (내 영어 죄송합니다)

답변

1

귀하의 FilterFreqResponseNFFT 점이 단위 원의 상반부에만 균등 한 간격으로 평가됩니다. FilterFreqResponse = freqz(b,a,NFFT,'whole')을 사용해 보셨습니까?

+0

감사!먼저 James의 솔루션을 시도한 다음 귀하의 의견을 보았습니다. 둘 다 같은 결과를 얻었습니다 (다행스럽게도!). 지금 나는 그것을 얻는다 :) – user3015199

1

사용 역 FFT의 실수 부 :

filteredSignal = real(ifft(FFTfilteredSignal, NFFT)); 
+0

나는 이것을 시도했지만 불행히도 작동하지 않습니다. 이렇게하면 결과 신호가 진폭의 절반 이상을 잃어 버리고 "필터"기능을 사용하여 필터링 된 신호와 위상이 맞지 않게됩니다. – user3015199

3

그냥 결과의 실수 부분을 사용하는 잘못,

당신의 대답은 복잡한 인 이유 점 현명한 곱셈이 대칭 적으로 수행되지 않았다는 것입니다. 즉, 해답을 이해하기 위해 벡터 FilterResponse가 중심 요소에 대해 대칭이어야합니다. Fs/2 (즉, 더 작은 벡터)까지만 필터 응답을 작성한 다음 미러 주파수에 공액 대칭 적으로 적용 할 수있는 로직을 작성해야합니다. 또는 Matlab은 자동으로 다음을 통해 이것을 수행 할 수 있습니다 : FilterFreqResponse = freqz(b,a,NFFT,'whole')

작성한 대칭간에 존재할 수있는 작은 수치 오류를 방지하기위한 목적으로 만 ifft와 함께 'symmetric'옵션을 사용해야합니다.

+0

대단히 감사합니다! 나는 당신이 설명했듯이 그것을 "수동으로"시도했고, 그것은 효과가있었습니다. 그리고 lennon310이 제안한 것처럼 '전체'를 사용하는 것과 똑같은 결과를냅니다. – user3015199

0

주파수 도메인에서의 곱셈은 시간 도메인에서 순환 컨벌루션입니다. 순환 컨볼 루션 인공물을 제거하려면 FFT 전에 필터 응답 길이만큼 신호를 제로 패드해야합니다. 곱하기 전에 복소 공액 대칭이되도록 주파수 응답 필터를 미러링해야합니다 (아마도 두 벡터 길이를 모두 2N으로 만듭니다. IFFT 후 추가 된 패딩을 버리거나 추가 오버랩 추가/저장 처리를 위해 유지합니다.

+0

고마워! 그것이 다소 다르다면 나는 알지 못한다. 그러나 나는 이것을했다 : 나는 내 신호를 그 자체로 덧붙였다. (그러나 역으로) : signal = [flipud (신호); 신호; 플립 (신호)]; 그 다음 출력의 중간 부분을 유지했습니다. 그것도 맞습니까? – user3015199

관련 문제