Python3 OpenCV3で2つの画像の一致する特徴を線で結ぶ

Facebook にシェア
Pocket
LINEで送る
このエントリーを Google ブックマーク に追加

Python3 OpenCV3で画像の特徴点を抽出 に関連。

前提

ディレクトリ構成などはこことかこことか。

更に今回は描画のために、matplotlibをインストールした。

(opencv_python) $ pip install matplotlib
gnureadline==6.3.3
ipython==3.1.0
matplotlib==1.4.3
nose==1.3.7
numpy==1.9.2
Pillow==2.9.0
pyparsing==2.0.3
python-dateutil==2.4.2
pytz==2015.4
scipy==0.16.0
six==1.9.0
sympy==0.7.6

requirements.txtに上記の一覧を記述して、

$ pip install -r requirements.txt

とすればOpenCV以外の同じ環境が構築できる。

 

使用する画像

ダンボーの画像(dambo.jpg)とダンボーを逆さまにした画像(dambo_turn.jpg)を使用した。
source/imageディレクトリに設置した。

dambo

 

dambo_turn

 
 

ちょっと(分かる範囲で)解説

SIFTやらORBやらなにやらでてきたので調べてみた。

SIFT・ORB

SIFTは「Scale-Invariant Feature Transform」の略で、特徴点の検出と特徴量の出力を行うアルゴリズム。
画像などのマッチングや物体検出を行うときに使われる。

理論的な概要、解説に関してはこちらのpdfが読みやすい。
(数学系学科の初年度の微積分と線形代数を理解しているとある程度読める。)

Gradient ベースの特徴抽出 -SIFT と HOG-

ORBは「Oriented FAST and Rotated BRIEF」の略で、SIFTに変わる新たな特徴点の検出と特徴量の出力を行うディスパッチャー。
3Dの検出なども行うことができる模様。

英語だけど、こちらが参考になりそう。

ORB: an efficient alternative to SIFT or SURF
A tutorial on binary descriptors – part 3 – The ORB descriptor

 

マッチングした特徴点を先で結ぶ

ORBで特徴点の算出と特徴量を出力しマッチングして特徴点同士を描画して、matplotlibで表示する。

sourceディレクトリにdescripting.pyを作成する。

# -*- coding: utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

if __name__ == '__main__':

    img_src1 = cv2.imread('./image/dambo.jpg',0) # queryImage
    img_src2 = cv2.imread('./image/dambo_turn.jpg',0) # trainImage
    img_dst = img_src1

    # ORB(https://en.wikipedia.org/wiki/ORB_(feature_descriptcriptor))オブジェクトを生成する。
    orb = cv2.ORB_create()

    # img_src1とimg_src2の キーポイントと特徴量を抽出する。
    keypoint1, descript1 = orb.detectAndCompute(img_src1, None)
    keypoint2, descript2 = orb.detectAndCompute(img_src2, None)

    # BFMatcher オブジェクトを生成する。
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    # 2つの特徴量をマッチングする。
    matches = bf.match(descript1, descript2)

    # マッチした特徴点の距離の短い順にソートする。
    matches = sorted(matches, key=lambda x:x.distance)

    # マッチングした特徴点同士を線で結ぶ
    img3 = cv2.drawMatches(img_src1, keypoint1, img_src2, keypoint2, matches, img_dst, flags=2)

    # 表示
    plt.imshow(img3),plt.show()

実行してみる。

python descripting.py

figure_1

 

ちょっと線の量が多いため、以下の点でわかりやすいように描画数を少なくする。

    # マッチングした特徴点同士を線で結ぶ
    img3 = cv2.drawMatches(img_src1, keypoint1, img_src2, keypoint2, matches[:30], img_dst, flags=2)

figure_2

 

目や右手同士がマッチングされている。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です