2011-07-11 11 views
20

2つの(類似した)画像のどちらがシャープであるかを検出する方法を探しています。私は、これは全体的なシャープさのいくつかの指標を使用してスコアを生成することができ思っていシャープな画像を検出する

は:;

私は(仮想的な例がそうimage1のは鋭くている画像1は、9の鋭スコアを有する、画像2は、7の切れ味スコアを有します)シャープネス検出/採点アルゴリズムの検索をいくつか行いましたが、画像のシャープネスを向上させるものだけを見つけました。

誰もこのようなことをやったことがありますか、または有用なリソース/リードを持っていますか?

私はこの機能をWebアプリケーションのコンテキストで使用しているので、PHPまたはC/C++が優先されます。

+2

同じオブジェクト/距離の2つの画像ですが、一方が他方よりシャープですか? –

+3

興味深い論文:http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?tp=&arnumber=4697259(固有値を使った画像のシャープネス測定) –

+0

@gigantt、ありがとう。ほとんどの場合、私は画像がほとんど*似ていると想像しています。おそらく、距離のわずかな変化は、被写体のサイズのわずかな変動を引き起こすか、または被写界深度が狭くなると、異なる部分が焦点の合っている/離れている可能性があります。 – econstantin

答えて

2

チェックコントラスト伝達関数(CTF)

Here's実装
Here's説明

+1

私が見る限り、論文と実装は電子顕微鏡に適用されます。通常の写真への補外は単純ではないようです。私はCTFがここでどのように使用されるかを知ることに非常に関心があり、あなたの答えを編集して強化した後に私の投票を削除することに非常に興味がありますので、私は下降しました。ありがとう! –

+1

リンクが壊れています:( –

11

簡単な方法は、コントラストを測定することである - ピクセル値の間の最大の差を有する画像が鮮明です。たとえば、ピクセル値の分散(または標準偏差)を計算することができます。全体のコントラストを最大限に引き出すことができます。これは、あなたの望むものとは異なる場合があります。特に、被写界深度が最大の写真が好まれる傾向があります。

FFTのようなものを使用して最も高い周波数のコンテンツが表示されるようにすることができます。これにより、被写界深度の深い部分よりもはるかにシャープな画像が得られるようになりますが、画像の鮮明度はかなり高くなりますが、最大のシャープネスは低くなります(これは一般的ですより小さいアパーチャを有する回折に対して)。

+0

FFT方法について興味深いアプローチFFT変換された画像の特定の部分で画像の明るさを比較することは意味しますか?画像の中央または端に高い周波数を配置するのですか? – ellockie

+1

@ellockie:あなたが持っているものは、画像を記述するデータですが、もはや実際の画像ではありません。周波数が高いほど画像の内容ではなく、画像の場所に依存します(つまり、 –

+0

FFTのトランシルムイメージでは、中心から離れたピクセルは、より詳細なフィーチャに関連する頻度が高いと言えるでしょうか?説明をありがとうございます。 – ellockie

3

This paperには、DWTを使用してぼかし係数を計算する方法が記載されている。かなりまっすぐに見えましたが、鮮明さを検出する代わりにぼやけを検出しています。最初にエッジを検出(単純な畳み込み)した後、DWTを使用して累積してスコア付けします。

4

簡単な実用的なアプローチは、エッジ検出(よりエッジ==シャープな画像)を使用することです。

間に合わせハンズオンPHP GD

function getBlurAmount($image) { 
    $size = getimagesize($image); 
    $image = imagecreatefromjpeg($image); 
    imagefilter($image, IMG_FILTER_EDGEDETECT);  
    $blur = 0; 
    for ($x = 0; $x < $size[0]; $x++) { 
     for ($y = 0; $y < $size[1]; $y++) { 
      $blur += imagecolorat($image, $x, $y) & 0xFF; 
     } 
    } 
    return $blur; 
} 

$e1 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Jonquil_flowers_at_f32.jpg/800px-Jonquil_flowers_at_f32.jpg'); 
$e2 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Jonquil_flowers_at_f5.jpg/800px-Jonquil_flowers_at_f5.jpg'); 

echo "Relative blur amount: first image " . $e1/min($e1, $e2) . ", second image " . $e2/min($e1, $e2); 

を用いて(より少ないぼやけた画像がシャープである) より効率的なアプローチは、Sobelオペレータを使用して、コード内のエッジを検出することであろう。 PHP example(C++でのリライトは、私が推測するように、大幅なパフォーマンス向上をもたらすはずです)。

+0

最後に返されたバイト'imagecolorat()'には青色成分が含まれています。赤と緑を考慮するには 'imagefilter($ image、IMG_FILTER_GRAYS CALE);前に。 – hermannk

+0

'imagefilter($ image、IMG_FILTER_EDGEDETECT)'は127を中心に値を返します。画像にコントラストがあると、その値はその値より多く異なります。それにもかかわらず、平均値は常に127に近いです。修正するには:グレー値の分散を計算します。 – hermannk

4

this Matlab Central pageに示すように、平均勾配の大きさによって鮮明度を推定することができる。

同様の番号ではなく、numpy.gradientnumpy.diff単純で計算することができる

from PIL import Image 
import numpy as np 

im = Image.open(filename).convert('L') # to grayscale 
array = np.asarray(im, dtype=np.int32) 

gy, gx = np.gradient(array) 
gnorm = np.sqrt(gx**2 + gy**2) 
sharpness = np.average(gnorm) 

ように私はPythonでこれを使用します。結果として得られる配列のサイズは、次のように調整する必要があります。

dx = np.diff(array)[1:,:] # remove the first row 
dy = np.diff(array, axis=0)[:,1:] # remove the first column 
dnorm = np.sqrt(dx**2 + dy**2) 
sharpness = np.average(dnorm) 
+0

少しぼやけていますか? –

+0

はい、シャープネスが薄いほどぼかしが多くなります。 –

+0

これは、MATLABコードのように、グレースケールイメージ上で行う必要がありますか?それともカラフルなイメージでも動作するのでしょうか? (私はarray = list(img.getdata())と仮定していますが、これは正しいですか?) – faerubin

関連する問題