Minta keresése és illesztése
Az alábbi példában megnézzük, hogy hogyan tudunk egy mintát megtalálni egy képen. Ehhez a következő lépéseket kell végrehajtanunk:
- Képek megnyitása.
- Képek szürkeárnyalatossá konvertálása
- Jellemzőpontok keresése és leírók készítése mindkét képen.
- Jellemzőpontok párosítása.
- A pontpárok közötti homográfia kiszámítása.
- A homográfia végrehajtása.
A feladat megoldásához az OpenCV függvénykönyvtárat fogjuk használni.
Az alábbi képeket fogjuk használni:
import cv2
import numpy as np
SOURCE_IMAGE1='../DIP_konyv.jpg'
SOURCE_IMAGE2='../konyvek09.jpg'
MATCHING_IMAGE='flann_matching_DIP_konyv.jpg'
## képek beolvasása
img1 = cv2.imread(SOURCE_IMAGE1);
img2 = cv2.imread(SOURCE_IMAGE2);
h1,w1 = img1.shape[:2]
h2,w2 = img2.shape[:2]
## a képet szürkeárnyalatossá konvertáljuk
gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray_img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
## jellemzőpontok detektálása
surf = cv2.xfeatures2d.SURF_create()
keypoints1 = surf.detect(gray_img1, None)
keypoints2 = surf.detect(gray_img2, None)
## kulcspont leírók számítása
keypoints1, descriptors1 = surf.compute(gray_img1, keypoints1)
keypoints2, descriptors2 = surf.compute(gray_img2, keypoints2)
## pontpárok keresése
# FLANN parameterek
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(descriptors1,descriptors2,k=2) ## ez kNN-alapú,
## minden pontnak két lehetséges párja lehet
# csak a jó párosításokat tároljuk el, amelyek átmentek a Lowe-teszten
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
points1 = []
points2 = []
for m in good:
points1.append(keypoints1[m.queryIdx].pt)
points2.append(keypoints2[m.trainIdx].pt)
points1, points2 = np.float32((points1, points2))
H, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
matchesMask = mask.ravel().tolist() # azok a pontok, amelyek szerepelnek a párosításban
## a minta keretét egy téglalapként reprezentáljuk és ezt transzformáljuk
bounding_points = np.float32([ [0,0],[0,h1-1],[w1-1,h1-1],[w1-1,0] ]).reshape(-1,1,2)
transformed_points = cv2.perspectiveTransform(bounding_points,H)
int_transformed_points = np.int32(transformed_points)
img2 = cv2.polylines(img2,[int_transformed_points],True,255,10, cv2.LINE_AA)
draw_params = dict(matchColor = (0,255,0), # zöld színnel rajzolunk
singlePointColor = None,
matchesMask = matchesMask, # csak amit lemaszkoltunk azt rajzoljuk
flags = 2)
found_template_img = cv2.drawMatches(img1,keypoints1,img2,keypoints2,good,None,**draw_params)
cv2.imwrite("template_found.png", found_template_img )