W dzisiejszym wpisie zgłębimy fascynujący świat przetwarzania obrazu, demonstrując, jak wykorzystać bibliotekę OpenCV do odkrywania i podkreślania różnic między dwoma obrazami. Ta technika ma szerokie zastosowanie, od automatycznego wykrywania zmian na zdjęciach satelitarnych, przez kontrolę jakości w produkcji, aż po zastosowania w bezpieczeństwie i monitoringu. Dzięki prostemu, ale potężnemu skryptowi w Pythonie, pokażemy, jak za pomocą kilku kroków można zidentyfikować i wizualnie przedstawić różnice między obrazami.
Wstęp do Problemu
Porównywanie obrazów to zadanie, które na pierwszy rzut oka może wydawać się trywialne. Jednak w kontekście automatycznego przetwarzania i analizy obrazu, jest to zadanie wymagające zastosowania specjalistycznych technik. Cel jest prosty: zidentyfikować i wizualizować różnice między dwoma obrazami. Może to być szczególnie przydatne w przypadkach, gdzie różnice nie są łatwo dostrzegalne dla ludzkiego oka.
Narzędzia i Technologie
Do realizacji tego zadania wykorzystamy OpenCV, otwartoźródłową bibliotekę do przetwarzania obrazów i wizji komputerowej. OpenCV oferuje bogaty zestaw narzędzi, które umożliwiają realizację zaawansowanych operacji na obrazach z łatwością.
Krok po Kroku: Algorytm Porównywania Obrazów
Przygotowanie Obrazów
Na wstępie, konwertujemy oba obrazy do skali szarości. Jest to standardowy krok wstępny w wielu aplikacjach przetwarzania obrazów, ponieważ upraszcza on operacje, redukując obrazy do jednego wymiaru intensywności.
Detekcja Cech i Dopasowanie
Wykorzystujemy detektor ORB (Oriented FAST and Rotated BRIEF), aby zidentyfikować kluczowe punkty i ich deskryptory w obu obrazach. Następnie, używając dopasowania brute-force z normą Hamminga, znajdujemy odpowiadające sobie punkty między obrazami.
Wyliczenie Homografii i Wyrównanie Obrazów
Znalezienie homografii pozwala nam na przekształcenie perspektywy jednego obrazu tak, aby odpowiadał on drugiemu. Dzięki temu, obrazy są porównywalne w bezpośredni sposób.
Podkreślanie Różnic
Obliczamy bezwzględną różnicę między wyrównanymi obrazami, a następnie stosujemy progu, aby zaznaczyć znaczące różnice. Kontury różnic są następnie wypełniane różowym kolorem, co ułatwia wizualną identyfikację zmian.
Kod
import cv2
import numpy as np
def align_images(im1, im2):
# Konwersja obrazów do skali szarości
im1_gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
im2_gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
# Inicjalizacja ORB detektora
orb = cv2.ORB_create()
# Znajdowanie kluczowych punktów i deskryptorów z ORB
keypoints1, descriptors1 = orb.detectAndCompute(im1_gray, None)
keypoints2, descriptors2 = orb.detectAndCompute(im2_gray, None)
# Dopasowywanie deskryptorów za pomocą BFMatcher
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = matcher.match(descriptors1, descriptors2)
# Sortowanie dopasowań
matches = sorted(matches, key=lambda x:x.distance)
# Wyodrębnienie lokalizacji kluczowych punktów dla najlepszych dopasowań
points1 = np.zeros((len(matches), 2), dtype=np.float32)
points2 = np.zeros((len(matches), 2), dtype=np.float32)
for i, match in enumerate(matches):
points1[i, :] = keypoints1[match.queryIdx].pt
points2[i, :] = keypoints2[match.trainIdx].pt
# Znalezienie homografii
h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
# Przekształcenie im1 do przestrzeni im2
height, width, channels = im2.shape
im1_aligned = cv2.warpPerspective(im1, h, (width, height))
return im1_aligned, im2
def compare_images_and_highlight_differences(im1, im2):
# Wyrównanie obrazów
im1_aligned, im2_aligned = align_images(im1, im2)
# Obliczenie bezwzględnej różnicy między wyrównanymi obrazami
difference = cv2.absdiff(im1_aligned, im2_aligned)
# Konwersja różnicy na skalę szarości
gray_diff = cv2.cvtColor(difference, cv2.COLOR_BGR2GRAY)
# Próg, aby uzyskać znaczące różnice
_, thresh = cv2.threshold(gray_diff, 50, 255, cv2.THRESH_BINARY)
# Znajdowanie konturów różnic
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Nałożenie różowego koloru na różniące się obszary
pink_color = (180, 105, 255) # BGR for pink
im1_highlighted = im1_aligned.copy()
for contour in contours:
cv2.drawContours(im1_highlighted, [contour], -1, pink_color, -1)
return im1_highlighted
# Zakładając, że masz dwa obrazy: '1.jpg' i '2.jpg' - pamiętaj, aby zaktualizować ścieżki do obrazów
im1 = cv2.imread('1.jpg')
im2 = cv2.imread('2.jpg')
# Upewnij się, że obrazy zostały poprawnie wczytane
if im1 is not None and im2 is not None:
highlighted_diff = compare_images_and_highlight_differences(im1, im2)
# Wyświetlenie obrazu z zaznaczonymi różnicami
cv2.imshow('Highlighted Differences', highlighted_diff)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("Error loading images. Please check the file paths.")
Efekt działania
Obrazy wejściowe:
A oto efekt (różnice zaznaczone są na różowo):
Zastosowania i Potencjał
Zaprezentowana technika ma szerokie zastosowanie w wielu dziedzinach. W medycynie może służyć do porównywania obrazów rentgenowskich w czasie, aby monitorować postępy choroby lub leczenia. W bezpieczeństwie, może wykrywać zmiany w monitorowanych obszarach. W produkcji, umożliwia kontrolę jakości poprzez wykrywanie defektów.
Podsumowanie
Demonstracja ta ukazuje siłę OpenCV i możliwości, jakie oferuje w zakresie przetwarzania i analizy obrazu. Poprzez stosunkowo prosty skrypt, możemy automatycznie wykrywać i wizualizować różnice między obrazami, co otwiera drzwi do wielu zastosowań praktycznych. Przetwarzanie obrazów i wizja komputerowa nadal ewoluują, a techniki takie jak przedstawiona, podkreślają ich rosnące znaczenie w świecie technologii.
Taka eksploracja możliwości OpenCV to tylko wierzchołek góry lodowej. Zachęcam do eksperymentowania i rozszerzania przedstawionego kodu, aby lepiej służył waszym unikalnym wymaganiom i pomysłom. Przestrzeń przetwarzania obrazów jest ogromna i pełna możliwości do odkrycia.