OpenCV - 特徴点マッチングで物体検出、移動、回転量を推定する - pystyle
画像から特徴量を抽出し、透視変換行列を導出して画像を変形する - Qiita
ORB特徴量を用いて、ホモグラフィ変換を行う - Qiita
import cv2 import numpy as np MAX_FEATURES = 500 GOOD_MATCH_PERCENT = 0.15 def alignImages(im1, im2): # 特徴量の抽出と記述子の計算 detector = cv2.ORB_create(MAX_FEATURES) keypoints1, descriptors1 = detector.detectAndCompute(im1, None) keypoints2, descriptors2 = detector.detectAndCompute(im2, None) # 特徴量のマッチング matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING) matches = matcher.match(descriptors1, descriptors2, None) print(matches) # 特徴量をスコアでソート ハミング距離などで定義可能 # matches.sort(key=lambda x: x.distance, reverse=False) matches = sorted(matches, key=lambda x: x.distance) # スコアのよい特徴量上位 N%を抽出 numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT) matches = matches[:numGoodMatches] # 特徴量マッチングの結果の描画 imMatches = cv2.drawMatches(im1, keypoints1, im2, keypoints2, matches, None) cv2.imwrite("matches.png", imMatches) # 特徴点と記述子の対応をとる 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 # 射影変換行列の算出と適用 h, mask = cv2.findHomography(points1, points2, cv2.RANSAC) height, width, channels = im2.shape im1Reg = cv2.warpPerspective(im1, h, (width, height)) return im1Reg #実行用 if __name__ == '__main__': # 画像補正のリファレンス # refFilename = "origin.png" refFilename = "lena.jpg" imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR) # 射影補正ターゲットの画像 # imFilename = "target.png" imFilename = "lena_copy.jpg" im = cv2.imread(imFilename, cv2.IMREAD_COLOR) # 射影変換の適用 imReg = alignImages(im, imReference) # 補正した画像の保存 outFilename = "aligned.png" cv2.imwrite(outFilename, imReg) imdiff = cv2.absdiff(imReference,imReg) cv2.imshow("diff",imdiff)