私は電気工学の学部生です。信号および画像処理アルゴリズム(再構成、セグメンテーション、フィルタリングなど)に関する多くの技術論文を読んでいます。これらの論文に示されているアルゴリズムのほとんどは、連続時間と連続周波数で定義されており、複雑な方程式で解を与えることがよくあります。 C++またはMATLABでテクニカルペーパーを最初から実装して、そのペーパーで得られた結果を再現するにはどうすればよいでしょうか。
より具体的には、Wang et al( IEEE Trans Med Imaging。1993; 12(3):486-96 )による論文「一般的なコーンビーム再構成アルゴリズム」を見ていたところ、疑問に思って、どうすればそれらのアルゴリズムの実装を開始できますか式10は、での再構成画像の公式を示します。それをどのようにコード化しますか?各ボクセルを通過して対応する数式を計算するforループはありますか?その式で関数の関数をどのようにコーディングしますか?任意の点で関数をどのように評価しますか?
ゴンザレスとウッズの「デジタル画像処理」という本を読んだことがあるが、それでも途方に暮れている。数値レシピ本シリーズについても読みました。それは正しい方法でしょうか?
研究論文からアルゴリズムをプログラミングした経験はありますか?ヒントや提案はありますか?
連続時間/空間/周波数で定義された信号処理アルゴリズムは、通常、離散グリッドで信号をサンプリングし、積分を合計に(および微分を差分に)変換することによって実装されます。空間フィルターは、たたみ込みカーネル(つまり、近傍の加重和)を使用したたたみ込みによって実装されます。
サンプリングされた時間領域信号のフィルタリングに関する膨大な知識があります。時間領域フィルターは、 有限インパルス応答フィルター のいずれかとして実装されます。現在の出力サンプルは、前のN個の入力サンプルの重み付き合計として計算されます。または、無限インパルス応答フィルター。現在の出力は、以前の入力と以前の出力の重み付き合計です。形式的には、離散時間フィルターは ラプラス変換 の離散時間アナログである z-transform を使用して記述されます。 双線形変換 は、一方を他方にマッピングします(Matlabでは_c2d
_および_d2c
_)。
任意の点で関数をどのように評価しますか?
サンプリンググリッド上に直接存在しないポイントで信号の値が必要な場合、 補間 近くのポイントからの値を使用します。補間は、最も近いサンプルを選択する、最も近いサンプルの加重平均を計算する、または任意に複雑な分析関数をサンプルデータにフィッティングし、必要な座標でこの関数を評価するなどの単純なものにすることができます。均一で細かいグリッドへの補間は psampling です。元の(連続)信号にサンプリンググリッドの半分より細かい詳細(つまり、周波数)が含まれていない場合、連続関数はサンプルバージョンから完全に再構築できます( Nyquist-Shannonサンプリング定理 )。 2Dで補間する方法の例については、 双線形補間 を参照してください。
Matlabでは、_interp1
_または_interp2
_を使用して1Dまたは定期的にサンプリングされた2Dデータを(それぞれ)補間するか、griddata
を使用して不規則にサンプリングされた2Dデータから補間できます。
各ボクセルを通過して対応する数式を計算するforループはありますか?
はい、正確に。
Matlabは行列とベクトル(つまり、多次元配列)を操作するように設計されているため、明示的なforループを介してこれを行う必要がなくなります。 Matlabではこれは「ベクトル化」と呼ばれています。定積分は、sum
、cumsum
、trapz
、cumtrapz
などで近似できます。
ゴンザレスとウッズの「デジタル画像処理」という本を読んだことがあるが、それでも途方に暮れている。数値レシピ本シリーズについても読みました。それは正しい方法でしょうか?
はい、Numerical Recipesは素晴らしいスタートです。これは非常に実用的であり、最終的に必要になる数値計算方法のほとんどをカバーしています。 (Matlabはすでに必要なすべてを実装していることがわかりますが、Numerical Recipesは優れた背景を提供します。)
「アルゴリズムとデータ構造」のクラスを受講しましたが、そこに示されている資料と科学的アルゴリズムの実装との関係がわかりません。
「アルゴリズムとデータ構造」コースで扱われる資料は、整数や文字列を含むリスト、配列、ツリー、グラフなどの構造と、並べ替えや選択などの操作に集中する傾向があります。通常、単一の正しい結果がある問題。科学的アルゴリズムに関しては、これは話の半分にすぎません。残りの半分は、実数と分析関数を推定する方法に関係しています。これは、「数値法」(または「数値解析」のようなコースで見つかります。-- これ -スライドを下にスクロールしてください):特殊な関数を推定する方法、積分と導関数を推定する方法ここで、主なタスクの1つは結果の精度を推定することであり、一般的なパターンの1つは、十分に正確になるまで推定を改善するルーチンを繰り返すことです。 (Matlabがx
のsin(x)
の値を推定するだけの簡単な方法をどのように知っているかを自問するかもしれません。)
簡単な例として、Matlabで画像のラドン変換を計算する短いスクリプトを次に示します。ラドン変換は、一連の投影角度にわたる画像の投影を行います。任意の角度に沿って投影を計算する代わりに、imrotate
を使用して画像全体を回転させ、投影が常に垂直になるようにします。次に、行列のsum
は各列の合計を含むベクトルを返すため、sum
を使用して単純に射影を取ることができます。
必要に応じて、_interp2
_を使用して独自のimrotate
を作成することもできます。
_%%# Home-made Radon Tranform
%# load a density map (image).
A = phantom;
n_pixels = size(A, 1); %# image width (assume square)
%# At what rotation angles do we want to take projections?
n_thetas = 101;
thetas = linspace(0, 180, n_thetas);
result = zeros(n_thetas, n_pixels);
%# Loop over angles
for ii=1:length(thetas)
theta = thetas(ii);
rotated_image = imrotate(A, theta, 'crop');
result(ii, :) = sum(rotated_image);
end
%# display the result
imagesc(thetas, 1:n_pixels, result.');
xlabel('projection angle [degrees]');
_
かつて光線に沿った密度の積分であったものが、離散的にサンプリングされた画像の列の合計になりました。これは、変換された座標系で元の画像を補間することで見つかりました。
Nibotの 優れた説明 に追加すると、さらにいくつかのポイントが追加されます。
MATLAB、Octave、SciPy/NumPyなどの数値計算環境では、C++などの汎用プログラミング言語ですべてを実行する場合に比べて、多くの労力を節約できます。 double
の配列とループをジャグリングしても、複素数などのデータ型や積分などの演算をすぐに利用できることと比較することはできません。 (それは確かに実行可能であり、優れたC++コードは桁違いに高速であり、優れたライブラリの抽象化とテンプレートを使用すれば、かなりクリーンでクリアなものにすることもできますが、MATLABなどから始めるのは間違いなく簡単です。)
MATLABには、たとえば「ツールキット」もあります。 画像処理 と デジタル信号処理 は、作業内容に応じて非常に役立ちます。
数値法。通常、大学の上級課程と教科書です。
DSPは通常、数値手法と効率的な実装の交差点にあります。効率を無視する場合、探しているのは、対象のテクニカルペーパーの方程式に対して「十分に正確な」結果を生成する可能性がある数値近似法です。場合によっては、サンプリングされたデータを扱う場合があります。その場合、サンプリング定理は、データ取得方法(プレフィルタリング)と、そのデータから得られる結果の範囲または品質の両方にいくつかの制限を課します。
場合によっては、Matlab、数値レシピ、またはさまざまな画像/信号処理ライブラリに、目的の数値解のための効率的なアルゴリズムまたはコードが含まれることがあります。ただし、場合によっては独自にロールする必要があるため、さまざまな数値解法の背後にある数学を理解するのに役立ちます。そして、それ自体が大きな課題です。