Jak mogę obliczyć różnicę między dwoma obrazami?
Oto co chciałbym zrobić:
Robię zdjęcia kamerką w regularnych odstępach czasu. Coś w stylu poklatkowego. Jeśli jednak nic się tak naprawdę nie zmieniło, czyli zdjęcie wygląda tak samo, nie chcę zapisywać najnowszej migawki.
Wyobrażam sobie, że jest jakiś sposób na oszacowanie różnicy i musiałbym empirycznie określić próg.
Szukam prostoty, a nie doskonałości. Używam Pythona.
20 answers
Idea Ogólna
Opcja 1: załaduj oba obrazy jako tablice (scipy.misc.imread
) i Oblicz różnicę elementów (piksel po pikselu). Oblicz normę różnicy.
Opcja 2: Załaduj oba obrazy. Oblicz jakiś wektor funkcji dla każdego z nich (jak histogram). Oblicz odległość między wektorami funkcji, a nie obrazami.
Są jednak pewne decyzje, które należy podjąć najpierw.
Pytania
Powinieneś odpowiedzieć na te pytania pierwszy:
-
Czy obrazy mają ten sam kształt i wymiar?
Jeśli nie, może być konieczna zmiana ich rozmiaru lub przycinanie. Biblioteka PIL pomoże to zrobić w Pythonie.
Jeśli są zrobione z tymi samymi ustawieniami i tym samym urządzeniem, prawdopodobnie są takie same.
-
Czy obrazy są dobrze dopasowane?
Jeśli nie, możesz najpierw uruchomić korelację krzyżową, aby znaleźć najlepsze wyrównanie. SciPy ma do tego zadania.
Jeśli aparat i sceny są nieruchome, obrazy prawdopodobnie będą dobrze wyrównane.
-
Czy ekspozycja obrazów jest zawsze taka sama? (Czy jasność / kontrast jest taki sam?)
Jeśli nie, możesz chcieć znormalizować obrazy.
[18]}ale bądź ostrożny, w niektórych sytuacjach może to zrobić więcej zła niż dobra. Na przykład pojedynczy jasny piksel na ciemnym tle sprawi, że znormalizowany obraz będzie bardzo różny. -
Czy informacje o kolorze są ważne?
Jeśli chcesz aby zauważyć zmiany kolorów, będziesz mieć wektor wartości kolorów na punkt, a nie wartość skalarną, jak na obrazie w skali szarości. Potrzebujesz więcej uwagi przy pisaniu takiego kodu.
-
Czy na obrazie są wyraźne krawędzie? Czy mogą się ruszyć?
Jeśli tak, możesz najpierw zastosować algorytm wykrywania krawędzi (np. obliczyć gradient transformacją Sobela lub Prewitta, zastosować jakiś próg), a następnie porównać krawędzie na pierwszym obrazie z krawędziami na drugi.
-
Czy na obrazie jest szum?
Wszystkie czujniki zanieczyszczają obraz pewną ilością szumu. Tanie czujniki mają więcej hałasu. Przed porównaniem obrazów warto zastosować redukcję szumów. Rozmycie jest tu najprostszym (ale nie najlepszym) podejściem.
-
Jakie zmiany chcesz zauważyć?
Może to wpłynąć na wybór normy do wykorzystania dla różnicy między obrazami.
Rozważ użycie normy Manhattan (suma wartości bezwzględnych) lub zero norm (liczba elementów nie równa zero), aby zmierzyć, jak bardzo obraz się zmienił. Pierwszy powie Ci, jak bardzo obraz jest wyłączony, drugi powie tylko, ile pikseli się różni.
Przykład
Zakładam, że Twoje obrazy są dobrze wyrównane, tego samego rozmiaru i kształtu, prawdopodobnie z inną ekspozycją. Dla uproszczenia konwertuję je do skali szarości, nawet jeśli są to obrazy kolorowe (RGB).
Będziesz potrzebował tych import:
import sys
from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average
Główna funkcja, odczyt dwóch obrazów, konwersja do skali szarości, porównywanie i drukowanie wyników:
def main():
file1, file2 = sys.argv[1:1+2]
# read images as 2D arrays (convert to grayscale for simplicity)
img1 = to_grayscale(imread(file1).astype(float))
img2 = to_grayscale(imread(file2).astype(float))
# compare
n_m, n_0 = compare_images(img1, img2)
print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size
Jak porównywać. img1
i img2
są macierzami 2D SciPy tutaj:
def compare_images(img1, img2):
# normalize to compensate for exposure difference, this may be unnecessary
# consider disabling it
img1 = normalize(img1)
img2 = normalize(img2)
# calculate the difference and its norms
diff = img1 - img2 # elementwise for scipy arrays
m_norm = sum(abs(diff)) # Manhattan norm
z_norm = norm(diff.ravel(), 0) # Zero norm
return (m_norm, z_norm)
Jeśli plik jest obrazem kolorowym, imread
zwraca tablicę 3D, średnie kanały RGB (ostatnia oś tablicy)w celu uzyskania intensywności. Nie trzeba tego robić dla obrazów w skali szarości (np. .pgm
):
def to_grayscale(arr):
"If arr is a color image (3D array), convert it to grayscale (2D array)."
if len(arr.shape) == 3:
return average(arr, -1) # average over the last axis (color channels)
else:
return arr
Normalizacja jest trywialna, możesz wybrać normalizację do [0,1] zamiast [0,255]. arr
jest Tablica SciPy tutaj, więc wszystkie operacje są elementowe:
def normalize(arr):
rng = arr.max()-arr.min()
amin = arr.min()
return (arr-amin)*255/rng
Uruchom funkcję main
:
if __name__ == "__main__":
main()
Teraz możesz umieścić to wszystko w skrypcie i uruchomić na dwóch obrazkach. Jeśli porównamy obraz do siebie, nie ma różnicy:
$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0
Jeśli rozmyjemy obraz i porównamy z oryginałem, jest pewna różnica:
$ python compare.py one.jpg one-blurred.jpg
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0
P. S. całość compare.py skrypt.
Aktualizacja: odpowiednie techniki
Ponieważ pytanie dotyczy sekwencji wideo, jeśli ramki są prawdopodobnie prawie takie same, a ty szukasz czegoś niezwykłego, chciałbym wspomnieć o kilku alternatywnych podejściach, które mogą być istotne: {]}
- Odejmowanie i segmentacja tła (wykrywanie obiektów pierwszoplanowych) [36]}
- Rzadki przepływ optyczny (do wykrywania ruchu)
- porównywanie histogramów lub innych statystyk zamiast obrazów
Zdecydowanie polecam zajrzenie do książki "Learning OpenCV", rozdziały 9 (Części obrazów i segmentacja) i 10 (śledzenie i ruch). Pierwszy uczy korzystania z metody odejmowania tła, drugi podaje pewne informacje na temat metod przepływu optycznego. Wszystkie metody są zaimplementowane w bibliotece OpenCV. Jeśli używasz Pythona, sugeruję użycie OpenCV ≥ 2.3 i jego cv2
modułu Pythona.
Najprostsza wersja odejmowania tła:
- poznaj średnią wartość μ i odchylenie standardowe σ dla każdego piksela tła
- porównaj bieżące wartości pikseli z zakresem (μ-2σ,μ+2σ) lub (μ-σ,μ+σ)
Bardziej zaawansowane wersje uwzględniają szeregi czasowe dla każdego piksela i obsługują niestatyczne sceny (takie jak poruszające się drzewa lub trawa).
Idea przepływu optycznego polega na pobraniu dwóch lub więcej klatek i przypisaniu wektora prędkości każdemu pikselowi (gęsty przepływ optyczny) lub niektórym z nich (Rzadki przepływ optyczny). Aby oszacować niewielki przepływ optyczny, możesz użyć metody Lucas-Kanade (jest ona również zaimplementowana w OpenCV). Oczywiście, jeśli jest dużo flow (high average over max values of the velocity field), wtedy coś porusza się w kadrze, a kolejne obrazy są bardziej różne.Porównywanie histogramów może pomóc wykryć nagłe zmiany między kolejnymi klatkami. Podejście to zostało wykorzystane w Courbon et al, 2010:
podobieństwo kolejnych klatek. odległość między dwoma kolejnymi klatkami jest mierzona. Jeśli jest zbyt wysoka, oznacza to, że druga klatka jest uszkodzona, a tym samym obraz został wyeliminowany. Odległość Kullbacka–Leiblera (50), czyli wzajemna Entropia na histogramach obu klatek:
Gdzie p i q są histogramami ramek. Próg jest ustalony na 0,2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-21 17:15:21
Proste rozwiązanie:
Zakoduj obraz jako jpeg i poszukaj znaczącej zmiany w Rozmiar pliku .
Zaimplementowałem coś podobnego z miniaturkami wideo i miałem wiele sukcesów i skalowalności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 04:44:19
Możesz porównać dwa obrazy za pomocą funkcji z PIL .
import Image
import ImageChops
im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")
diff = ImageChops.difference(im2, im1)
Obiekt diff jest obrazem, w którym każdy piksel jest wynikiem odejmowania wartości kolorów tego piksela na drugim obrazie od pierwszego obrazu. Używając obrazu diff możesz zrobić kilka rzeczy. Najprostszą z nich jest funkcja diff.getbbox()
. Pokaże Ci minimalny prostokąt, który zawiera wszystkie zmiany między dwoma obrazami.
Możesz prawdopodobnie zaimplementować przybliżenia innych rzeczy wymienione tutaj przy użyciu funkcji z PIL, jak również.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-13 06:50:17
Dwie popularne i stosunkowo proste metody to: (a) odległość euklidesowa już sugerowana lub (b) znormalizowana korelacja krzyżowa. Znormalizowana korelacja krzyżowa wydaje się być zauważalnie bardziej odporna na zmiany oświetlenia niż prosta korelacja krzyżowa. Wikipedia podaje wzór na znormalizowaną korelację krzyżową . Istnieją też bardziej wyrafinowane metody, ale wymagają one nieco więcej pracy.
Używając składni numpy,
dist_euclidean = sqrt(sum((i1 - i2)^2)) / i1.size dist_manhattan = sum(abs(i1 - i2)) / i1.size dist_ncc = sum( (i1 - mean(i1)) * (i2 - mean(i2)) ) / ( (i1.size - 1) * stdev(i1) * stdev(i2) )
Zakładając, że i1
i i2
są 2D tablice obrazów w skali szarości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 03:47:44
Trywialna rzecz do wypróbowania:
Porównuj oba obrazy do małych miniaturek (np. 64 x 64) i porównaj miniatury piksel po pikselu z określonym progiem. Jeśli oryginalne obrazy są prawie takie same, ponownie próbkowane miniatury będą bardzo podobne lub nawet dokładnie takie same. Metoda ta zajmuje się hałasem, który może wystąpić zwłaszcza w scenach przy słabym oświetleniu. Może nawet lepiej, jeśli przejdziesz do skali szarości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 03:49:32
Zwracam się konkretnie do pytania, jak obliczyć, czy są one "wystarczająco różne". Zakładam, że możesz wymyślić, jak odjąć piksele jeden po drugim.
Po Pierwsze, chciałbym wziąć kilka obrazów z nic zmienia się, i dowiedzieć się maksymalną ilość, że każdy piksel zmienia tylko z powodu zmian w przechwytywaniu, szum w systemie obrazowania, artefakty kompresji JPEG, i moment za moment zmiany w oświetleniu. Być może przekonasz się, że różnice 1 lub 2 bitowe są można się spodziewać, nawet gdy nic się nie rusza.
Następnie dla" prawdziwego " testu, chcesz kryterium jak to:
- to samo, jeśli do P pikseli różnią się nie więcej niż E.
Więc, być może, jeśli E = 0.02, P = 1000, to oznacza (w przybliżeniu), że będzie "inaczej", jeśli każdy pojedynczy piksel zmieni się o więcej niż ~5 jednostek (zakładając obrazy 8-bitowe), lub jeśli więcej niż 1000 pikseli ma jakiekolwiek błędy w ogóle.
Jest to przeznaczona głównie jako dobra technika "triage", aby szybko zidentyfikuj obrazy, które są wystarczająco blisko, aby nie wymagały dalszej analizy. Obrazy, które "nie" może następnie bardziej do bardziej skomplikowanej / kosztownej techniki, która nie miałaby fałszywych alarmów, gdyby aparat potrząsnął trochę, na przykład, lub był bardziej wytrzymały na zmiany oświetlenia.
Prowadzę projekt open source, OpenImageIO , który zawiera narzędzie o nazwie "idiff", które porównuje różnice z takimi progami (nawet bardziej rozbudowanymi). Nawet jeśli nie chcesz używać tego oprogramowania, może zajrzysz do źródła, żeby zobaczyć, jak to zrobiliśmy. Jest używany komercyjnie dość dużo i ta technika progowania została opracowana tak, że możemy mieć zestaw testów dla renderowania i przetwarzania obrazu oprogramowania ,z "obrazów referencyjnych", które mogą mieć małe różnice od platformy do platformy lub jak zrobiliśmy drobne poprawki do algorytmów tha, więc chcieliśmy" dopasowanie w tolerancji " operacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-14 16:10:21
Większość udzielonych odpowiedzi Nie dotyczy poziomów oświetlenia.
Chciałbym najpierw normalizować obraz do standardowego poziomu światła przed wykonaniem porównania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 03:55:20
Czy widziałeś algorytm wyszukiwania podobnych obrazów pytanie? Sprawdź, aby zobaczyć sugestie.
Sugerowałbym transformację falkową Twoich ramek (napisałem do tego rozszerzenie C za pomocą transformacji Haara); następnie, porównując indeksy największych (proporcjonalnie) współczynników falkowych między dwoma obrazami, powinieneś uzyskać numeryczne przybliżenie podobieństwa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53
Miałem podobny problem w pracy, przepisywałem nasz punkt końcowy transformacji obrazu i chciałem sprawdzić, czy nowa wersja produkuje to samo lub prawie to samo wyjście co stara wersja. Więc napisałem to:
Https://github.com/nicolashahn/diffimg
, który działa na obrazach o tej samej wielkości i na poziomie piksela, mierzy różnicę wartości w każdym kanale: R, G, B (, A), bierze średnią różnicę tych kanałów, a następnie uśrednia różnica w stosunku do wszystkich pikseli i Zwraca współczynnik.
Na przykład, przy obrazie 10x10 białych pikseli i tym samym obrazie, ale jeden piksel zmienił się na czerwony, różnica w tym pikselu wynosi 1/3 lub 0,33... (RGB 0,0,0 vs 255,0,0) i dla wszystkich innych pikseli wynosi 0. Razem 100 pikseli, 0,33.../ 100 = a ~ 0,33% różnicy w obrazie.
Wierzę, że to będzie działać idealnie dla projektu OP (zdaję sobie sprawę, że jest to bardzo stary post teraz, ale post dla przyszłych StackOverflowers, którzy również chcą porównać obrazy w Pythonie).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-27 15:27:49
Przepraszam, jeśli jest za późno, aby odpowiedzieć, ale ponieważ robię coś podobnego, pomyślałem, że mogę się jakoś przyczynić.
Może w OpenCV przydałoby się dopasowanie szablonu. Zakładając, że używasz kamery internetowej, jak powiedziałeś:
- Uprość obrazy (może?)
- Zastosuj dopasowanie szablonu i sprawdź max_val za pomocą minMaxLoc
Wskazówka: max_val (lub min_val w zależności od użytej metody) da ci liczby, duże liczby. Aby uzyskać różnicę w procentach użyj dopasowania szablonu z tym samym obrazem - wynik będzie twój 100%.
Pseudo kod na przykładzie:
previous_screenshot = ...
current_screenshot = ...
# simplify both images somehow
# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)
# hundred_p_val is now the 100%
res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)
difference_percentage = max_val / hundred_p_val
# the tolerance is now up to you
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 16:08:16
Odległość od Ziemi może być dokładnie tym, czego potrzebujesz. Może to być abit ciężki do wdrożenia w czasie rzeczywistym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 02:48:35
A co z obliczeniem odległości Manhattanu dwóch obrazów? To daje wartości n * N. Następnie możesz zrobić coś takiego jak średnia wiersza, aby zmniejszyć do wartości n i funkcji nad tym, aby uzyskać jedną pojedynczą wartość.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 02:53:30
[[0]] mam sporo szczęścia ze zdjęciami jpg zrobionymi tym samym aparatem na statywie przez (1) znaczne uproszczenie (jak przejście z 3000 pikseli szerokości do 100 pikseli szerokości lub nawet mniej) (2) spłaszczenie każdej tablicy jpg w jeden wektor (3) parami korelujące obrazy sekwencyjne z prostym algorytmem korelacji, aby uzyskać współczynnik korelacji (4) kwadratowy współczynnik korelacji, aby uzyskać R-kwadrat (tj. ułamek zmienności w jednym obrazie wyjaśniony zmiennością w następnym) (5) ogólnie w moja aplikacja jeśli R-kwadrat
To jest solidne i szybkie w mojej implementacji (Mathematica 7)
Warto pobawić się tą częścią obrazu, którą jesteś zainteresowany i skupić się na tym, przycinając Wszystkie zdjęcia do tego małego obszaru, w przeciwnym razie pominięta zostanie odległa od kamery, ale ważna zmiana.
Nie wiem jak używać Pythona, ale jestem pewien, że też nie?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-19 21:28:00
Możesz obliczyć histogram obu obrazów, a następnie obliczyć współczynnik Bhattacharyya , jest to bardzo szybki algorytm i użyłem go do wykrywania zmian ujęć w filmie krykieta (w C za pomocą openCV)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 20:44:46
Zobacz jak Haar-daemon jest zaimplementowany przez ISK-daemon . Możesz użyć kodu Imgdb C++, aby obliczyć różnicę między obrazami w locie:
ISK-daemon jest serwerem bazodanowym typu open source, który umożliwia dodawanie obrazów opartych na treści (wizualnych)do dowolnej strony internetowej lub oprogramowania.
Ta technologia pozwala użytkownikom dowolnej strony internetowej lub oprogramowania związanego z obrazem na szkic w widżecie, który obraz chcą znaleźć i na który strona internetowa odpowiada im najbardziej podobne obrazy lub po prostu poprosić o Więcej podobnych zdjęć na każdej stronie szczegółów obrazu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-16 21:11:08
Miałem ten sam problem i napisałem prosty moduł Pythona, który porównuje dwa obrazy tej samej wielkości za pomocą ImageChops pillow ' a do utworzenia czarno-białego obrazu różnicowego i podsumowania wartości histogramu.
Możesz uzyskać ten wynik bezpośrednio lub wartość procentową w porównaniu do pełnego porównania czerń i biel.
Zawiera również prostą funkcję is_equal, z możliwością podania rozmytego progu pod (i włącznie) obrazem przechodzi jako równy.
Podejście nie jest bardzo rozbudowany, ale może jest przydatny dla innych, którzy zmagają się z tym samym problemem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-21 00:23:54
Nieco bardziej pryncypialnym podejściem jest użycie globalnego deskryptora do porównywania obrazów, takich jak GIST lub CENTRIST. Funkcja hash, jak opisano tutaj, również dostarcza podobnego rozwiązania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-29 00:53:36
Kolejny ładny, prosty sposób na zmierzenie podobieństwa między dwoma obrazami:
import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread
# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))
# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)
Jeśli inni są zainteresowani bardziej wydajnym sposobem porównywania podobieństwa obrazów, przygotowałemtutorial i webapp do pomiaru i wizualizacji podobnych obrazów za pomocą Tensorflow.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-30 16:29:02
import os
from PIL import Image
from PIL import ImageFile
import imagehash
#just use to the size diferent picture
def compare_image(img_file1, img_file2):
if img_file1 == img_file2:
return True
fp1 = open(img_file1, 'rb')
fp2 = open(img_file2, 'rb')
img1 = Image.open(fp1)
img2 = Image.open(fp2)
ImageFile.LOAD_TRUNCATED_IMAGES = True
b = img1 == img2
fp1.close()
fp2.close()
return b
#through picturu hash to compare
def get_hash_dict(dir):
hash_dict = {}
image_quantity = 0
for _, _, files in os.walk(dir):
for i, fileName in enumerate(files):
with open(dir + fileName, 'rb') as fp:
hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
image_quantity += 1
return hash_dict, image_quantity
def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
"""
max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
recommend to use
"""
ImageFile.LOAD_TRUNCATED_IMAGES = True
hash_1 = None
hash_2 = None
with open(image_file_name_1, 'rb') as fp:
hash_1 = imagehash.average_hash(Image.open(fp))
with open(image_file_name_2, 'rb') as fp:
hash_2 = imagehash.average_hash(Image.open(fp))
dif = hash_1 - hash_2
if dif < 0:
dif = -dif
if dif <= max_dif:
return True
else:
return False
def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
"""
max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
"""
ImageFile.LOAD_TRUNCATED_IMAGES = True
hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)
if image_quantity_1 > image_quantity_2:
tmp = image_quantity_1
image_quantity_1 = image_quantity_2
image_quantity_2 = tmp
tmp = hash_dict_1
hash_dict_1 = hash_dict_2
hash_dict_2 = tmp
result_dict = {}
for k in hash_dict_1.keys():
result_dict[k] = None
for dif_i in range(0, max_dif + 1):
have_none = False
for k_1 in result_dict.keys():
if result_dict.get(k_1) is None:
have_none = True
if not have_none:
return result_dict
for k_1, v_1 in hash_dict_1.items():
for k_2, v_2 in hash_dict_2.items():
sub = (v_1 - v_2)
if sub < 0:
sub = -sub
if sub == dif_i and result_dict.get(k_1) is None:
result_dict[k_1] = k_2
break
return result_dict
def main():
print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 6))
r = compare_image_dir_with_hash('image1\\', image2\\', 10)
for k in r.keys():
print(k, r.get(k))
if __name__ == '__main__':
main()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-29 11:34:08
Myślę, że można po prostu obliczyć odległość euklidesową (tj. sqrt (suma kwadratów różnic, piksel po pikselu)) pomiędzy luminancją obu obrazów i uznać je za równe, Jeśli mieści się to pod pewnym empirycznym progiem. I lepiej zrób to zawijając funkcję C.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-10 04:08:13