エッジ検出のためのCannyアルゴリズムを実行します.
パラメタ: |
|
---|
この関数は,Cannyアルゴリズムを用いて入力画像 image 中のエッジを検出し,出力画像 edges 上に記録します. threshold1 と threshold2 の内,小さい方の値はエッジ同士の接続に利用され,大きい方の値は強いエッジの初期検出に利用されます.
コーナー検出のための,画像の固有値と固有ベクトルを求めます.
パラメタ: |
|
---|
この関数では,まず各ピクセルに対して block_size block_size の近傍領域 S(p) を考えます.そして,以下のように各近傍領域全体に対して導関数の共変動行列を求めます:
この行列の固有ベクトルと固有値を求めて,出力画像に の形式で保存します.ここで,
は, の固有値(ソートされていません),
は, に対応する固有ベクトル,
は, に対応する固有ベクトル
です.
Harrisエッジ検出器.
パラメタ: |
|
---|
この関数は,入力画像に対してHarrisエッジ検出を行います. CornerMinEigenVal や CornerEigenValsAndVecs と同様に,各ピクセルの サイズの近傍領域全体に対して の勾配共変動行列 が求められます.
そして,
が出力画像に格納されます.入力画像中のコーナーは,出力画像における極大点として検出できます.
コーナー検出のための,勾配行列の最小固有値を求めます.
パラメタ: |
|
---|
この関数は,関数 CornerEigenValsAndVecs と似ていますが,これは各ピクセルに対して導関数の共変動行列の最小固有値のみを求めます.つまりそれは,前述の関数の に相当します.
画像からSURF(Speeded Up Robust Features)を抽出します.
パラメタ: |
|
---|
%–
パラメタ: |
|
---|
typedef struct CvSURFPoint
{
CvPoint2D32f pt; // 画像中の特徴点の位置
int laplacian; // -1, 0, +1 .その点におけるラプラシアンの符号.
// 特徴点同士の比較を高速化するために用いられるます
// (通常,ラプラシアンの符号が異なる特徴同士は一致しません).
int size; // 特徴のサイズ
float dir; // 特徴の方向: 0 〜 360度
float hessian; // ヘッシアン:ヘッセ行列の行列式
// (特徴の強さの大まかな推定に用いられます.params.hessianThreshold を参照してください)
}
CvSURFPoint;
パラメタ: |
|
---|
typedef struct CvSURFParams
{
int extended; // 0 :基本的なディスクリプタ(64要素)
// 1 :拡張されたディスクリプタ(128要素)
double hessianThreshold; // keypoint.hessian の値が,
// この閾値よりも大きい特徴だけが検出されます.
// 適切なデフォルト値は,おおよそ 300 〜 500 です
// (画像の平均局所コントラストやシャープネスに依存します).
// ユーザは,ヘッシアンや,その他の特徴に基づいて,
// 不要な特徴点を除去することができます.
int nOctaves; // 特徴検出に用いられるオクターブ数.
// オクターブが一つ上がる度に,特徴のサイズが 2 倍になります(デフォルトは 3 ).
int nOctaveLayers; // 各オクターブ内に存在するレイヤ数(デフォルトは 4 ).
}
CvSURFParams;
CvSURFParams cvSURFParams(double hessianThreshold, int extended=0);
// デフォルトパラメータを返す.
この関数は,画像からロバストな特徴を検出します.詳細は, Boy06 で述べられています.各特徴に対して,位置,サイズ,方向,そして基本あるいは拡張ディスクリプタ(オプション),が返されます.この関数は,物体追跡や位置決定,画像張り合わせなどに利用できます.
OpenCV サンプルディレクトリの find_obj.cpp デモを参照してください.
コーナー位置を高精度化します.
パラメタ: |
|
---|
この関数は,以下の図に示されるような,サブピクセル精度のコーナー,あるいは鞍点を検出するために繰り返し処理を行います.
サブピクセル精度のコーナー位置決めは,近傍領域の中心 から,その領域内に位置する点 に向かう各ベクトルが, における(画像自身と観測ノイズに従う)画像勾配と直交する,という考えに基づいています.これは,以下の式で表現されます:
ここで は,近傍領域 内の点 における画像勾配を表します. は,この を最小にする値として求められます. を 0 とすることで連立方程式が得られます:
ここで,画像勾配は の近傍領域(「探索窓」)での総和をとられます.1次勾配を ,2次勾配を とすると,以下の関係が得られます:
このアルゴリズムは,探索窓の中心をこの新しい値 に再設定し,値の変化量が与えられた閾値内に収まるようになるまで繰り返し計算を行います.
StarDetectorアルゴリズムを用いて,キーポイントを検出します.
パラメタ: |
|
---|
typedef struct CvStarDetectorParams
{
int maxSize; // 検出される特徴の最大サイズ.
// 以下のパラメータの値がサポートされます:
// 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
int responseThreshold; // 近似ラプラシアンに対する閾値,
// 弱い特徴を除外すために利用されます.
int lineThresholdBinarized; // ラプラシアン対する別の閾値
// エッジを除外するために利用されます.
int lineThresholdBinarized; // 特徴スケールに対する閾値
// エッジを除外するために利用されます.
int suppressNonmaxSize; // ピクセルの近傍領域の長さサイズ
// 極大値以外の除外に利用されます.
}
CvStarDetectorParams;
この関数は,キーポイント,つまり局所的スケール空間における極大値を検出します.このスケール空間は,各ピクセルに対して異なるシグマでのラプラシアン近似値を計算することで得られます.計算時間を節約する一般的な手法として画像ピラミッドがありますが,それを利用する代わりに,オリジナル高解像度画像の各ピクセルにおける全ラプラシアンを計算します.しかし,インテグラルイメージを利用することで,各ラプラシアンの近似値の計算量はシグマに関わらずO(1)となります.このアルゴリズムは,[Agrawal08] に基づいています.ただし,関数名からも分かるように,四角形,六角形,八角形の代わりに,まっすぐな正方形と45度傾いた正方形が重なり合った形状である八角星を利用しています.
計算された特徴は,以下の構造体で表現されます:
typedef struct CvStarKeypoint
{
CvPoint pt; // 特徴点の座標
int size; // 特徴のサイズ, CvStarDetectorParams::maxSize を参照してください
float response; // その点におけるラプラシアンの近似値
}
CvStarKeypoint;
inline CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response);
以下は,使い方の簡単なサンプルです:
#include "cv.h"
#include "highgui.h"
int main(int argc, char** argv)
{
const char* filename = argc > 1 ? argv[1] : "lena.jpg";
IplImage* img = cvLoadImage( filename, 0 ), *cimg;
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* keypoints = 0;
int i;
if( !img )
return 0;
cvNamedWindow( "image", 1 );
cvShowImage( "image", img );
cvNamedWindow( "features", 1 );
cimg = cvCreateImage( cvGetSize(img), 8, 3 );
cvCvtColor( img, cimg, CV_GRAY2BGR );
keypoints = cvGetStarKeypoints( img, storage, cvStarDetectorParams(45) );
for( i = 0; i < (keypoints ? keypoints->total : 0); i++ )
{
CvStarKeypoint kpt = *(CvStarKeypoint*)cvGetSeqElem(keypoints, i);
int r = kpt.size/2;
cvCircle( cimg, kpt.pt, r, CV_RGB(0,255,0));
cvLine( cimg, cvPoint(kpt.pt.x + r, kpt.pt.y + r),
cvPoint(kpt.pt.x - r, kpt.pt.y - r), CV_RGB(0,255,0));
cvLine( cimg, cvPoint(kpt.pt.x - r, kpt.pt.y + r),
cvPoint(kpt.pt.x + r, kpt.pt.y - r), CV_RGB(0,255,0));
}
cvShowImage( "features", cimg );
cvWaitKey();
}
画像内の強いコーナーを検出します.
パラメタ: |
|
---|
この関数は,与えられた画像から大きな固有値を持つコーナーを検出します.これはまず,関数 CornerMinEigenVal を利用して入力画像の各ピクセルに対する最小固有値を計算し,それを eigImage に格納します.そして,non-maxima suppression を行います( の近傍領域内において,その極大値のみが残ります).次に, よりも小さな固有値を持つコーナーを棄却します.最後に,あらゆる2つのコーナー同士の距離が minDistance よりも小さくならないようにします.これによって,強い方のコーナーに近すぎる,弱い方のコーナー(最小固有値が小さいコーナー)が削除されます.
この関数が,パラメータ qualityLevel に異なる値 A と B を与えられて呼び出され,その時に A > {B} であるとします.その場合,出力コーナー配列において qualityLevel=A で求められたコーナーの配列が, qualityLevel=B で求められたものよりも前に位置することに注意してください.
ハフ変換を用いて,2値画像から直線を検出します.
パラメタ: |
|
---|
この関数は,線を検出するハフ変換のいくつかのバリエーションの実装です.
Example. Detecting lines with Hough transform.
/* これは,単独で動作するプログラムである.プログラムの最初の引数として画像名を渡します.
"#if 1" を "#if 0" に変更したり戻したりすることで,
標準的ハフ変換と確率的ハフ変換を切り替えることができます. */
#include <cv.h>
#include <highgui.h>
#include <math.h>
int main(int argc, char** argv)
{
IplImage* src;
if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
{
IplImage* dst = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* color_dst = cvCreateImage( cvGetSize(src), 8, 3 );
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
int i;
cvCanny( src, dst, 50, 200, 3 );
cvCvtColor( dst, color_dst, CV_GRAY2BGR );
#if 1
lines = cvHoughLines2( dst,
storage,
CV_HOUGH_STANDARD,
1,
CV_PI/180,
100,
0,
0 );
for( i = 0; i < MIN(lines->total,100); i++ )
{
float* line = (float*)cvGetSeqElem(lines,i);
float rho = line[0];
float theta = line[1];
CvPoint pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
}
#else
lines = cvHoughLines2( dst,
storage,
CV_HOUGH_PROBABILISTIC,
1,
CV_PI/180,
80,
30,
10 );
for( i = 0; i < lines->total; i++ )
{
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
}
#endif
cvNamedWindow( "Source", 1 );
cvShowImage( "Source", src );
cvNamedWindow( "Hough", 1 );
cvShowImage( "Hough", color_dst );
cvWaitKey(0);
}
}
サンプル画像.上記のプログラムはこの画像用にパラメータを調整しています:
上記のプログラムにおいて確率的ハフ変換を行った( #if 0 の場合)結果:
コーナー検出のための特徴マップを求めます.
パラメタ: |
|
---|
この関数は,以下の関数を計算します.
ここで, は1次微分画像, は2次微分画像を表します.
コーナーは,以下のように関数の極大点として計算できます:
// 浮動小数点型の画像であるとします.
IplImage* corners = cvCloneImage(image);
IplImage* dilated_corners = cvCloneImage(image);
IplImage* corner_mask = cvCreateImage( cvGetSize(image), 8, 1 );
cvPreCornerDetect( image, corners, 3 );
cvDilate( corners, dilated_corners, 0, 1 );
cvSubS( corners, dilated_corners, corners );
cvCmpS( corners, 0, corner_mask, CV_CMP_GE );
cvReleaseImage( &corners );
cvReleaseImage( &dilated_corners );
ラスタ表現された線分を読み込み,バッファに書き込みます.
パラメタ: |
|
---|
この関数は,ラインイテレータの応用の一種です.これは, pt1 と pt2 を結ぶ線上にある画像ピクセル(終点を含みます)を全て読み込み,それをバッファに格納します.