これまでエッジ処理の理論と実装について勉強しました。
今回からコーナー検出について勉強していきたいと思います。
目次
- 第一回:コーナー検出の概要と雑実装(本記事)
- 第2回:【Pythonでコーナー検出】ヘシアンコーナー検出器の理論と実装 - Ayataの
※随時更新
1. コーナー検出の概要
コーナー検出器は、エッジ検出器と並び特徴点を抽出する代表的な検出器です。
wikiを見るとコーナーの定義は、「コーナーとは2つのエッジの交点と定義することができる」とあります。(コーナー検出法 - Wikipedia)
定義通りだとコーナーのような点(x,y方向共に輝度が大きく変わっている点)を見つけるだけなので、実際に物体のコーナーであるかは別途判定が必要になります。しかし、以下に挙げるような検出器ではコーナーを見つけると同時に、コーナーであることの判定を行っています。
2. コーナー検出器の種類
ここでは、いくつかのコーナー検出器を挙げ概要を説明します。しっかり理解できていない部分しかないので、詳しくはこつこつ勉強したいと思います。
有名なものはヘシアンコーナー検出器、モラベックコーナー検出器、ハリスコーナー検出器、FASTコーナー検出器などがあります。
■ヘシアンコーナー検出器
曲率を考える手法。画像をx,y平面 + 輝度の3次元空間としてとらえたときに、コーナーでは曲率が大きくなるとして検出します。
■モラベックコーナー検出器
画像内で小領域を作り、領域を動かします。その時、領域内にコーナーがあればどの方向に動かしても大きく変化し、コーナーが無ければ変化が少ないとして検出します。これを領域の自己相関のスコアとして処理していきます。
■ハリスコーナー検出器
モラベックコーナー検出器の改良版。より直線性を考慮したものになっているらしい、らしい、、
■FASTコーナー検出器
名前の通り高速にコーナーを計算する手法。注目画素をコーナーか非コーナーかに分類するという問題とみなし、決定木により解いていきます。適切な決定木は機械学習により得られます。
3. コーナー検出の雑実装
「コーナーとは2つのエッジの交点と定義することができる」を真に受けてそのまま実装してみます。
この前作ったx,y方向のエッジ処理を組み合わせて、コーナー検出にしていきます。
今回はエッジ処理において求められたエッジ強度に対して、しきい値を設定することでコーナーを検出しました。適当にエッジ強度が255より大きければコーナーとして判定するものにしました。出力結果を以下に示します。入力画像に対してエッジが求められ、エッジの交点がコーナーとして正しく検出されました。
↓以下ソースコード
import matplotlib.pyplot as plt import cv2 #OpenCVのインポート import numpy as np #画像パス FILE_PATH = 'C:/Users/.../aaa.png' #画像の読み込み img = cv2.imread(FILE_PATH) #画像サイズの取得 height, width, color = img.shape print("width = " + str(height)) print("height = " + str(height)) print("color channel = " + str(color)) #グレースケールへの変換 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #1次微分のフィルタ #横方向 fil_x = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]]) #縦方向 fil_y = np.array([[0, -1, 0], [0, 0, 0], [0, 1, 0]]) #空間フィルタリングの演算部 N = 1 img_fil_x = np.zeros((height - N, width - N)) img_fil_y = np.zeros((height - N, width - N)) #横方向の演算 for x in range(N, width - N, 1): for y in range(N, height - N, 1): a = 0 for i in range(-N, N+1, 1): for j in range(-N, N+1, 1): a = a + img_gray[y+j, x+i]*fil_x[j+N, i+N] img_fil_x[y-1, x-1] = abs(a) #縦方向の演算 for x in range(N, width - N, 1): for y in range(N, height - N, 1): a = 0 for i in range(-N, N+1, 1): for j in range(-N, N+1, 1): a = a + img_gray[y+j, x+i]*fil_y[j+N, i+N] img_fil_y[y-1, x-1] = abs(a) #コーナーの計算 img_edge_xy = np.zeros((height - N, width - N)) img_corner_xy = np.zeros((height - N, width - N)) for x in range(width - N): for y in range(height - N): #エッジ強度 img_edge_xy[x, y] = pow(pow(img_fil_x[y, x], 2) + pow(img_fil_y[y, x], 2), 0.5) # コーナー判定(しきい値は適当) if pow(pow(img_fil_x[y, x],2) + pow(img_fil_y[y, x],2), 0.5) > 255: img_corner_xy[y, x] = pow(pow(img_fil_x[y, x],2) + pow(img_fil_y[y, x],2), 0.5) else: img_corner_xy[x, y] = 0
まとめ
今回はコーナー検出器の概要の勉強と、コーナー検出器を定義通りに雑実装しました。
次回はヘシアンコーナー検出器について勉強・実装をしていきたいと思います。