特徴検出

cv::Canny

Canny(image, edges, threshold1, threshold2, aperture_size=3) → None

エッジ検出のためのCannyアルゴリズムを実行します.

パラメタ:
  • image (CvArr) – シングルチャンネルの入力画像
  • edges (CvArr) – シングルチャンネルの出力画像,この関数によって検出されたエッジを格納します
  • threshold1 (float) – 1番目の閾値
  • threshold2 (float) – 2番目の閾値
  • aperture_size (int) – Sobelオペレータのアパーチャサイズ( Sobel を参照してください)

この関数は,Cannyアルゴリズムを用いて入力画像 image 中のエッジを検出し,出力画像 edges 上に記録します. threshold1threshold2 の内,小さい方の値はエッジ同士の接続に利用され,大きい方の値は強いエッジの初期検出に利用されます.

cv::CornerEigenValsAndVecs

CornerEigenValsAndVecs(image, eigenvv, blockSize, aperture_size=3) → None

コーナー検出のための,画像の固有値と固有ベクトルを求めます.

パラメタ:
  • image (CvArr) – 入力画像
  • eigenvv (CvArr) – 結果を保存するための画像.入力画像の6倍の幅が必要です
  • blockSize (int) – 近傍領域のサイズ(以下の説明を参照してください)
  • apertureSize – Sobelオペレータのアパーチャサイズ( Sobel を参照してください)

この関数では,まず各ピクセルに対して block_size \times block_size の近傍領域 S(p) を考えます.そして,以下のように各近傍領域全体に対して導関数の共変動行列を求めます:

M =  \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 &  \sum _{S(p)}(dI/dx  \cdot dI/dy)^2  \\ \sum _{S(p)}(dI/dx  \cdot dI/dy)^2 &  \sum _{S(p)}(dI/dy)^2 \end{bmatrix}

この行列の固有ベクトルと固有値を求めて,出力画像に (\lambda_1, \lambda_2, x_1, y_1, x_2, y_2) の形式で保存します.ここで,

  • \lambda_1, \lambda_2

    は, M の固有値(ソートされていません),

  • x_1, y_1

    は, \lambda_1 に対応する固有ベクトル,

  • x_2, y_2

    は, \lambda_2 に対応する固有ベクトル

です.

cv::CornerHarris

CornerHarris(image, harris_dst, blockSize, aperture_size=3, k=0.04) → None

Harrisエッジ検出器.

パラメタ:
  • image (CvArr) – 入力画像
  • harris_dst (CvArr) – 検出結果を保存するための画像. image と同じサイズでなければいけません
  • block_size – 近傍領域サイズ( CornerEigenValsAndVecs の説明を参照してください)
  • aperture_size (int) – Sobelオペレータのアパーチャサイズ( Sobel を参照してください)
  • k (float) – Harris 検出器のパラメータ.後述の式を参照してください

この関数は,入力画像に対してHarrisエッジ検出を行います. CornerMinEigenValCornerEigenValsAndVecs と同様に,各ピクセルの \texttt{block\_size} \times \texttt{block\_size} サイズの近傍領域全体に対して 2\times2 の勾配共変動行列 M が求められます.

そして,

det(M) - k  \, trace(M)^2

が出力画像に格納されます.入力画像中のコーナーは,出力画像における極大点として検出できます.

cv::CornerMinEigenVal

CornerMinEigenVal(image, eigenval, blockSize, aperture_size=3) → None

コーナー検出のための,勾配行列の最小固有値を求めます.

パラメタ:
  • image (CvArr) – 入力画像
  • eigenval (CvArr) – 最小固有値を保存するための画像. image と同じサイズでなければいけません
  • blockSize (int) – 近傍領域サイズ( CornerEigenValsAndVecs の説明を参照してください)
  • apertureSize – Sobelオペレータのアパーチャサイズ( Sobel を参照してください)

この関数は,関数 CornerEigenValsAndVecs と似ていますが,これは各ピクセルに対して導関数の共変動行列の最小固有値のみを求めます.つまりそれは,前述の関数の min(\lambda_1, \lambda_2) に相当します.

CvSURFPoint

class CvSURFPoint

タプル ((x, y), laplacian, size, dir, hessian) で表現される SURF キーポイント

x
画像内の特徴点のx座標
y
画像内の特徴点のy座標
laplacian
-1,0 または +1.その点におけるラプラシアンの符号.ラプラシアンの符号が異なる特徴同士はマッチしないので,特徴点の比較に利用できます
size
特徴のサイズ
dir
特徴の方向:0...360 度
hessian
ヘッシアンの値(特徴の強さの大まかな推定に利用できます.params.hessianThresholdを参照してください)

cv::ExtractSURF

ExtractSURF(image, mask, storage, params)-> (keypoints, descriptors)

画像からSURF(Speeded Up Robust Features)を抽出します.

パラメタ:
  • image (CvArr) – 8ビット,グレースケールの入力画像
  • mask (CvArr) – オプション.8ビットのマスク画像.非0 のマスクピクセルが 50 % 以上を占める領域からのみ,特徴点検出を行います

%–

パラメタ:
  • mask (CvArr) – The optional input 8-bit mask. The features are only found in the areas that contain more than 50 % of non-zero mask pixels
  • keypoints (CvSeq of CvSURFPoint) – キーポイントのシーケンス
  • descriptors (CvSeq of list of float) – ディスクリプタのシーケンス.それぞれの SURF ディスクリプタは,float のリストで,そのサイズは 64 または 128 です
  • storage (CvMemStorage) – キーポイントとディスクリプタが保存されるメモリストレージ
  • params (CvSURFParams) –

    様々なアルゴリズムパラメータを表すタプル (extended, hessianThreshold, nOctaves, nOctaveLayers)

    • extended 0 は通常のディスクリプタ(64要素)を,1 は拡張ディスクリプタ(128要素)を,それぞれ意味します
    • hessianThreshold この値よりも大きなヘッシアン値をもつ特徴のみが抽出されます.適切なデフォルト値は,おおよそ 300 〜 500 です(画像の平均局所コントラストやシャープネスに依存します).ユーザは,ヘッシアンやその他の特徴に基づいて,不要な特徴点を除去することができます
    • nOctaves 特徴検出に用いられるオクターブ数. オクターブが一つ上がる度に,特徴のサイズが 2 倍になります(デフォルトは 3 )
    • nOctaveLayers 各オクターブ内に存在するレイヤ数(デフォルトは 4 )

この関数は,画像からロバストな特徴を検出します.詳細は, Boy06 で述べられています.各特徴に対して,位置,サイズ,方向,そして基本あるいは拡張ディスクリプタ(オプション),が返されます.この関数は,物体追跡や位置決定,画像張り合わせなどに利用できます.

画像から強い SURF 特徴を抽出するには,次のようにします.

>>> import cv
>>> im = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
>>> (keypoints, descriptors) = cv.ExtractSURF(im, None, cv.CreateMemStorage(), (0, 30000, 3, 1))
>>> print len(keypoints), len(descriptors)
6 6
>>> for ((x, y), laplacian, size, dir, hessian) in keypoints:
...     print "x=%d y=%d laplacian=%d size=%d dir=%f hessian=%f" % (x, y, laplacian, size, dir, hessian)
x=30 y=27 laplacian=-1 size=31 dir=69.778503 hessian=36979.789062
x=296 y=197 laplacian=1 size=33 dir=111.081039 hessian=31514.349609
x=296 y=266 laplacian=1 size=32 dir=107.092300 hessian=31477.908203
x=254 y=284 laplacian=1 size=31 dir=279.137360 hessian=34169.800781
x=498 y=525 laplacian=-1 size=33 dir=278.006592 hessian=31002.759766
x=777 y=281 laplacian=1 size=70 dir=167.940964 hessian=35538.363281

cv::FindCornerSubPix

FindCornerSubPix(image, corners, win, zero_zone, criteria) → corners

コーナー位置を高精度化します.

パラメタ:
  • image (CvArr) – 入力画像
  • corners (sequence of (float, float)) – (x, y)ペアのリストで表される,入力コーナーの初期座標
  • win (CvSize) – 探索窓の半分のサイズ.例えば, win =(5,5)の場合,5*2+1 \times 5*2+1 = 11 \times 11 サイズの探索窓が利用されます
  • zero_zone (CvSize) – 探索領域の中心に存在する対象外領域(後述の式において総和を計算する際に含まれない)の半分のサイズ.この値は,自己相関行列において発生しうる特異点を避けるために用いられます. 値が(-1,-1) の場合は,そのようなサイズはないということを意味します
  • criteria (CvTermCriteria) – コーナー位置高精度化のための繰り返し処理の停止基準.つまり,この繰り返し処理は,規定回数に達するか要求精度に達したときに停止します. criteria は,最大反復数と要求精度のどちらか,あるいは両方を指定します

この関数は,以下の図に示されるような,サブピクセル精度のコーナー,あるいは鞍点を検出するために繰り返し処理を行います.

高精度化された座標が (x, y) ペアのリストとして返されます.

_images/cornersubpix.png

サブピクセル精度のコーナー位置決めは,近傍領域の中心 q から,その領域内に位置する点 p に向かう各ベクトルが, p における(画像自身と観測ノイズに従う)画像勾配と直交する,という考えに基づいています.これは,以下の式で表現されます:

\epsilon _i = {DI_{p_i}}^T  \cdot (q - p_i)

ここで {DI_{p_i}} は,近傍領域 q 内の点 p_i における画像勾配を表します. q は,この \epsilon_i を最小にする値として求められます. \epsilon_i を 0 とすることで連立方程式が得られます:

\sum _i(DI_{p_i}  \cdot {DI_{p_i}}^T) q =  \sum _i(DI_{p_i}  \cdot {DI_{p_i}}^T  \cdot p_i)

ここで,画像勾配は q の近傍領域(「探索窓」)での総和をとられます.1次勾配を G ,2次勾配を b とすると,以下の関係が得られます:

q = G^{-1}  \cdot b

このアルゴリズムは,探索窓の中心をこの新しい値 q に再設定し,値の変化量が与えられた閾値内に収まるようになるまで繰り返し計算を行います.

cv::GetStarKeypoints

GetStarKeypoints(image, storage, params) → keypoints

StarDetectorアルゴリズムを用いて,キーポイントを検出します.

パラメタ:
  • image (CvArr) – 8ビット,グレースケールの入力画像
  • storage (CvMemStorage) – キーポイントが保存されるメモリストレージ
  • params (CvStarDetectorParams) –

    様々なアルゴリズムパラメータを表すタプル (maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize) :

    • maxSize 検出される特徴の最大サイズ.次のパラメータの値がサポートされます: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
    • responseThreshold 近似ラプラシアンに対する閾値.弱い特徴を除外すために利用されます
    • lineThresholdProjected ラプラシアンに対する別の閾値.エッジを除外するために利用されます
    • lineThresholdBinarized 特徴スケールに対する閾値.エッジを除外するために利用されます
    • suppressNonmaxSize ピクセルの近傍領域の長さサイズ.極大値以外の除外に利用されます

この関数は,キーポイント,つまり局所的スケール空間における極大値を検出します.このスケール空間は,各ピクセルに対して異なるシグマでのラプラシアン近似値を計算することで得られます.計算時間を節約する一般的な手法として画像ピラミッドがありますが,それを利用する代わりに,オリジナル高解像度画像の各ピクセルにおける全ラプラシアンを計算します.しかし,インテグラルイメージを利用することで,各ラプラシアンの近似値の計算量はシグマに関わらずO(1)となります.このアルゴリズムは,[Agrawal08] に基づいています.ただし,関数名からも分かるように,四角形,六角形,八角形の代わりに,まっすぐな正方形と45度傾いた正方形が重なり合った形状である八角星を利用しています.

それぞれのキーポイントは,タプル ((x, y), size, response) で表現されます:

  • x, y キーポイントのスクリーン座標
  • size 特徴のサイズ. maxSize 以下
  • response キーポイントの近似ラプラシアン値

cv::GoodFeaturesToTrack

GoodFeaturesToTrack(image, eigImage, tempImage, cornerCount, qualityLevel, minDistance, mask=NULL, blockSize=3, useHarris=0, k=0.04) → corners

画像内の強いコーナーを検出します.

パラメタ:
  • image (CvArr) – 8ビット,または32ビット浮動小数点型シングルチャンネルの入力画像
  • eigImage (CvArr) – 32ビット浮動小数点型のテンポラリ画像.サイズは image と同じです
  • tempImage (CvArr) – 別のテンポラリ画像.サイズ・フォーマットともに eig_image と同じです
  • cornerCount (int) – 検出されたコーナーの数
  • qualityLevel (float) – 最大固有値,最小固有値に乗ずる定数.これは,検出される画像コーナーの許容最低品質を指定します
  • minDistance (float) – 検出されるコーナー間の許容最小距離.ユークリッド距離が用いられます
  • mask (CvArr) – ROI.関数は,この指定領域内から点を選択しますが,NULLならば画像全体から選択します
  • blockSize (int) – 平均化ブロックサイズ.この関数内部で利用される CornerMinEigenValCornerHarris に渡される値です
  • useHarris (int) – 0でない場合は,デフォルトの CornerMinEigenVal の代わりに Harris オペレータ( CornerHarris )が利用されます
  • k (float) – Harris 検出器のパラメータ. ( \texttt{use\_harris} != 0 ) の場合にのみ用いられます

この関数は,与えられた画像から大きな固有値を持つコーナーを検出します.これはまず,関数 CornerMinEigenVal を利用して入力画像の各ピクセルに対する最小固有値を計算し,それを eigImage に格納します.そして,non-maxima suppression を行います( 3\times 3 の近傍領域内において,その極大値のみが残ります).次に, \texttt{qualityLevel} \cdot max(\texttt{eigImage}(x,y)) よりも小さな固有値を持つコーナーを棄却します.最後に,あらゆる2つのコーナー同士の距離が minDistance よりも小さくならないようにします.これによって,強い方のコーナーに近すぎる,弱い方のコーナー(最小固有値が小さいコーナー)が削除されます.

この関数が,パラメータ qualityLevel に異なる値 AB を与えられて呼び出され,その時に A > {B} であるとします.その場合,出力コーナー配列において qualityLevel=A で求められたコーナーの配列が, qualityLevel=B で求められたものよりも前に位置することに注意してください.

cv::HoughLines2

HoughLines2(image, storage, method, rho, theta, threshold, param1=0, param2=0) → lines

ハフ変換を用いて,2値画像から直線を検出します.

パラメタ:
  • image (CvArr) – 入力画像.8ビット,シングルチャンネル,2値.確率的手法の場合は,この画像は関数により書き換えられます
  • storage (CvMemStorage) – 検出された線を保存するストレージ.これは,メモリストレージ(この場合,ストレージ内に線のシーケンスが作成され,そのポインタがこの関数によって返されます),あるいは,線のパラメータが書き込まれる特定の型(後述の説明を参照してください)を持つ1列あるいは1行の行列(CvMat*)です.その行列のヘッダの colsrows は,検出された線の個数を表すようにこの関数によって書き換えられます.また, storage が行列であり,かつ実際の線の個数が行列のサイズを越えていた場合,行列に収まる線の最大数が返されます(標準的ハフ変換の場合,線は投票数によってソートされます)
  • method (int) –

    ハフ変換のバリエーション,以下のうちの1つ:

    • CV_HOUGH_STANDARD 古典的,あるいは標準的ハフ変換.各直線は,2つの浮動小数点数 (\rho, \theta) で表現されます.ここで, \rho は点(0,0)から直線までの距離, \theta はx軸と直線の法線が成す角度を表します.したがって,行列のデータは必ず CV_32FC2 型でなければいけません(作成されるシーケンスもそうなります)
    • CV_HOUGH_PROBABILISTIC 確率的ハフ変換(数本の長い線分を含むだけの写真の場合,より効率的です).この場合,関数は直線全体ではなく線分を返します.各線分は始点と終点で表現されるので,行列のデータは必ず CV_32SC4 型でなければいけません(作成されるシーケンスもそうなります)
    • CV_HOUGH_MULTI_SCALE 古典的ハフ変換のマルチスケール版.直線は, CV_HOUGH_STANDARD の場合と同じようにエンコードされます
  • rho (float) – ピクセルに依存した単位で表される距離分解能
  • theta (float) – ラジアン単位で表される角度分解能
  • threshold (int) – 閾値パラメータ.その投票数がこの threshold よりも大きい線のみが返されます
  • param1 (float) –

    手法依存の1番目のパラメータ:

    • 古典的ハフ変換では使用されません(0)
    • 確率的ハフ変換では,線分長の最小値を表します
    • マルチスケールハフ変換では,距離分解能 \rho に対する除数を表します(粗い分解能は \rho となり,細かい分解能は (\rho / \texttt{param1}) となります)
  • param2 (float) –

    手法依存の2番目のパラメータ:

    • 古典的ハフ変換では使用されません(0)
    • 確率的ハフ変換では,同一線上に存在する線分として扱うための(つまり,それらを統合しても問題ない),2つの線分間距離の最大値を表します
    • マルチスケールハフ変換では,角度分解能 \theta に対する除数を表します(粗い分解能は \theta となり,細かい分解能は (\theta / \texttt{param2}) となります)

この関数は,線を検出するハフ変換のいくつかのバリエーションの実装です.

cv::PreCornerDetect

PreCornerDetect(image, corners, apertureSize=3) → None

コーナー検出のための特徴マップを求めます.

パラメタ:
  • image (CvArr) – 入力画像
  • corners (CvArr) – コーナー候補を保存するための画像
  • apertureSize (int) – Sobelオペレータのアパーチャサイズ( Sobel を参照してください)

この関数は,以下の関数を計算します.

D_x^2 D_{yy} + D_y^2 D_{xx} - 2 D_x D_y D_{xy}

ここで, D_? は1次微分画像, D_{??} は2次微分画像を表します.

コーナーは,以下のように関数の極大点として計算できます:

import cv

def precornerdetect(image):
    # assume that the image is floating-point 
    corners = cv.CloneMat(image)
    cv.PreCornerDetect(image, corners, 3)

    dilated_corners = cv.CloneMat(image)
    cv.Dilate(corners, dilated_corners, None, 1)

    corner_mask = cv.CreateMat(image.rows, image.cols, cv.CV_8UC1)
    cv.Sub(corners, dilated_corners, corners)
    cv.CmpS(corners, 0, corner_mask, cv.CV_CMP_GE)
    return (corners, corner_mask)