2011-07-11 16 views
20

Szukam sposobu na wykrycie, który z dwóch (podobnych) obrazów jest ostrzejszy.Wykryj, który obraz jest ostrzejszy

myślę to może być za pomocą jakiejś mierze ogólną ostrość i generowania wynik (hipotetyczny przykład: Image1 ma ocenę ostrości 9, image2 ma ocenę ostrości 7; tak Image1 jest ostrzejszy)

I Wcześniej przeszukaliśmy algorytmy wykrywania/oceniania ostrości, ale natrafiliśmy tylko na te, które poprawią ostrość obrazu.

Czy ktoś zrobił coś takiego, lub miał jakieś użyteczne zasoby/prowadzi?

Używałbym tej funkcji w kontekście aplikacji webowej, więc preferowany jest PHP lub C/C++.

+2

Czy są to dwa obrazy tego samego obiektu/odległości, ale jeden jest ostrzejszy od drugiego? –

+3

Interesujący artykuł: http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?tp=&arnumber=4697259 (Pomiar ostrości obrazu przy użyciu wartości własnych) –

+0

@gigantt, dzięki to to sprawdzę. w większości wyobrażam sobie, że obrazy będą * w większości podobne. Być może niewielkie zmiany odległości mogą spowodować niewielkie zmiany w rozmiarze obiektu lub z wąską głębią ostrości, która może powodować ogniskowanie różnych części. – econstantin

Odpowiedz

2

Funkcje Sprawdź Kontrast transferowe (CTF)

Here's implementacji
Here's wyjaśnienie

+1

Z tego, co widzę, artykuł i implementacja odnoszą się do mikroskopii elektronowej. Ekstrapolacja do normalnej fotografii nie wydaje się prosta. Wycofałem się, ponieważ bardzo mnie interesuje wiedza, w jaki sposób można tu użyć CTF, i usunę mój głos po edycji i wzbogaceniu odpowiedzi. Dzięki! –

+1

łącza są przerywane :( –

11

Prosta metoda jest pomiar kontrastu - obraz z największych różnic między wartościami pikseli jest najostrzejszy. Można na przykład obliczyć wariancję (lub odchylenie standardowe) wartości pikseli, a zależnie od tego, która wartość zostanie większa, wygrywa większa liczba. Wygląda to na maksymalny ogólny kontrast, który może nie być tym, czego chcesz - w szczególności będzie faworyzował zdjęcia o maksymalnej głębi ostrości.

W zależności od tego, co chcesz, możesz chcieć użyć czegoś takiego jak FFT, aby zobaczyć, który wyświetla najwyższą zawartość częstotliwości. To pozwala faworyzować obraz, który jest wyjątkowo ostry w niektórych częściach (ale mniej w innych) nad tym, który ma większą głębię ostrości, więc więcej obrazu jest rozsądnie ostre, ale maksymalna ostrość jest mniejsza (co jest powszechne, z powodu do dyfrakcji z mniejszymi otworami).

+0

O metodzie FFT, Interesujące podejście! Czy chodzi o porównanie jasności obrazów w niektórych częściach przekształconego obrazu FFT? Czy wyższe częstotliwości byłyby zlokalizowane w środku lub na krawędziach obrazu? – ellockie

+1

@ellockie: Po FFT masz dane opisujące obraz, ale już nie rzeczywisty obraz. Wyższe częstotliwości zależą od zawartości obrazu, a nie od lokalizacji na obrazie (tzn. jest to, że działo się to w najostrzejszych częściach) –

+0

Tak więc w obrazie transormalnym FFT można powiedzieć, że piksele dalej od centrum reprezentują wyższe częstotliwości związane z bardziej szczegółowymi funkcjami? Dziękuję za wyjaśnienie – ellockie

3

This paper opisuje metodę obliczania współczynnika rozmycia za pomocą DWT. Wyglądał całkiem prosto, ale zamiast wykrywać ostrość, wykrywa rozmycie. Wygląda na to, że najpierw wykrywa krawędzie (proste splatanie), a następnie używa DWT do gromadzenia i oceniania.

4

Prostym praktycznym podejściem byłoby użycie wykrywania krawędzi (więcej krawędzi == ostrzejszy obraz).

szybki i brudny praktyczne z wykorzystaniem 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); 

(obraz z mniej plama jest ostrzejszy) Bardziej efektywne podejście byłoby wykryć krawędzie w kodzie, używając Sobel operatora. PHP example (przepisanie w C++ powinno dać ogromne zwiększenie wydajności, jak sądzę).

+0

Ostatni bajt wrócił z 'imagecolorat()' zawiera niebieski komponent. Aby rozważyć czerwony i zielony użyj filtru 'imagefilter ($ image, IMG_FILTER_GRAYS CALE); 'before. – hermannk

+0

"Filtr obrazu ($ image, IMG_FILTER_EDGEDETECT)" zwraca wartości około 127. Jeśli na obrazie jest więcej kontrastu, wartości różnią się bardziej od tej wartości _locally_. Niemniej jednak, średnia wartość jest zawsze bliska 127. Aby naprawić: Oblicz wariancję szarości. – hermannk

4

Jak np. pokazany w this Matlab Central page, ostrość może być oszacowana przez średnią wielkość gradientu.

ta była wykorzystywana w Pythonie jak

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) 

Podobnie liczba może być obliczony z prostszym numpy.diff zamiast numpy.gradient. Wynikowe rozmiary macierzy muszą być tam dostosowane:

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

Mniej jest bardziej rozmyta? –

+0

Tak, mniejsza ostrość oznacza większe rozmycie. –

+0

Czy należy to zrobić na obrazie w skali szarości, jak w kodzie matlab? A może powinna działać również na kolorowym obrazie? (Zakładam, że tablica = lista (img.getdata()), czy to jest poprawne?) – faerubin

Powiązane problemy