ミッキーを特徴点マッチングで検出する

# 目的
ミッキーマウスをopenCVを使った特徴点マッチングを利用して検出します。

# 準備

python環境と
openCVを用意します。

元画像 test.png
<img width="160" alt="test1のコピー.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/c78cba7c-14f1-8518-dbb9-8fc745be7562.png">

テンプレート画像(元画像から切出します) test2.png
<img width="120" alt="test2のコピー.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/701a1aae-98f6-00e1-84c4-61a74f70d77a.png">

下記手順で求めます。
　1.特徴点を抽出して、対応を求める。特徴点は[AKAZE](http://pwiki.awm.jp/~yoya/?AKAZE)を使います。
　2.画像間の変換行列（ホモグラフィ行列）を求める
　3.元画像中のテンプレート画像の座標を求めて矩形を描画

# コード

```ruby:sample.py
import cv2
import numpy as np

fname_img1='test1.png'
fname_img2='test2.png'

img1 = cv2.imread(fname_img1)
img2 = cv2.imread(fname_img2)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
akaze = cv2.AKAZE_create()
kp1, des1 = akaze.detectAndCompute(gray1, None)
kp2, des2 = akaze.detectAndCompute(gray2, None)

#img1_sift = cv2.drawKeypoints(gray1, kp1, None, flags=4)
#img2_sift = cv2.drawKeypoints(gray2, kp2, None, flags=4)
#cv2.imwrite('out1.png', img1_sift)
#cv2.imwrite('out2.png', img2_sift)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)
cv2.imwrite('out-match.png', img3)

#homography
good_match_rate = 0.15;
good = matches[:int(len(matches) * good_match_rate)]

min_match=10
if len(good) > min_match:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
    # Find homography
    M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC)
    matchesMask = mask.ravel().tolist()

    print(M)
    print(M[0][2])
    print(M[1][2])

    height = img2.shape[0]
    width = img2.shape[1]
    top_left = (int(M[0][2] +0.5), int(M[1][2] +0.5)); #tx,ty
    bottom_right = (top_left[0] + width, top_left[1] + height)

#result
result = cv2.imread(fname_img1)
cv2.rectangle(result,top_left, bottom_right, (255, 0, 0), 10)
cv2.imwrite("result.png", result)

```

# テスト

1.特徴点を抽出して、対応を求める
下記画像を取得できます。

![out-matchのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/da05f8f1-285b-9fdf-732e-c5a0d4bf09a8.png)


2.画像間の変換行列（ホモグラフィ行列）を求める

下記のようなホモグラフィ行列を求めました。
tx,ty = (512, 316) 辺りだと思います。

```

[[1.16838899e+00 1.36261013e-02 5.12202590e+02]
 [9.62912057e-03 1.16040454e+00 3.16537616e+02]
 [1.98399751e-05 1.89682781e-05 1.00000000e+00]]
```

3.元画像中のテンプレート画像の座標を求めて矩形を描画
下記画像を取得できます。

![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/b85b6270-1cb1-6549-f2f2-f6457ac91c53.png)


# CodingError対策

特になし


# 参考
[特徴点のマッチングとHomographyによる物体検出](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html)
[画像の特徴点を抽出する](https://qiita.com/fukuit/items/546f19d2abf98eccd3e7)
[簡単にできるOpenCVを使った顔検出](https://ai-coordinator.jp/opencv)
[[【コンピュータビジョン】3章「画像間の写像」　ホモグラフィ(点の調整)]](http://yaju3d.hatenablog.jp/entry/2014/03/30/231134)
[AKAZE](http://pwiki.awm.jp/~yoya/?AKAZE)