Jak mogę zmierzyć podobieństwo między dwoma obrazami? [Zamknięte]

95

Chciałbym porównać zrzut ekranu jednej aplikacji (może to być strona internetowa) z wcześniej wykonanym zrzutem ekranu, aby określić, czy aplikacja wyświetla się poprawnie. Nie chcę dokładnego porównania dopasowania, ponieważ aspekt może być nieco inny (w przypadku aplikacji internetowej, w zależności od przeglądarki, jakiś element może znajdować się w nieco innym miejscu). Powinien pokazać, jak podobne są zrzuty ekranu.

Czy istnieje biblioteka / narzędzie, które już to robi? Jak byś to zaimplementował?

Antoine Aubry
źródło
1
Jest kilka dobrych odpowiedzi na to inne podobne pytanie: stackoverflow.com/questions/75891/ ...
blak
1
I więcej tutaj: stackoverflow.com/questions/189943/…
Anoyz
1
Czas zaktualizować odpowiedzi w świetle ostatnich postępów w uczeniu maszynowym, a dokładniej „uczeniu głębokim”.
jldupont,
Moje laboratorium potrzebne, aby rozwiązać ten problem też, i stosuje się obieg opisane tutaj: douglasduhaime.com/posts/...
duhaime

Odpowiedzi:

75

Zależy to całkowicie od tego, jak inteligentny ma być algorytm.

Na przykład, oto kilka problemów:

  • obrazy przycięte a niecięte
  • obrazy z dodanym tekstem vs. inne bez
  • obrazy lustrzane

Najłatwiejszym i najprostszym algorytmem , jaki widziałem, jest po prostu wykonanie następujących kroków dla każdego obrazu:

  1. skalować do czegoś małego, na przykład 64x64 lub 32x32, zignorować proporcje, użyć łączącego algorytmu skalowania zamiast najbliższego piksela
  2. przeskaluj zakresy kolorów tak, aby najciemniejszy był czarny, a najjaśniejszy był biały
  3. obróć i odwróć obraz tak, aby najjaśniejszy kolor był w lewym górnym rogu, a następnie w prawym górnym rogu był następny ciemniejszy, dolny lewy był następny ciemniejszy (oczywiście o ile to możliwe)

Edycja łącząc algorytm skalowania jest, że podczas skalowania 10 pikseli w dół do jednego zrobi to za pomocą funkcji, która pobiera kolor wszystkich tych 10 pikseli i łączy je w jeden. Można to zrobić za pomocą algorytmów, takich jak uśrednianie, średnia wartość lub bardziej złożonych, takich jak dwusześcienne splajny.

Następnie oblicz średnią odległość piksel po pikselu między dwoma obrazami.

Aby wyszukać możliwe dopasowanie w bazie danych, zapisz kolory pikseli jako pojedyncze kolumny w bazie danych, zindeksuj kilka z nich (ale nie wszystkie, chyba że używasz bardzo małego obrazu) i wykonaj zapytanie, które używa zakresu dla każdego wartość piksela, tj. każdy obraz, w którym piksel małego obrazka znajduje się między -5 a +5 obrazu, który chcesz sprawdzić.

Jest to łatwe do wdrożenia i dość szybkie w działaniu, ale oczywiście nie poradzi sobie z najbardziej zaawansowanymi różnicami. Do tego potrzebne są znacznie bardziej zaawansowane algorytmy.

Lasse V. Karlsen
źródło
14
Co to jest „algorytm łączący skalowanie”?
Gregg Lind
32

„Klasyczny” sposób pomiaru polega na rozbiciu obrazu na pewną kanoniczną liczbę sekcji (powiedzmy na siatce 10x10), a następnie obliczeniu histogramu wartości RGB wewnątrz każdej komórki i porównaniu odpowiednich histogramów. Ten typ algorytmu jest preferowany zarówno ze względu na jego prostotę, jak i niezmienność skalowania i (małych!) Tłumaczeń.

Louis Brandy
źródło
6
Czy nie jest to podobne do wykonania pojedynczego histogramu dla całego obrazu, ale z dodatkowymi wadami polegającymi na tym, że nie jest odporny na odbicie lustrzane i obrót?
dodgy_coder
2 histogramy z 2 połówek obrazu będą miały lepszą dokładność dopasowania niż 1 histogram całości. Chociaż ma wady, o których wspomniałeś, zależy to od problemu, który rozwiązujesz.
psycho brm
25

Użyj histogramu znormalizowanych kolorów. (Przeczytaj sekcję dotyczącą aplikacji tutaj ), są one powszechnie używane w systemach wyszukiwania / dopasowywania obrazów i są standardowym sposobem dopasowywania obrazów, który jest bardzo niezawodny, stosunkowo szybki i bardzo łatwy do wdrożenia.

Zasadniczo histogram kolorów uchwyci rozkład kolorów obrazu. Można to następnie porównać z innym obrazem, aby sprawdzić, czy rozkłady kolorów są zgodne.

Ten typ dopasowania jest dość odporny na skalowanie (po znormalizowaniu histogramu), rotację / przesuwanie / ruch itp.

Unikaj porównań piksel po pikselu, ponieważ jeśli obraz jest nieznacznie obrócony / przesunięty, może to prowadzić do zgłaszania dużej różnicy.

Histogramy byłyby łatwe do samodzielnego wygenerowania (zakładając, że możesz uzyskać dostęp do wartości pikseli), ale jeśli nie masz na to ochoty, biblioteka OpenCV jest świetnym źródłem do robienia tego rodzaju rzeczy. Oto prezentacja PowerPoint, która pokazuje, jak utworzyć histogram przy użyciu OpenCV.

Lehane
źródło
14

Czy algorytmy kodowania wideo, takie jak MPEG, nie obliczają różnicy między każdą klatką wideo, aby mogły po prostu zakodować deltę? Możesz przyjrzeć się, jak algorytmy kodowania wideo obliczają te różnice w klatkach.

Spójrz na tę aplikację do wyszukiwania obrazów typu open source http://www.semanticmetadata.net/lire/ . Opisuje kilka algorytmów podobieństwa obrazu, z których trzy pochodzą ze standardu MPEG-7: ScalableColor, ColorLayout, EdgeHistogram i Auto Color Correlogram.

Mark B.
źródło
1
To nie dałoby odpowiedzi na pytanie. Nie chodzi o porównanie pikseli na piksel.
Kousha
@Kousha Prawda, ale wciąż ciekawy kierunek myślenia.
znaczenie ma znaczenie
13

Możesz użyć czysto matematycznego podejścia O(n^2) , ale będzie to przydatne tylko wtedy, gdy masz pewność, że nie ma przesunięcia lub czegoś podobnego. (Chociaż jeśli masz kilka obiektów o jednorodnym zabarwieniu, nadal będzie działać całkiem dobrze).

W każdym razie chodzi o obliczenie znormalizowanego iloczynu skalarnego dwóch macierzy. C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)).

Ta formuła jest właściwie „cosinusem” kąta między macierzami (wierd). Im większe podobieństwo (powiedzmy Pij=Qij), C będzie i,j Qij = 1równe 1, a jeśli są zupełnie różne, powiedzmy dla każdego (unikając dzielenia przez zero) Pij = 255, to dla rozmiaru nxn, im większe nbędzie, tym bliżej zera będziemy otrzymać. (W przybliżeniu:) C=1/n^2.

Shachar
źródło
8

Będziesz potrzebować do tego rozpoznawania wzorców . Aby określić małe różnice między dwoma obrazami, siatki Hopfielda działają dość dobrze i są dość łatwe do wdrożenia. Nie znam jednak żadnych dostępnych wdrożeń.

Konrad Rudolph
źródło
7

Rozwiązanie rubinowe można znaleźć tutaj

Z pliku readme:

Phashion to opakowanie Ruby wokół biblioteki pHash, „percepcyjny hash”, który wykrywa zduplikowane i prawie zduplikowane pliki multimedialne

edk750
źródło
5

Sposób mierzenia podobieństwa między dwoma obrazami zależy całkowicie od tego, co chcesz zmierzyć, na przykład: kontrastu, jasności, modalności, szumu ... a następnie wybierz najbardziej odpowiednią miarę podobieństwa. Możesz wybierać spośród MAD (średnia różnica bezwzględna), MSD (średnia kwadratowa różnica), które są dobre do pomiaru jasności ... dostępna jest również CR (współczynnik korelacji), który jest dobry w reprezentowaniu korelacji między dwoma obrazami. Można również wybrać miary podobieństwa oparte na histogramie, takie jak SDH (odchylenie standardowe histogramu obrazu różnicowego) lub miary podobieństwa multimodalności, takie jak MI (informacje wzajemne) lub NMI (znormalizowane informacje wzajemne).

Ponieważ te miary podobieństwa kosztują dużo czasu, zaleca się przeskalowanie obrazów w dół przed zastosowaniem na nich tych miar.

Gregor Simončič
źródło
4

Zastanawiam się (i tak naprawdę rzucam pomysł, aby go zestrzelić), czy coś można uzyskać, odejmując jeden obraz od drugiego, a następnie skompresowując wynikowy obraz jako jpeg gif i przyjmując rozmiar pliku jako miara podobieństwa.

Gdybyś miał dwa identyczne obrazy, dostałbyś białe pudełko, które byłoby naprawdę dobrze skompresowane. Im bardziej obrazy się różniły, tym bardziej złożona byłaby reprezentacja, a tym samym mniej kompresowalna.

Prawdopodobnie nie jest to idealny test i prawdopodobnie znacznie wolniejszy niż to konieczne, ale może działać jako szybka i brudna implementacja.

Matt Sheppard
źródło
Pomyśl o obrocie o 90 stopni; obrazy są nadal podobne.
znaczenie ma znaczenie
3

Możesz spojrzeć na kod narzędzia open source findimagedupes , chociaż wygląda na to, że został napisany w perlu, więc nie mogę powiedzieć, jak łatwo będzie go przeanalizować ...

Czytając stronę findimagedupes, która mi się podobała, widzę, że istnieje implementacja C ++ tego samego algorytmu . Prawdopodobnie będzie to łatwiejsze do zrozumienia.

Wygląda na to, że możesz też użyć gqview .

dmckee --- kociak byłego moderatora
źródło
2

Cóż, nie odpowiadam bezpośrednio na twoje pytanie, ale widziałem, jak to się dzieje. Firma Microsoft niedawno uruchomiła narzędzie o nazwie PhotoSynth, które robi coś bardzo podobnego do określania nakładających się obszarów w dużej liczbie obrazów (które mogą mieć różne proporcje).

Zastanawiam się, czy mają jakieś dostępne biblioteki lub fragmenty kodu na swoim blogu.

Vaibhav
źródło
1
Ta technologia. zostało przerwane.
Joseph Rosson,
2

rozszerzyć na notatki Vaibhav za, Hugin jest open-source „autostitcher”, który powinien mieć pewne wyobrażenie na ten problem.

hometoast
źródło
2

Istnieje oprogramowanie do pobierania obrazów w oparciu o zawartość, które (częściowo) robi to, czego potrzebujesz. Linki do wszystkich odnośników i wyjaśnień znajdują się na stronie projektu, a także w krótkim podręczniku (Kindle): LIRE

Mathias
źródło
1

Możesz skorzystać z Siamese Network, aby sprawdzić, czy te dwa obrazy są podobne lub niepodobne po tym samouczku . Ten samouczek grupuje podobne obrazy, podczas gdy możesz użyć L2odległości do zmierzenia podobieństwa dwóch obrazów.

cpwah
źródło
0

Jeśli będziesz to robić od czasu do czasu i nie potrzebujesz automatyzacji, możesz to zrobić w edytorze obrazów obsługującym warstwy, takim jak Photoshop lub Paint Shop Pro (prawdopodobnie również GIMP lub Paint.Net, ale ja ' nie jestem tego pewien). Otwórz oba zrzuty ekranu i umieść jeden na drugim jako warstwę. Zmień tryb mieszania warstw na Różnica, a wszystko, co między nimi jest takie samo, stanie się czarne. Możesz przesunąć górną warstwę, aby zminimalizować wszelkie różnice w wyrównaniu.

Mark Okup
źródło
Innym narzędziem, które bardzo ułatwia tego typu różnicowanie, jest kaleidoscopeapp.com
Michael Osofsky
0

Beyond Compare oferuje porównywanie piksel po pikselu dla obrazów, np.

wprowadź opis obrazu tutaj

emallove
źródło
@xilpex, OP pyta: Czy istnieje biblioteka / narzędzie, które już to robi ? Moja odpowiedź zawiera link do takiej biblioteki / narzędzia.
emallove
-1

Cóż, naprawdę podstawowa metoda mogłaby przejść przez każdy kolor piksela i porównać go z odpowiednim kolorem piksela na drugim obrazie - ale to prawdopodobnie bardzo powolne rozwiązanie.

Ross
źródło