ガウス分布でランダム信号をたたみ込み、ノイズ(この場合はポアソンノイズ)を追加して、ノイズの多い信号を生成しました。次に、このノイズの多い信号をデコンボリューションして、同じガウスを使用して元の信号を抽出します。
問題は、1Dでデコンボリューションを行うコードが必要なことです。(私はすでに2Dでいくつか見つけましたが、私の主な目的は1Dです)。
そうすることができるいくつかのパッケージまたはプログラムを私に提案していただけませんか?(できればMATLABで)
助けてくれてありがとう。
ガウス分布でランダム信号をたたみ込み、ノイズ(この場合はポアソンノイズ)を追加して、ノイズの多い信号を生成しました。次に、このノイズの多い信号をデコンボリューションして、同じガウスを使用して元の信号を抽出します。
問題は、1Dでデコンボリューションを行うコードが必要なことです。(私はすでに2Dでいくつか見つけましたが、私の主な目的は1Dです)。
そうすることができるいくつかのパッケージまたはプログラムを私に提案していただけませんか?(できればMATLABで)
助けてくれてありがとう。
回答:
StackOverflowで一度説明しました。
信号はベクトルとして表すことができ、畳み込みはN対角行列(Nはフィルターの長さ)との乗算です。答えのために、フィルターは信号よりもはるかに小さいと仮定しています
例えば:
あなたのベクトル/信号は:
V1
V2
...
Vn
フィルター(畳み込み要素)は次のとおりです。
[b1 b2 b3];
したがって、行列はnxn:(Aと呼ばれます):
[b2 b3 0 0 0 0.... 0]
[b1 b2 b3 0 0 0.... 0]
[0 b1 b2 b3 0 0.... 0]
.....
[0 0 0 0 0 0...b2 b3]
畳み込みは:
A*v;
そして、デコンボリューションは
A^(-1) * ( A) * v;
明らかに、いくつかのケースではデコンボリューションが不可能です。これらは、特異Aがある場合です。特異ではないが特異に近い行列でさえ、数値エラーが大きくなるため、問題になる可能性があります。行列の条件数を計算することで推定できます。
Aの条件が低い場合、逆を計算して結果に適用できます。
ここで、Matlabでいくつかの例を見てみましょう。
まず、畳み込み行列を計算する関数を作成しました。
function A = GetConvolutionMatrix(b,numA)
A = zeros(numA,numA);
vec = [b zeros(1,numA-numel(b))];
for i=1:size(A,1)
A(i,:) = circshift(vec,[1 i]);
end
end
さて、異なるカーネルで何が起こるか見てみましょう:
b = [1 1 1];
A = GetConvolutionMatrix(b,10);
disp(cond(A));
条件番号は次のとおりです。
7.8541
予想通り、これは問題があります。平均化した後、元の信号に戻すのは困難です。
ここで、より穏やかな平均化を試してみましょう。
b = [0.1 0.8 0.1];
A = GetConvolutionMatrix(b,10);
disp(cond(A));
結果は次のとおりです。
1.6667
それは私たちの直感によく合い、元の信号の穏やかな平均化は元に戻すことがはるかに簡単です。
また、逆行列が次のように見えることも確認できます。
figure;imagesc(inv(A));
マトリックスの1行は次のとおりです。
0.0003 -0.0026 0.0208 -0.1640 1.2910 -0.1640 0.0208 -0.0026 0.0003 -0.0001
各線のエネルギーのほとんどが中心の周りに3〜5個の係数に集中していることがわかります。したがって、デコンボリューションを行うには、次の近似を使用して信号を再度コンボリューションするだけです。
[0.0208 -0.1640 1.2910 -0.1640 0.0208]
このカーネルは面白そうです!研ぎオペレーターです。私たちの直感は正しいです、シャープはぼかしをキャンセルします。
これはまだ未解決の問題だと思います。
元の信号を最大限に回復しようとする研究論文は数多くあります。
古典的なアプローチの1つは、Waveletベースのメソッドによるものです。
このような辞書のアプローチもあります。
David L. Donho、Michael Elad、Alfred M. Brucksteinなどの研究をフォローすることで、問題のより詳細なビューを得ることができます。
ノイズが再構築された信号で任意に拡大されるため、ノイズの多いデータのデコンボリューションは不適切な問題であることが知られています。したがって、解を安定させるために正則化法が必要です。ここでは、ティホノフの正則化アルゴリズムを実装することにより、この問題に対処するMATLABパッケージを見つけることができます。
質問の最初に行きます。画像処理アプリケーションに使用されるMATLABのデコンボリューション関数があります。ただし、これらの関数は1D信号にも使用できます。例えば、
% a random signal
sig_clean = zeros(1,200);
sig_clean(80:100)=100;
figure
subplot(1,3,1)
plot(sig_clean,'b-.','LineWidth',2)
legend('Clean Signal')
% convolve it with a gaussian
x=1:30;
h = exp(-(x-15).^2/20); h=h/sum(h);
sig_noisy = conv(sig_clean,h,'same');
% and add noise
sig_noisy = awgn(sig_noisy,0,'measured');
subplot(1,3,2)
plot(sig_noisy,'r')
hold on, plot(sig_clean,'b-.','LineWidth',3)
legend('Blurred and noise added signal','Clean Signal')
(sig_noisy = sig_clean * h + noise
)次に、出力信号をh
関数でデコンボリューションして、(ほぼ)入力信号を取得します。ここではウィーナーデコンボリューションを使用しています
sig_deconvolved=deconvwnr(sig_noisy,h,1);
subplot(1,3,3)
plot(sig_noisy,'r')
hold on, plot(sig_clean,'b-.','LineWidth',2)
hold on, plot(sig_deconvolved,'k--','LineWidth',2)
legend('Blurred and noise added signal','Clean Signal','Deconvolved Signal')
あるいは、h
関数はわからないが、入力と出力はわかっている場合は、今回は、入力信号をh^-1
関数に与える出力でデコンボリューションしないでください。次に、それをフィルターとして使用して、ノイズの多い信号をフィルター処理できます。(sig_clean = sig_noisy * h^-1
)
h_inv=deconvwnr(sig_clean,sig_noisy,1);
figure;
subplot(1,2,1)
plot(h_inv)
legend('h^-^1')
sig_filtered=conv(sig_noisy,h_inv,'same');
subplot(1,2,2)
plot(sig_noisy,'r')
hold on, plot(sig_clean,'b-.','LineWidth',2)
hold on, plot(sig_filtered,'k--','LineWidth',2)
legend('Blurred and noise added signal','Clean Signal','Filtered Signal')
お役に立てば幸いです。
畳み込みとは、2つの信号を相互に乗算および加算することです。私は2つの決定論的なシグナルについて話している。互いにデコンボリューションしたい場合、これは連立方程式の解に相当します。ご存知かもしれませんが、連立方程式は常に解けるとは限りません。方程式系は、過決定、過小決定、または正確に解ける可能性があります。
ノイズを追加した場合、一部の情報が失われ、この情報を取り戻すことはできません。ここでもできることは、各係数にノイズ項が追加されるという事実を考慮して、線形連立方程式を解くことです。または、質問の別の回答でわかるように、最初にノイズの多い信号から元の信号を推定し、次に方程式系を解いてみることができます。
乗算および合計された係数にノイズが追加されることに注意することが重要です。したがって、最終的に方程式系が一意に解けない場合もあります。一意に解けることを確実にするために、係数行列は正方でフルランクでなければなりません。
これは難しいでしょう。ガウスによる畳み込みは、周波数領域でのガウスのフーリエ変換による乗算と同等です。これはたまたま本質的にガウシアンでもあり、これはローパスフィルターであり、非常に効果的なフィルターです。ノイズを追加すると、ガウシアンの「ストップバンド」にあるすべての情報が破壊されます。それを回復する方法はありません。
デコンボリューションは、基本的に周波数応答の逆数を乗算しています。ここに問題があります:元のガウスが非常に小さい場合、周波数応答の逆が本当に大きくなります。これらの周波数では、基本的にノイズを膨大な量で増幅します。すべてが完全にノイズのない状態であったとしても、おそらく数値的な問題に遭遇するでしょう。
デコンボリューションには多くの方法があります(つまり、分解演算子は線形であり、時間/空間不変です)。
それらのすべては、問題が多くの場合病気で落ち着いているという事実に対処しようとします。
より良い方法は、復元するデータのモデルにいくつかの正則化を追加するものです。
統計モデル(事前)または任意の知識を使用できます。
画像の場合、適切なモデルは、断片的な滑らかさまたはグラデーションのスパース性です。
しかし、答えのために、単純なパラメトリックアプローチが採用されます--モデル内の復元されたデータと測定値の間の最小二乗誤差を最小化します。
最小二乗モデルは単純です。
データの関数としての目的関数は以下によって与えられます:
最適化問題は次のように与えられます:
ここで、は復元するデータ、はぼかしカーネル(この場合はガウス)、は所定の測定値のセットです。
モデルは、測定値が畳み込みの有効な部分に対してのみ与えられることを前提としています。つまり、および場合、ここでです。
これは有限空間での線形演算であるため、行列形式を使用して記述できます。
ここで、はたたみ込み行列です。
最小二乗解は次で与えられます:
見てわかるように、行列の反転が必要です。
これを適切に解決する能力は、演算子の条件数に依存しますこれは、従います。 cond(H ) = √
この条件番号の背後にあるものは何ですか?
線形代数を使用して答えることができます。
しかし、私の意見では、より直観的なアプローチは、周波数領域で考えることです。
基本的に、分解オペレーターは、一般的に高周波のエネルギーを減衰させます。
さて、周波数ではこれは基本的に要素ごとの乗算なので、逆フィルターを使用して要素ごとに除算することで簡単に反転できます。
さて、それは上記で行われたことです。
この問題は、フィルターがエネルギーを実質的にゼロに減衰させる場合に発生します。次に、実際の問題が発生します...
これは基本的に、条件数が私たちに伝えていることであり、いくつかの周波数が他の周波数に比べてどれほど激しく減衰されたかです。
上では、コンディションナンバー([dB]単位を使用)をガウスフィルターのSTDパラメーターの関数として見ることができます。
予想通り、STDが高いほど条件数が悪くなります。STDが高いほどLPFが強くなるためです(最後に下がる値は数値的な問題です)。
Ensemble of Gaussian Blur Kernelが作成されました。
パラメータは、、、です。
データはランダムで、ノイズは追加されていません。k = 31 m = 270
MATLABでは、線形システムはpinv()
SVDベースの疑似逆行列と\
演算子を使用して解決されました。
ご覧のように、SVDを使用すると、ソリューションは期待どおりに感度が大幅に低下します。
エラーが発生するのはなぜですか?
ソリューションを見る(最高のSTDの場合):
見てわかるように、信号は開始と終了を除いて非常によく復元されます。
これは、これらのサンプルについてほとんど説明しないValid Convolutionを使用しているためです。
ノイズを追加すると、状況が変わってしまいます。
以前に結果が良かったのは、MATLABがデータのDRを処理し、条件数が大きい場合でも方程式を解くことができるためです。
ただし、条件数が大きいと、逆フィルターが一部の周波数を強く増幅します(強い減衰を元に戻すため)。
それらがノイズを含んでいる場合、それはノイズが増幅され、復元が悪いことを意味します。
上記のように、今は再建は機能しません。
劣化演算子を正確に知っていて、SNRが非常に優れている場合は、単純なデコンボリューションメソッドが機能します。
デコンボリューションの主な問題は、Degradation Operatorが周波数をどれだけ減衰させるかです。
減衰が大きいほど、復元するために必要なSNRが多くなります(これは基本的にWiener Filterの背後にある考え方です)。
ゼロに設定された周波数は復元できません!
実際には、安定した結果を得るために、いくつかの事前計算を追加する必要があります。
このコードは、私のStackExchange Signal Processing Q2969 GitHubリポジトリで入手できます。
一般に、2つ以上の成分を抽出する問題に実質的に一般化する問題を処理する1つの方法は、信号#1、#2、...、#nのスペクトルG¹、G²⋯、Gⁿを取り、合計を集計することです2乗Γ(ν)= |G¹(ν)|²+ |G²(ν)|²+⋯+ |Gⁿ(ν)|²各周波数νで、G₁(ν)≡G¹(ν)* /Γを正規化(ν)、G₂(ν)≡G²(ν)* /Γ(ν)、...、G_n(ν)≡Gⁿ(ν)* /Γ(ν)。不明瞭さとノイズの問題は、周波数νによってはΓ(ν)〜0が可能であるという事実に対応しています。これを処理するには、別の「信号」を追加してG⁰(ν)=定数-「ノイズ」信号を抽出します。これで、Γ(ν)は以下に厳密に制限されます。これはほぼ確実にティホノフの正則化と関連していますが、同等の結果や他の通信文を見つけたり、確立したりすることはありませんでした。シンプルで、より直接的で直感的です。
あるいは、Gを適切な内積を備えたベクトルとして扱うこともできます。たとえば、«G、G '»∫∫G(ν)* G'(ν)dνとし、(G₀、G₁、⋯、G_n)を双対として(例えば、一般化された逆)(G⁰、G¹、⋯、Gⁿ)-もちろん、成分ベクトルは線形独立であると仮定します。
ガウスデコンボリューションの場合、n = 1、G⁰=「ノイズ」信号、G¹=「ガウス」信号を設定します。
Andrey Rubshteinによって提供された答えは、ノイズの存在下では無残に失敗します。これは、前述の問題がノイズとモデリングエラーに非常に敏感であるためです。畳み込み行列を作成することは良い考えですが、このような問題では、反転での正則化の使用は絶対に必要です。非常にシンプルで単純な正則化手法(計算コストはかかりますが)は、切り捨て特異値分解(TSVD)です。Tikhonov正則化や合計変動正則化などの方法チェックアウトする価値があります。Tikhonov正則化(およびその一般的な形式)は、Matlabで実装しやすい非常にエレガントなスタック形式です。Samuli SiltanenとJennifer Muellerによる本:線形および非線形の逆問題と実用的なアプリケーション。
実際のところ、問題は明確ではありません。しかし、答えはあなたが求めたものを具体化しました。一部の人々の助言に従って、線形代数方程式のシステムを構築できますが、これは正しいですが、既知の信号に基づいて構築された行列は、いわゆる条件がよくありません。つまり、逆にしようとすると、切り捨てエラーによってソリューションが強制終了され、結果として乱数が返されます。一般的なアプローチは、制約された極値です。ソリューションのノルムを最小化します|| x || 制約付き|| Ax-y || <デルタ。したがって、Axとyの差が大きくならないような最小のノルムを持つxを探しています。最小二乗法の適用で得られる行列の主対角線にいわゆる正則化のパラメーターを追加する必要があるのは非常に簡単です。これはティホノフ正則化と呼ばれます。それを行うコーディングサンプルがあります。