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:
- OpenCV / SURF jak wygenerować hash obrazu / odcisk palca / podpis z deskryptorów?
- Obraz odcisk palca do porównania podobieństwa wielu obrazów
- Wykrywanie Prawie Zduplikowanego Obrazu
- OpenCV: Obraz odcisków palców i porównanie z Bazą Danych .
- więcej, więcej, więcej, więcej, więcej, więcej, więcej
Również natknąłem się na te implementacje, które mają takie funkcje, aby uzyskać odcisk palca:
- pHash
- imgSeek (GitHub repo ) (GPL) na podstawie papieru Szybkie wyszukiwanie obrazów z wieloma rozdzielczością
- dopasowanie obrazu . Bardzo podobne do tego, czego szukałem. Podobne do pHash, oparte na sygnaturze obrazu dla każdego rodzaju obrazu, Goldberg et al . Używa Pythona i Elasticsearch.
- iqdb
- ImageHash . obsługuje pHash.
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.
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.
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
#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ść img_hash też jest dobra
Porównanie prędkości z biblioteką PHash (100 zdjęć z ukbench)
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).
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.
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).
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ą GPUWarning: 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łoWarning: 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.
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