Prosta i szybka metoda porównywania obrazów pod kątem podobieństwa

Potrzebuję prostego i szybkiego sposobu na porównanie dwóch obrazów pod kątem podobieństwa. Chcę uzyskać wysoką wartość, jeśli zawierają dokładnie to samo, ale mogą mieć nieco inne tło i mogą być przesuwane / zmieniane o kilka pikseli.

(bardziej konkretny, jeśli to ma znaczenie: jedno zdjęcie jest ikoną, a drugie obrazem jest podobszarem zrzutu ekranu i chcę wiedzieć, czy ten Podobszar jest dokładnie ikoną, czy nie.)

Mam OpenCV pod ręką, ale nadal nie jestem tak przyzwyczajony do to.

Jedna z możliwości, o której do tej pory myślałem: podziel oba zdjęcia na komórki 10x10 i dla każdej z tych 100 komórek porównaj histogram koloru. Następnie mogę ustawić jakąś wymyśloną wartość progową i jeśli wartość, którą otrzymuję, jest powyżej tego progu, zakładam, że są one podobne.

Jeszcze nie próbowałem, jak to działa, ale myślę, że to wystarczy. Obrazy są już bardzo podobne (w moim przypadku użycia), więc mogę użyć dość wysokiej wartości progowej.

Chyba istnieją dziesiątki innych możliwych rozwiązań, które zadziałałyby mniej więcej (ponieważ samo zadanie jest dość proste, ponieważ chcę wykryć podobieństwo tylko wtedy, gdy są naprawdę bardzo podobne). Co sugerujesz?


Istnieje kilka bardzo powiązanych / podobnych pytań dotyczących uzyskania podpisu / odcisku palca / skrótu z obrazu:

Również natknąłem się na te implementacje, które mają takie funkcje, aby uzyskać odcisk palca:

Niektóre Dyskusje o hashach obrazu percepcyjnego: tutaj


Trochę offtopic: istnieje wiele metod tworzenia odcisków palców audio. MusicBrainz , usługa internetowa, która zapewnia wyszukiwanie utworów za pomocą odcisków palców, ma dobry przegląd na wiki . Teraz używająAcoustID . Służy do znajdowania dokładnych (lub głównie dokładnych) dopasowań. Aby znaleźć podobne dopasowania (lub jeśli masz tylko kilka fragmentów lub wysoki szum), spójrz na Echoprint. Podobne pytanie brzmi tutaj . Wygląda więc na to, że dla audio jest to rozwiązane. Wszystkie te rozwiązania działają całkiem dobrze.

Nieco bardziej ogólne Pytanie o wyszukiwanie rozmyte w ogóle jest tutaj . Np. istnieje hashowanie wrażliwe na lokalizację i wyszukiwanie najbliższych sąsiadów.

Author: Albert, 2010-11-16

7 answers

Czy można przekształcić zrzut ekranu lub ikonę (skalować, obracać, przekrzywiać ...)? Jest kilka metod na głowie, które mogłyby Ci pomóc:

  • prosta odległość euklidesowa Jak wspomniano przez @ carlosdc (nie działa z przekształconymi obrazami i potrzebujesz progu).
  • (znormalizowana) korelacja Krzyżowa - prosta metryka, której można użyć do porównania obszarów obrazu. Jest bardziej wytrzymały niż prosta odległość euklidesowa, ale nie pracuj nad przekształconymi obrazami, a ponownie będziesz potrzebować progu.
  • Porównanie histogramów - Jeśli używasz znormalizowanych histogramów, ta metoda działa dobrze i nie ma wpływu na transformacje afiniczne. Problem polega na określeniu WŁAŚCIWEGO progu. Jest również bardzo wrażliwy na zmiany kolorów (jasność, kontrast itp.). Można go połączyć z dwoma poprzednimi.
  • detektory najważniejszych punktów / obszarów - np. MSER (maksymalnie stabilne regiony Ekstremalne) , SURF lub SIFT . Są to bardzo solidne algorytmy i mogą być zbyt skomplikowane dla prostego zadania. Dobrą rzeczą jest to, że nie musisz mieć dokładnego obszaru z tylko jedną ikoną, te detektory są wystarczająco silne, aby znaleźć odpowiednie dopasowanie. Miłą ocenę tych metod znajduje się w tym artykule: Local invariant feature detectors: a survey .

Większość z nich jest już zaimplementowana w OpenCV-patrz na przykład metoda cvMatchTemplate (używa histogram pasujący): http://dasl.mem.drexel.edu / ~noahKuntz/openCVTut6.html. dostępne są również najważniejsze detektory punktu/obszaru-zobacz Detekcja funkcji OpenCV.

 93
Author: Karel Petranek,
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-11-17 09:59:36

Spotykam się ostatnio z tymi samymi problemami, aby rozwiązać ten problem (prosty i szybki algorytm porównujący dwa obrazy) raz na zawsze, dodaję moduł img_hashdo opencv_contrib, szczegóły znajdziesz z ten link.

Moduł Img_hash zapewnia sześć algorytmów hashowania obrazów, dość łatwych w użyciu.

Przykład kodów

pochodzeniepochodzenie lena

blur lenablur lena

Zmień rozmiar LenyZmień rozmiar lena

/ align = "left" /shift Lena

#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/img_hash.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>

void compute(cv::Ptr<cv::img_hash::ImgHashBase> algo)
{
    auto input = cv::imread("lena.png");
    cv::Mat similar_img;

    //detect similiar image after blur attack
    cv::GaussianBlur(input, similar_img, {7,7}, 2, 2);
    cv::imwrite("lena_blur.png", similar_img);
    cv::Mat hash_input, hash_similar;
    algo->compute(input, hash_input);
    algo->compute(similar_img, hash_similar);
    std::cout<<"gaussian blur attack : "<<
               algo->compare(hash_input, hash_similar)<<std::endl;

    //detect similar image after shift attack
    similar_img.setTo(0);
    input(cv::Rect(0,10, input.cols,input.rows-10)).
            copyTo(similar_img(cv::Rect(0,0,input.cols,input.rows-10)));
    cv::imwrite("lena_shift.png", similar_img);
    algo->compute(similar_img, hash_similar);
    std::cout<<"shift attack : "<<
               algo->compare(hash_input, hash_similar)<<std::endl;

    //detect similar image after resize
    cv::resize(input, similar_img, {120, 40});
    cv::imwrite("lena_resize.png", similar_img);
    algo->compute(similar_img, hash_similar);
    std::cout<<"resize attack : "<<
               algo->compare(hash_input, hash_similar)<<std::endl;
}

int main()
{
    using namespace cv::img_hash;

    //disable opencl acceleration may(or may not) boost up speed of img_hash
    cv::ocl::setUseOpenCL(false);

    //if the value after compare <= 8, that means the images
    //very similar to each other
    compute(ColorMomentHash::create());

    //there are other algorithms you can try out
    //every algorithms have their pros and cons
    compute(AverageHash::create());
    compute(PHash::create());
    compute(MarrHildrethHash::create());
    compute(RadialVarianceHash::create());
    //BlockMeanHash support mode 0 and mode 1, they associate to
    //mode 1 and mode 2 of PHash library
    compute(BlockMeanHash::create(0));
    compute(BlockMeanHash::create(1));
}

W tym przypadku ColorMomentHash daje nam najlepszy wynik

  • gaussian blur attack : 0.567521
  • shift attack: 0.229728
  • resize attack : 0.229358

Plusy i minusy każdego algorytmu

Wydajność przy różnych atakach

Wydajność img_hash też jest dobra

Porównanie prędkości z biblioteką PHash (100 zdjęć z ukbench) wydajność obliczeniowa wydajność porównania

Jeśli chcesz poznać zalecane progi dla tych algorytmów, sprawdź ten post ( http://qtandopencv.blogspot.my/2016/06/introduction-to-image-hash-module-of.html ). Jeśli interesuje Cię jak mierzyć wydajność modułów img_hash( wliczając szybkość i różne ataki), sprawdź to link(http://qtandopencv.blogspot.my/2016/06/speed-up-image-hashing-of-opencvimghash.html).

 33
Author: StereoMatching,
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-06-27 14:25:25

Czy zrzut ekranu zawiera tylko ikonę? Jeśli tak, Odległość L2 obu obrazów może wystarczyć. Jeśli odległość L2 nie działa, następnym krokiem jest wypróbowanie czegoś prostego i dobrze ugruntowanego, na przykład: Lucas-Kanade . Który na pewno jest dostępny w OpenCV.

 8
Author: carlosdc,
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-11-16 23:19:06

Jeśli możesz być pewien precyzyjnego wyrównania szablonu (ikony) do obszaru testowania, wtedy każda stara suma różnic w pikselach będzie działać.

Jeśli wyrównanie będzie tylko trochę wyłączone, możesz przejść oba obrazy za pomocą CV::GaussianBlur przed znalezieniem sumy różnic w pikselach.

Jeśli jakość wyrównania jest potencjalnie słaba, polecam albo Histogram zorientowanych gradientów lub jeden z wygodnych OpenCV algorytmy detekcji/deskryptora punktów kluczowych (takie jak SIFT lub SURF).

 4
Author: rcv,
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-11-17 23:28:02

Jeśli chcesz uzyskać indeks o podobieństwie dwóch zdjęć, proponuję ci z metryki indeks SSIM. Jest bardziej zgodny z ludzkim okiem. Oto artykuł na ten temat: Wskaźnik podobieństwa strukturalnego

OpenCV jest również implementowany w OpenCV i może być przyspieszany za pomocą GPU: OpenCV SSIM za pomocą GPU
 4
Author: ramez,
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-09-12 16:49:00

Jeśli dla dopasowania identycznych obrazów-kod Dla odległości L2

// Compare two images by getting the L2 error (square-root of sum of squared error).
double getSimilarity( const Mat A, const Mat B ) {
if ( A.rows > 0 && A.rows == B.rows && A.cols > 0 && A.cols == B.cols ) {
    // Calculate the L2 relative error between images.
    double errorL2 = norm( A, B, CV_L2 );
    // Convert to a reasonable scale, since L2 error is summed across all pixels of the image.
    double similarity = errorL2 / (double)( A.rows * A.cols );
    return similarity;
}
else {
    //Images have a different size
    return 100000000.0;  // Return a bad value
}
Szybko. Ale nie wytrzymały na zmiany oświetlenia / punktu widzenia itp. Źródło
 3
Author: Kiran,
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
2014-04-04 08:28:09

Jeśli chcesz porównać obraz pod kątem podobieństwa, proponuję użyć OpenCV. W OpenCV istnieje niewiele dopasowania funkcji i dopasowania szablonów. W celu dopasowania funkcji są wykrywacze surfowania, przesiewania, szybkiego i tak dalej. Można tego użyć do wykrycia, opisania, a następnie dopasowania obrazu. Następnie możesz użyć określonego indeksu, aby znaleźć liczbę dopasowań między dwoma obrazami.

 2
Author: Hua Er Lim,
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-01-19 05:17:24