Cannyアルゴリズムを用いて,画像のエッジを検出します.
パラメタ: |
|
---|
関数 Canny は,Cannyアルゴリズムを用いて入力画像 image 中のエッジを検出し,マップ edges に出力します. threshold1 と threshold2 の内,小さい方の値がエッジの接続に利用され,大きい方の値が明確なエッジの初期セグメントを検出するのに利用されます.詳しくは, http://en.wikipedia.org/wiki/Canny_edge_detector を参照してください.
コーナーを検出するために,画像ブロックの固有値と固有ベクトルを求めます.
パラメタ: |
|
---|
関数 cornerEigenValsAndVecs は,各ピクセル に対して, blockSize blockSize サイズの近傍領域 を考えます.そして,この近傍領域の微分画像の共分散行列を次のように求めます:
ここで,微分画像は Sobel() オペレータを利用して求められます.
その後,共分散行列 の固有値と固有ベクトルを求め,それを出力画像に という形式で格納します.ここで,
となります.
この関数の出力は,ロバストなエッジ検出やコーナー検出に利用できます.
参考: cornerMinEigenVal() , cornerHarris() , preCornerDetect()
Harris エッジ検出器.
パラメタ: |
|
---|
関数 cornerHarris は,画像に対して Harris エッジ検出器を適用します. cornerMinEigenVal() や cornerEigenValsAndVecs() と同様に, サイズの近傍領域全体に渡って勾配の積和を計算することで,ピクセル における の勾配共分散行列 を求めます.次に,そこから次の特徴量を計算します:
画像中のコーナーは,この応答マップの極大点として検出されます.
コーナーを検出するために,勾配行列の最小の固有値を求めます.
パラメタ: |
|
---|
関数 cornerMinEigenVal は, cornerEigenValsAndVecs() と似ていますが,微分画像の共分散行列の最小固有値だけを求めます.つまり, cornerEigenValsAndVecs() の説明にある式の だけを求めます.
コーナー位置を高精度化します.
パラメタ: |
|
---|
関数 cornerSubPix は,以下の図に示されるような,サブピクセル精度のコーナー,あるいは鞍点を検出するために繰り返し処理を行います.
サブピクセル精度のコーナー位置決めは,近傍領域の中心 から,その領域内に位置する点 に向かう各ベクトルが, における(画像自身と観測ノイズに従う)画像勾配と直交する,という考えに基づいています.これは,以下の式で表現されます:
ここで は,近傍領域 内の点 における画像勾配を表します. は,この を最小にする値として求められます. を 0 とすることで連立方程式が得られます:
ここで,画像勾配は の近傍領域(「探索窓」)での総和をとられます.1次勾配を ,2次勾配を とすると,以下の関係が得られます:
このアルゴリズムは,探索窓の中心をこの新しい値 に再設定し,値の変化量が与えられた閾値内に収まるようになるまで繰り返し計算を行います.
画像内の強いコーナーを検出します.
パラメタ: |
|
---|
この関数は, Shi94 で述べられるように,画像中または画像の指定領域内の最も強いコーナーを検出します:
この関数は,点ベースの物体追跡器を初期化するために利用できます.
この関数が,パラメータ qualityLevel に異なる値 A と B を与えられて呼び出され,その時に A > {B} であるとします.その場合,出力コーナー配列において qualityLevel=A で求められたコーナーの配列が, qualityLevel=B で求められたものよりも前に位置することに注意してください.
参考: cornerMinEigenVal() , cornerHarris() , calcOpticalFlowPyrLK() , estimateRigidMotion() , PlanarObjectDetector() , OneWayDescriptor()
ハフ変換を用いて,グレースケール画像から円を検出します.
パラメタ: |
|
---|
関数 houghCircles は,ハフ変換の改良版を用いてグレースケール画像から円を検出します.ここでは,簡単な利用例を示します:
#include <cv.h>
#include <highgui.h>
#include <math.h>
using namespace cv;
int main(int argc, char** argv)
{
Mat img, gray;
if( argc != 2 && !(img=imread(argv[1], 1)).data)
return -1;
cvtColor(img, gray, CV_BGR2GRAY);
// 平滑化を行います.これがないと誤検出が起こりやすくなります.
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
2, gray->rows/4, 200, 100 );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// 円の中心を描画します.
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// 円を描画します.
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
return 0;
}
通常,この関数は円の中心を上手く検出しますが,円の半径については失敗することもある点に注意してください.もし事前知識があれば,半径の範囲( minRadius と maxRadius )を指定することで,これの補助ができます.または,出力された半径は無視して中心だけを利用し,別の追加処理によって正しい半径を求めることもできます.
標準ハフ変換を用いて,2値画像から直線を検出します.
パラメタ: |
|
---|
関数 HoughLines は,直線検出のためのハフ変換,またはマルチスケールハフ変換の実装です.コードの例については, HoughLinesP() を参照してください.
確率的ハフ変換を利用して,2値画像から線分を検出します.
パラメタ: |
|
---|
関数 HoughLinesP は, Matas00 で述べられている,直線検出のための確率的ハフ変換アルゴリズムの実装です.以下に直線検出の例を示します:
/* これは,単独で動作するプログラムです.プログラムの最初の引数として画像ファイル名を渡します.
"#if 1" を "#if 0" に変更したり戻したりすることで,
標準的ハフ変換と確率的ハフ変換を切り替えることができます. */
#include <cv.h>
#include <highgui.h>
#include <math.h>
using namespace cv;
int main(int argc, char** argv)
{
Mat src, dst, color_dst;
if( argc != 2 || !(src=imread(argv[1], 0)).data)
return -1;
Canny( src, dst, 50, 200, 3 );
cvtColor( dst, color_dst, CV_GRAY2BGR );
#if 0
vector<Vec2f> lines;
HoughLines( dst, lines, 1, CV_PI/180, 100 );
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0];
float theta = lines[i][1];
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
Point pt1(cvRound(x0 + 1000*(-b)),
cvRound(y0 + 1000*(a)));
Point pt2(cvRound(x0 - 1000*(-b)),
cvRound(y0 - 1000*(a)));
line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 );
}
#else
vector<Vec4i> lines;
HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
line( color_dst, Point(lines[i][0], lines[i][1]),
Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
}
#endif
namedWindow( "Source", 1 );
imshow( "Source", src );
namedWindow( "Detected Lines", 1 );
imshow( "Detected Lines", color_dst );
waitKey(0);
return 0;
}
サンプル画像.上記のプログラムはこの画像用にパラメータを調整しています:
上記のプログラムにおいて確率的ハフ変換を行った結果:
コーナー検出のための特徴マップを求めます.
パラメタ: |
|
---|
関数 preCornerDetect は,入力画像の,複合偏微分に基づいた写像を求めます.
ここで , は画像の1次微分, , は画像の2次微分, は混合微分です.
次に示すように,コーナーは,この写像の極大値として得られます:
Mat corners, dilated_corners;
preCornerDetect(image, corners, 3);
// 3x3 の矩形構造要素で膨張させます.
dilate(corners, dilated_corners, Mat(), 1);
Mat corner_mask = corners == dilated_corners;
salient point 検出器のためのデータ構造.
KeyPoint
{
public:
// デフォルトコンストラクタ
KeyPoint();
// 2 種類の完全なコンストラクタ
KeyPoint(Point2f _pt, float _size, float _angle=-1,
float _response=0, int _octave=0, int _class_id=-1);
KeyPoint(float x, float y, float _size, float _angle=-1,
float _response=0, int _octave=0, int _class_id=-1);
// 点の座標
Point2f pt;
// 特徴サイズ
float size;
// 度単位であらわされる特徴方向
// (方向が,未定義または計算されない場合は,
// これが負値になります)
float angle;
// 特徴の強さ
// (最も著しい keypoint だけを選択する
// ために利用されます)
float response;
// 特徴が検出された,スケール-空間オクターブ.
// これは,特徴サイズと相関をもちます.
int octave;
// ポイントクラス(特徴分類器や
// 物体検出器で利用されます)
int class_id;
};
// keypoint のベクトルをファイルストレージから読み込み,または書き込み.
void write(FileStorage& fs, const string& name, const vector<KeyPoint>& keypoints);
void read(const FileNode& node, vector<KeyPoint>& keypoints);
Maximally-Stable Extrenal Region 抽出器
class MSER : public CvMSERParams
{
public:
// デフォルトコンストラクタ
MSER();
// すべてのアルゴリズムパラメータを初期化するコンストラクタ
MSER( int _delta, int _min_area, int _max_area,
float _max_variation, float _min_diversity,
int _max_evolution, double _area_threshold,
double _min_margin, int _edge_blur_size );
// 指定した画像上でこの抽出器を走らせると,個々に輪郭
// ( vector<Point>, findContours を参照)としてエンコードされた複数の MSER が返されます.
// オプションマスクは, MSER を検索する対象となる領域を指定します.
void operator()( const Mat& image, vector<vector<Point> >& msers, const Mat& mask ) const;
};
このクラスは,MSER( http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions を参照してください)抽出アルゴリズムの全パラメータをカプセル化します.
画像から SURF を抽出するためのクラス.
class SURF : public CvSURFParams
{
public:
// デフォルトコンストラクタ
SURF();
// すべてのアルゴリズムパラメータを初期化するコンストラクタ
SURF(double _hessianThreshold, int _nOctaves=4,
int _nOctaveLayers=2, bool _extended=false);
// 各ディスクリプタの要素数を返す( 64 または 128 )
int descriptorSize() const;
// 高速なマルチスケール Hesian 検出器を用いて keypoint を検出します.
void operator()(const Mat& img, const Mat& mask,
vector<KeyPoint>& keypoints) const;
// keypoint を検出し,その SURF ディスクリプタを計算します.
void operator()(const Mat& img, const Mat& mask,
vector<KeyPoint>& keypoints,
vector<float>& descriptors,
bool useProvidedKeypoints=false) const;
};
SURF クラスは,SURF ディスクリプタ Bay06 の実装です.(デフォルトでは)keypoint の検出に,高速マルチスケール Hessian keypoint 検出器が利用されます. しかし,ディスクリプタ自体は,ユーザが指定した他の keypoint に対しても計算することができます.この関数は,物体追跡,位置同定,画像の縫い合わせなどに利用できます. OpenCV のサンプルディレクトリにある find_obj.cpp デモを参照してください.
Star keypoint 検出器の実装.
class StarDetector : CvStarDetectorParams
{
public:
// デフォルトコンストラクタ
StarDetector();
// すべてのアルゴリズムパラメータを初期化する完全なコンストラクタ
// maxSize - 特徴の最大サイズ.以下のパラメータの値
// がサポートされます:
// 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
// responseThreshold - 近似ラプラシアンに対する閾値.
// 弱い特徴を除外するために利用されます.大きくなるほど
// 検出される特徴が少なくなります.
// lineThresholdProjected - ラプラシアンに対する別の閾値.
// エッジを除外するために利用されます.
// lineThresholdBinarized - 特徴サイズに対する別の閾値.
// エッジを除外するために利用されます.
// これら2つの閾値が大きくなるほど,検出される特徴点が増えます.
StarDetector(int maxSize, int responseThreshold,
int lineThresholdProjected,
int lineThresholdBinarized,
int suppressNonmaxSize);
// 画像中の keypoints を検出します.
void operator()(const Mat& image, vector<KeyPoint>& keypoints) const;
};
このクラスは, Agrawal08 で述べられる CenSurE keypoint 検出器の改良版の実装です.