2011-07-11 112 views
20

我正在尋找一種方法來檢測哪兩個(類似)圖像更清晰。檢測哪個圖像更清晰

我想這可能是使用整體銳度的某種度量,併產生評分(假設的例子:image1的具有9清晰度評分,圖像2具有7清晰度評分;因此image1的更尖銳)

I」我們已經對銳度檢測/評分算法進行了一些搜索,但只會遇到可以提高圖像清晰度的算法。

有沒有人做過這樣的事情,或有任何有用的資源/線索?

我會在web應用程序的上下文中使用這個功能,所以PHP或C/C++是首選。

+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:在FFT之後,你所擁有的是描述圖像的數據,但不再是實際的圖像。較高的頻率將取決於圖像的內容,而不是圖像中的位置(即,可能在任何地方 - 想法是否會發生在最銳利的部分) –

+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左右的值。如果圖片中有更多的對比度,那麼值與_locally_的值相差更大。儘管如此,平均值總是接近127.解決方法:計算灰度值的方差。 – hermannk

4

例如,如this Matlab Central page所示,銳度可以通過平均梯度幅度來估計。

我用這個在Python作爲

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) 

類似的數目可以使用更簡單的numpy.diff代替numpy.gradient來計算。由此產生的陣列大小需要在那裏適應:

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