高域通過信号は、信号から低域通過信号を引いたものと同じですか?


14

私の質問は、信号をハイパスしたい場合、信号をローパスして信号から減算することと同じですか?理論的には同じですか?実質的に同じですか?

(googleとdsp.stackexchangeの両方で)検索しましたが、矛盾する答えが見つかりました。私は信号で遊んでいますが、ここに結果があります。私はそれをあまり理解できません。これは、4秒ごとに1回サンプリング周波数を持つ信号です。0.8 mHz〜1 mHzの遷移帯域を持つデジタルローパスフィルターを設計し、信号をフィルター処理しました。次に、同じ遷移帯域を持つハイパスフィルターを設計し、信号をフィルター処理しました。結果は次のとおりです。

ここに画像の説明を入力してください

この最初の画像は、元の信号を黒で、ローパス信号を青で示しています。それらはほぼ重なり合っていますが、完全ではありません。赤い曲線は、信号から信号の真上にあるハイパス信号を引いたものです。

ここに画像の説明を入力してください

この2番目の画像は、何が起こっているかを示すためにズームインした最初の画像です。ここでは、明らかに2つが同じではないことがわかります。私の質問はなぜですか?それは2つのフィルターをどのように実装したかに関するものですか、それとも私の実装とは独立した理論的なものですか?フィルターの設計についてはあまり知りませんが、直感に反することで有名です。これをすべて再現する完全なMATLABコードを次に示します。filtfiltコマンドを使用して、位相遅延を解消しています。ただし、ここで指摘するもう1つの点は、フィルターが正規化されていないことです。sum(Hd.Numerator)を実行すると、ローパスで0.9930、ハイパスで0.007が得られます。これを説明する方法がわかりません。係数の合計が1にならないため、出力を何らかの方法でスケーリングする必要がありますか?このスケーリングはこれと何か関係がありますか?

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

1
フィルターの次数が非常に高い。設計プロセス中に数値の問題に遭遇する可能性があります。FFTの大きさを計算してプロットすることにより、設計されたフィルターを確認します。さらに、減算を使用してローパスフィルターからハイパスフィルターを生成する方法については、以下の回答を参照してください。
マットL.

:あなたは、ハイパスがこのように信号はなく、ロールオフの順序が常に最初の順序で行うことができますsound.westhost.com/articles/derived-xovers.htm あなたが最初に引い前に、LPFの群遅延によって信号を遅延した場合、3番目の注文を取得できます
エンドリス

回答:


8

一般に、元の信号からローパスフィルタリングされたバージョンの信号を単純に減算して、ハイパスフィルタリングされた信号を取得することはできません。その理由は次のとおりです。実際にやっているのは、周波数応答のあるシステムを実装することです

(1)H(ω)=1HLP(ω)

ここで、はローパスフィルターの周波数応答です。は複雑な関数であることに注意してください。おそらく欲しいものはHLP(ω)HLP(ω)

(2)|H(ω)|=|1|HLP(ω)||

しかし、これは一般に(1)が満たされる場合には当てはまりません。

次に、をHLP(ω)

HLP(ω)=|HLP(ω)|ejϕ(ω)

ここで、はローパスフィルターの位相応答です。フィルターを次のように定義した場合ϕ(ω)

(3)HHP(ω)=ejϕ(ω)HLP(ω)=ejϕ(ω)(1|HLP(ω)|)

この新しいフィルターは、実際に大小関係を満たします(2)。したがって、(3)のように減算を行うと、ローパスフィルターの応答を補完する振幅応答を持つハイパスフィルターを実現できます。これは、信号のローパスフィルターバージョンを減算する前に、周波数応答オールパスフィルターで信号をフィルターする必要があることを意味します。ejϕ(ω)

実際には、ローパスフィルターに線形位相応答がある場合、これは非常に簡単です。なぜなら、位相項は

(4)ejϕ(ω)=ejωτ

単純な遅延に対応します。FIRフィルターは正確に線形の位相応答を持つことができ、Parks-McClellanアルゴリズムによって設計されたフィルターは線形の位相を持っています。(4)の遅延を整数にすることは有利です。これは、偶数のフィルター次数選択することによって実現されます。τnτ=n/2

だからあなたがしなければならないことは次のとおりです:

  • 偶数次の線形位相FIRローパスフィルターを設計する
  • filter(); を使用して信号をフィルタリングします。結果をと呼びましょうxLP[n]
  • 元の信号をサンプルだけ遅延させます。遅延信号呼び出しましょうτ=n/2xd[n]
  • 減算によりハイパスフィルター処理された信号を生成します:xHP[n]=xd[n]xLP[n]

Matlab / Octaveの非常に簡単な図を次に示します。

h_lp = fir1(100、.3); ローパス設計
h_hp = [zeros(50,1); 1; zeros(50,1)]-h_lp; 減算によるハイパス設計%
[H_lp、w] = freqz(h_lp、1,1024);
[H_hp、w] = freqz(h_hp、1,1024);
plot(w / 2 / pi、20 * log10(abs(H_lp))、w / 2 / pi、20 * log10(abs(H_hp)))
グリッド、軸([0、.5、-100,5])

ここに画像の説明を入力してください

編集:

filtfiltコマンドを使用したため、位相は人為的に排除され、すべての周波数応答は実際に設計された応答の大きさの2乗であるため、上記の式(1)と(2)は同等になります。そのため、フィルター設計プロセスによる小さな差、数値誤差、filtfilt関数による小さな差(開始時と終了時のトランジェントを最小化する自動的に選択された初期条件)を除き、元のデータからフィルタリングされたデータを減算した結果は直接フィルタリングによく似ているはずです相補フィルターを使用します。これはあなたの例には当てはまらないので、非常に高いフィルター次数のためにフィルター設計ルーチンが問題を引き起こすと思われます。より単純なフィルターで同じことを行う場合(を選択しましたn=100)、あなたはあなたが期待するものを得ます。下の図では、青のデータのセクション、緑のローパスフィルターの出力、赤の元のデータからのハイパスフィルターの出力の減算結果が表示されています。緑と赤の曲線はほぼ同じです。

x = load( 'data.txt'); フィルタリングするデータの割合
h_lp = fir1(100、.3); %LPインパルス応答
h_hp = fir1(100、.3、 'high'); %HPインパルス応答
y = filtfilt(h_lp、1、x); %ローパスフィルターを適用
yh = filtfilt(h_hp、1、x); %ハイパスフィルターを適用する
yd = x-yh; ハイパスフィルターとの差によるローパス%
n = 1:length(x);
plot(n、x、n、y、 'g。'、n、yd、 'r')
axis([3500,4000,140,​​150])

ここに画像の説明を入力してください


この方法でハイパスフィルターを設計しようとしている場合、ローパスフィルターの仕様に注意する必要があります。ローパスフィルターのストップバンド減衰は通常、ハイパスで小さなパスバンドリップルを達成するのに十分高いですが、LPフィルターでのパスバンドリップルは多くの場合、HPフィルターで十分なストップバンド減衰を達成しません。
デビッド

詳細な対応ありがとうございます。いくつかのことを解決しました。
固定小数点

3

スケーリングについて:

係数を合計すると、DCの大きさがわかります。したがって、それはあなたがこれらの数字(取得という意味になり LPのため、 HPのために)。10

Matt L.の優れた答えに加えて、彼が使用しているものは振幅相補フィルターと呼ばれることを指摘することができます。これは線形位相FIRフィルターの一般的なケースです。

|HLP|+|HHP|=1

2つの並列オールパスセクションからフィルターを作成し、出力を加算/減算する場合、ローパス/ハイパスフィルターは代わりに電力を補完します。

|HLP|2+|HHP|2=1

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.