Porównanie obrazów-szybki algorytm

Chcę utworzyć tabelę bazową obrazów, a następnie porównać z nią nowe obrazy, aby określić, czy nowy obraz jest dokładnym (lub bliskim) duplikatem bazy.

Na przykład: jeśli chcesz zmniejszyć przechowywanie tego samego obrazu 100 razy, możesz zapisać jedną jego kopię i podać odnośniki do niego. Po wprowadzeniu nowego obrazu należy porównać go z istniejącym obrazem, aby upewnić się, że nie jest duplikatem... pomysły?

Jednym z moich pomysłów było zredukowanie do małego miniaturkę, a następnie losowo wybrać lokalizacje 100 pikseli i porównać.

Author: Chuck Savage, 2009-05-10

8 answers

Poniżej znajdują się trzy podejścia do rozwiązania tego problemu (i jest wiele innych).

  • Pierwszym z nich jest standardowe podejście w wizji komputerowej, dopasowywanie punktów kluczowych. Może to wymagać pewnej wiedzy w tle do wdrożenia i może być powolne.

  • Druga metoda wykorzystuje tylko elementarne przetwarzanie obrazu i jest potencjalnie szybsza niż pierwsza metoda i jest łatwa do wdrożenia. Jednak to, co zyskuje na zrozumiałości, brakuje mu solidności -- dopasowanie nie powiodło się na obrazach skalowanych, obróconych lub przebarwionych.

  • Trzecia metoda jest szybka i solidna, ale potencjalnie najtrudniejsza do wdrożenia.

Keypoint Matching

Lepszy od wybrania 100 losowych punktów jest wybranie 100 ważnych punktów. Niektóre części obrazu zawierają więcej informacji niż inne (w szczególności krawędzie i narożniki), a są to te, których chcesz użyć do inteligentnego dopasowywania obrazu. Google "KeyPoint extraction "i" KeyPoint matching " i znajdziesz sporo prac naukowych na ten temat. Obecnie, Sift keypoints są prawdopodobnie najbardziej popularne, ponieważ mogą dopasować obrazy w różnych skalach, obrotach i oświetleniu. Niektóre implementacje SIFT można znaleźć tutaj.

Minusem dopasowania punktów klawiszowych jest czas pracy naiwnej implementacji: O (N^2m), gdzie n to liczba punktów klawiszowych w każdym obrazie, A m to liczba zdjęć w bazie danych. Niektóre sprytne algorytmy mogą znaleźć najbliższe dopasowanie szybciej, jak quadtrees lub Binary space partitioning.


Rozwiązanie alternatywne: metoda histogramu

Innym mniej solidnym, ale potencjalnie szybszym rozwiązaniem jest tworzenie histogramów funkcji dla każdego obrazu i wybieranie obrazu z histogramem najbliżej histogramu obrazu wejściowego. Zaimplementowałem to jako licencjat i użyliśmy 3 kolorowych histogramów (czerwony, zielony i niebieski) i dwa histogramy tekstury, kierunek i skala. Podam szczegóły poniżej, ale powinienem zauważyć, że działało to dobrze tylko w przypadku dopasowania obrazów bardzo podobnych do obrazów bazy danych. Przeskalowane, obrócone lub przebarwione obrazy mogą się nie udać dzięki tej metodzie, ale małe zmiany, takie jak kadrowanie, nie zepsują algorytmu

Obliczanie histogramów kolorów jest proste - po prostu wybierz zakres dla wiadra histogramu i dla każdego zakresu Przelicz liczbę pikseli z kolorem w tym zakresie. Na przykład, rozważmy histogram" zielony " i załóżmy, że wybieramy 4 wiadra dla naszego histogramu: 0-63, 64-127, 128-191 i 192-255. Następnie dla każdego piksela patrzymy na zieloną wartość i dodajemy tally do odpowiedniego wiadra. Po zakończeniu liczenia dzielimy każdą sumę przez liczbę pikseli w całym obrazie, aby uzyskać znormalizowany histogram dla zielonego kanału.

W przypadku histogramu kierunku tekstury zaczęliśmy od detekcji krawędzi na obrazie. Każdy punkt krawędzi ma wektor normalny skierowany w kierunku prostopadłym do krawędzi. Skwantowaliśmy kąt wektora normalnego na jeden z 6 wektorów między 0 A PI (ponieważ krawędzie mają symetrię 180 stopni, zamieniliśmy kąty między-PI a 0 Na między 0 A PI). Po zliczeniu liczby punktów krawędzi w każdym kierunku mamy unormalizowany histogram reprezentujący kierunek tekstury, który znormalizowaliśmy dzieląc każdy kubełek przez całkowitą liczbę punktów krawędzi na obrazie.

Aby obliczyć histogram skali tekstury, dla każdego punktu krawędzi, mierzyliśmy odległość do najbliższego punktu krawędzi w tym samym kierunku. Na przykład, jeśli punkt krawędzi A ma kierunek 45 stopni, algorytm idzie w tym kierunku, aż znajdzie inny punkt krawędzi o kierunku 45 stopni (lub w rozsądnym odchyleniu). Po obliczeniu tej odległości dla każdego punktu krawędzi, zrzucamy te wartości do histogramu i normalizujemy je, dzieląc przez całkowitą liczbę krawędzi punktów.

Teraz masz 5 histogramów dla każdego obrazu. Aby porównać dwa obrazy, należy wziąć wartość bezwzględną różnicy między każdym zasobnikiem histogramu, a następnie zsumować te wartości. Na przykład, aby porównać obrazy A i B, obliczymy

|A.green_histogram.bucket_1 - B.green_histogram.bucket_1| 

Dla każdego wiadra w zielonym histogramie i powtórz dla innych histogramów, a następnie podsumuj wszystkie wyniki. Im mniejszy wynik, tym lepszy mecz. Powtórz dla wszystkich obrazów w bazie danych, a mecz z najmniejszym wynik wygrywa. Prawdopodobnie chciałbyś mieć próg, powyżej którego algorytm stwierdza, że nie znaleziono dopasowania.


Third Choice-Keypoints + Decision Trees

Trzecie podejście, które jest prawdopodobnie znacznie szybsze niż dwa pozostałe, wykorzystuje semantyczne lasy tekstowe (PDF). Polega to na wyodrębnieniu prostych punktów klawiszowych i wykorzystaniu drzew decyzyjnych kolekcji do klasyfikacji obrazu. Jest to szybsze niż proste dopasowanie przesiać keypoint, ponieważ pozwala uniknąć kosztowny proces dopasowywania i punkty kluczowe są znacznie prostsze niż SIFT, więc ekstrakcja punktów kluczowych jest znacznie szybsza. Jednak zachowuje niezmienność metody SIFT do obrotu, skali i oświetlenia, ważną cechę, której brakowało w metodzie histogramu.

Update :

Mój błąd -- Semantic Texton Forests paper nie chodzi konkretnie o dopasowanie obrazu, ale raczej o etykietowanie regionu. Oryginalny papier, który nie dopasowuje jest ten: Rozpoznawanie punktów za pomocą Randomizowane Drzewa . Ponadto, poniższe dokumenty nadal rozwijać pomysły i reprezentują stan wiedzy (c. 2010): {]}

 411
Author: Kyle Simek,
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-07-21 11:44:15

Najlepszą metodą, jaką znam, jest użycie haszu percepcyjnego. Wydaje się, że istnieje dobra implementacja open source takiego hasha dostępna pod adresem:

Http://phash.org/

Główną ideą jest to, że każdy obraz jest zredukowany do małego kodu skrótu lub "odcisku palca" poprzez identyfikację najważniejszych cech w oryginalnym pliku obrazu i haszowanie zwartej reprezentacji tych cech (zamiast haszowania danych obrazu bezpośrednio). Oznacza to, że wskaźnik fałszywych alarmów jest znacznie zmniejszono za pomocą uproszczonego podejścia, takiego jak redukcja obrazów do obrazu o małym rozmiarze i porównywanie odcisków kciuka.

Phash oferuje kilka rodzajów skrótu i może być używany do obrazów, audio lub wideo.

 70
Author: redcalx,
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-11-09 22:17:32

Ten post był punktem wyjścia mojego rozwiązania, wiele dobrych pomysłów tutaj, więc pomyślałem, że podzielę się moimi wynikami. Głównym wglądem jest to, że znalazłem sposób, aby obejść powolność dopasowania obrazu opartego na punktach kluczowych, wykorzystując szybkość phash.

Dla ogólnego rozwiązania, najlepiej zastosować kilka strategii. Każdy algorytm najlepiej nadaje się do pewnych typów transformacji obrazu i można z tego skorzystać.

Na górze najszybsze algorytmy; na dole najwolniejszy (choć dokładniejszy). Możesz pominąć te powolne, jeśli dobry mecz zostanie znaleziony na szybszym poziomie.

  • plik-hash oparty (md5, sha1, itp.) dla dokładnych duplikatów
  • perceptual hashing (phash) dla przeskalowanych obrazów
  • feature-based (SIFT) for modified images

Mam bardzo dobre wyniki z phash. Dokładność jest dobra dla przeskalowanych obrazów. Nie jest to dobre dla (percepcyjnie) zmodyfikowanych obrazów (przyciętych, obróconych, lustrzanych, itp.). Aby poradzić sobie z szybkością haszowania, musimy użyć pamięci podręcznej dysku/bazy danych, aby utrzymać hasze dla stogu siana.

Naprawdę fajną rzeczą w phash jest to, że po zbudowaniu bazy danych hash (która dla mnie wynosi około 1000 zdjęć / sek), wyszukiwanie może być bardzo, bardzo szybkie, w szczególności, gdy można trzymać całą bazę danych hash w pamięci. Jest to dość praktyczne, ponieważ hash wynosi tylko 8 bajtów.

Na przykład, jeśli masz 1 milion obrazów, wymagałoby to tablicy 1 miliona 64-bitowe wartości skrótu (8 MB). Na niektórych procesorach mieści się to w pamięci podręcznej L2 / L3! W praktycznym użyciu widziałem porównanie corei7 z ponad 1 Giga-hamm/s, to tylko kwestia przepustowości PAMIĘCI do procesora. Baza danych o wielkości 1 miliarda obrazów jest praktyczna na 64-bitowym procesorze (potrzebny 8GB RAM) i wyszukiwanie nie przekroczy 1 sekundy!

Dla zmodyfikowanych / przyciętych obrazów wydaje się, że transformator-niezmienny detektor funkcji/punktów kluczowych, jak SIFT, jest drogą do zrobienia. SIFT będzie produkować dobre klawiatury, które wykryją przycinanie/obracanie / lustro itp. Jednak porównywanie deskryptorów jest bardzo powolne w porównaniu z odległością Hamminga używaną przez phash. Jest to poważne ograniczenie. Istnieje wiele porównań do wykonania, ponieważ istnieje maksymalny deskryptor IxJxK porównujący jeden obraz (i=liczba obrazów stogów siana, J=docelowe punkty na obraz stogów siana, K = docelowe punkty na obraz igły).

Aby obejść problem z prędkością, próbowałem użyć phash wokół każdego znalezionego punktu kluczowego, używając rozmiaru funkcji/promienia do określenia podprostka. Sztuczka, aby to działa dobrze, jest zwiększenie / zmniejszenie promienia, aby wygenerować różne poziomy sub-rect (na obrazie igły). Zazwyczaj pierwszy poziom (bez szwu) będzie pasować, jednak często zajmuje to kilka więcej. Nie jestem w 100% pewien, dlaczego to działa, ale mogę sobie wyobrazić, że umożliwia funkcje, które są zbyt małe, aby phash działał (phash skaluje obrazy do 32x32).

Kolejną kwestią jest to, że SIFT nie rozdzieli optymalnie punktów klawiszowych. Jeśli istnieje sekcja obrazu z wieloma krawędziami, punkty kluczowe skupią się tam i nie otrzymasz żadnych w innym obszarze. Używam GridAdaptedFeatureDetector w OpenCV, aby poprawić dystrybucję. Nie wiem, jaki rozmiar siatki jest najlepszy, używam małej siatki (1x3 lub 3x1 w zależności od orientacji obrazu).

Prawdopodobnie chcesz przeskalować wszystkie obrazy stogów siana (i igły) do mniejszych rozmiarów przed wykryciem funkcji (używam 210px wzdłuż maksymalnego wymiaru). Zmniejszy to szum w obrazie (zawsze problem dla algorytmów widzenia komputerowego), również skupi detektor na bardziej znanych cechach.

W przypadku obrazów osób można spróbować wykryć twarz i użyć jej do określenia rozmiaru obrazu do skalowania i rozmiaru siatki (na przykład największa twarz skalowana do 100px). Detektor funkcji uwzględnia wiele poziomów skali (za pomocą piramid), ale istnieje ograniczenie do tego, ile poziomów będzie używał (jest to oczywiście dostrajalne).

Wykrywacz punktów kluczowych działa prawdopodobnie najlepiej, gdy zwraca mniej niż liczba funkcji chciałeś. Na przykład, jeśli poprosisz o 400 i otrzymasz 300 z powrotem, to dobrze. Jeśli otrzymasz 400 za każdym razem, prawdopodobnie niektóre dobre funkcje musiały zostać pominięte.

Obraz igły może mieć mniej punktów klawiszowych niż obrazy stogów siana i nadal uzyskać dobre wyniki. Dodanie więcej nie musi ci ogromne zyski, na przykład z J = 400 I K = 40 mój wskaźnik trafień jest o 92%. Przy J = 400 i K = 400 wskaźnik trafień wzrasta tylko do 96%.

Możemy wykorzystać ekstremalną prędkość Hamminga funkcja rozwiązywania skalowania, obracania, dublowania itp. Można zastosować technikę wielokrotnego przejścia. Przy każdej iteracji przekształć pod-prostokąty, Zmień hash i ponownie uruchom funkcję wyszukiwania.

 24
Author: wally,
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
2013-12-01 20:21:32

Mam pomysł, który może zadziałać i najprawdopodobniej będzie bardzo szybki. Możesz poddawać próbce obraz o rozdzielczości 80x60 lub porównywalnej, i przekonwertować na skalę szarości(po podpróbkowaniu będzie szybciej). Przetwarzaj oba obrazy, które chcesz porównać. Następnie uruchom znormalizowaną sumę kwadratowych różnic między dwoma obrazami (obraz zapytania i każdy z db), lub jeszcze lepiej znormalizowaną korelację krzyżową, co daje odpowiedź bliższą 1, jeśli oba obrazy są podobne. Następnie, jeśli obrazy są podobne, możesz przejdź do bardziej wyrafinowanych technik aby sprawdzić, czy są to te same obrazy. Oczywiście algorytm ten jest liniowy pod względem liczby obrazów w bazie danych więc nawet jeśli będzie to bardzo szybkie do 10000 obrazów na sekundę na nowoczesnym sprzęcie. Jeśli potrzebujesz niezmienniczości do obrotu, to można obliczyć gradient dominujący dla tego małego obrazu, a następnie cały układ współrzędnych może być obrócony do kanonicznego orientacja będzie jednak wolniejsza. I nie, nie ma niezmienności dla skaluj tutaj.

Jeśli chcesz czegoś bardziej ogólnego lub korzystania z dużych baz danych( milionów zdjęć), to musisz przyjrzeć się teorii pobierania obrazów (mnóstwo prac pojawiło się w ciągu ostatnich 5 lat). Istnieją pewne wskazówki w innych odpowiedziach. Ale to może być przesada, a sugerowane podejście histogramu załatwi sprawę. Chociaż myślę, że połączenie wielu różnych szybkie podejścia będą jeszcze lepsze.

 6
Author: Denis 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
2009-06-11 21:22:11

Jak zauważył cartman, możesz użyć dowolnego rodzaju wartości skrótu do znalezienia dokładnych duplikatów.

Punktem wyjścia do znalezienia bliskich obrazów może być TUTAJ . Jest to narzędzie używane przez firmy CG do sprawdzania, czy odświeżone obrazy nadal pokazują zasadniczo tę samą scenę.

 5
Author: Tobiesque,
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
2009-05-09 20:47:03

Uważam, że zmniejszenie rozmiaru obrazu do prawie rozmiaru ikony, powiedzmy 48x48, a następnie konwersja do skali szarości, a następnie wzięcie różnicy między pikselami, lub Delta, powinno działać dobrze. Ponieważ porównujemy zmianę koloru pikseli, a nie rzeczywisty kolor pikseli, nie ma znaczenia, czy obraz jest nieco jaśniejszy czy ciemniejszy. Duże zmiany będą miały znaczenie, ponieważ piksele zbyt jasne/ciemne zostaną utracone. Możesz zastosować to w jednym wierszu lub tyle, ile chcesz, aby zwiększyć dokładność. Co najwyżej będziesz miał 47x47=2209 odejmowań, aby utworzyć porównywalny klucz.

 4
Author: Tanoshimi,
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-11-05 13:04:01

Wybranie 100 losowych punktów może oznaczać, że podobne (lub czasami nawet odmienne) obrazy będą oznaczone jako takie same, co zakładam, że nie jest tym, czego chcesz. Skróty MD5 nie zadziałałyby, gdyby obrazy były w różnych formatach (png, jpeg itp.), miały różne rozmiary lub miały inne metadane. Redukcja wszystkich obrazów do mniejszych rozmiarów jest dobrym rozwiązaniem, porównanie pikseli do pikseli nie powinno trwać zbyt długo, o ile używasz dobrej biblioteki obrazów / szybkiego języka , a rozmiar jest wystarczająco mały.

Możesz spróbować zrobić je malutkimi, a jeśli są takie same, wykonaj kolejne porównanie na większym rozmiarze - może to być dobre połączenie szybkości i dokładności...

 3
Author: HarryM,
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
2009-05-09 20:31:03

Jeśli masz dużą liczbę obrazów, spójrz na filtr Bloom , który używa wielu skrótów dla prawdopodobnego, ale wydajnego wyniku. Jeśli liczba obrazów nie jest duża, wówczas hash kryptograficzny, taki jak md5, powinien być wystarczający.

 2
Author: jdigital,
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
2009-05-09 20:26:42