NCC テンプレートマッチング

ビデオチュートリアル8 - NCCテンプレートマッチング: https://singtown.com/learn/49598/

NCCアルゴリズム:

# テンプレートマッチングの例 - 正規化相互相関 (NCC)
#
# この例は、OpenMV Cam の NCC 機能を使用して、画像パッチを画像内の一部分と
# マッチングする方法を示しています…非常に条件が制御された環境を除けば、
# NCC はあまり実用的ではありません。
#
# 警告: NCC のサポートは見直しが必要です!現時点では、この機能を実用的なものに
# するにはまだ多くの作業が必要です。このスクリプトはこの機能が存在することを
# 示すために残していますが、現状のままでは実用には不十分です。

import csi
import time, csi, image
csi0 = csi.CSI()

from image import SEARCH_EX, SEARCH_DS
#image モジュールから SEARCH_EX と SEARCH_DS を読み込みます。from import を使うことで、
#image モジュール全体ではなく、必要な SEARCH_EX と SEARCH_DS の2つの部分だけを読み込みます。

# センサーをリセット
csi0.reset()

# センサーの設定
csi0.contrast(1)
csi0.gainceiling(16)
# SEARCH_EX を使ったテンプレートマッチングの最大解像度は QQVGA です
csi0.framesize(csi.QQVGA)
# 検索対象の画像を縮小するためにウィンドウを設定することもできます。
#csi0.window(((640-80)//2, (480-60)//2, 80, 60))
csi0.pixformat(csi.GRAYSCALE)

# テンプレートを読み込みます。
# テンプレートは小さな(例: 32x32ピクセル)グレースケール画像である必要があります。
template = image.Image("template.pgm")
#テンプレート画像を読み込みます

clock = time.clock()

# テンプレートマッチングを実行
while (True):
    clock.tick()
    img = csi0.snapshot()

    # find_template(template, threshold, [roi, step, search])
    # ROI: 関心領域を表すタプル (x, y, w, h)。
    # Step: ループのステップ幅 (y+=step, x+=step)。大きい値にすると高速化できます。
    # search には、網羅的探索を行う image.SEARCH_EX か、ダイヤモンド探索を行う image.SEARCH_DS を指定します
    #
    # 注1: ROI は画像より小さく、テンプレートより大きい必要があります。
    # 注2: ダイヤモンド探索では、step と ROI はどちらも無視されます。
    r = img.find_template(template, 0.70, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    #find_template(template, threshold, [roi, step, search])、threshold の
    #0.7は類似度の閾値、roiはマッチングを行う領域です(左上頂点が(10,0)、幅80高さ60の矩形)。
    #roi のサイズはテンプレート画像より大きく、フレームバッファより小さくする必要があります。
    #マッチングした画像に印を付けます
    if r:
        img.draw_rectangle(r)

    print(clock.fps())

テンプレート画像のサイズが openmv の内蔵フラッシュ容量を超えるため、以下の手順を実行する前に SD カードを挿入する必要があります。(電源を入れる前に SD カードを挿入しておいてください。)また、このテンプレートマッチングはファームウェアバージョン 1.6 以降でのみ使用できます。それ以前のバージョンでは、実行時に「can not find SEARCH_EX」と表示されます。

まず、テンプレートを作成またはインポートする必要があります。このテンプレートは pgm 形式でなければならず、サイズは openmv のピクセルサイズを超えることはできません。openmv から直接テンプレート画像をキャプチャすることができます。まず helloworld.py のルーチンを実行してフレームバッファに画像を表示させ、それをキャプチャしてください。

「Save image」でPCへの保存を選択します。openmv から直接キャプチャして保存した画像は bmp 形式であることに注意してください。これを pgm 形式に変換する必要があります。以下のサイトでオンライン変換ができます。 https://convertio.co/zh/bmp-pgm/

次に、変換した pgm テンプレートを SD カードに保存します(この SD カードには8つのテンプレートが含まれており、上の画像のテンプレートは ball0.pgm として保存されています)。

次に、テンプレートマッチングのルーチンを開きます。

28行目のテンプレートファイル名 template.pgm を、先ほどの ball0.pgm に変更します。

そのまま実行してください!

これは、テンプレートマッチング関数 find_template の使い方です。

r = img.find_template(template, 0,7, roi=(10,0,80,60), step=4, search=SEARCH_EX) threshold の 0.7 は類似度の閾値であり、roi はマッチングを行う領域です(左上頂点が (10, 0)、幅80・高さ60)。roi のサイズはテンプレート画像より大きく、フレームバッファより小さくする必要があります。

このテンプレートマッチングは ncc アルゴリズムを使用しており、テンプレートとほぼ同じサイズの領域しかマッチングできません。異なるサイズの画像をマッチングしたい場合は、サイズの異なる複数のテンプレートを保存する必要があります。

プログラム実行後に以下のような問題が発生した場合:

  1. テンプレート画像が大きすぎます。テンプレート画像は80*60より小さくすることをお勧めします。

  1. OpenMV2 のメモリが不足しています。QQVGA を QQCIF に変更してください。


テンプレートマッチングと特徴点検出の比較:
  • テンプレートマッチング (find_temolate) は ncc アルゴリズムを使用しており、テンプレート画像とほぼ同じサイズ・角度のパターンしかマッチングできません。制約が比較的大きく、視野内のターゲットパターンがテンプレート画像よりわずかに大きい、または小さい場合、マッチングに失敗することがあります。

  • テンプレートマッチングは、カメラとターゲット物体との距離が一定で、動的な動きを必要としない状況に適しています。たとえば、組み立てラインでの特定物体の検出には適していますが、動くバレーボールを車で追跡する用途には適していません(動くバレーボールとカメラの距離は変化するため、カメラに映るバレーボールのサイズも変わり、テンプレート画像と完全には一致しなくなるためです)。

  • 複数の角度・複数のサイズでのマッチングを行いたい場合は、複数のテンプレートを保存し、複数テンプレート マッチング を使用してみてください。

  • 特徴点検出 (find_keypoint): プログラムを最初に実行すると、このルーチンは最初の画像をターゲット物体の特徴として抽出し、kpts1 にターゲット物体の特徴を保存します。デフォルトでは、ターゲット特徴のサイズと角度だけでなく、複数のスケールと角度でマッチングを行います。テンプレートマッチングより柔軟であり、複数テンプレートマッチングのように複数のテンプレート画像を保存する必要もありません。

  • 特徴点検出でも、あらかじめターゲットの特徴を保存しておくことができます。以前はこれは推奨されていませんでした。周囲光などの干渉により、プログラムを実行するたびに照明条件の異なる特徴が抽出され、マッチング度が低下する可能性があったためです。しかし、最新版のファームウェアでは、露出・ホワイトバランス・自動ゲイン値の調整機能が追加されており、露出値とホワイトバランス値を手動で設定できるため、光の干渉を相対的に低減できます。あらかじめターゲットの特徴を保存しておく方法も試してみることができます。


results matching ""

    No results matching ""