特徴マッチングによる複数の物体検知

2019/09/05

Python2.7.8, OpenCV4.1.1

# -*- coding: utf-8 -*-
import numpy as np
import cv2

MIN_MATCH_COUNT = 10
QUERY_IMAGE_PATH = 'box.png'
TRAIN_IMAGE_PATH = 'box_multi_test.png'

img1 = cv2.imread(QUERY_IMAGE_PATH) 
img2 = cv2.imread(TRAIN_IMAGE_PATH)

# 拡大(特徴点検出量の向上のため)
rate = 2.0
img1 = cv2.resize(img1,None,interpolation=cv2.INTER_LINEAR,fx=rate,fy=rate)
rate = 3.0
img2 = cv2.resize(img2,None,interpolation=cv2.INTER_LINEAR,fx=rate,fy=rate)

img2c = img2.copy()
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

#検出
detector = cv2.AKAZE_create()
kp1, des1 = detector.detectAndCompute(img1, None)
kp2, des2 = detector.detectAndCompute(img2, None)

bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

#絞込み
good = []
for m,n in matches:
    if m.distance < 0.7*n.distance:
        good.append(m)
matches = good

mask = None
while True:
    if mask is not None:
        new_matches = []
        for j in range(len(matches)):
            if mask[j][0] == 0:
                new_matches.append(matches[j])
        matches = new_matches

    if len(good) > MIN_MATCH_COUNT:
        src_pts = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1,1,2)
        dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1,1,2)

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0, mask)

        if M is None:
            print ('No Homography')
            break
        else:
            print ('Find Homography')
            matchesMask = mask.ravel().tolist()

            h,w = img1.shape
            pts = np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)
            dst = cv2.perspectiveTransform(pts,M)

            img2c = cv2.polylines(img2c,[np.int32(dst)],True,(0,0,255),3,cv2.LINE_AA)

    else:
        print ('Not enough matches are found - %d/%d' % (len(good),MIN_MATCH_COUNT))
        matchesMask = None
        break

img3 = cv2.drawMatches(img1,kp1,img2c,kp2,good,None,flags=0)

cv2.namedWindow('Result', cv2.WINDOW_KEEPRATIO | cv2.WINDOW_NORMAL)
cv2.imshow('Result', img3)
cv2.waitKey(0)


素材画像 box.png  box_multi_test.png

これでよいのか・・・?


OpenCV feature matching multiple objects
https://stackoverflow.com/questions/42938149/opencv-feature-matching-multiple-objects