FPM 特徴点応用マッチング

Classes

ClassDescription
Public classCFviFPM2Data
(FPM2) マッチングデータ構造クラス
Public classCFviFPM2Feature
(FPM2) 特徴量クラス(処理対象画像)
Public classCFviFPM2Matching
(FPM2) 特徴点応用マッチングクラス
Public classCFviFPM2Param
(FPM2) 基本パラメータクラス
Public classCFviFPM2ParamAreaScore
(FPM2) 領域スコア算出用パラメータクラス
Public classCFviFPM2ParamEssential
(FPM2) 不可欠領域スコア算出用パラメータクラス
Public classCFviFPM2Result
(FPM2) 特徴点応用マッチング結果
Public classCFviFPM2Template
(FPM2) 特徴量クラス(テンプレート)
Public classFunction
FPM2 関数群

Enumerations

EnumerationDescription
Public enumerationFeatureMethod
特徴量抽出手法
Public enumerationMatchMode
マッチング処理モード
Public enumerationPolarity
エッジ極性

Remarks

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

このクラス群は、FIE ライブラリの fnFIE_fpm_xxxx 関数群を集約したものです。 内部のアルゴリズムは、従来の 特徴点応用マッチング とほぼ同様ですが、 エッジ検出処理の違いにより最終的なマッチング結果に差異がある場合があります。 また、処理対象画像からエッジ点を取得する機能や不可欠領域スコア計算など、 いくつかの機能追加やインターフェースの改良を行っています。


トピック:


解説:

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

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

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

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

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

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


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

[↑戻る]


構成:

この機能は、テンプレートマッチングを行う本体のクラスとデータ構造クラスで構成されます。

  • 本体:
    クラス内容
    CFviFPM2Matchingマッチングを実行する本体のクラスです。
  • データ構造: (特徴量)
    クラスデータID内容
    CFviFPM2Feature1800処理対象画像の特徴量を抽出するクラスです。
    CFviFPM2Template1801マッチングテンプレート(パタン画像)の特徴量を抽出するクラスです。
  • データ構造: (回答)
    クラスデータID内容
    CFviFPM2Result1806マッチング結果を格納するクラスです。上記の CFviFPM2Matching から取得できます。
    CFviFPM2Data18021件分のマッチングデータを格納するクラスです。上記の CFviFPM2Matching (または CFviFPM2Result)から取得できます。
  • データ構造: (パラメータ)
    クラスデータID内容
    CFviFPM2Param1803基本的なパラメータを保有するクラスです。
    CFviFPM2ParamAreaScore1804領域スコア算出用のパラメータを保有するクラスです。
    CFviFPM2ParamEssential1805不可欠領域スコア計算用のパラメータを保有するクラスです。
  • データ構造: (エッジ検出処理)
    クラスデータID内容
    CFviEdge2DCorrelationParam1023相関エッジ法によるエッジ検出で使用されるパラメータを保有します。
    CFviEdge2DSobelParam1024ソーベル法によるエッジ検出で使用されるパラメータを保有します。
  • データ構造: (マッチングテンプレート)
    クラスデータID内容
    CFviPattern101処理対象画像とマッチングを行う為のテンプレート画像を格納するオブジェクトです。

[↑戻る]


コンポーネント:

特徴点応用マッチングクラス(CFviFPM2Matching) は、 処理対象画像の特徴量テンプレートの特徴量 を必要とします。 これら2つは実行前にユーザが設定する必要があります。 パラメータは本体の内部に保有しており、設定を行うか否かは任意です。 本体の Execute メソッドを実行すると、マッチング結果を内部の配列に格納します。 マッチング結果(個数とデータ)を取得するには、 本体の ResultSize と インデクサ(Item[([( Int32])]) ) を使用してください。


処理対象画像の特徴量:

CFviFPM2Feature クラスは、 処理対象画像(CFviImage)から特徴量を抽出するクラスです。 特徴量抽出に使用する手法は、指定されたエッジ検出パラメータ( 相関エッジ または ソーベル )によって決定します。
画像オブジェクトから抽出した特徴量は、このクラスの内部に保有され、 Item[([( Int32])]) クラスから利用されます。 ユーザは、GetFeatureEdges()()()() を介して、 特徴量をエッジ点群として取得できます。


テンプレートの特徴量:

CFviFPM2Template クラスは、 テンプレートから特徴量を抽出するクラスです。 CFviImage または CFviPattern を対象とします。 特徴量抽出に使用する手法は、指定されたエッジ検出パラメータ( 相関エッジ または ソーベル )によって決定します。
画像オブジェクトから抽出した特徴量は、このクラスの内部に保有され、 Item[([( Int32])]) クラスから利用されます。 ユーザは、GetFeatureEdges()()()() を介して、 特徴量をエッジ点群として取得できます。


[↑戻る]


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

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

1) 線幅が細い画像

【パタン画像】


【関数の出力】
User.SampleCode.FPM2.Search_CorrelationEdge(0,1)
edges=283
edges=1792
execute. 163.443 msec, count=10 
		
2) 線幅が太い画像

【パタン画像】


【関数の出力】
User.SampleCode.FPM2.Search_CorrelationEdge(1,0)
edges=262
edges=1308
execute. 48.798 msec, count=3   
		

ソースコード:

・上記1 の結果は、下記コード内の関数 void Search_CorrelationEdge01() を実行したものです。
・上記2 の結果は、下記コード内の関数 void Search_CorrelationEdge10() を実行したものです。

C# Copy imageCopy
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using fvalgcli;    // FvPluginXXXX attribute requires fvalgcli

namespace User.SampleCode
{
    public partial class FPM2
    {
        /// <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.FPM2.CFviFPM2Matching matching = new FVIL.FPM2.CFviFPM2Matching();
            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) パラメータ準備.
            // ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            // 

            // 3-1) (FPM2) 基本パラメータ設定
            FVIL.FPM2.CFviFPM2Param param = matching.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;                // [ ] 高圧縮処理時のスコア閾値.

            // 3-2) (FPM2) 領域スコア算出用パラメータ設定
            FVIL.FPM2.CFviFPM2ParamAreaScore paramA = matching.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;                // [ ] スコア閾値 (領域スコア算出時)

            // 3-3) (FPM2) 不可欠領域スコア算出用パラメータ設定
            FVIL.FPM2.CFviFPM2ParamEssential paramE = matching.ParamEssential;
            paramE.ErrorRange = 1;                    // [ ] 誤差範囲 (画素)
            paramE.ScoreThreshold = 60;                // [ ] スコア閾値 (高精度ポーズ推定時)

            // 3-4) (FPM2) 特徴量
            // (相関エッジ) 特徴量抽出用パラメータ生成
            FVIL.Edge.CFviEdge2DCorrelationParam edge_param = new FVIL.Edge.CFviEdge2DCorrelationParam();
            edge_param.RegionWidth = 13;            // [ ] 局所領域サイズ(横方向)
            edge_param.RegionHeight = 5;            // [ ] 局所領域サイズ(縦方向)
            edge_param.SigmoidK = 1.0;                // [ ] シグモイド関数パラメータ. 
            edge_param.VarThreshold = 25.0;            // [ ] 分散閾値.
            edge_param.EdgeThreshold = 160;            // [ ] エッジ強度値に対する閾値.
            edge_param.NmsLength = 6;                // [ ] 非極大抑制処理のフィルタ片幅.

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

            // 3-4-1) (FPM2) 特徴量(テンプレート) 生成
            FVIL.FPM2.CFviFPM2Template templ = new FVIL.FPM2.CFviFPM2Template(pattern, FVIL.FPM2.MatchMode.Normal, edge_param);

            // 3-4-2) (FPM2) 特徴量(処理対象画像) 生成
            FVIL.FPM2.CFviFPM2Feature feature = new FVIL.FPM2.CFviFPM2Feature(src, FVIL.FPM2.MatchMode.Normal, edge_param, false);

            // 4) 画像処理準備.
            // 4-1) 処理対象オブジェクトの設定.
            matching.Param = param;                    // 3-1 基本パラメータ.
            matching.ParamAreaScore = paramA;        // 3-2 領域スコア算出.
            matching.ParamEssential = paramE;        // 3-3 不可欠領域スコア計算.
            matching.Target = feature;                // 3-4-1 特徴量(処理対象画像)
            matching.Template = templ;                // 3-4-2 特徴量(テンプレート)
            matching.EnableAreaScore = false;        // [ ] 領域スコア算出 (false:行わない)
            matching.EnableEssential = false;        // [ ] 不可欠領域スコア計算 (false:行わない)

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

            // 確認用) 処理対象画像のエッジ点
            {
                List<FVIL.Edge.CFviEdgeData> edges_image = (List<FVIL.Edge.CFviEdgeData>)feature.GetFeatureEdges();
                Console.WriteLine("edges={0}", edges_image.Count);
            }

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

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


Visual Basic Copy imageCopy
Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports fvalgcli
' FvPluginXXXX attribute requires fvalgcli
Namespace SampleCode
    Public Partial Class FPM2
        ''' <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 matching As New FVIL.FPM2.CFviFPM2Matching()
            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) パラメータ準備.
            ' ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            ' 

            ' 3-1) (FPM2) 基本パラメータ設定
            Dim param As FVIL.FPM2.CFviFPM2Param = matching.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
            ' [ ] 高圧縮処理時のスコア閾値.
            ' 3-2) (FPM2) 領域スコア算出用パラメータ設定
            Dim paramA As FVIL.FPM2.CFviFPM2ParamAreaScore = matching.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
            ' [ ] スコア閾値 (領域スコア算出時)
            ' 3-3) (FPM2) 不可欠領域スコア算出用パラメータ設定
            Dim paramE As FVIL.FPM2.CFviFPM2ParamEssential = matching.ParamEssential
            paramE.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramE.ScoreThreshold = 60
            ' [ ] スコア閾値 (高精度ポーズ推定時)
            ' 3-4) (FPM2) 特徴量
            ' (相関エッジ) 特徴量抽出用パラメータ生成
            Dim edge_param As New FVIL.Edge.CFviEdge2DCorrelationParam()
            edge_param.RegionWidth = 13
            ' [ ] 局所領域サイズ(横方向)
            edge_param.RegionHeight = 5
            ' [ ] 局所領域サイズ(縦方向)
            edge_param.SigmoidK = 1.0
            ' [ ] シグモイド関数パラメータ. 
            edge_param.VarThreshold = 25.0
            ' [ ] 分散閾値.
            edge_param.EdgeThreshold = 160
            ' [ ] エッジ強度値に対する閾値.
            edge_param.NmsLength = 6
            ' [ ] 非極大抑制処理のフィルタ片幅.
            Select Case [option]
                Case 0
                    ' default
                    Exit Select
                Case 1
                    ' WxH=3x3,Nms=1 (線幅が細い画像)
                    edge_param.RegionWidth = 3
                    ' [*] 局所領域サイズ(横方向)
                    edge_param.RegionHeight = 3
                    ' [*] 局所領域サイズ(縦方向)
                    edge_param.NmsLength = 1
                    ' [*] 非極大抑制処理のフィルタ片幅.
                    Exit Select
                Case 2
                    ' WxH=17x5,Nms=6 (線幅が太い画像)
                    edge_param.RegionWidth = 17
                    ' [*] 局所領域サイズ(横方向)
                    edge_param.RegionHeight = 5
                    ' [ ] 局所領域サイズ(縦方向)
                    edge_param.NmsLength = 6
                    ' [ ] 非極大抑制処理のフィルタ片幅.
                    Exit Select
            End Select

            ' 3-4-1) (FPM2) 特徴量(テンプレート) 生成
            Dim templ As New FVIL.FPM2.CFviFPM2Template(pattern, FVIL.FPM2.MatchMode.Normal, edge_param)

            ' 3-4-2) (FPM2) 特徴量(処理対象画像) 生成
            Dim feature As New FVIL.FPM2.CFviFPM2Feature(src, FVIL.FPM2.MatchMode.Normal, edge_param, False)

            ' 4) 画像処理準備.
            ' 4-1) 処理対象オブジェクトの設定.
            matching.Param = param
            ' 3-1 基本パラメータ.
            matching.ParamAreaScore = paramA
            ' 3-2 領域スコア算出.
            matching.ParamEssential = paramE
            ' 3-3 不可欠領域スコア計算.
            matching.Target = feature
            ' 3-4-1 特徴量(処理対象画像)
            matching.Template = templ
            ' 3-4-2 特徴量(テンプレート)
            matching.EnableAreaScore = False
            ' [ ] 領域スコア算出 (false:行わない)
            matching.EnableEssential = False
            ' [ ] 不可欠領域スコア計算 (false:行わない)
            ' 確認用) パタンのエッジ点
            If True Then
                Dim edges_pattern As List(Of FVIL.Edge.CFviEdgeData) = templ.GetFeatureEdges()
                Console.WriteLine("edges={0}", edges_pattern.Count)
            End If

            ' 確認用) 処理対象画像のエッジ点
            If True Then
                Dim edges_image As List(Of FVIL.Edge.CFviEdgeData) = DirectCast(feature.GetFeatureEdges(), List(Of FVIL.Edge.CFviEdgeData))
                Console.WriteLine("edges={0}", edges_image.Count)
            End If

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

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

C# Copy imageCopy
//    $Revision: 1.2 $

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

namespace User.SampleCode
{
    public partial class FPM2
    {
        /// <summary>
        /// マッチング結果の表示
        /// </summary>
        /// <param name="src">マッチング対象画像</param>
        /// <param name="templ">マッチングテンプレート</param>
        /// <param name="matching">マッチング本体</param>
        /// <param name="filename">保存する画像ファイル</param>
        public void SaveResult(FVIL.Data.CFviImage src, FVIL.FPM2.CFviFPM2Template templ, FVIL.FPM2.CFviFPM2Matching matching, 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 offset = templ.Offset;        // パタン登録時の基準点.
            double width = templ.Width;
            double height = templ.Height;

            for (int i = 0; i < matching.ResultSize; i++)
            {
                FVIL.FPM2.CFviFPM2Data data = matching[i];

                // マッチング結果の取得.
                FVIL.Data.CFviPoint pos = data.Position;        // 回答位置.
                FVIL.Data.CFviAngle angle = data.Angle;            // 回転角.
                double scale = data.Scale;                        // スケール (%)
                int score = data.Score;                            // スコア (%)

                FVIL.Data.CFviRectangle rect = new FVIL.Data.CFviRectangle();    // 矩形.
                rect.St = new FVIL.Data.CFviPoint(pos.X - offset.X, pos.Y - offset.Y);
                rect.Ed = new FVIL.Data.CFviPoint(rect.St.X + width, rect.St.Y + height);
                rect.Center = offset;
                rect.Angle = angle;

                // 描画用.
                // --- 矩形.
                FVIL.GDI.CFviGdiRectangle _rect = new FVIL.GDI.CFviGdiRectangle(rect);
                _rect.Pen.Color = Color.FromArgb(0x00, 0x00, 0xFF);
                _rect.FillEnable = true;
                _rect.FillAlpha = 0x3F;
                _rect.FillColor = System.Drawing.Color.FromArgb(0xFF, 0x00, 0x00);

                // --- 回答位置.
                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(_rect);
                pOverlay0.Figures.Add(_pos);
                pOverlay0.Figures.Add(_score);
                pOverlay0.Figures.Add(_scale);
                pOverlay0.Figures.Add(_angle);
            }

            // 保存.
            using (FVIL.Data.CFviImage canvas = new FVIL.Data.CFviImage())
            {
                display.SaveImage(canvas, display.DisplayRect, 1.0);
                canvas.Save(filename);
            }
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

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

Namespace SampleCode
    Public Partial Class FPM2
        ''' <summary>
        ''' マッチング結果の表示
        ''' </summary>
        ''' <param name="src">マッチング対象画像</param>
        ''' <param name="templ">マッチングテンプレート</param>
        ''' <param name="matching">マッチング本体</param>
        ''' <param name="filename">保存する画像ファイル</param>
        Public Sub SaveResult(src As FVIL.Data.CFviImage, templ As FVIL.FPM2.CFviFPM2Template, matching As FVIL.FPM2.CFviFPM2Matching, 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 offset As FVIL.Data.CFviPoint = templ.Offset
            ' パタン登録時の基準点.
            Dim width As Double = templ.Width
            Dim height As Double = templ.Height

            For i As Integer = 0 To matching.ResultSize - 1
                Dim data As FVIL.FPM2.CFviFPM2Data = matching(i)

                ' マッチング結果の取得.
                Dim pos As FVIL.Data.CFviPoint = data.Position
                ' 回答位置.
                Dim angle As FVIL.Data.CFviAngle = data.Angle
                ' 回転角.
                Dim scale As Double = data.Scale
                ' スケール (%)
                Dim score As Integer = data.Score
                ' スコア (%)
                Dim rect As New FVIL.Data.CFviRectangle()
                ' 矩形.
                rect.St = New FVIL.Data.CFviPoint(pos.X - offset.X, pos.Y - offset.Y)
                rect.Ed = New FVIL.Data.CFviPoint(rect.St.X + width, rect.St.Y + height)
                rect.Center = offset
                rect.Angle = angle

                ' 描画用.
                ' --- 矩形.
                Dim _rect As New FVIL.GDI.CFviGdiRectangle(rect)
                _rect.Pen.Color = Color.FromArgb(&H0, &H0, &Hff)
                _rect.FillEnable = True
                _rect.FillAlpha = &H3f
                _rect.FillColor = System.Drawing.Color.FromArgb(&Hff, &H0, &H0)

                ' --- 回答位置.
                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(_rect)
                pOverlay0.Figures.Add(_pos)
                pOverlay0.Figures.Add(_score)
                pOverlay0.Figures.Add(_scale)
                pOverlay0.Figures.Add(_angle)
            Next

            ' 保存.
            Using canvas As New FVIL.Data.CFviImage()
                display.SaveImage(canvas, display.DisplayRect, 1.0)
                canvas.Save(filename)
            End Using
        End Sub
    End Class
End Namespace

[↑戻る]


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

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

1) 線幅が細い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM2.Search_Sobel(0,0)
edges=244
edges=1585
execute. 140.273 msec, count=10 			
		
2) 線幅が太い画像


【パタン画像】


【関数の出力】
User.SampleCode.FPM2.Search_Sobel(1,0)
edges=396
edges=1888
execute. 71.012 msec, count=3  				
		

ソースコード:

・上記1 の結果は、下記コード内の関数 public void Search_Sobel00() を実行したものです。
・上記2 の結果は、下記コード内の関数 public void Search_Sobel10() を実行したものです。

C# Copy imageCopy
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using fvalgcli;    // FvPluginXXXX attribute requires fvalgcli

namespace User.SampleCode
{
    public partial class FPM2
    {
        /// <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=13x5(Nms=6)、1=3x3(Nms=1)、2=17x5(Nms=6)</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.FPM2.CFviFPM2Matching matching = new FVIL.FPM2.CFviFPM2Matching();
            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) パラメータ準備.
            // ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            // 

            // 3-1) (FPM2) 基本パラメータ設定
            FVIL.FPM2.CFviFPM2Param param = matching.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;                // [ ] 高圧縮処理時のスコア閾値.

            // 3-2) (FPM2) 領域スコア算出用パラメータ設定
            FVIL.FPM2.CFviFPM2ParamAreaScore paramA = matching.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;                // [ ] スコア閾値 (領域スコア算出時)

            // 3-3) (FPM2) 不可欠領域スコア算出用パラメータ設定
            FVIL.FPM2.CFviFPM2ParamEssential paramE = matching.ParamEssential;
            paramE.ErrorRange = 1;                    // [ ] 誤差範囲 (画素)
            paramE.ScoreThreshold = 60;                // [ ] スコア閾値 (高精度ポーズ推定時)

            // 3-4) (FPM2) 特徴量
            // (ソーベル) 特徴量抽出用パラメータ生成
            FVIL.Edge.CFviEdge2DSobelParam edge_param = new FVIL.Edge.CFviEdge2DSobelParam();
            edge_param.EdgeThreshold = 120;            // [ ] エッジ強度値に対する閾値.
            edge_param.NmsLength = 3;                // [ ] 非極大抑制処理のフィルタ片幅.

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

            // 3-4-1) (FPM2) 特徴量(テンプレート) 生成
            FVIL.FPM2.CFviFPM2Template templ = new FVIL.FPM2.CFviFPM2Template(pattern, FVIL.FPM2.MatchMode.Normal, edge_param);

            // 3-4-2) (FPM2) 特徴量(処理対象画像) 生成
            FVIL.FPM2.CFviFPM2Feature feature = new FVIL.FPM2.CFviFPM2Feature(src, FVIL.FPM2.MatchMode.Normal, edge_param, false);

            // 4) 画像処理準備.
            // 4-1) 処理対象オブジェクトの設定.
            matching.Param = param;                    // 3-1 基本パラメータ.
            matching.ParamAreaScore = paramA;        // 3-2 領域スコア算出.
            matching.ParamEssential = paramE;        // 3-3 不可欠領域スコア計算.
            matching.Target = feature;                // 3-4-1 特徴量(処理対象画像)
            matching.Template = templ;                // 3-4-2 特徴量(テンプレート)
            matching.EnableAreaScore = false;        // [ ] 領域スコア算出 (false:行わない)
            matching.EnableEssential = false;        // [ ] 不可欠領域スコア計算 (false:行わない)

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

            // 確認用) 処理対象画像のエッジ点
            {
                List<FVIL.Edge.CFviEdgeData> edges_image = (List<FVIL.Edge.CFviEdgeData>)feature.GetFeatureEdges();
                Console.WriteLine("edges={0}", edges_image.Count);
            }

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

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


Visual Basic Copy imageCopy
Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports fvalgcli
' FvPluginXXXX attribute requires fvalgcli
Namespace SampleCode
    Public Partial Class FPM2
        ''' <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=13x5(Nms=6)、1=3x3(Nms=1)、2=17x5(Nms=6)</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 matching As New FVIL.FPM2.CFviFPM2Matching()
            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) パラメータ準備.
            ' ※パラメータを既定値から変更した部分は、コメントに [*] を記述しています.
            ' 

            ' 3-1) (FPM2) 基本パラメータ設定
            Dim param As FVIL.FPM2.CFviFPM2Param = matching.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
            ' [ ] 高圧縮処理時のスコア閾値.
            ' 3-2) (FPM2) 領域スコア算出用パラメータ設定
            Dim paramA As FVIL.FPM2.CFviFPM2ParamAreaScore = matching.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
            ' [ ] スコア閾値 (領域スコア算出時)
            ' 3-3) (FPM2) 不可欠領域スコア算出用パラメータ設定
            Dim paramE As FVIL.FPM2.CFviFPM2ParamEssential = matching.ParamEssential
            paramE.ErrorRange = 1
            ' [ ] 誤差範囲 (画素)
            paramE.ScoreThreshold = 60
            ' [ ] スコア閾値 (高精度ポーズ推定時)
            ' 3-4) (FPM2) 特徴量
            ' (ソーベル) 特徴量抽出用パラメータ生成
            Dim edge_param As New FVIL.Edge.CFviEdge2DSobelParam()
            edge_param.EdgeThreshold = 120
            ' [ ] エッジ強度値に対する閾値.
            edge_param.NmsLength = 3
            ' [ ] 非極大抑制処理のフィルタ片幅.
            Select Case [option]
                Case 0
                    ' Nms=3
                    Exit Select
                Case 1
                    ' Nms=7
                    edge_param.NmsLength = 7
                    ' [*] 非極大抑制処理のフィルタ片幅.
                    Exit Select
            End Select

            ' 3-4-1) (FPM2) 特徴量(テンプレート) 生成
            Dim templ As New FVIL.FPM2.CFviFPM2Template(pattern, FVIL.FPM2.MatchMode.Normal, edge_param)

            ' 3-4-2) (FPM2) 特徴量(処理対象画像) 生成
            Dim feature As New FVIL.FPM2.CFviFPM2Feature(src, FVIL.FPM2.MatchMode.Normal, edge_param, False)

            ' 4) 画像処理準備.
            ' 4-1) 処理対象オブジェクトの設定.
            matching.Param = param
            ' 3-1 基本パラメータ.
            matching.ParamAreaScore = paramA
            ' 3-2 領域スコア算出.
            matching.ParamEssential = paramE
            ' 3-3 不可欠領域スコア計算.
            matching.Target = feature
            ' 3-4-1 特徴量(処理対象画像)
            matching.Template = templ
            ' 3-4-2 特徴量(テンプレート)
            matching.EnableAreaScore = False
            ' [ ] 領域スコア算出 (false:行わない)
            matching.EnableEssential = False
            ' [ ] 不可欠領域スコア計算 (false:行わない)
            ' 確認用) パタンのエッジ点
            If True Then
                Dim edges_pattern As List(Of FVIL.Edge.CFviEdgeData) = templ.GetFeatureEdges()
                Console.WriteLine("edges={0}", edges_pattern.Count)
            End If

            ' 確認用) 処理対象画像のエッジ点
            If True Then
                Dim edges_image As List(Of FVIL.Edge.CFviEdgeData) = DirectCast(feature.GetFeatureEdges(), List(Of FVIL.Edge.CFviEdgeData))
                Console.WriteLine("edges={0}", edges_image.Count)
            End If

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

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

C# Copy imageCopy
//    $Revision: 1.2 $

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

namespace User.SampleCode
{
    public partial class FPM2
    {
        /// <summary>
        /// マッチング結果の表示
        /// </summary>
        /// <param name="src">マッチング対象画像</param>
        /// <param name="templ">マッチングテンプレート</param>
        /// <param name="matching">マッチング本体</param>
        /// <param name="filename">保存する画像ファイル</param>
        public void SaveResult(FVIL.Data.CFviImage src, FVIL.FPM2.CFviFPM2Template templ, FVIL.FPM2.CFviFPM2Matching matching, 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 offset = templ.Offset;        // パタン登録時の基準点.
            double width = templ.Width;
            double height = templ.Height;

            for (int i = 0; i < matching.ResultSize; i++)
            {
                FVIL.FPM2.CFviFPM2Data data = matching[i];

                // マッチング結果の取得.
                FVIL.Data.CFviPoint pos = data.Position;        // 回答位置.
                FVIL.Data.CFviAngle angle = data.Angle;            // 回転角.
                double scale = data.Scale;                        // スケール (%)
                int score = data.Score;                            // スコア (%)

                FVIL.Data.CFviRectangle rect = new FVIL.Data.CFviRectangle();    // 矩形.
                rect.St = new FVIL.Data.CFviPoint(pos.X - offset.X, pos.Y - offset.Y);
                rect.Ed = new FVIL.Data.CFviPoint(rect.St.X + width, rect.St.Y + height);
                rect.Center = offset;
                rect.Angle = angle;

                // 描画用.
                // --- 矩形.
                FVIL.GDI.CFviGdiRectangle _rect = new FVIL.GDI.CFviGdiRectangle(rect);
                _rect.Pen.Color = Color.FromArgb(0x00, 0x00, 0xFF);
                _rect.FillEnable = true;
                _rect.FillAlpha = 0x3F;
                _rect.FillColor = System.Drawing.Color.FromArgb(0xFF, 0x00, 0x00);

                // --- 回答位置.
                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(_rect);
                pOverlay0.Figures.Add(_pos);
                pOverlay0.Figures.Add(_score);
                pOverlay0.Figures.Add(_scale);
                pOverlay0.Figures.Add(_angle);
            }

            // 保存.
            using (FVIL.Data.CFviImage canvas = new FVIL.Data.CFviImage())
            {
                display.SaveImage(canvas, display.DisplayRect, 1.0);
                canvas.Save(filename);
            }
        }
    };
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

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

Namespace SampleCode
    Public Partial Class FPM2
        ''' <summary>
        ''' マッチング結果の表示
        ''' </summary>
        ''' <param name="src">マッチング対象画像</param>
        ''' <param name="templ">マッチングテンプレート</param>
        ''' <param name="matching">マッチング本体</param>
        ''' <param name="filename">保存する画像ファイル</param>
        Public Sub SaveResult(src As FVIL.Data.CFviImage, templ As FVIL.FPM2.CFviFPM2Template, matching As FVIL.FPM2.CFviFPM2Matching, 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 offset As FVIL.Data.CFviPoint = templ.Offset
            ' パタン登録時の基準点.
            Dim width As Double = templ.Width
            Dim height As Double = templ.Height

            For i As Integer = 0 To matching.ResultSize - 1
                Dim data As FVIL.FPM2.CFviFPM2Data = matching(i)

                ' マッチング結果の取得.
                Dim pos As FVIL.Data.CFviPoint = data.Position
                ' 回答位置.
                Dim angle As FVIL.Data.CFviAngle = data.Angle
                ' 回転角.
                Dim scale As Double = data.Scale
                ' スケール (%)
                Dim score As Integer = data.Score
                ' スコア (%)
                Dim rect As New FVIL.Data.CFviRectangle()
                ' 矩形.
                rect.St = New FVIL.Data.CFviPoint(pos.X - offset.X, pos.Y - offset.Y)
                rect.Ed = New FVIL.Data.CFviPoint(rect.St.X + width, rect.St.Y + height)
                rect.Center = offset
                rect.Angle = angle

                ' 描画用.
                ' --- 矩形.
                Dim _rect As New FVIL.GDI.CFviGdiRectangle(rect)
                _rect.Pen.Color = Color.FromArgb(&H0, &H0, &Hff)
                _rect.FillEnable = True
                _rect.FillAlpha = &H3f
                _rect.FillColor = System.Drawing.Color.FromArgb(&Hff, &H0, &H0)

                ' --- 回答位置.
                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(_rect)
                pOverlay0.Figures.Add(_pos)
                pOverlay0.Figures.Add(_score)
                pOverlay0.Figures.Add(_scale)
                pOverlay0.Figures.Add(_angle)
            Next

            ' 保存.
            Using canvas As New FVIL.Data.CFviImage()
                display.SaveImage(canvas, display.DisplayRect, 1.0)
                canvas.Save(filename)
            End Using
        End Sub
    End Class
End Namespace

[↑戻る]