2016-09-03 3 views
0

私はこれが何か簡単だと確信していますが、私はむしろそれに困惑しています。私は、それぞれ異なる露出時間で撮影された一連の画像を取り込み、出力の平均値(DN)と信号のRMSを測定しています。全体のポイントは、光子伝達曲線を構築することです。私が実行している問題は、ウィンドウの信号またはRMSの平均を取ろうとするとき、または1つのピクセルさえも平均して保存しようとすると、格納された値がわかりにくいということです。これはむしろまっすぐ進むはずなので、それはとてもイライラしています。どんな洞察にも感謝します。ダムMatlab問題

pix 
    16 
    18 
    21 
    19 
    22 
    17 
    19 
    18 
    16 
    20 
    18 
    21 
    23 
    17 
    20 

pixmean 
    19 

pixrms 
frame(t) 
    19 

framerms(t) 
    18.8880 

mean(frame) 
    0.4404 

frameMean(i) 
    0.4404 

********** 
frameRMS(i) 
    0.4404 

********** 

は、あなたがこのいずれかを明確にしたい場合は私に知らせてください:

stacklength = 25; 
frame = []; 
frameMean = []; 
framerms = []; 
frameRMS = []; 
t = 1; 
stacknum = 99; 
stackdepth = 15; 
imagewidth=1944; 
imageheight=2592; 
uStart = 1001; 
uEnd = 1001; 
vStart = 1001; 
vEnd = 1001; 
tic; 
for i=1:stacklength 
    filename=sprintf('PTLstack_%d.mat' ,i); %name files one at a time 
    load(filename); 
    for u = uStart:uEnd 
     for v = vStart:vEnd 
      pix = double(squeeze(pixel(u,v,:))); 
      pixmean = mean(pix); 
      pixrms = rms(pix); 
      frame(t) = pixmean; 
      framerms(t) = abs(pixrms-pixmean); 
      t = t+1; 
     end 
    end 
    frameMean(i) = mean(frame); 
    frameRMS(i) = mean(framerms); 
    t = 1; 
    disp(i); 
end 
toc; 

そして、ここでは、私はそれが私のために表示されていたいくつかの値です:

は、ここに私のコードです。私はコードの塊を見て、その中で起こっていること全てを理解することが期待されるのは面倒かもしれません。

ありがとう、10^6。

+0

'frame'と' framerms'をゼロ初期化する必要があります。データセットのサイズが異なる場合は古い値を再利用しています。ループ内の配列の成長は、とにかく非効率的なので、事前に割り当てる必要があります。もし 'uEnd'、' vEnd'などがマットファイル間で変化すると、汚染されたデータを簡単に得ることができます(例えば、2番目の反復では、サイズが '5000x5000'、次にサイズが' 1000x1000'です...)この場合、多くの割り当てられているが設定されていない要素)。 double forループの前に 'frame = zeros(...)'を設定し、 'framerms'についても同様に設定することをお勧めします。ここで' ... 'は' t'インデックスの総数です。 –

+0

マットファイル内の浮遊変数によって変数を汚染しないようにしたい場合は、structにロードしてみてください: 'tmpvars = load(...);ピクセル= tmpvars.pixel; '。このようにして、他のパラメータをロードすることはできません。それを考えると、 'load(...、 'pixel')' –

+0

は毎回15になるでしょう。私は特定の積分時間に15枚の画像を取り、その後積分時間を増やして再度行います。戦略は、特定のピクセルの出力を平均してベクトルに保存することです。次に、そのベクトルの平均値を取る。そうすれば、チップの特定のウィンドウで光の応答を平均化することができます。以前にフレームとフレームを事前に割り当てていましたが、可能な限り単純化するためにジェネリックアレイに戻ってきました。別の何かが起きている。 frameMean(i)とframeRMS(i)はともに最小値の約15よりかなり低いです。 –

答えて

1

結果には、frame変数にいくつかの迷子ゼロがあり、平均値が低くなることが示唆されています。これらがどこに来るかは私には分かりませんが、これはこの種のコードを扱うMatlabスタイルの方法ではないからです。あなたはまた、いくつかの偽のデータを有していてもよく、予備のゼロを持っている場合は

frameMean(i) = mean(frame(frame~=0)); 

ショートカット、洗練ものの、これを修正する唯一の非ゼロの平均を取るために、それを伝えることであろうそこに他の並べ替え。

もっと良い解決策は、これらのループと増分変数などを完全に取り除くことです。あなたのイメージのサイズの画像スタック(X、Y、15)としてロードされていると仮定すると、あなたが意味かかることがありますが、単一行くに望む地域全体のrms:

pix = pix(ustart:uend,vstart:vend,:); % take window area of choice 
frame = mean(pix,3); % make mean 
framerms = rms(pix,3); 
framerms = abs(framerms-frame); 

ここでの出力は、2D行列でありますフレーム全体にわたって。フレーム全体に渡って平均を取るのが最も簡単です。 mean(frame(:))

+0

ああ、大きなアドバイス。どうもありがとう。誰も今までにないし、優雅にコーディングすることを私に非難することもありません。私はまだ各フレームの各ピクセルのRMSを見つけ出し、それを平均化するという問題に直面しています。私はrms()関数は実際に私が探しているものではないが、私が本当に必要なのはsqrt(var(pix(u、v、:)))であると判断しました。私はすべてのピクセルのノイズを測定しようとしています。私はそれがループに頼ることなく可能である方法を見ていない。アイデア? –

+0

ほぼすべての機能がマトリックスレベルで機能します。常にイメージ/イメージスタック全体で作業できるはずです。ピクセル単位でループする必要はありません。どのディメンションで作業したいのかを関数に伝える関数( 'mean'や' rms'、 'dim'など)に' dim'入力を探します。 – nkjt