FPM 特徴点応用マッチング(従来版)

Classes

ClassDescription
Public classCFviFPM
特徴点応用マッチングクラス
Public classCFviFPMCorrelationEdge
特徴点応用マッチングクラス(相関エッジフィルタ)
Public classCFviFPMData
特徴点応用マッチングデータ構造クラス
Public classCFviFPMParam
特徴点応用マッチングパラメータクラス
Public classCFviFPMParamAreaScore
特徴点応用マッチングパラメータクラス(領域スコア算出用)
Public classCFviFPMParamCorrelationEdge
特徴点応用マッチングパラメータクラス(相関エッジフィルタ用)
Public classCFviFPMParamRefine
特徴点応用マッチングパラメータクラス(高精度ポーズ推定用)
Public classCFviFPMParamSobel
特徴点応用マッチングパラメータクラス(ソーベルフィルタ用)
Public classCFviFPMResult
特徴点応用マッチング結果クラス
Public classCFviFPMSobel
特徴点応用マッチングクラス(ソーベルフィルタ)
Public classErrorCode
エラーコード(特徴点応用マッチング関連)

Enumerations

EnumerationDescription
Public enumerationCenterMarkAutoFlag
回答基準点自動取得実行指示フラグ
Public enumerationExecuteAreaScoreFlag
領域スコア算出実行指示フラグ
Public enumerationExecuteFlag
高精度ポーズ推定実行指示フラグ
Public enumerationMatchMode
マッチング処理モード

Remarks

ここには、特徴点応用マッチング関連のクラスを集約しています。

ここに集約されたクラスは過去のバージョンとの互換性の為に残されているものです。 新しい開発では FVIL.FPM2 ネームスペースに集約された 特徴点応用マッチング(FIE版) を使用すること推奨します。


トピック:


解説:

FPM は、対象物の輪郭が形成するエッジ分布を特徴量とし、多数決方式により一致度を評価するサーチ手法です。 機能面では平行移動、回転、スケール変化を扱うことが可能で、 一部の特徴量に欠損があっても変換パラメータ(平行移動、回転、スケール変化)の推定結果に影響を与えません。

本ライブラリの長所として次が挙げられます。

  • 平行移動、回転、スケール変化を扱うことができる
  • 汚れの付着による欠損の影響を受けない
  • 対象物の一部が視野外にあっても探索が可能
  • シェーディングの影響を受けにくい
  • オンライン時の光量変化に応じてパラメータを調整する必要がほとんどない
  • ボケによる精度の低下を抑制
  • 対象物のコントラストが低い場合のノイズの影響を低減
  • 特定形状以外でも安定した探索を実現
  • 処理時間変動の抑制

逆に短所としては次が挙げられます。
  • (光量の加減による)太り細りの影響を受ける

同様のサーチ機能を持つライブラリとして、
正規化相関サーチ があります。
FPM は正規化相関サーチに比べて次の点で優れています。
  • パターンの回転、スケール変化に対応できる
  • シェーディング、背景の変化の影響を受けない
  • 汚れの付着による欠損があっても影響を受けない
  • 対象物の一部が視野外にあっても探索が可能

逆に次の点では正規化相関サーチの方が優れています。
  • 処理時間が非常に高速である


詳細については、別冊の画像処理解説書をご参照ください。

[↑戻る]


構成:

この機能の本体は、基本クラスと2種類の派生クラスで構成されます。 派生クラスは、特徴点の抽出に使用するフィルタの違いによって分類されています。

  • 本体:
    クラス内容
    CFviFPM特徴点応用マッチングの基本クラスです。
    CFviFPMCorrelationEdge特徴点の抽出に相関エッジフィルタを使用します。
    CFviFPMSobel特徴点の抽出にソーベルフィルタを使用します。
  • データ構造:
    クラスデータID内容
    CFviFPMData13001件分のマッチングデータを格納するクラスです。下記の CFviFPMResult から取得できます。
    CFviFPMResult1301マッチングの結果を格納するクラスです。
    CFviFPMParam1302基本的なパラメータを保有するクラスです。
    CFviFPMParamRefine1303高精度ポーズ推定用のパラメータを保有するクラスです。
    CFviFPMParamAreaScore1304領域スコア算出用のパラメータを保有するクラスです。
    CFviFPMParamCorrelationEdge1305相関エッジフィルタ用のパラメータを保有するクラスです。CFviFPMCorrelationEdge で使用します。
    CFviFPMParamSobel1306ソーベルフィルタ用のパラメータを保有するクラスです。CFviFPMSobel で使用します。
  • データ構造: (マッチングテンプレート)
    クラスデータID内容
    CFviPattern101処理対象画像とマッチングを行う為のテンプレート画像を格納するオブジェクトです。

[↑戻る]


コンポーネント:

特徴点応用マッチングの基本クラス(CFviFPM)は、 マッチング対象の濃淡画像(CFviImage)と マッチングを行う為のマッチングテンプレート(CFviPattern)を要求し、 マッチング結果を格納するオブジェクト(CFviFPMResult)を提供します。 マッチング対象の濃淡画像とマッチングテンプレートは、実行前にユーザが設定する必要があります。 各種パラメータは、本体の内部に保有しており、設定を変更するか否かは任意です。 設定を変更する場合は、以下のプロパティを介して行えます。

プロパティ備考
Param基本的なパラメータです。
ParamRefine 高精度ポーズ推定用のパラメータです。
ExecuteFlagOff の時は使用されません。
ParamAreaScore 領域スコア算出用のパラメータです。
ExecuteAreaScoreFlagOff の時は使用されません。

但し、CFviFPM クラスは抽象クラスですので、インスタンスの生成は行えません。 実際の処理は以下の派生クラスで実装されています。 これらのクラスは、特徴点の抽出に使用するフィルタの違いによって分類されています。


  • 相関エッジフィルタ:
    クラス内容
    CFviFPMCorrelationEdgeCFviFPM から派生したクラスです。
    CFviFPMParamCorrelationEdge 特徴点の抽出で使用するパラメータを保有するクラスです。
    本体の ParamEdge プロパティからインスタンスを取得できます。
  • ソーベルフィルタ:
    クラス内容
    CFviFPMSobelCFviFPM から派生したクラスです。
    CFviFPMParamSobel 特徴点の抽出で使用するパラメータを保有するクラスです。
    本体の ParamEdge プロパティからインスタンスを取得できます。

パタンオープン後に 特徴点の抽出で使用するパラメータ を変更した場合は、 OpenPattern メソッドで再度パタンオープンを行ってください。

[↑戻る]

Examples

サンプルコード (相関エッジフィルタ):

CFviFPMCorrelationEdge を使用したマッチング処理の例を示します。
マッチングテンプレート(FVIL.Data.CFviPattern)は、 処理対象画像から
MakePattern(CFviImage, CFviRectangle, CFviPoint) を行って保存していたものを使用しています。 マッチングテンプレートの生成やファイル保存については、 CFviPattern のサンプルコードを参考にしてください。
処理結果の画像下に記述している処理時間は、Pentium4 3.2GHz 1.0GB RAM で実行した時のものです。 画像サイズは 320x240 です。処理対象画像の状態やパラメータの設定内容によって速度は変化します。


1) 線幅が細い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM.Search_CorrelationEdge(0,1)
edges=103
execute. 23.988 msec, count=5 

【パラメータ調整】
項目メンバ
局所領域サイズ(横方向)3RegionWidth
局所領域サイズ(縦方向)3RegionHeight
非極大抑制処理のフィルタ片幅1NmsLength

【参考】
下図は、 CFviEdge2DCorrelation によって検出したエッジ点とエッジ強度です。
上段が既定値で実行した場合、下段が前述のパラメータ調整値で実行した場合です。
対象物の線幅が細いので既定値では正確に検出できません。

エッジ点エッジ強度マッチング結果
  • 注) エッジ検出で使用している相関エッジフィルタは、FPM で使用している処理コードとは物理的に別物ですので、 同一のパラメータを指定しても処理結果が同一にならない場合があります。ここでは目安として使用しています。

2) 線幅が太い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM.Search_CorrelationEdge(1,2)
edges=101
execute. 5.046 msec, count=3 

【パラメータ調整】
項目メンバ
局所領域サイズ(横方向)17RegionWidth
局所領域サイズ(縦方向)5RegionHeight
非極大抑制処理のフィルタ片幅6NmsLength
【参考】
下図は、 CFviEdge2DCorrelation によって検出したエッジ点とエッジ強度です。
上段が既定値で実行した場合、下段が前述のパラメータ調整値で実行した場合です。
対象物の線幅が太いので既定値でも輪郭が抽出できています。 逆に下段は局所領域サイズを大きくした為に背景(影)のエッジを拾っています。 これを防ぐには、 分散閾値 を上げる必要があります。

エッジ点エッジ強度マッチング結果
  • 注) エッジ検出で使用している相関エッジフィルタは、FPM で使用している処理コードとは物理的に別物ですので、 同一のパラメータを指定しても処理結果が同一にならない場合があります。ここでは目安として使用しています。

ソースコード:

上記 1) の処理は、下記の関数に引数 0,1 を指定して実行したものです。 2) の処理は、引数 1,2 を指定して実行したものです。

C# Copy imageCopy
//    $Revision: 1.3 $

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using fvalgcli;    // FvPluginXXXX attribute requires fvalgcli

namespace User.SampleCode
{
    public partial class FPM
    {
        /// <summary>
        /// 0,0:clip,WxH=13x5,Nms=6
        /// </summary>
        [FvPluginExecute]
        public void Search_CorrelationEdge00()
        {
            Search_CorrelationEdge(0, 0);    // 0,0:clip,WxH=13x5,Nms=6
        }

        /// <summary>
        /// 0,1:clip,WxH=3x3,Nms=1
        /// </summary>
        [FvPluginExecute]
        public void Search_CorrelationEdge01()
        {
            Search_CorrelationEdge(0, 1);    // 0,1:clip,WxH=3x3,Nms=1
        }

        /// <summary>
        /// 1,0:key,WxH=13x5,Nms=6
        /// </summary>
        [FvPluginExecute]
        public void Search_CorrelationEdge10()
        {
            Search_CorrelationEdge(1, 0);    // 1,0:key,WxH=13x5,Nms=6
        }

        /// <summary>
        /// 1,2:key,WxH=17x5,Nms=6
        /// </summary>
        [FvPluginExecute]
        public void Search_CorrelationEdge12()
        {
            Search_CorrelationEdge(1, 2);    // 1,2:key,WxH=17x5,Nms=6
        }

        /// <summary>
        /// マッチング実行 (相関エッジ)
        /// </summary>
        /// <param name="target">0=clip、1=key1</param>
        /// <param name="option">0=13x5(Nms=6)、1=3x3(Nms=1)、2=17x5(Nms=6)</param>
        public void Search_CorrelationEdge(int target, int option)
        {
            System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
            Console.WriteLine("{0}.{1}({2},{3})", method.DeclaringType.FullName, method.Name, target, option);

            // 1) インスタンスの準備.
            FVIL.FPM.CFviFPMCorrelationEdge parser = new FVIL.FPM.CFviFPMCorrelationEdge();
            FVIL.Data.CFviImage src = new FVIL.Data.CFviImage();
            FVIL.Data.CFviPattern pattern = new FVIL.Data.CFviPattern();

            // 2-1) 処理対象画像の取り込み.
            System.String[]    szSrcFile =
            {
                Defs.TestImageDir + "/clip_UC8_M.png",
                Defs.TestImageDir + "/key_UC8_M.png",
            };
            FVIL.File.Function.LoadImageFile( szSrcFile[target], src, FVIL.PixelMode.Unpacking );

            // 2-2) パタン画像の読み込み.
            System.String[]    szPatFile =
            {
                Defs.TestImageDir + "/clip.pat",
                Defs.TestImageDir + "/key1.pat",
            };
            pattern.Load( szPatFile[target] );

            // 3) 処理対象画像の有効性検査.
            if( FVIL.ErrorCode._SUCCESS != FVIL.FPM.CFviFPMCorrelationEdge.CheckValidity( src ) ) return;
            if( FVIL.ErrorCode._SUCCESS != FVIL.FPM.CFviFPMCorrelationEdge.CheckValidity( pattern ) ) return;

            // 4) 画像処理準備.
            // --- 処理対象画像と結果格納用オブジェクトの設定.
            parser.SrcImages[0] = src;

            // 
            // ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            // 

            // 5-1) パラメータ設定 (本体)
            parser.ExecuteFlag = FVIL.FPM.ExecuteFlag.On;        // [ ] 高精度ポーズ推定 (1:行う)
                                                                // [ ] 領域スコア算出 (0:行わない)
            parser.ExecuteAreaScoreFlag = FVIL.FPM.ExecuteAreaScoreFlag.Off;
            parser.MatchMode = FVIL.FPM.MatchMode.HighSpeed;    // [*] 処理モード (1:高速モード)
                                                                // [ ] 回答基準点自動取得の実行指示 (0:手動)
            parser.CenterMarkAutoFlag = FVIL.FPM.CenterMarkAutoFlag.Manual;

            // 5-2) パラメータ設定 (基本)
            FVIL.FPM.CFviFPMParam param = parser.Param;
            param.Count = 10;                        // [*] 検索個数.
            param.AngleMin = new FVIL.Data.CFviAngle(-180);    // [ ] 回転角(下限)
            param.AngleMax = new FVIL.Data.CFviAngle(180);    // [ ] 回転角(上限)
            param.ScaleMin = 100;                    // [ ] スケール(下限) (%)
            param.ScaleMax = 100;                    // [ ] スケール(上限) (%)
            param.CompressionLevel = 3;                // [ ] 圧縮レベル (3: 1/8)  
            param.ErrorRange = 1;                    // [ ] 誤差範囲 (画素)
            param.ScoreThresholdL = 50;                // [ ] 低圧縮処理時のスコア閾値.
            param.ScoreThresholdH = 50;                // [ ] 高圧縮処理時のスコア閾値.

            // 5-3) パラメータ設定 (高精度ポーズ推定用)
            FVIL.FPM.CFviFPMParamRefine paramR = parser.ParamRefine;
            paramR.ErrorRange = 1;                    // [ ] 誤差範囲 (画素)
            paramR.ScoreThreshold = 60;                // [ ] スコア閾値 (高精度ポーズ推定時)

            // 5-4) パラメータ設定 (領域スコア算出用)
            FVIL.FPM.CFviFPMParamAreaScore paramA = parser.ParamAreaScore;
            paramA.ErrorRangeTx = 0.5;                // [ ] 誤差範囲(X方向並進値) (画素) 
            paramA.ErrorRangeTy = 0.5;                // [ ] 誤差範囲(Y方向並進値) (画素)
            paramA.ErrorRangeTq = 0.5;                // [ ] 誤差範囲(回転角) (度)
            paramA.ErrorRangeTs = 0.5;                // [ ] 誤差範囲(スケール) (%)
            paramA.ErrorRange = 1;                    // [ ] 誤差範囲 (画素)
            paramA.NoiseWeight = 0.2;                // [ ] ノイズデータ重み係数.
            paramA.ScoreThreshold = 60;                // [ ] スコア閾値 (領域スコア算出時)

            // 5-5) パラメータ設定 (エッジ検出処理用)
            FVIL.FPM.CFviFPMParamCorrelationEdge paramE = parser.ParamEdge;
            paramE.RegionWidth = 13;                // [ ] 局所領域サイズ(横方向)
            paramE.RegionHeight = 5;                // [ ] 局所領域サイズ(縦方向)
            paramE.SigmoidK = 1.0;                    // [ ] シグモイド関数パラメータ. 
            paramE.VarThreshold = 25.0;                // [ ] 分散閾値.
            paramE.EdgeThreshold = 160;                // [ ] エッジ強度値に対する閾値.
            paramE.NmsLength = 6;                    // [ ] 非極大抑制処理のフィルタ片幅.

            switch( option )
            {
                case 0:        // default
                    break;
                case 1:        // WxH=3x3,Nms=1 (線幅が細い画像)
                    paramE.RegionWidth = 3;            // [*] 局所領域サイズ(横方向)
                    paramE.RegionHeight = 3;        // [*] 局所領域サイズ(縦方向)
                    paramE.NmsLength = 1;            // [*] 非極大抑制処理のフィルタ片幅.
                    break;
                case 2:        // WxH=17x5,Nms=6 (線幅が太い画像)
                    paramE.RegionWidth = 17;        // [*] 局所領域サイズ(横方向)
                    paramE.RegionHeight = 5;        // [ ] 局所領域サイズ(縦方向)
                    paramE.NmsLength = 6;            // [ ] 非極大抑制処理のフィルタ片幅.
                    break;
            }

            // 5-E) サーチパタンのオープン.
            parser.OpenPattern( pattern );

            // 確認用) パタンのエッジ点.
            {
                List<FVIL.Edge.CFviEdgeData> edges = parser.GetPatternEdges();
                Console.WriteLine("edges={0}", edges.Count);
            }

            // 6) 画像処理実行.
            FVIL.CFviTimeCounter timer = new FVIL.CFviTimeCounter();
            timer.Start();
            parser.Execute();
            double msec = timer.Stop();
            Console.WriteLine("execute. {0} msec, count={1} ", msec.ToString("0.###"), parser.Result.Count);

            // E) 確認用.
            System.String filename = Defs.ResultDir + "/" + System.String.Format("FPM.Search_CorrelationEdge-{0}_{1}.png", target, option);
            SaveResult(src, pattern, parser.Result, filename);
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports fvalgcli
' FvPluginXXXX attribute requires fvalgcli
Namespace SampleCode
    Public Partial Class FPM
        ''' <summary>
        ''' 0,0:clip,WxH=13x5,Nms=6
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_CorrelationEdge00()
            Search_CorrelationEdge(0, 0)
            ' 0,0:clip,WxH=13x5,Nms=6
        End Sub

        ''' <summary>
        ''' 0,1:clip,WxH=3x3,Nms=1
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_CorrelationEdge01()
            Search_CorrelationEdge(0, 1)
            ' 0,1:clip,WxH=3x3,Nms=1
        End Sub

        ''' <summary>
        ''' 1,0:key,WxH=13x5,Nms=6
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_CorrelationEdge10()
            Search_CorrelationEdge(1, 0)
            ' 1,0:key,WxH=13x5,Nms=6
        End Sub

        ''' <summary>
        ''' 1,2:key,WxH=17x5,Nms=6
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_CorrelationEdge12()
            Search_CorrelationEdge(1, 2)
            ' 1,2:key,WxH=17x5,Nms=6
        End Sub

        ''' <summary>
        ''' マッチング実行 (相関エッジ)
        ''' </summary>
        ''' <param name="target">0=clip、1=key1</param>
        ''' <param name="option">0=13x5(Nms=6)、1=3x3(Nms=1)、2=17x5(Nms=6)</param>
        Public Sub Search_CorrelationEdge(target As Integer, [option] As Integer)
            Dim method As System.Reflection.MethodBase = System.Reflection.MethodBase.GetCurrentMethod()
            Console.WriteLine("{0}.{1}({2},{3})", method.DeclaringType.FullName, method.Name, target, [option])

            ' 1) インスタンスの準備.
            Dim parser As New FVIL.FPM.CFviFPMCorrelationEdge()
            Dim src As New FVIL.Data.CFviImage()
            Dim pattern As New FVIL.Data.CFviPattern()

            ' 2-1) 処理対象画像の取り込み.
            Dim szSrcFile As System.String() = {Defs.TestImageDir & "/clip_UC8_M.png", Defs.TestImageDir & "/key_UC8_M.png"}
            FVIL.File.[Function].LoadImageFile(szSrcFile(target), src, FVIL.PixelMode.Unpacking)

            ' 2-2) パタン画像の読み込み.
            Dim szPatFile As System.String() = {Defs.TestImageDir & "/clip.pat", Defs.TestImageDir & "/key1.pat"}
            pattern.Load(szPatFile(target))

            ' 3) 処理対象画像の有効性検査.
            If FVIL.ErrorCode._SUCCESS <> FVIL.FPM.CFviFPMCorrelationEdge.CheckValidity(src) Then
                Return
            End If
            If FVIL.ErrorCode._SUCCESS <> FVIL.FPM.CFviFPMCorrelationEdge.CheckValidity(pattern) Then
                Return
            End If

            ' 4) 画像処理準備.
            ' --- 処理対象画像と結果格納用オブジェクトの設定.
            parser.SrcImages(0) = src

            ' 
            ' ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            ' 

            ' 5-1) パラメータ設定 (本体)
            parser.ExecuteFlag = FVIL.FPM.ExecuteFlag.[On]
            ' [ ] 高精度ポーズ推定 (1:行う)
            ' [ ] 領域スコア算出 (0:行わない)
            parser.ExecuteAreaScoreFlag = FVIL.FPM.ExecuteAreaScoreFlag.Off
            parser.MatchMode = FVIL.FPM.MatchMode.HighSpeed
            ' [*] 処理モード (1:高速モード)
            ' [ ] 回答基準点自動取得の実行指示 (0:手動)
            parser.CenterMarkAutoFlag = FVIL.FPM.CenterMarkAutoFlag.Manual

            ' 5-2) パラメータ設定 (基本)
            Dim param As FVIL.FPM.CFviFPMParam = parser.Param
            param.Count = 10
            ' [*] 検索個数.
            param.AngleMin = New FVIL.Data.CFviAngle(-180)
            ' [ ] 回転角(下限)
            param.AngleMax = New FVIL.Data.CFviAngle(180)
            ' [ ] 回転角(上限)
            param.ScaleMin = 100
            ' [ ] スケール(下限) (%)
            param.ScaleMax = 100
            ' [ ] スケール(上限) (%)
            param.CompressionLevel = 3
            ' [ ] 圧縮レベル (3: 1/8)  
            param.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            param.ScoreThresholdL = 50
            ' [ ] 低圧縮処理時のスコア閾値.
            param.ScoreThresholdH = 50
            ' [ ] 高圧縮処理時のスコア閾値.
            ' 5-3) パラメータ設定 (高精度ポーズ推定用)
            Dim paramR As FVIL.FPM.CFviFPMParamRefine = parser.ParamRefine
            paramR.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramR.ScoreThreshold = 60
            ' [ ] スコア閾値 (高精度ポーズ推定時)
            ' 5-4) パラメータ設定 (領域スコア算出用)
            Dim paramA As FVIL.FPM.CFviFPMParamAreaScore = parser.ParamAreaScore
            paramA.ErrorRangeTx = 0.5
            ' [ ] 誤差範囲(X方向並進値) (画素) 
            paramA.ErrorRangeTy = 0.5
            ' [ ] 誤差範囲(Y方向並進値) (画素)
            paramA.ErrorRangeTq = 0.5
            ' [ ] 誤差範囲(回転角) (度)
            paramA.ErrorRangeTs = 0.5
            ' [ ] 誤差範囲(スケール) (%)
            paramA.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramA.NoiseWeight = 0.2
            ' [ ] ノイズデータ重み係数.
            paramA.ScoreThreshold = 60
            ' [ ] スコア閾値 (領域スコア算出時)
            ' 5-5) パラメータ設定 (エッジ検出処理用)
            Dim paramE As FVIL.FPM.CFviFPMParamCorrelationEdge = parser.ParamEdge
            paramE.RegionWidth = 13
            ' [ ] 局所領域サイズ(横方向)
            paramE.RegionHeight = 5
            ' [ ] 局所領域サイズ(縦方向)
            paramE.SigmoidK = 1.0
            ' [ ] シグモイド関数パラメータ. 
            paramE.VarThreshold = 25.0
            ' [ ] 分散閾値.
            paramE.EdgeThreshold = 160
            ' [ ] エッジ強度値に対する閾値.
            paramE.NmsLength = 6
            ' [ ] 非極大抑制処理のフィルタ片幅.
            Select Case [option]
                Case 0
                    ' default
                    Exit Select
                Case 1
                    ' WxH=3x3,Nms=1 (線幅が細い画像)
                    paramE.RegionWidth = 3
                    ' [*] 局所領域サイズ(横方向)
                    paramE.RegionHeight = 3
                    ' [*] 局所領域サイズ(縦方向)
                    paramE.NmsLength = 1
                    ' [*] 非極大抑制処理のフィルタ片幅.
                    Exit Select
                Case 2
                    ' WxH=17x5,Nms=6 (線幅が太い画像)
                    paramE.RegionWidth = 17
                    ' [*] 局所領域サイズ(横方向)
                    paramE.RegionHeight = 5
                    ' [ ] 局所領域サイズ(縦方向)
                    paramE.NmsLength = 6
                    ' [ ] 非極大抑制処理のフィルタ片幅.
                    Exit Select
            End Select

            ' 5-E) サーチパタンのオープン.
            parser.OpenPattern(pattern)

            ' 確認用) パタンのエッジ点.
            If True Then
                Dim edges As List(Of FVIL.Edge.CFviEdgeData) = parser.GetPatternEdges()
                Console.WriteLine("edges={0}", edges.Count)
            End If

            ' 6) 画像処理実行.
            Dim timer As New FVIL.CFviTimeCounter()
            timer.Start()
            parser.Execute()
            Dim msec As Double = timer.[Stop]()
            Console.WriteLine("execute. {0} msec, count={1} ", msec.ToString("0.###"), parser.Result.Count)

            ' E) 確認用.
            Dim filename As System.String = Defs.ResultDir & "/" & System.[String].Format("FPM.Search_CorrelationEdge-{0}_{1}.png", target, [option])
            SaveResult(src, pattern, parser.Result, filename)
        End Sub
    End Class
End Namespace

C# Copy imageCopy
//    $Revision: 1.1 $

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace User.SampleCode
{
    public partial class FPM
    {
        /// <summary>
        /// マッチング結果の表示
        /// </summary>
        /// <param name="src">マッチング対象画像</param>
        /// <param name="pattern">パタン画像(マッチングテンプレート)</param>
        /// <param name="result">マッチング結果</param>
        /// <param name="filename">保存する画像ファイル</param>
        public void SaveResult(FVIL.Data.CFviImage src, FVIL.Data.CFviPattern pattern, FVIL.FPM.CFviFPMResult result, string filename)
        {
            // 画像表示の準備.
            FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay();
            display.Image = src;
            display.DisplayRect = src.Window;

            // オーバレイの生成.
            FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay();
            pOverlay0.Scaling = true;
            display.Overlays.Add(pOverlay0);

            FVIL.Data.CFviPoint pat_mark = pattern.CenterMark;        // パタン登録時の基準点.
            FVIL.Data.CFviRectangle pat_rect = pattern.RegistRect;    // パタン登録時の矩形.

            double    width  = pat_rect.Width;
            double    height = pat_rect.Height;

            for (int i = 0; i < result.Count; i++)
            {
                FVIL.FPM.CFviFPMData data = result[i];

                // マッチング結果の取得.
                FVIL.Data.CFviPoint pos = data.Position;        // 回答位置.
                FVIL.Data.CFviPoint mark = data.CenterMark;        // 基準点.
                FVIL.Data.CFviPoint trans= data.TransferAmount;    // 移動量.
                FVIL.Data.CFviRectangle    rect = new FVIL.Data.CFviRectangle();    // 矩形.
                double scale = data.Scale;        // スケール (%)
                int score = data.Score;            // スコア (%)

                // --- 検出データの基準点と移動量とパタン情報から矩形を復元.
                {
                    FVIL.Data.CFviPoint center = new FVIL.Data.CFviPoint();
                    center.X = mark.X + trans.X;
                    center.Y = mark.Y + trans.Y;

                    FVIL.Data.CFviPoint st = new FVIL.Data.CFviPoint();
                    FVIL.Data.CFviPoint ed = new FVIL.Data.CFviPoint();
                    st.X = center.X - (scale / 100.0 * mark.X);
                    st.Y = center.Y - (scale / 100.0 * mark.Y);
                    ed.X = st.X + ( scale/100.0 * width );
                    ed.Y = st.Y + ( scale/100.0 * height );
                    center.X -= st.X;
                    center.Y -= st.Y;

                    rect.St = st;
                    rect.Ed = ed;
                    rect.Center = center;
                    rect.Angle = data.Angle;
                }

                // 描画用.
                // --- 矩形(塗り潰し)
                FVIL.GDI.CFviGdiImage _fill = new FVIL.GDI.CFviGdiImage();
                _fill.SetSize( 1, 1, 32 );        // WxH=1x1 (32bpp)
                _fill.SetPixelRGB( 0, 0, Color.FromArgb(0xFF,0x00,0x00,0xFF) );    // A,R,G,B
                _fill.Position = rect.St;
                _fill.Axis = rect.Center;
                _fill.Angle = rect.Angle;
                _fill.Alpha = 0x3F;
                _fill.AlphaFormat = 0;
                _fill.StretchHorzSize = (int)width;
                _fill.StretchVertSize = (int)height;

                // --- 矩形(枠)
                FVIL.GDI.CFviGdiRectangle _rect = new FVIL.GDI.CFviGdiRectangle(rect);
                _rect.Pen.Color = Color.FromArgb(0x00,0x00,0xFF);

                // --- 回答位置.
                FVIL.GDI.CFviGdiPoint _pos = new FVIL.GDI.CFviGdiPoint(pos);
                _pos.Size = new Size( 5, 5 );
                _pos.Pen.Color = Color.FromArgb(0xFF,0x00,0x00);
                _pos.Angle = rect.Angle;

                // --- スコア.
                FVIL.GDI.CFviGdiString _score = new FVIL.GDI.CFviGdiString();
                _score.Text = score.ToString();
                _score.Position = pos;
                _score.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Bottom;
                _score.BkMode = FVIL.GDI.BkMode.Transparent;
                _score.Color = Color.FromArgb(0xFF,0xFF,0x00);
                _score.Angle = rect.Angle;

                // --- スケール.
                FVIL.GDI.CFviGdiString _scale = new FVIL.GDI.CFviGdiString();
                _scale.Text = scale.ToString("0");
                _scale.Position = pos;
                _scale.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Top;
                _scale.BkMode = FVIL.GDI.BkMode.Transparent;
                _scale.Color = Color.FromArgb(0x7F,0xFF,0x00);
                _scale.Angle = rect.Angle;

                // --- 傾き.
                FVIL.GDI.CFviGdiString _angle = new FVIL.GDI.CFviGdiString();
                _angle.Text = rect.Angle.Degree.ToString("0");
                _angle.Position = new FVIL.Data.CFviPoint(pos.X, pos.Y+_scale.Font.Height);
                _angle.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Top;
                _angle.BkMode = FVIL.GDI.BkMode.Transparent;
                _angle.Color = Color.FromArgb(0x00,0xFF,0xFF);
                _angle.Angle = rect.Angle;
                _angle.Axis = new FVIL.Data.CFviPoint(0, -_scale.Font.Height);

                // 追加.
                pOverlay0.Figures.Add( _fill );
                pOverlay0.Figures.Add(_rect);
                pOverlay0.Figures.Add(_pos);
                pOverlay0.Figures.Add(_score);
                pOverlay0.Figures.Add(_scale);
                pOverlay0.Figures.Add(_angle);
            }

            // 保存.
            FVIL.Data.CFviImage canvas = new FVIL.Data.CFviImage();
            display.SaveImage( canvas, display.DisplayRect, 1.0 );
            FVIL.File.Function.SaveImageFile(filename, canvas);
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing

Namespace SampleCode
    Public Partial Class FPM
        ''' <summary>
        ''' マッチング結果の表示
        ''' </summary>
        ''' <param name="src">マッチング対象画像</param>
        ''' <param name="pattern">パタン画像(マッチングテンプレート)</param>
        ''' <param name="result">マッチング結果</param>
        ''' <param name="filename">保存する画像ファイル</param>
        Public Sub SaveResult(src As FVIL.Data.CFviImage, pattern As FVIL.Data.CFviPattern, result As FVIL.FPM.CFviFPMResult, filename As String)
            ' 画像表示の準備.
            Dim display As New FVIL.GDI.CFviDisplay()
            display.Image = src
            display.DisplayRect = src.Window

            ' オーバレイの生成.
            Dim pOverlay0 As New FVIL.GDI.CFviOverlay()
            pOverlay0.Scaling = True
            display.Overlays.Add(pOverlay0)

            Dim pat_mark As FVIL.Data.CFviPoint = pattern.CenterMark
            ' パタン登録時の基準点.
            Dim pat_rect As FVIL.Data.CFviRectangle = pattern.RegistRect
            ' パタン登録時の矩形.
            Dim width As Double = pat_rect.Width
            Dim height As Double = pat_rect.Height

            For i As Integer = 0 To result.Count - 1
                Dim data As FVIL.FPM.CFviFPMData = result(i)

                ' マッチング結果の取得.
                Dim pos As FVIL.Data.CFviPoint = data.Position
                ' 回答位置.
                Dim mark As FVIL.Data.CFviPoint = data.CenterMark
                ' 基準点.
                Dim trans As FVIL.Data.CFviPoint = data.TransferAmount
                ' 移動量.
                Dim rect As New FVIL.Data.CFviRectangle()
                ' 矩形.
                Dim scale As Double = data.Scale
                ' スケール (%)
                Dim score As Integer = data.Score
                ' スコア (%)
                ' --- 検出データの基準点と移動量とパタン情報から矩形を復元.
                If True Then
                    Dim center As New FVIL.Data.CFviPoint()
                    center.X = mark.X + trans.X
                    center.Y = mark.Y + trans.Y

                    Dim st As New FVIL.Data.CFviPoint()
                    Dim ed As New FVIL.Data.CFviPoint()
                    st.X = center.X - (scale / 100.0 * mark.X)
                    st.Y = center.Y - (scale / 100.0 * mark.Y)
                    ed.X = st.X + (scale / 100.0 * width)
                    ed.Y = st.Y + (scale / 100.0 * height)
                    center.X -= st.X
                    center.Y -= st.Y

                    rect.St = st
                    rect.Ed = ed
                    rect.Center = center
                    rect.Angle = data.Angle
                End If

                ' 描画用.
                ' --- 矩形(塗り潰し)
                Dim _fill As New FVIL.GDI.CFviGdiImage()
                _fill.SetSize(1, 1, 32)
                ' WxH=1x1 (32bpp)
                _fill.SetPixelRGB(0, 0, Color.FromArgb(&Hff, &H0, &H0, &Hff))
                ' A,R,G,B
                _fill.Position = rect.St
                _fill.Axis = rect.Center
                _fill.Angle = rect.Angle
                _fill.Alpha = &H3f
                _fill.AlphaFormat = 0
                _fill.StretchHorzSize = CInt(Math.Truncate(width))
                _fill.StretchVertSize = CInt(Math.Truncate(height))

                ' --- 矩形(枠)
                Dim _rect As New FVIL.GDI.CFviGdiRectangle(rect)
                _rect.Pen.Color = Color.FromArgb(&H0, &H0, &Hff)

                ' --- 回答位置.
                Dim _pos As New FVIL.GDI.CFviGdiPoint(pos)
                _pos.Size = New Size(5, 5)
                _pos.Pen.Color = Color.FromArgb(&Hff, &H0, &H0)
                _pos.Angle = rect.Angle

                ' --- スコア.
                Dim _score As New FVIL.GDI.CFviGdiString()
                _score.Text = score.ToString()
                _score.Position = pos
                _score.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Bottom
                _score.BkMode = FVIL.GDI.BkMode.Transparent
                _score.Color = Color.FromArgb(&Hff, &Hff, &H0)
                _score.Angle = rect.Angle

                ' --- スケール.
                Dim _scale As New FVIL.GDI.CFviGdiString()
                _scale.Text = scale.ToString("0")
                _scale.Position = pos
                _scale.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Top
                _scale.BkMode = FVIL.GDI.BkMode.Transparent
                _scale.Color = Color.FromArgb(&H7f, &Hff, &H0)
                _scale.Angle = rect.Angle

                ' --- 傾き.
                Dim _angle As New FVIL.GDI.CFviGdiString()
                _angle.Text = rect.Angle.Degree.ToString("0")
                _angle.Position = New FVIL.Data.CFviPoint(pos.X, pos.Y + _scale.Font.Height)
                _angle.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Top
                _angle.BkMode = FVIL.GDI.BkMode.Transparent
                _angle.Color = Color.FromArgb(&H0, &Hff, &Hff)
                _angle.Angle = rect.Angle
                _angle.Axis = New FVIL.Data.CFviPoint(0, -_scale.Font.Height)

                ' 追加.
                pOverlay0.Figures.Add(_fill)
                pOverlay0.Figures.Add(_rect)
                pOverlay0.Figures.Add(_pos)
                pOverlay0.Figures.Add(_score)
                pOverlay0.Figures.Add(_scale)
                pOverlay0.Figures.Add(_angle)
            Next

            ' 保存.
            Dim canvas As New FVIL.Data.CFviImage()
            display.SaveImage(canvas, display.DisplayRect, 1.0)
            FVIL.File.[Function].SaveImageFile(filename, canvas)
        End Sub
    End Class
End Namespace

[↑戻る]


サンプルコード (ソーベルフィルタ):

CFviFPMSobel を使用したマッチング処理の例を示します。
マッチングテンプレート(FVIL.Data.CFviPattern)は、 処理対象画像から
MakePattern(CFviImage, CFviRectangle, CFviPoint) を行って保存していたものを使用しています。 マッチングテンプレートの生成やファイル保存については、 CFviPattern のサンプルコードを参考にしてください。
処理結果の画像下に記述している処理時間は、Pentium4 3.2GHz 1.0GB RAM で実行した時のものです。 画像サイズは 320x240 です。処理対象画像の状態やパラメータの設定内容によって速度は変化します。


1) 線幅が細い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM.Search_Sobel(0,0)
edges=163
execute. 30.706 msec, count=7 

2) 線幅が太い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM.Search_Sobel(1,0)
edges=220
execute. 13.418 msec, count=2 

ソースコード:

上記 1) の処理は、下記の関数に引数 0,0 を指定して実行したものです。 2) の処理は、引数 1,0 を指定して実行したものです。

C# Copy imageCopy
//    $Revision: 1.3 $

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using fvalgcli;    // FvPluginXXXX attribute requires fvalgcli

namespace User.SampleCode
{
    public partial class FPM
    {
        /// <summary>
        /// 0,0:clip,Nms=3
        /// </summary>
        [FvPluginExecute]
        public void Search_Sobel00()
        {
            Search_Sobel(0, 0);                // 0,0:clip,Nms=3
        }

        /// <summary>
        /// 1,0:key,Nms=3
        /// </summary>
        [FvPluginExecute]
        public void Search_Sobel10()
        {
            Search_Sobel(1, 0);                // 1,0:key,Nms=3
        }

        /// <summary>
        /// マッチング実行 (ソーベル)
        /// </summary>
        /// <param name="target">0=clip、1=key1</param>
        /// <param name="option">0=(Nms=3)、1=(Nms=7)</param>
        public void Search_Sobel(int target, int option)
        {
            System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
            Console.WriteLine("{0}.{1}({2},{3})", method.DeclaringType.FullName, method.Name, target, option);

            // 1) インスタンスの準備.
            FVIL.FPM.CFviFPMSobel parser = new FVIL.FPM.CFviFPMSobel();
            FVIL.Data.CFviImage src = new FVIL.Data.CFviImage();
            FVIL.Data.CFviPattern pattern = new FVIL.Data.CFviPattern();

            // 2-1) 処理対象画像の取り込み.
            System.String[]    szSrcFile =
            {
                Defs.TestImageDir + "/clip_UC8_M.png",
                Defs.TestImageDir + "/key_UC8_M.png",
            };
            FVIL.File.Function.LoadImageFile( szSrcFile[target], src, FVIL.PixelMode.Unpacking );

            // 2-2) パタン画像の読み込み.
            System.String[]    szPatFile =
            {
                Defs.TestImageDir + "/clip.pat",
                Defs.TestImageDir + "/key1.pat",
            };
            pattern.Load( szPatFile[target] );

            // 3) 処理対象画像の有効性検査.
            if( FVIL.ErrorCode._SUCCESS != FVIL.FPM.CFviFPMSobel.CheckValidity( src ) ) return;
            if( FVIL.ErrorCode._SUCCESS != FVIL.FPM.CFviFPMSobel.CheckValidity( pattern ) ) return;

            // 4) 画像処理準備.
            // --- 処理対象画像と結果格納用オブジェクトの設定.
            parser.SrcImages[0] = src;

            // 
            // ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            // 

            // 5-1) パラメータ設定 (本体)
            parser.ExecuteFlag = FVIL.FPM.ExecuteFlag.On;        // [ ] 高精度ポーズ推定 (1:行う)
                                                                // [ ] 領域スコア算出 (0:行わない)
            parser.ExecuteAreaScoreFlag = FVIL.FPM.ExecuteAreaScoreFlag.Off;
            parser.MatchMode = FVIL.FPM.MatchMode.HighSpeed;    // [*] 処理モード (1:高速モード)
                                                                // [ ] 回答基準点自動取得の実行指示 (0:手動)
            parser.CenterMarkAutoFlag = FVIL.FPM.CenterMarkAutoFlag.Manual;

            // 5-2) パラメータ設定 (基本)
            FVIL.FPM.CFviFPMParam param = parser.Param;
            param.Count = 10;                                    // [*] 検索個数.
            param.AngleMin = new FVIL.Data.CFviAngle(-180);        // [ ] 回転角(下限)
            param.AngleMax = new FVIL.Data.CFviAngle(180);        // [ ] 回転角(上限)
            param.ScaleMin = 100;                                // [ ] スケール(下限) (%)
            param.ScaleMax = 100;                                // [ ] スケール(上限) (%)
            param.CompressionLevel = 3;                            // [ ] 圧縮レベル (3: 1/8)  
            param.ErrorRange = 1;                                // [ ] 誤差範囲 (画素)
            param.ScoreThresholdL = 50;                            // [ ] 低圧縮処理時のスコア閾値.
            param.ScoreThresholdH = 50;                            // [ ] 高圧縮処理時のスコア閾値.

            // 5-3) パラメータ設定 (高精度ポーズ推定用)
            FVIL.FPM.CFviFPMParamRefine paramR = parser.ParamRefine;
            paramR.ErrorRange = 1;                        // [ ] 誤差範囲 (画素)
            paramR.ScoreThreshold = 60;                    // [ ] スコア閾値 (高精度ポーズ推定時)

            // 5-4) パラメータ設定 (領域スコア算出用)
            FVIL.FPM.CFviFPMParamAreaScore paramA = parser.ParamAreaScore;
            paramA.ErrorRangeTx = 0.5;                    // [ ] 誤差範囲(X方向並進値) (画素) 
            paramA.ErrorRangeTy = 0.5;                    // [ ] 誤差範囲(Y方向並進値) (画素)
            paramA.ErrorRangeTq = 0.5;                    // [ ] 誤差範囲(回転角) (度)
            paramA.ErrorRangeTs = 0.5;                    // [ ] 誤差範囲(スケール) (%)
            paramA.ErrorRange = 1;                        // [ ] 誤差範囲 (画素)
            paramA.NoiseWeight = 0.2;                    // [ ] ノイズデータ重み係数.
            paramA.ScoreThreshold = 60;                    // [ ] スコア閾値 (領域スコア算出時)

            // 5-5) パラメータ設定 (エッジ検出処理用)
            FVIL.FPM.CFviFPMParamSobel paramE = parser.ParamEdge;
            paramE.EdgeThreshold = 120;                    // [ ] エッジ強度値に対する閾値.
            paramE.NmsLength = 3;                        // [ ] 非極大抑制処理のフィルタ片幅.

            switch( option )
            {
                case 0:        // Nms=3
                    break;
                case 1:        // Nms=7
                    paramE.NmsLength = 7;                // [*] 非極大抑制処理のフィルタ片幅.
                    break;
            }


            // 5-E) サーチパタンのオープン.
            parser.OpenPattern( pattern );

            // 確認用) パタンのエッジ点.
            {
                List<FVIL.Edge.CFviEdgeData> edges = parser.GetPatternEdges();
                Console.WriteLine("edges={0}", edges.Count);
            }

            // 6) 画像処理実行.
            FVIL.CFviTimeCounter timer = new FVIL.CFviTimeCounter();
            timer.Start();
            parser.Execute();
            double msec = timer.Stop();
            Console.WriteLine("execute. {0} msec, count={1} ", msec.ToString("0.###"), parser.Result.Count);

            // E) 確認用.
            System.String filename = Defs.ResultDir + "/" + System.String.Format("FPM.Search_Sobel-{0}_{1}.png", target, option);
            SaveResult(src, pattern, parser.Result, filename);
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports fvalgcli
' FvPluginXXXX attribute requires fvalgcli
Namespace SampleCode
    Public Partial Class FPM
        ''' <summary>
        ''' 0,0:clip,Nms=3
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_Sobel00()
            Search_Sobel(0, 0)
            ' 0,0:clip,Nms=3
        End Sub

        ''' <summary>
        ''' 1,0:key,Nms=3
        ''' </summary>
        <FvPluginExecute> _
        Public Sub Search_Sobel10()
            Search_Sobel(1, 0)
            ' 1,0:key,Nms=3
        End Sub

        ''' <summary>
        ''' マッチング実行 (ソーベル)
        ''' </summary>
        ''' <param name="target">0=clip、1=key1</param>
        ''' <param name="option">0=(Nms=3)、1=(Nms=7)</param>
        Public Sub Search_Sobel(target As Integer, [option] As Integer)
            Dim method As System.Reflection.MethodBase = System.Reflection.MethodBase.GetCurrentMethod()
            Console.WriteLine("{0}.{1}({2},{3})", method.DeclaringType.FullName, method.Name, target, [option])

            ' 1) インスタンスの準備.
            Dim parser As New FVIL.FPM.CFviFPMSobel()
            Dim src As New FVIL.Data.CFviImage()
            Dim pattern As New FVIL.Data.CFviPattern()

            ' 2-1) 処理対象画像の取り込み.
            Dim szSrcFile As System.String() = {Defs.TestImageDir & "/clip_UC8_M.png", Defs.TestImageDir & "/key_UC8_M.png"}
            FVIL.File.[Function].LoadImageFile(szSrcFile(target), src, FVIL.PixelMode.Unpacking)

            ' 2-2) パタン画像の読み込み.
            Dim szPatFile As System.String() = {Defs.TestImageDir & "/clip.pat", Defs.TestImageDir & "/key1.pat"}
            pattern.Load(szPatFile(target))

            ' 3) 処理対象画像の有効性検査.
            If FVIL.ErrorCode._SUCCESS <> FVIL.FPM.CFviFPMSobel.CheckValidity(src) Then
                Return
            End If
            If FVIL.ErrorCode._SUCCESS <> FVIL.FPM.CFviFPMSobel.CheckValidity(pattern) Then
                Return
            End If

            ' 4) 画像処理準備.
            ' --- 処理対象画像と結果格納用オブジェクトの設定.
            parser.SrcImages(0) = src

            ' 
            ' ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            ' 

            ' 5-1) パラメータ設定 (本体)
            parser.ExecuteFlag = FVIL.FPM.ExecuteFlag.[On]
            ' [ ] 高精度ポーズ推定 (1:行う)
            ' [ ] 領域スコア算出 (0:行わない)
            parser.ExecuteAreaScoreFlag = FVIL.FPM.ExecuteAreaScoreFlag.Off
            parser.MatchMode = FVIL.FPM.MatchMode.HighSpeed
            ' [*] 処理モード (1:高速モード)
            ' [ ] 回答基準点自動取得の実行指示 (0:手動)
            parser.CenterMarkAutoFlag = FVIL.FPM.CenterMarkAutoFlag.Manual

            ' 5-2) パラメータ設定 (基本)
            Dim param As FVIL.FPM.CFviFPMParam = parser.Param
            param.Count = 10
            ' [*] 検索個数.
            param.AngleMin = New FVIL.Data.CFviAngle(-180)
            ' [ ] 回転角(下限)
            param.AngleMax = New FVIL.Data.CFviAngle(180)
            ' [ ] 回転角(上限)
            param.ScaleMin = 100
            ' [ ] スケール(下限) (%)
            param.ScaleMax = 100
            ' [ ] スケール(上限) (%)
            param.CompressionLevel = 3
            ' [ ] 圧縮レベル (3: 1/8)  
            param.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            param.ScoreThresholdL = 50
            ' [ ] 低圧縮処理時のスコア閾値.
            param.ScoreThresholdH = 50
            ' [ ] 高圧縮処理時のスコア閾値.
            ' 5-3) パラメータ設定 (高精度ポーズ推定用)
            Dim paramR As FVIL.FPM.CFviFPMParamRefine = parser.ParamRefine
            paramR.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramR.ScoreThreshold = 60
            ' [ ] スコア閾値 (高精度ポーズ推定時)
            ' 5-4) パラメータ設定 (領域スコア算出用)
            Dim paramA As FVIL.FPM.CFviFPMParamAreaScore = parser.ParamAreaScore
            paramA.ErrorRangeTx = 0.5
            ' [ ] 誤差範囲(X方向並進値) (画素) 
            paramA.ErrorRangeTy = 0.5
            ' [ ] 誤差範囲(Y方向並進値) (画素)
            paramA.ErrorRangeTq = 0.5
            ' [ ] 誤差範囲(回転角) (度)
            paramA.ErrorRangeTs = 0.5
            ' [ ] 誤差範囲(スケール) (%)
            paramA.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramA.NoiseWeight = 0.2
            ' [ ] ノイズデータ重み係数.
            paramA.ScoreThreshold = 60
            ' [ ] スコア閾値 (領域スコア算出時)
            ' 5-5) パラメータ設定 (エッジ検出処理用)
            Dim paramE As FVIL.FPM.CFviFPMParamSobel = parser.ParamEdge
            paramE.EdgeThreshold = 120
            ' [ ] エッジ強度値に対する閾値.
            paramE.NmsLength = 3
            ' [ ] 非極大抑制処理のフィルタ片幅.
            Select Case [option]
                Case 0
                    ' Nms=3
                    Exit Select
                Case 1
                    ' Nms=7
                    paramE.NmsLength = 7
                    ' [*] 非極大抑制処理のフィルタ片幅.
                    Exit Select
            End Select


            ' 5-E) サーチパタンのオープン.
            parser.OpenPattern(pattern)

            ' 確認用) パタンのエッジ点.
            If True Then
                Dim edges As List(Of FVIL.Edge.CFviEdgeData) = parser.GetPatternEdges()
                Console.WriteLine("edges={0}", edges.Count)
            End If

            ' 6) 画像処理実行.
            Dim timer As New FVIL.CFviTimeCounter()
            timer.Start()
            parser.Execute()
            Dim msec As Double = timer.[Stop]()
            Console.WriteLine("execute. {0} msec, count={1} ", msec.ToString("0.###"), parser.Result.Count)

            ' E) 確認用.
            Dim filename As System.String = Defs.ResultDir & "/" & System.[String].Format("FPM.Search_Sobel-{0}_{1}.png", target, [option])
            SaveResult(src, pattern, parser.Result, filename)
        End Sub
    End Class
End Namespace

C# Copy imageCopy
//    $Revision: 1.1 $

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace User.SampleCode
{
    public partial class FPM
    {
        /// <summary>
        /// マッチング結果の表示
        /// </summary>
        /// <param name="src">マッチング対象画像</param>
        /// <param name="pattern">パタン画像(マッチングテンプレート)</param>
        /// <param name="result">マッチング結果</param>
        /// <param name="filename">保存する画像ファイル</param>
        public void SaveResult(FVIL.Data.CFviImage src, FVIL.Data.CFviPattern pattern, FVIL.FPM.CFviFPMResult result, string filename)
        {
            // 画像表示の準備.
            FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay();
            display.Image = src;
            display.DisplayRect = src.Window;

            // オーバレイの生成.
            FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay();
            pOverlay0.Scaling = true;
            display.Overlays.Add(pOverlay0);

            FVIL.Data.CFviPoint pat_mark = pattern.CenterMark;        // パタン登録時の基準点.
            FVIL.Data.CFviRectangle pat_rect = pattern.RegistRect;    // パタン登録時の矩形.

            double    width  = pat_rect.Width;
            double    height = pat_rect.Height;

            for (int i = 0; i < result.Count; i++)
            {
                FVIL.FPM.CFviFPMData data = result[i];

                // マッチング結果の取得.
                FVIL.Data.CFviPoint pos = data.Position;        // 回答位置.
                FVIL.Data.CFviPoint mark = data.CenterMark;        // 基準点.
                FVIL.Data.CFviPoint trans= data.TransferAmount;    // 移動量.
                FVIL.Data.CFviRectangle    rect = new FVIL.Data.CFviRectangle();    // 矩形.
                double scale = data.Scale;        // スケール (%)
                int score = data.Score;            // スコア (%)

                // --- 検出データの基準点と移動量とパタン情報から矩形を復元.
                {
                    FVIL.Data.CFviPoint center = new FVIL.Data.CFviPoint();
                    center.X = mark.X + trans.X;
                    center.Y = mark.Y + trans.Y;

                    FVIL.Data.CFviPoint st = new FVIL.Data.CFviPoint();
                    FVIL.Data.CFviPoint ed = new FVIL.Data.CFviPoint();
                    st.X = center.X - (scale / 100.0 * mark.X);
                    st.Y = center.Y - (scale / 100.0 * mark.Y);
                    ed.X = st.X + ( scale/100.0 * width );
                    ed.Y = st.Y + ( scale/100.0 * height );
                    center.X -= st.X;
                    center.Y -= st.Y;

                    rect.St = st;
                    rect.Ed = ed;
                    rect.Center = center;
                    rect.Angle = data.Angle;
                }

                // 描画用.
                // --- 矩形(塗り潰し)
                FVIL.GDI.CFviGdiImage _fill = new FVIL.GDI.CFviGdiImage();
                _fill.SetSize( 1, 1, 32 );        // WxH=1x1 (32bpp)
                _fill.SetPixelRGB( 0, 0, Color.FromArgb(0xFF,0x00,0x00,0xFF) );    // A,R,G,B
                _fill.Position = rect.St;
                _fill.Axis = rect.Center;
                _fill.Angle = rect.Angle;
                _fill.Alpha = 0x3F;
                _fill.AlphaFormat = 0;
                _fill.StretchHorzSize = (int)width;
                _fill.StretchVertSize = (int)height;

                // --- 矩形(枠)
                FVIL.GDI.CFviGdiRectangle _rect = new FVIL.GDI.CFviGdiRectangle(rect);
                _rect.Pen.Color = Color.FromArgb(0x00,0x00,0xFF);

                // --- 回答位置.
                FVIL.GDI.CFviGdiPoint _pos = new FVIL.GDI.CFviGdiPoint(pos);
                _pos.Size = new Size( 5, 5 );
                _pos.Pen.Color = Color.FromArgb(0xFF,0x00,0x00);
                _pos.Angle = rect.Angle;

                // --- スコア.
                FVIL.GDI.CFviGdiString _score = new FVIL.GDI.CFviGdiString();
                _score.Text = score.ToString();
                _score.Position = pos;
                _score.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Bottom;
                _score.BkMode = FVIL.GDI.BkMode.Transparent;
                _score.Color = Color.FromArgb(0xFF,0xFF,0x00);
                _score.Angle = rect.Angle;

                // --- スケール.
                FVIL.GDI.CFviGdiString _scale = new FVIL.GDI.CFviGdiString();
                _scale.Text = scale.ToString("0");
                _scale.Position = pos;
                _scale.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Top;
                _scale.BkMode = FVIL.GDI.BkMode.Transparent;
                _scale.Color = Color.FromArgb(0x7F,0xFF,0x00);
                _scale.Angle = rect.Angle;

                // --- 傾き.
                FVIL.GDI.CFviGdiString _angle = new FVIL.GDI.CFviGdiString();
                _angle.Text = rect.Angle.Degree.ToString("0");
                _angle.Position = new FVIL.Data.CFviPoint(pos.X, pos.Y+_scale.Font.Height);
                _angle.Align = FVIL.GDI.TextAlign.Right | FVIL.GDI.TextAlign.Top;
                _angle.BkMode = FVIL.GDI.BkMode.Transparent;
                _angle.Color = Color.FromArgb(0x00,0xFF,0xFF);
                _angle.Angle = rect.Angle;
                _angle.Axis = new FVIL.Data.CFviPoint(0, -_scale.Font.Height);

                // 追加.
                pOverlay0.Figures.Add( _fill );
                pOverlay0.Figures.Add(_rect);
                pOverlay0.Figures.Add(_pos);
                pOverlay0.Figures.Add(_score);
                pOverlay0.Figures.Add(_scale);
                pOverlay0.Figures.Add(_angle);
            }

            // 保存.
            FVIL.Data.CFviImage canvas = new FVIL.Data.CFviImage();
            display.SaveImage( canvas, display.DisplayRect, 1.0 );
            FVIL.File.Function.SaveImageFile(filename, canvas);
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing

Namespace SampleCode
    Public Partial Class FPM
        ''' <summary>
        ''' マッチング結果の表示
        ''' </summary>
        ''' <param name="src">マッチング対象画像</param>
        ''' <param name="pattern">パタン画像(マッチングテンプレート)</param>
        ''' <param name="result">マッチング結果</param>
        ''' <param name="filename">保存する画像ファイル</param>
        Public Sub SaveResult(src As FVIL.Data.CFviImage, pattern As FVIL.Data.CFviPattern, result As FVIL.FPM.CFviFPMResult, filename As String)
            ' 画像表示の準備.
            Dim display As New FVIL.GDI.CFviDisplay()
            display.Image = src
            display.DisplayRect = src.Window

            ' オーバレイの生成.
            Dim pOverlay0 As New FVIL.GDI.CFviOverlay()
            pOverlay0.Scaling = True
            display.Overlays.Add(pOverlay0)

            Dim pat_mark As FVIL.Data.CFviPoint = pattern.CenterMark
            ' パタン登録時の基準点.
            Dim pat_rect As FVIL.Data.CFviRectangle = pattern.RegistRect
            ' パタン登録時の矩形.
            Dim width As Double = pat_rect.Width
            Dim height As Double = pat_rect.Height

            For i As Integer = 0 To result.Count - 1
                Dim data As FVIL.FPM.CFviFPMData = result(i)

                ' マッチング結果の取得.
                Dim pos As FVIL.Data.CFviPoint = data.Position
                ' 回答位置.
                Dim mark As FVIL.Data.CFviPoint = data.CenterMark
                ' 基準点.
                Dim trans As FVIL.Data.CFviPoint = data.TransferAmount
                ' 移動量.
                Dim rect As New FVIL.Data.CFviRectangle()
                ' 矩形.
                Dim scale As Double = data.Scale
                ' スケール (%)
                Dim score As Integer = data.Score
                ' スコア (%)
                ' --- 検出データの基準点と移動量とパタン情報から矩形を復元.
                If True Then
                    Dim center As New FVIL.Data.CFviPoint()
                    center.X = mark.X + trans.X
                    center.Y = mark.Y + trans.Y

                    Dim st As New FVIL.Data.CFviPoint()
                    Dim ed As New FVIL.Data.CFviPoint()
                    st.X = center.X - (scale / 100.0 * mark.X)
                    st.Y = center.Y - (scale / 100.0 * mark.Y)
                    ed.X = st.X + (scale / 100.0 * width)
                    ed.Y = st.Y + (scale / 100.0 * height)
                    center.X -= st.X
                    center.Y -= st.Y

                    rect.St = st
                    rect.Ed = ed
                    rect.Center = center
                    rect.Angle = data.Angle
                End If

                ' 描画用.
                ' --- 矩形(塗り潰し)
                Dim _fill As New FVIL.GDI.CFviGdiImage()
                _fill.SetSize(1, 1, 32)
                ' WxH=1x1 (32bpp)
                _fill.SetPixelRGB(0, 0, Color.FromArgb(&Hff, &H0, &H0, &Hff))
                ' A,R,G,B
                _fill.Position = rect.St
                _fill.Axis = rect.Center
                _fill.Angle = rect.Angle
                _fill.Alpha = &H3f
                _fill.AlphaFormat = 0
                _fill.StretchHorzSize = CInt(Math.Truncate(width))
                _fill.StretchVertSize = CInt(Math.Truncate(height))

                ' --- 矩形(枠)
                Dim _rect As New FVIL.GDI.CFviGdiRectangle(rect)
                _rect.Pen.Color = Color.FromArgb(&H0, &H0, &Hff)

                ' --- 回答位置.
                Dim _pos As New FVIL.GDI.CFviGdiPoint(pos)
                _pos.Size = New Size(5, 5)
                _pos.Pen.Color = Color.FromArgb(&Hff, &H0, &H0)
                _pos.Angle = rect.Angle

                ' --- スコア.
                Dim _score As New FVIL.GDI.CFviGdiString()
                _score.Text = score.ToString()
                _score.Position = pos
                _score.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Bottom
                _score.BkMode = FVIL.GDI.BkMode.Transparent
                _score.Color = Color.FromArgb(&Hff, &Hff, &H0)
                _score.Angle = rect.Angle

                ' --- スケール.
                Dim _scale As New FVIL.GDI.CFviGdiString()
                _scale.Text = scale.ToString("0")
                _scale.Position = pos
                _scale.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Top
                _scale.BkMode = FVIL.GDI.BkMode.Transparent
                _scale.Color = Color.FromArgb(&H7f, &Hff, &H0)
                _scale.Angle = rect.Angle

                ' --- 傾き.
                Dim _angle As New FVIL.GDI.CFviGdiString()
                _angle.Text = rect.Angle.Degree.ToString("0")
                _angle.Position = New FVIL.Data.CFviPoint(pos.X, pos.Y + _scale.Font.Height)
                _angle.Align = FVIL.GDI.TextAlign.Right Or FVIL.GDI.TextAlign.Top
                _angle.BkMode = FVIL.GDI.BkMode.Transparent
                _angle.Color = Color.FromArgb(&H0, &Hff, &Hff)
                _angle.Angle = rect.Angle
                _angle.Axis = New FVIL.Data.CFviPoint(0, -_scale.Font.Height)

                ' 追加.
                pOverlay0.Figures.Add(_fill)
                pOverlay0.Figures.Add(_rect)
                pOverlay0.Figures.Add(_pos)
                pOverlay0.Figures.Add(_score)
                pOverlay0.Figures.Add(_scale)
                pOverlay0.Figures.Add(_angle)
            Next

            ' 保存.
            Dim canvas As New FVIL.Data.CFviImage()
            display.SaveImage(canvas, display.DisplayRect, 1.0)
            FVIL.File.[Function].SaveImageFile(filename, canvas)
        End Sub
    End Class
End Namespace

[↑戻る]