2015-01-09 14 views
5

jestem pobierania zdjęć satelitarnych jak ten satellite_image http://home.chpc.utah.edu/~u0553130/NASA_SPoRT_VIIRS_Images/VIIRS_11um_20150104_1834_UTC.gif Ponieważ niektóre obrazy są przeważnie czarne, jak ten, nie chcę, aby go zapisać.Python - dowiedzieć się, ile obraz jest czarno

Jak mogę użyć Pythona, aby sprawdzić, czy obraz jest większy niż 50% czerni?

+2

'Załaduj' obraz, wykonaj iterację nad pikselami i zwiększaj licznik za każdym razem, gdy znajdziesz kolor (0,0,0). – Kevin

+0

Wygląda na to, że czarny to (1, 1, 1), więc możesz po prostu sprawdzić, czy wartość pikseli jest mniejsza niż 10 lub coś podobnego. – Matthew

+0

Powinieneś użyć PIL (Python Imaging Library). Oto jak go użyć: http://stackoverflow.com/a/11064935/1612701 –

Odpowiedz

0
  • obraz Załaduj
  • Czytaj każdy wynik piksela i przyrostu jeśli piksel = (0,0,0)
  • Jeśli wynik = < (image.width * image.height)/2
  • Zapisz obraz

Lub sprawdź, czy jest prawie czarny, zwracając wartość true, jeśli piksel R (lub G lub B) jest mniejszy niż 15 na przykład.

7

Masz do czynienia z gifami, które w większości są w skali szarości dzięki wyglądowi twojego przykładowego obrazu, więc możesz oczekiwać, że większość komponentów RGB będzie równa.

Korzystanie PIL:

from PIL import Image 
im = Image.open('im.gif') 
pixels = im.getdata()   # get the pixels as a flattened sequence 
black_thresh = 50 
nblack = 0 
for pixel in pixels: 
    if pixel < black_thresh: 
     nblack += 1 
n = len(pixels) 

if (nblack/float(n)) > 0.5: 
    print("mostly black") 

Dostosuj próg "czarny" pomiędzy 0 (boisko czarny) i 255 (śnieżnobiały) w stosownych przypadkach).

+1

W razie problemów zmień na 'Image.open ('im.gif'). Convert ('L')' – Asakura

+0

Powinien 'piksel Jake

0

Wykorzystując swój testowy obraz, najczęściej używany kolor ma wartość RGB (1, 1, 1). To jest bardzo czarne, ale nie do końca czarne. Moja odpowiedź korzysta z PIL library, webcolors i hojny pomoc kodu z this odpowiedzi.

from PIL import Image 
import webcolors 

def closest_color(requested_color): 
    min_colors = {} 
    for key, name in webcolors.css3_hex_to_names.items(): 
     r_c, g_c, b_c = webcolors.hex_to_rgb(key) 
     rd = (r_c - requested_color[0]) ** 2 
     gd = (g_c - requested_color[1]) ** 2 
     bd = (b_c - requested_color[2]) ** 2 
     min_colors[(rd + gd + bd)] = name 
    return min_colors[min(min_colors.keys())] 

def get_color_name(requested_color): 
    try: 
     closest_name = actual_name = webcolors.rgb_to_name(requested_color) 
    except ValueError: 
     closest_name = closest_color(requested_color) 
     actual_name = None 
    return actual_name, closest_name 

if __name__ == '__main__': 
    lt = Image.open('test.gif').convert('RGB').getcolors() 
    lt.sort(key=lambda tup:tup[0], reverse=True) 
    actual_name, closest_name = get_color_name(lt[0][4]) 
    print lt[0], actual_name, closest_name 

wyjściowa:

(531162, (1, 1, 1)) None black 

W tym przypadku, byłbyś zainteresowany zmiennej closest_name. Pierwszy (lt[0]) pokazuje najbardziej popularną wartość RGB. To nie ma zdefiniowanej nazwy kolorów internetowej, stąd None dla actual_name


Objaśnienie:

to otwarcie pliku masz zapewnione, przekształcając go na RGB, a następnie uruchomić getcolors metodę pil w sprawie Obraz. Wynikiem tego jest lista krotek w formacie (count, RGB_color_value). Następnie sortuję listę (w odwrotnej kolejności). Korzystając z funkcji z innego answer, przekazuję najbardziej powszechną wartość koloru RGB (teraz pierwsza krotka na liście, a RBG to drugi element krotki).

0

Dokładnym sposobem jest policzenie pikseli za pomocą czegoś podobnego do PIL, jak podano w innych odpowiedziach.

Jednakże, jeśli wszystkie są skompresowanymi obrazami, możesz mieć możliwość sprawdzenia rozmiaru pliku, ponieważ obrazy z wieloma obszarami o jednolitym kolorze powinny kompresować o wiele więcej niż te z odmianą taką jak chmura.

W przypadku niektórych testów można przynajmniej znaleźć heurystyczną wersję zdjęć z dużą ilością chmur, o których wiadomo, że można je od razu odrzucić bez kosztownej pętli nad pikselami. Inne bliższe 50% można sprawdzić piksel po pikselu.

Dodatkowo, podczas iteracji pikseli, nie trzeba liczyć wszystkich czarnych pikseli, a następnie sprawdzić, czy co najmniej 50% jest czarne. Zamiast tego, przestań liczyć i odrzuć, gdy tylko wiesz, że co najmniej 50% jest czarne.

Druga optymalizacja: jeśli wiesz, że zdjęcia są przeważnie raczej pochmurne niż przeważnie czarne, przejdź w drugą stronę. Policz liczbę nie-czarnych pikseli, zatrzymaj i zachowaj obrazy, gdy tylko przekroczy 50%.

Powiązane problemy