1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【OpenCV】2つの画像の類似点の座標(X,Y)をndarray形式の変数に格納する【Python】

Last updated at Posted at 2022-11-07

参考文献:opencv画像をマッチングする

はじめに

前回のQiitaの記事ではAkazaのおかげで特徴点マッチングを実現することができた。今回は、その特徴点の座標を取得し、より数学的に画像を扱えるように加工していく。

環境

OS : Ubuntu 20.04 LTS
Python : 3.8.10
OpenCV-Python : 4.6.0

特徴点の詳細データを取得

前回のプログラムの続きから説明します。前回のプログラムに関する記事はこの記事の「はじめに」に書かれています。

kp1,des1 = detector.detectAndCompute(gray_image1,None)
kp2,des2 = detector.detectAndCompute(gray_image2,None)

bf = cv2.BFMatcher()
matches = bf.match(des1,des2)
matches = sorted(matches,key = lambda x:x.distance)
# 追加ここから 
for x in range(len(matches[:20])): 
    print(kp1[matches[x].queryIdx].pt)
    print(kp2[matches[x].trainIdx].pt)
    image1list.append(kp1[matches[x].queryIdx].pt)
    image2list.append(kp2[matches[x].trainIdx].pt)
    print("---------------------------------------------")
# 追加ここまで

では一行ずつ説明していきたいと思います。

1.for文のmatchesについて

みなさんに嫌がらせをします。この星の数を数えてください。(しなくていいです)
southerncross.jpg (187.9 kB)
この答えはほぼ無限にありますよね。実は特徴点マッチングでも同じことが言えて、特徴点は無限にあります。
無駄に多くの特徴点を捉えるとプログラムの動作を重くしたり、人間が理解しにくくさせたりするので厄介です。今回は”20”という値を設定しましたが、これはあくまで私が理解しやすい数値です。

for x in range(len(matches[:20])): 

みなさんが開発するときに適宜数字を変えて開発を進めてください。

2.kp1[],kp2[]について

K~P~(乾杯)のノリではありません。(多分、K~P~は3年後は死語)
kp1は[des1,des2]で処理された類似点データをもとに座標やサイズなどのデータを取り出しやすくするための変数という感覚で捉えてください。

print(kp1[matches[x].queryIdx].pt)
print(kp2[matches[x].trainIdx].pt)

xという変数にはforで繰り返された回数の数字が代入されています。したがってmatchesのx個目を取得しています。
次に.queryIdx.trainIdxについですが、これは元画像と比較対象画像のデータを取得するOpenCVの変数です。(detectAndComputeで処理されたキーポイントのインデックスです)

百聞は一見に如かず、どんな値が帰ってくるのかを実際に見てみましょう

画像を読み込んで処理する例
print(matches[0].distance)
print(matches[0].trainIdx)
print(matches[0].queryIdx)
print(matches[0].imgIdx)
結果
# -----出力-----
121.76616668701172
214
207
0

3. [~queryIdx].ptのptってなんですか?

keypointオブジェクトは以下の属性を持っています。

  • pt:キーポイントの座標(ヒント:タプルで(x,y)が戻り値として返ってきます)
  • size:キーポイント周辺の重要領域の直径
  • angle:計算されたキーポイントの方向(計算できない場合は -1 )
  • response:最も強いキーポイントが選択されたときの応答
  • octave:キーポイントが抽出されるオクターブ(ピラミッドの階層)
  • class_id:オブジェクトクラス
    pt以外今のところまだ使ったことがないので、使い次第、上のリストにヒントを追記していきます。

これも百聞は一見に如かず、例を見てみましょう

画像を読み込んで処理する例
print(kp1[0].pt)
print(kp1[0].size)
print(kp1[0].angle)
print(kp1[0].response)
print(kp1[0].octave)
print(kp1[0].class_id)
結果
# -----出力-----
(60.0, 129.0)
31.0
276.7517395019531
0.001297724898904562
0
-1

4.最後にndarrayに変換!

ndarrayはnumpyの変数の一つです。プログラムの先頭にインポートすることをお忘れなく...

import cv2
# 追加ここから
import numpy as np
# 追加ここまで

次に必ずプログラムの先頭らへんにimage1listimage2listというリストを準備しておきましょう。

理由は、forのプログラムで処理したタプルの座標データを二つのimage{}listリストに.appendしているからです。全体プログラムを見てみてください
最後にPythonのリストをndarrayに変換するためfor文の外で以下のプログラムを実行するだけです。

resultbefore = np.array(image1list,dtype=float)
resultafter = np.array(image2list,dtype=float)

長い記事を読んでいただきありがとうございました。
貫徹。

1
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?