補正アルゴリズム③の概要
焦点のブレなどを補正する3つ目のアルゴリズムとして、目印を使わずに画像の精度を向上させる方法を提案して卒業したいと考えています。目印を使わずに画像の精度向上を行うためには、CT画像の評価の指標としてこれまで使ってきた、サイノグラムのサインカーブの抽出を行っ て、抽出できるサインカーブを増やせるようにサイノグラムに処理を施そうと考えています。最急勾配法や焼きなまし法(SA)など最適化アルゴリズムの考え方を使って抽出できるサインカーブの本数が最大になるサイノグラムを作りたいと考えています。
サインカーブの抽出について
サイノグラムの画素をサインカーブ状に順番に調べていくことでサインカーブの抽出を行っています。サインカーブの抽出には2つの指標を用いて、判断をおこなっています。一つ目の指標を連続値と呼んでいます。連続値はサインカーブ上にどれくらい許容誤差以下の連続した画素があるかを調べていて、今回は750px程度連続した画素があればサインカーブと判断しています。もう一つの指標として濃度の平均値を使っています。サインカーブ上に画素の濃度を加算していき、投影方向数で割ったものが境界平均値よりも大きいかどうかを調べています。境界平均値よりも大きいと被写体のある領域だと判断されます。この2つの条件を満たすときサインカーブと判断されます。また、一点境界値以下の領域は被写体以外の領域だと判断して、一つでもそれ以下のピクセルがあるとサインカーブであるとみなされません。
最急勾配法による方法
まずは、最急勾配法の考え方?(正しいかどうかは不明)を使ってサイノグラムを動かします。最急勾配法は反復法を用いて最適解を求める手法で、勾配しか見ないので、単純で計算も速いです。しかし局所解にはまりやすい特徴もあります。今回は抽出できるサイノグラムの本数を評価値として、抽出できるサインカーブが最大になるサイノグラムを求めます。また、これを評価する関数を評価関数といいます。試しにサイノグラムを0°から動かしてみて、その都度最も抽出できたサインカーブの本数が最も多くなるように、サイノグラムを動かしていきます。今回は最大で1000回計算を行うことにします。アルゴリズムは以下のようになっています。
- 元のサイノグラムの抽出できるサインカーブの本数を調べる。変数iniに格納。
- 上(0°)から順番にサイノグラムを移動させる。計算回数p番目の時はp行目以降のサイノグラムを0.3×p[px]Z方向(-Z方向)に移動させる。
- 何番目以降のサイノグラムを移動させたときサイノグラムが最大になるかを変数maxに、その時の行数を変数staに格納しておく。
- sta番目から2,3の計算を行う。
- 2,3,4を繰り返す。1000回繰り返すか、抽出されるサインカーブの最大値が変化しなくなったら計算終了。
ソースコードを以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | public static void moveSino(){ int proj = 800; //投影方向数 double den = 0; //移動する濃度 int max = 0; //抽出できたサイノグラムの最大値 boolean end = true ; //終了判定用 for ( int k = 0; k < 1000; k++){ int cnt=0, sta=0, ini=0; den+=0.2; //移動する濃度を増やす sta=start; //移動を開始する位置を決める for ( int p = sta; p< 800; p++){ cnt = 0; for ( int j = 0; j < 512; j++){ for ( int i = 0; i < 800; i++){ sinogram[j][i] = FBP.sino[j][i]; } } //Z方向に移動 if (noudo>=1){ for ( int j = 0; j < 512-( int )noudo; j++){ for ( int i = p; i < 800; i++){ sinogram[511-j][i] = FBP.sino[511-j-( int )noudo][i]; } }noudo-=( int )noudo; } for ( int j = 0; j < 512-1; j++){ for ( int i = p; i < 800; i++){ if (p==0) continue ; sinogram3[511-j][i]+=FBP.sino[510-j][i]*noudo; sinogram3[511-j][i]-=FBP.sino[511-j][i]*noudo; } } //サインカーブの本数を調べる cnt = cntSineCarb(); if (p==0)ini = cnt; //抽出できた最大値とその時の行を格納 if (max<cnt){ max = cnt; start = p; end = false ; } } if (end) break ; //最大値が更新されなかったら終了 end = true ; } |
プログラムを実行します。境界平均値を8000、一点境界値を5000、連続値を750、許容誤差を1000に設定して、サイノグラムの本数を順番に調べ、本数が増える方向にサイノグラムを移動させました。結果を以下に示します。
サインカーブの本数だけでは、19本(4%)と今までで最も抽出できたサインカーブの本数が増えましたがコントラストと輪郭が変化した程度で、見た目の変化はほとんどありませんでした。計算も4周目で計算が終わってしまったので局所解に収まってしまったと考えられます。-Z方向に動かした場合、移動させる濃度を変更した場合も結果はほとんど変わりませんでした。
焼きなまし法(SA)による方法
焼きなまし法も勾配法の一種ですが、計算の途中で敢えて評価値が悪くなる方に解を動かすことによって、局所解にはまりにくくする手法です。