特徴点の抽出とCSVファイルへの書き出し detectAndCompute()



画像から特徴点を抽出し、特徴点を画像およびCSVファイルに書き出す方法を紹介します。
開発環境はjupyter notebook、言語はpythonです。
今回使用した画像・コード一式はgoogle driveにも保存しておりますので、必要に応じてお使いください。

作成したコード

#モジュールのインポート
import cv2
import glob
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
%matplotlib inline

akaze = cv2.AKAZE_create() 

filepath = glob.glob("*.jpg")
for num in range(len(filepath)):
    img = cv2.imread(filepath[num])
    kp, des = akaze.detectAndCompute(img, None)
    df = pd.DataFrame(columns=['x', 'y', 'size', 'angle','response','octave','class_id'])  
    for i in range(len(kp)):
        df.loc["kp"+str(i)] = [kp[i].pt[0],kp[i].pt[1],kp[i].size,kp[i].angle,kp[i].response,kp[i].octave,kp[i].class_id]
    df.to_csv("key point"+"_"+os.path.split(filepath[num])[1][:-4]+".csv")
    img_key = cv2.drawKeypoints(img, kp, None,color=(0,0,255), flags=4)
    cv2.imwrite(os.path.split(filepath[num])[1][:-4]+"_keypoint.png",img_key)

処理の解説

1.検出器の生成

特徴点を検出する際は、以下のコマンドで特徴点の検出器を生成する必要があります。
akaze = cv2.AKAZE_create() 
今回はakazeを用いていますが、他にもORBなど様々な検出器があるので、速度や精度を考慮して好きなものを選んでいただければと思います。
個々の手法と検出結果についてはまた記事にしたいと思います。

2.特徴点の検出

次にcv2.imread()で読み込んだ画像imgに対して、以下のコマンドで特徴点の検出を行います。
kp, des = akaze.detectAndCompute(img, None)
第一引数のkp(key point)には特徴点の座標等の情報が、第二引数des(feature descriptor)には特徴量記述子の情報が格納されています。

今回はこのkp内の情報を特徴点ごとに取りだして、pandasのデータフレームに追加する処理を実行します。
df = pd.DataFrame(columns=['x', 'y', 'size', 'angle','response','octave','class_id'])  
    for i in range(len(kp)):
        df.loc["kp"+str(i)] = [kp[i].pt[0],kp[i].pt[1],kp[i].size,kp[i].angle,kp[i].response,kp[i].octave,kp[i].class_id]
ここで取り出している情報は次の表のものになります。

ParameterDetail
.pt[0]特徴点のX座標
.pt[1]特徴点のY座標
.size特徴点の直径
.angle特徴点の向きの角度
.response特徴点の強度
.octave特徴点が抽出された際のピラミッドオクターブ
.class_idオブジェクトのID

なお、表の情報を画像上で示すと以下のようになります。


df.to_csv()によって書き出されたcsvファイルは次のようになっています。

xysizeangleresponseoctaveclass_id
kp0935.688152.96644.8293.35840.00131800
kp1900.9185190.96694.8199.49410.00349100
kp21183.601203.10864.8284.49250.00111300
kp3885.3304204.49914.818.883640.00130800
kp41164.229223.47294.846.335570.00129200
kp51108.216224.95544.8103.87820.00132300
kp6885.7973226.64054.8193.17360.00393600
kp71112.51229.51344.8113.02880.00183900
kp8884.2508232.82864.8195.15440.00285100
kp9851.7514242.29134.8203.18260.00100900
kp10881.5363242.04234.8197.66280.00168500

今回は10点ほどの特徴点を抜粋していますが、何千何万といった単位で特徴点が抽出されます。

3.特徴点の書き出し

最終的に元の画像上に特徴点を書き出します。
img_key = cv2.drawKeypoints(img, kp, None, color=(255,0,0),flags=4)
この時flagsの値を0に変更することで特徴点の記述方法を変更することができます。
またcolorを今回はcolor=(0,0,255)としていますが、指定をしない場合は無作為にカラフルな色付けが行われます。


今回は以上になります。
幾何学的な形状のものの方が分かりやすいかと思い、ルービックキューブの画像にしましたが、そんなに分かりやすいものでもありませんでした。
特徴点のマッチングは次回紹介します。

コメント