Sprawdzanie podobieństw obrazów z OpenCV
Czy OpenCV obsługuje porównanie dwóch obrazów, zwracając jakąś wartość (może procent), która wskazuje, jak podobne są te obrazy? Np. 100% zostanie zwrócone, jeśli ten sam obraz zostanie przekazany dwa razy, 0% zostanie zwrócone, jeśli obrazy będą zupełnie inne.
Przeczytałem już wiele podobnych tematów tutaj na StackOverflow. Też trochę Wygooglowałem. Niestety nie mogłem znaleźć satysfakcjonującej odpowiedzi.
4 answers
To naprawdę ogromny temat, z odpowiedziami z 3 linii kodu do całych czasopism badawczych.
Przedstawię najczęstsze tego typu techniki i ich wyniki.
Porównywanie histogramów
Jedna z najprostszych i najszybszych metod. Zaproponowany kilkadziesiąt lat temu jako środek do znalezienia podobieństw obrazu. Chodzi o to, że las będzie miał dużo zieleni, a ludzka twarz dużo różu, czy cokolwiek. Więc jeśli porównasz dwa zdjęcia z lasami, dostaniesz trochę simmilarity między histogramami, bo w obu masz dużo zieleni.
Minusy: to zbyt uproszczone. Banan i Plaża będą wyglądać tak samo, ponieważ oba są żółte.
Metoda OpenCV: compareHist ()
Dopasowanie szablonu
Dobry przykład tutaj matchTemplate znalezienie dobrego dopasowania. To convolves obraz wyszukiwania z jednym jest szukaj w. Zwykle jest używany do znajdowania mniejszych części obrazu w większym.
Minusy: to tylko zwraca dobre wyniki z identycznymi obrazami, tym samym rozmiarem i orientacją.
Metoda OpenCV: matchTemplate ()
Dopasowanie funkcji
Uważany za jeden z najskuteczniejszych sposobów wyszukiwania obrazów. Wiele funkcji jest wyodrębnianych z obrazu w sposób, który gwarantuje, że te same funkcje będą ponownie rozpoznawane, nawet gdy zostaną obrócone/skalowane / Przekrzywione. Wyodrębnione w ten sposób funkcje można dopasować do innych zestawów funkcji obrazu. Kolejny obraz, który ma duży udział w rysy w pierwszym z nich najprawdopodobniej przedstawiają ten sam obiekt/scenę. Można go użyć, aby znaleźć względną różnicę w kącie fotografowania między zdjęciami lub ilość nakładania się.
Na tej stronie znajduje się wiele samouczków/sampli OpenCV oraz fajny filmik tutaj. Dedykowany jest mu cały moduł OpenCV (features2d).
Minusy: może być powolny. To nie jest idealne.
- możesz znaleźć bardziej szczegółowe informacje i inne podobne techniki tutaj: http://answers.opencv.org/question/877/how-to-match-2-hog-for-object-detection/#882
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:02:42
Jeśli dla dopasowania identycznych obrazów (ten sam rozmiar/orientacja)
// 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
}
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:11:56
Rozwiązanie sama powinno wystarczyć. Użyłem kombinacji zarówno różnicy histogramu i dopasowania szablonu, ponieważ żadna metoda nie działała dla mnie w 100% razy. Poświęciłem jednak mniej uwagi metodzie histogramu. Oto jak zaimplementowałem prosty skrypt Pythona.
import cv2
class CompareImage(object):
def __init__(self, image_1_path, image_2_path):
self.minimum_commutative_image_diff = 1
self.image_1_path = image_1_path
self.image_2_path = image_2_path
def compare_image(self):
image_1 = cv2.imread(self.image_1_path, 0)
image_2 = cv2.imread(self.image_2_path, 0)
commutative_image_diff = self.get_image_difference(image_1, image_2)
if commutative_image_diff < self.minimum_commutative_image_diff:
print "Matched"
return commutative_image_diff
return 10000 //random failure value
@staticmethod
def get_image_difference(image_1, image_2):
first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])
img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
img_template_diff = 1 - img_template_probability_match
# taking only 10% of histogram diff, since it's less accurate than template method
commutative_image_diff = (img_hist_diff / 10) + img_template_diff
return commutative_image_diff
if __name__ == '__main__':
compare_image = CompareImage('image1/path', 'image2/path')
image_difference = compare_image.compare_image()
print image_difference
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-08-03 13:44:45
Trochę off topic, ale przydatne jest podejście pythonic numpy
. Jego solidny i szybki, ale po prostu porównuje piksele, a nie Obiekty lub dane, które zawiera obraz (i wymaga obrazów o tym samym rozmiarze i kształcie): {]}
Bardzo prostym i szybkim podejściem do tego bez openCV i żadnej biblioteki do widzenia komputerowego jest normowanie tablic obrazkowych przez
import numpy as np
picture1 = np.random.rand(100,100)
picture2 = np.random.rand(100,100)
picture1_norm = picture1/np.sqrt(np.sum(picture1**2))
picture2_norm = picture2/np.sqrt(np.sum(picture2**2))
Po zdefiniowaniu obu znormalizowanych obrazów (lub macierzy) można po prostu zsumować przez mnożenie obrazów, które lubisz Porównaj:
1) jeśli porównasz Podobne Zdjęcia, suma zwróci 1:
In[1]: np.sum(picture1_norm**2)
Out[1]: 1.0
2) Jeśli nie są podobne, otrzymasz wartość między 0 a 1 (procent, jeśli pomnożysz przez 100):
In[2]: np.sum(picture2_norm*picture1_norm)
Out[2]: 0.75389941124629822
Proszę zauważyć, że jeśli masz kolorowe zdjęcia, musisz to zrobić we wszystkich 3 wymiarach lub po prostu porównać wersję szarą. Często muszę porównywać ogromne ilości zdjęć z dowolnymi treściami i jest to naprawdę szybki sposób na to.
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-09 13:44:43