リモートセンシング画像の制御ドットマッチングアルゴリズムについての一点の考え方(二)
OpenCVを用いてテンプレートマッチングを行う関数matchTemplateについては前述したが,matchTemplate関数の内部処理手順について簡単に説明する.matchTemplate関数のソースコードはOpenCVのソースコードディレクトリの下のmodules/imgproc/src/templmatch.cppファイルにあります.コア関数のコードは次のとおりです(コメントは私が追加したものです).
void matchTemplate( const Mat& _img, const Mat& _templ, Mat& result, int method )
{
CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
//numType ,0 ,1 ,2
//isNormed ,true ,false
int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 :
method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2;
bool isNormed = method == CV_TM_CCORR_NORMED ||
method == CV_TM_SQDIFF_NORMED ||
method == CV_TM_CCOEFF_NORMED;
// , , ,
Mat img = _img, templ = _templ;
if( img.rows < templ.rows || img.cols < templ.cols )
std::swap(img, templ);
CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) &&
img.type() == templ.type() );
//crossCorr DFT ( ), , result
int cn = img.channels();
crossCorr( img, templ, result,
Size(img.cols - templ.cols + 1, img.rows - templ.rows + 1),
CV_32F, Point(0,0), 0, 0);
// , ,
if( method == CV_TM_CCORR )
return;
// 1, ( 1, )
double invArea = 1./((double)templ.rows * templ.cols);
Mat sum, sqsum;
Scalar templMean, templSdv;
double *q0 = 0, *q1 = 0, *q2 = 0, *q3 = 0;
double templNorm = 0, templSum2 = 0;
//
if( method == CV_TM_CCOEFF )
{
integral(img, sum, CV_64F);// の の を める
templMean = mean(templ);//テンプレート の ベクトルの
}
Else//その のマッチングアルゴリズム
{
integral(img, sum, sqsum, CV_64F);// の の と を する
meanStdDev( templ, templMean, templSdv );//テンプレート の ベクトルと ベクトルの
templNorm = CV_SQR(templSdv[0]) + CV_SQR(templSdv[1]) +
CV_SQR(templSdv[2]) + CV_SQR(templSdv[3]);//すべてのチャネルの と
if( templNorm < DBL_EPSILON && method == CV_TM_CCOEFF_NORMED )
{//すべてのチャネルの の が0に しく、 マッチングを する が されている は、
result = Scalar::all(1);
return;
}
templSum2 = templNorm +
CV_SQR(templMean[0]) + CV_SQR(templMean[1]) +
CV_SQR(templMean[2]) + CV_SQR(templMean[3]);//すべてのチャネルの の
if(numType!=1)/マッチング ではなく、テンプレート ベクトルとtemplNormに を り て
{
templMean = Scalar::all(0);
templNorm = templSum2;
}
templSum2/= invArea;
templNorm = sqrt(templNorm);
templNorm/= sqrt(invArea);//care of accuracy here
q0 = (double*)sqsum.data;
q1 = q0 + templ.cols*cn;
q2 = (double*)(sqsum.data + templ.rows*sqsum.step);
q3 = q2 + templ.cols*cn;
}
// , , OpenCV
テスト 、 OpenCVで くと1 Gを える(この きさよりも さいかもしれません)の はエラーになります.OpenCVコードを てみると、 にすべての データをメモリにロードしたことに づき、メモリが しています.また、OpenCVは の な データフォーマットしかサポートしていません.ErdasのimgフォーマットやPCIのpixフォーマットを くことはできません.この2つの に して、 が した は データの み みライブラリとして GDALを い、そしてブロックに けてデータの を み す(1つのサイズを して、 が したのは64 Mのデータを むたびに)、もし データがこのサイズを えるならば、ブロック して、 1つのブロックを して、OpenCVは1つのメモリデータを することができて、 のRGBの を の でメモリの に み って、それからこのポインタをOpenCVに して、OpenCVはこのメモリデータを じて1つの を することができて、それから に しますテンプレートマッチングアルゴリズムを いて した は, の きな に された にある.
の では、 のように であり、 は1 Gのimg で128*128のテンプレートを するのに1 かかり、 のブログのように もスピードが がった(1 Gのデータはおよそ4 されていますが、まだ が わっていません).1 minで べた は できるはずですが、まだ し い じがしますので、まずテンプレートと の を に のサンプリング でピラミッドを り、ピラミッドの からマッチングし、 で つけた から、 の の するエリアへを します.これにより、 くの を らすことができます.テストを て、この を って、やはり の1 Gのデータで、 は10 S で することができて、しかも の もとても です.
プログラムの にGDALのRasteIO を して、 の3つのパラメータを して、 の のデータをOpenCVの の の BGRBGRBGRに み ることができます...
OpenCVについては、 のステップマッチングを う に で する、 する もOpenCVのソースコードディレクトリのmodules/imgproc/src/templmatchにある.cppファイルでは、DFT ( フーリエ )については で、 は に な が で できるが、 のある はgoogleや デジタル の を にすることができ、 なデジタル の にはある.DFTとFFTはデジタル や の で に く われているからだ.
Technoratiラベル:OpenCV、テンプレートマッチング