Halcon 記述子ベースのテンプレート マッチング

まず、Halcon ベースの記述子ベースのテンプレート マッチングについて話す前に、オペレーターについて話しましょう。SIFT (スケール不変特徴変換 (SIFT)) は、画像処理の分野で使用される記述です。この記述はスケール不変性を持ち、画像内のキーポイントを検出でき、局所特徴記述子です。SIFT 機能は、画像のサイズや回転とは無関係に、オブジェクト上のいくつかの局所的な外観の特徴点に基づいています。光、ノイズ、微細な視野角の変化に対する耐性も非常に高いです。
SIFT アルゴリズムには次の特徴があります。
1. SIFT 特徴は画像の局所的な特徴であり、回転、スケーリング、明るさの変化に対して不変性を維持し、視野角の変化、アフィン変換、および角度の変化に対してもある程度の安定性を維持します。ノイズが少ない; 2.
識別性が高く、情報量が豊富であるため、大規模な特徴データベースでの高速かつ正確なマッチングに適しています; 3.
大量であるため、少数のオブジェクトでも多数の SIFT 特徴ベクトルを生成できます;
4. 高最適化された SIFT マッチング アルゴリズムにより、リアルタイム要件を満たすことができます;
5. スケーラビリティ、他の形式の特徴ベクトルと簡単に組み合わせることができます。
2. Halcon の記述子ベースのテンプレート検出原理は、SIFT アルゴリズムに似ています。また、キーポイント先では、テンプレートは輪郭とは何の関係もありません。そのテンプレートはエッジ輪郭からではなく、特徴点から作成されます。
たとえば、点の位置や隣接するピクセルのグレースケール情報を記述子として使用できます。テクスチャ付きのフラット グラフィックスはこの方法に非常に適しており、特に回転や傾斜などのシーンでのマッチングに非常に適しており、非常に理想的な結果が得られます。記述子ベースのマッチングでは、ある程度の遠近変形が可能で、ラベル付き画像とラベルなし画像の両方で実行できます。記述子ベースのマッチングは、オブジェクトの輪郭とは関係ありませんが、ターゲットのテクスチャやターゲットの特徴点と密接に関連しています。
注: 記述子ベースのテンプレート マッチングは、テクスチャ付きイメージにのみ使用できます。
記述子ベースのテンプレートの作成は、テクスチャの複雑さに応じて時間のかかる手順です。
3. オペレーター
ROI は、接続されていない複数の領域を含め、
任意の形状にすることができます。 適切な記述モデルを作成します。
次の 2 つの方法を使用してモデルを作成します。
 Create_uncalib_descriptor_model
 Create_calib_descriptor_model
1 つはキャリブレーション済みのカメラに基づいており、もう 1 つはキャリブレーションされていないカメラに基づいていますカメラビデオカメラ。キャリブレーション済みカメラにはカメラの内部パラメータと基準ポーズが必要ですが、他の 2 つの機能のパラメータは同じです。
次に、具体的なパラメータの説明を見て、その方法を説明します。

検出器を選択して適応させる
記述子を調整する キャリブレー
ションされたマッチングの場合、指定されたカメラ パラメーターと対応するポーズ
モデルを作成後に表示および変更できます。
画像から関心のある点を検出するために検出器 (DetectorType、DetectorParamName、DetectorParamValue) を選択および適合させる方法
は、検出器と呼ばれます。
DetectorType は検出方法を指定します。可能な値は、lepetit、harris、harris_binomial です (なぜ halcon に sift surface や orb などの検出演算子が含まれていないのかはわかりません)。Lepetit は重要なポイントを検出するための非常に高速な方法ですが、Harris ほど堅牢ではありません。特に、テンプレートまたは検索された画像が暗い場合やコントラストが非常に低い場合は、lepetit を使用しないでください。Harris_binomial は良い妥協案であり、harris よりも高速ですが、lepetit よりも堅牢です。
検出器のタイプごとに、パラメータの共通セットが利用可能であり、パラメータ detecterParamName および detecterParamValue を介して調整できます。1 つ目は汎用パラメーターの名前を指定するために使用され、2 つ目は対応する値を指定するために使用されます。モデルを作成する前に、選択した点演算子を使用してテストすることをお勧めします。つまり、対応するドット オペレーターをテンプレート イメージに適用し、たとえば gen_corss_contour_xld を使用します。良好な結果を得るには、テンプレート イメージ全体に約 50 ~ 450 個のポイントが均等に配置されている必要があります。選択したポイント オペレーターに適切なパラメーター設定が見つかった場合、これらのパラメーターは、create_calib_descriptor_model または create_uncalib_descriptor_model を介してモデルに設定することもできます。ほとんどの場合、検出器のデフォルト値 (DetectorParamName および DetectorParamValue が [] に設定されている) が効果であることに注意してください。すでにとても良いです。
記述子の調整 (DescriptorParamName DesctiptorParamValue)
は、ランダム シダを使用して抽出されたポイントを分類し、位置フィーチャの説明と関心ポイントのローカル グレースケール近傍を確立する記述子を実装するようになりました。
記述子は、パラメータ descriptorParamName および descriptorParamValue を使用して調整できます。descriptorParamName は調整する必要がある汎用パラメータの名前を指定するために使用され、descriptorParamValue は対応する値を指定するために使用されます。
パラメータは 2 つあり、1 つは記述子のサイズを制御するパラメータで、堅牢性、速度、メモリ使用量を制御します。もう 1 つはシミュレーション パラメーター、つまりモデル ビュー トレーニングの空間範囲です。
記述子のサイズは次のパラメーターによって制御されます:
 深さ - 分類シダの深さを指定します深さが大きいほど、特徴点をよりよく区別できますが、計算時間が増加します。
 number_ferns - シダ構造の数を指定します。数が多いほど堅牢性が強くなり、計算時間も増加します。  patch_size - 説明サブフィールドの辺の長さを指定します。同様に、大きすぎると計算時間が長くなります
。が大きくなり、小さすぎると正確な特徴を抽出できなくなります。
深さと数のパラメータは、さまざまなニーズに応じて設定する必要がありますが、高速マッチングが必要な場合は、深さを小さくし、number_ferns を大きくすることをお勧めします。堅牢な一致が必要な場合は、より大きな深さが必要になり、number_ferns もより大きく設定する必要があり、同時に計算速度が大幅に低下します。メモリ要件が厳しい場合は、より小さいnumber_fernsをお勧めします。多くのアプリケーションでは、さまざまな要件の間にトレードオフが存在します。
シミュレーション制御パラメータは、モデルのトレインを制御します
。  チルト – シミュレーション段階で投影変換をオンまたはオフにします。オンにするとロバスト性が向上しますが、計算時間も増加します
 min_rot と max_rot (min_rotation) はモデルの法線ベクトル回転の角度範囲を定義します
 min_scale と max_scale はモデルのスケーリング範囲を定義します
回転角度の範囲とスケールの範囲を小さく設定すると、トレーニングを大幅にスピードアップできます。ただし、その後のアプリケーションのマッチングプロセスでは、モデルの角度とスケールがトレーニング範囲内にある場合にのみ見つけることができます。また、小さい画像の方がトレーニングが速いため、小さい参照画像と小さいテンプレート画像を選択し、「傾き」をオフに設定すると、トレーニングを高速化できます。ただし、参照画像と検索画像は同じサイズである必要があります。大きな画像を最初にスケーリングし、次にテンプレートをトレーニングし、次に収集された実際の画像も同じスケーリングしてから検索する必要があります。これにより速度が向上します。これはニューラル ネットワークに似ており、ニューラル ネットワークの入力は不可能です。大きすぎるので、入力側では比較的小さい画像になります。
create_uncalib_descriptor_model (ImageReduced, 'harris_binomial', [],
[], ['min_rot','max_rot','min_scale',
'max_scale'], [-90,90,0.2,1.1], 42,
ModelID)
はカメラを指定しますパラメータ
キャリブレーション カメラの基準 Pose(camParam,ReferencePose) と一致させるには、カメラ パラメータとカメラ ポーズを指定する必要があります。これら 2 つのパラメータを取得するには、カメラ キャリブレーションを使用することをお勧めします。飛行機の姿勢を決定するもう 1 つの代替方法は、モデルの範囲を手動で測定することですが、これはかなり複雑で、多くの場合不正確です。たとえば (ステレオ ビジョン、3D レーザー三角測量)
記述子モデルを表示および変更するには、
get_descriptor_model_points を通じてモデル内の注目点を表示できます。get_descriptor_model_params を通じてモデルのパラメーターを表示します。モデルが他のプログラムまたはモデルの作成時に使用される自動パラメータによって作成された場合、このメソッドはモデルのパラメータを表示できます。write_descriptor_model を使用してモデルを保存し、read_descriptor_model を使用してモデルを読み取ります。さらに、get_descriptor_model_origin を使用してモデルの座標原点をクエリします。
set_descriptor_model_origin を使用して原点を変更することでモデルを変更することもできますが、これはマッチング精度が低下するためお勧めできません。それでも基準点を変更する必要があり、キャリブレーション マッチングを適用したい場合は、パースペクティブ ワープ マッチングの対応する説明を参照することをお勧めします。ここでは、基準ポーズ、モデルポーズ、および基準点に手動で適用されるオフセットの間の関係が示されています。
マッチング後、get_descriptor_model_points を使用して、一致した特徴点をクエリできます。パラメーター Set は、「model」ではなく「search」に設定する必要があります。次のコードは、最初に一致したモデルの特徴点を示します。
get_descriptor_model_points (ModelIDs[Index2], 'search', 0, Row, Col)
さらに、照合後、get_descriptor_model_results を使用して、単一の検索ポイント間の対応スコアなど、検索中に蓄積された選択された数値結果をクエリすることができます。そしてモデルポイント。(ResultNames を「point_classification」に設定)
検索プロセスを最適化する
同じまたは類似のオブジェクトの未知の画像内でモデルに保存および記述されている同じ対象点を見つけるには、次の演算子が適用されます。  find_calib_descriptor_model は
、調整された記述子モデル。オブジェクトの 3D ポーズと一致するスコアを返します。
 find_uncalib_descriptor_model 未校正の記述子モデルの最も一致するものを検索します。2D 射影変換行列 (ホモグラフィー) と、一致の品質を表すスコアを返します。
2 つの関数の違いは、CamParam パラメーター 1 つだけです。他はすべて同じです。ここでは、モデル作成時に使用したカメラパラメータと同じものを使用するものとします。別のカメラを使用する場合は、カメラを再調整することをお勧めします。これは、カメラ パラメーターがある限り、さまざまなカメラを検索に使用できることを意味します。
次について話しましょう:
 検索スペース (ROI) を制限する
 検出器を調整して検索する。これはまれな場合にのみ推奨されます。
 検索記述子を調整します
 類似性スコアのしきい値
MinScore
を設定します

サーチ スペースの制限
サーチ スペースを制限すると、一致が高速化されます。実際には、スイッチを設定し、reduce_main で領域の 1 つを確保し、その領域を検索します。
検索用の検出器の調整は
主に、モデルの作成時に説明した DetectorParamName と DetectorParamValue を変更することです。ほとんどの場合、これらの値を変更する必要はありません。つまり、空のタプル ([ ]) を引数として使用できます。
まれに、特に参照画像と検索画像の間で照明に大きな変化がある場合、パラメータ値を変更できることがあります。たとえば、検索画像が「暗い」で、検出器として「lepetit」も使用する場合、「min_score」をより小さい値に設定できます。一般的に、パラメーター値を変更する必要があるかどうかをテストするには、次のようにします。検出器に対応する
点演算子は、モデルの作成に提案された参照画像だけでなく、探索画像にも適用されます。また、良好なマッチング結果を得るには、約 50 ~ 450 個の均等に分散された点を抽出する必要があります。参照画像と検索画像で使用される点演算子 (lepetit、harris など) が異なるパラメータを必要とする場合、それに応じて対応する検出器パラメータの値を変更する必要がある場合があります。
検索用記述子のパラメータ(DescriptorParamName、DescriptorParamValue)を調整して、
特徴点間の対応関係の決定を制御します。記述子パラメータ名と記述子パラメータ値により、検索画像とモデル画像を調整します。次の 2 つの一般パラメータを設定できます。
 min_score_descr — このパラメータは、検出されたスコアのしきい値である 0 より大きい任意の値 (できれば 0.1 より小さい値) に設定できます。これにより、計算に使用されるポイントの数が減り、マッチング速度が向上します。ただし、特に抽出ポイントの数が比較的少ない場合は、堅牢性が低下します。
 guided_matching - これには、on と off の 2 つの値があります (デフォルトは on) ガイド付きマッチングが有効な場合、モデルの位置推定の堅牢性が強化されます。特に、点は検索画像から抽出され、記述子によって分類されます。分類によって受け入れられた点は、最初の投影 2D (未校正の場合) または同次の 3D (校正済みの場合) 変換行列を計算するために使用されます。次に、すべてのモデル点を検索画像に投影するために使用されます。投影されたモデル点が元の抽出点の 1 つに近い場合、つまり分類とは独立している場合、この点は、それぞれ 2D 射影変換行列または 3D ポーズとしてマッチングによって返される同型性の最終計算に使用されます。一般に、分類がない場合、より多くの点を計算に使用でき、得られる同型写像の信頼性が高くなります。一方で、場合によってはマッチング速度が最大10%向上することもあります。したがって、堅牢性が速度ほど重要ではない場合は、「ブートストラップ」をオフにすることができます。
類似性スコアしきい値の設定 (minScore)
minscore パラメーターは、潜在的な一致が一致として返す必要がある最小スコアを指定します。スコアは、一致の品質、つまりモデルと検索画像の間の一致または「類似性」を表す値です。記述子ベースのマッチングの場合、出力パラメーター スコアにはさまざまなタイプのスコアがあることに注意してください。ただし、入力パラメータ minscore の場合は、「inlier_ratio」タイプのスコアが常に使用されます。モデル点の数に対する点対応の数の比率を計算します。ほとんどの場合、minscore は少なくとも 0.1 の値に設定する必要があります。検索を高速化するには、この値を大きく設定する必要がありますが、この値が大きすぎてはなりません。大きすぎると完全一致が必要になるため、この値を大きすぎることはできません。たとえば、一致が値 1.0 に達する可能性はほとんどありません。
NumMatches を設定し、複数のターゲットを検索します (NumMatches)
ゴールの最大数を設定します。0 に設定すると、すべての一致が返されます。複数のターゲットをターゲットにしている場合、返される結果は値、スコア、HomMat2D、ポーズなどではなくタプルです。複数のオブジェクトの検索は、1 つのオブジェクトの検索よりも少し遅くなるだけで、それほど遅くはありません。
スコアのタイプを選択します (ScoreType)
 num_points – 「num_points」の場合、各インスタンスのポイント対応の数を返します。4 つの対応関係は 2 つの画像間の数学的に正しい同型性を定義するため、信頼できる一致結果を仮定するには、この数は少なくとも 10 である必要があります。
 inlier_ratio – 「inlier_ratio」の場合、モデル ポイントの数に対する対応するリターン ポイントの数の比率。このパラメータの値は 0.0 ~ 1.0 ですが、一致の比率が 1.0 に達する可能性はほとんどありません。ただし、オブジェクトの内分比が 0.1 未満の場合は無視する必要があります。
通常、それらのうち 1 つだけを使用することも、2 つ使用することもできます。2 つ使用する場合は、2 つをタプルに入れる必要があり、結果もタプルを返します。
4. ケース
4.1 キャリブレーションなしの記述子ベースのテンプレート マッチング、Halcon ソース プログラム

这个例子在图片数据库中查找文章页面。
*在第一步中,训练不同的页面并创建模型。
*随后搜索未知图像和正确的文章
检测到几页。
*请注意,这个例子需要一些内存来训练模型。
dev_update_off ()
dev_close_window ()
read_image (Image, 'brochure/brochure_page_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_display (Image)
* 
*清除所有已经创建的描述符模型。
ModelIDs := []
ModelsFound := 0
NumPoints := []
NumModels := 3
TotalTime := 0
* 
*为可视化目的创建区域。
RowRoi := [10,10,Height - 10,Height - 10]
ColRoi := [10,Width - 10,Width - 10,10]
gen_rectangle1 (Rectangle, 10, 10, Height - 10, Width - 10)
disp_message (WindowHandle, ['Press \'Run\' to start model creation ...','(may take a few minutes)'], 'window', 10, 10, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
*为每个页面创建描述符模型。
for Index := 1 to NumModels by 1
    read_image (Image, 'brochure/brochure_page_' + Index$'.2')
    rgb1_to_gray (Image, ImageGray)
    get_image_size (ImageGray, Width, Height)
    reduce_domain (ImageGray, Rectangle, ImageReduced)
    dev_clear_window ()
    dev_display (ImageGray)
    disp_message (WindowHandle, 'Creating model no. ' + Index + '/' + NumModels + ' ... please wait.', 'window', 10, 10, 'black', 'true')
    * 
    *使用默认参数创建描述符模型(缩放除外)
    *为了快速检测,选择哈里斯二项点检测器。
    count_seconds (Seconds1)
    create_uncalib_descriptor_model (ImageReduced, 'harris_binomial', [], [], ['min_rot','max_rot','min_scale','max_scale'], [-90,90,0.2,1.1], 42, ModelID)
    count_seconds (Seconds2)
    TotalTime := TotalTime + (Seconds2 - Seconds1)
    * 设置模板中心点为图像中心点(为了在后面的步骤中正确投影矩形的原点)
    set_descriptor_model_origin (ModelID, -Height / 2, -Width / 2)
    ModelIDs := [ModelIDs,ModelID]
    * 从模板中获取所有的描述点
    *存储从模型中提取的点,以备后续匹配。
    get_descriptor_model_points (ModelID, 'model', 'all', Row_D, Col_D)
    NumPoints := [NumPoints,|Row_D|]
endfor
* 
* Model creation finished.
dev_display (ImageGray)
disp_message (WindowHandle, NumModels + ' models created in ' + TotalTime$'.4' + ' seconds.', 'window', 10, 10, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Initialize the window again, because the image size has changed.
read_image (Image, 'brochure/brochure_01')
dev_resize_window_fit_image (Image, 0, 0, -1, -1)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
* 
* Main loop:
* Search the models in all images
for Index1 := 1 to 12 by 1
    OutputString := []
    NumMsgs := 0
    ModelsFound := 0
    TotalTime := 0
    read_image (Image, 'brochure/brochure_' + Index1$'.2')
    rgb1_to_gray (Image, ImageGray)
    dev_display (Image)
    disp_message (WindowHandle, 'Searching image ...', 'window', 10, 10, 'black', 'true')
    * 
    * Search every model in each image
    for Index2 := 0 to |ModelIDs| - 1 by 1
        * 
        * Find model (using default parameters)
        count_seconds (Seconds1)
        find_uncalib_descriptor_model (ImageGray, ModelIDs[Index2], 'threshold', 600, ['min_score_descr','guided_matching'], [0.003,'on'], 0.25, 1, 'num_points', HomMat2D, Score)
        count_seconds (Seconds2)
        Time := Seconds2 - Seconds1
        TotalTime := TotalTime + Time
        * 
        * Check if the found instance is to be considered as a possible right match
        * depending on the number of points which were considered
        if ((|HomMat2D| > 0) and (Score > NumPoints[Index2] / 4))
       	    *获取搜索到的描述点坐标
            get_descriptor_model_points (ModelIDs[Index2], 'search', 0, Row, Col)
            gen_cross_contour_xld (Cross, Row, Col, 6, 0.785398)
            * 
            * 利用查找模板结果输出的投影变换矩阵,对原始模板区域仿射变换到当前找到的模板位置。
            * 利用查找模板结果输出的投影变换矩阵,对原始坐标进行变换
            projective_trans_region (Rectangle, TransRegion, HomMat2D, 'bilinear')
            projective_trans_pixel (HomMat2D, RowRoi, ColRoi, RowTrans, ColTrans)
            angle_ll (RowTrans[2], ColTrans[2], RowTrans[1], ColTrans[1], RowTrans[1], ColTrans[1], RowTrans[0], ColTrans[0], Angle)
            Angle := deg(Angle)
            * 
            * Check if the projected rectangle is to be considered as a right match
            * depending on the angle in the right upper edge.
            if (Angle > 70 and Angle < 110)
                area_center (TransRegion, Area, Row, Column)
                ModelsFound := ModelsFound + 1
                dev_set_color ('green')
                dev_set_line_width (4)
                dev_display (TransRegion)
                dev_set_colored (12)
                dev_set_line_width (1)
                dev_display (Cross)
                disp_message (WindowHandle, 'Page ' + (Index2 + 1), 'window', Row, Column, 'black', 'true')
                OutputString := [OutputString,'Page ' + (Index2 + 1) + ' found in ' + (Time * 1000)$'.4' + ' ms\n']
            endif
        endif
    endfor
    if (ModelsFound == 0)
        OutputString := 'No model found'
    endif
    NumMsgs := NumMsgs + 1
    OutputString := ['Search time over all pages: ' + (TotalTime * 1000)$'.4' + ' ms',OutputString]
    disp_message (WindowHandle, OutputString, 'window', 10, 10, 'black', 'true')
    disp_continue_message (WindowHandle, 'black', 'true')
    stop ()
endfor
dev_display (ImageGray)
disp_message (WindowHandle, 'Program finished.\nPress \'Run\' to clear all descriptor models.', 'window', 10, 10, 'black', 'true')

元画像
ここに画像の説明を挿入
と結果画像
ここに画像の説明を挿入
5. 注意事項
5.1 検索テンプレートの出力結果はスコアとアフィン変換行列のみです。通常のテンプレート マッチのように、見つかったテンプレートの座標は出力されません。ただし、出力行列 HoMat2D を使用して、元のテンプレート領域および領域座標にアフィン変換を実行して、現在検索されているテンプレート領域および領域座標を取得できます。

おすすめ

転載: blog.csdn.net/Douhaoyu/article/details/128370372