Minha pergunta é: se eu quero passar um sinal alto, é o mesmo que passar um sinal baixo e subtraí-lo do sinal? Teoricamente é o mesmo? É praticamente o mesmo?
Eu pesquisei (no google e no dsp.stackexchange) e encontro respostas conflitantes. Eu tenho jogado com um sinal e aqui estão os resultados. Eu não consigo entender muito. Aqui está o sinal com a frequência de amostragem uma vez a cada quatro segundos. Projetei um filtro passa-baixa digital com a banda de transição de 0,8 mHz a 1 mHz e filtrou o sinal. Também projetei um filtro passa-alto com a mesma banda de transição e filtrou o sinal. Aqui estão os resultados.
Esta primeira imagem mostra o sinal original em preto e o sinal passa-baixo em azul. Eles estão quase um em cima do outro, mas não completamente. A curva vermelha é o sinal menos o sinal passa-alto que fica logo acima do sinal.
Esta segunda imagem é apenas a primeira ampliada para mostrar o que está acontecendo. Aqui vemos que claramente os dois não são os mesmos. Minha pergunta é por que? É algo sobre como eu implementei os dois filtros ou é algo teórico independente da minha implementação? Não sei muito sobre o design de filtros, mas sei que é notoriamente contra-intuitivo. Aqui está o código completo do MATLAB para reproduzir tudo isso. Estou usando o comando filtfilt para eliminar atrasos de fase. Mas outra coisa a destacar aqui é que os filtros não são normalizados. Quando somar (Hd.Numerator), recebo 0,9930 para o passa-baixo e 0,007 para o passa-alto. Não vejo como explicar isso. A saída deve ser dimensionada de alguma forma, porque os coeficientes não somam um? Esse dimensionamento poderia ter algo a ver com isso?
close all
clear all
clc
data = dlmread('data.txt');
Fs = 0.25; % Sampling Frequency
N = 2674; % Order
Fpass = 0.8/1000; % Passband Frequency
Fstop = 1/1000; % Stopband Frequency
Wpass = 1; % Passband Weight
Wstop = 1; % Stopband Weight
dens = 20; % Density Factor
% Calculate the coefficients using the FIRPM function.
b = firpm(N, [0 Fpass Fstop Fs/2]/(Fs/2), [1 1 0 0], [Wpass Wstop], {dens});
Hd = dsp.FIRFilter('Numerator', b);
sum(Hd.Numerator)
datalowpassed = filtfilt(Hd.Numerator,1,data);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Fs = 0.25; % Sampling Frequency
N = 2674; % Order
Fstop = 0.8/1000; % Stopband Frequency
Fpass = 1/1000; % Passband Frequency
Wstop = 1; % Stopband Weight
Wpass = 1; % Passband Weight
dens = 20; % Density Factor
% Calculate the coefficients using the FIRPM function.
b = firpm(N, [0 Fstop Fpass Fs/2]/(Fs/2), [0 0 1 1], [Wstop Wpass], {dens});
Hd = dsp.FIRFilter('Numerator', b);
sum(Hd.Numerator)
datahighpassed = filtfilt(Hd.Numerator,1,data);
figure
subplot(2,1,1)
plot(data,'-ko')
hold on
plot(datalowpassed,'-bo')
plot(data-datahighpassed,'-ro')
legend('Original Signal','Low-Passed','Signal - High-Passed')
subplot(2,1,2)
plot(data-datalowpassed,'-bo')
hold on
plot(datahighpassed,'-ro')
legend('Signal - Low-Passed','High-Passed')
Respostas:
Em geral, você não pode simplesmente subtrair uma versão filtrada passa-baixa de um sinal do sinal original para obter um sinal filtrado passa-alta. O motivo é o seguinte. O que você está realmente fazendo é implementar um sistema com resposta em frequência
mas esse geralmente não é o caso quando (1) é satisfeito.
Na prática, isso é muito simples se o filtro passa-baixo tiver uma resposta de fase linear , porque o termo da fase é dado por
Então, o que você precisa fazer é o seguinte:
filter()
Aqui está uma ilustração muito simples em Matlab / Octave
EDITAR:
filtfilt
filtfilt
fonte
Em relação à escala:
Além da excelente resposta de Matt L., pode-se apenas salientar que o que ele está usando é chamado de filtros complementares de magnitude , que é o caso comum dos filtros FIR de fase linear, ou seja,
Ao criar filtros a partir de duas seções paralelas allpass e adicionar / subtrair as saídas, os filtros lowpass / highpass serão complementares em termos de energia , ou seja,
fonte