Pythonでキーワード分岐する時どう書くか（テンプレートトラッキングへの応用）

PythonにはSwitch文がありません。
長い処理分岐は難しいですが手法のキーワードに合わせて処理を微修正する程度なら以下の記事のように**辞書型**の記述を行うことで生成可能です。
https://qiita.com/hasegit/items/2cf05de74680717f9010


例えば，以下がopencvでの特徴点抽出に用いる特徴量記述方法によってDescriptorを分岐させる関数です。

```python
def get_des(name):
    return {
        'ORB': cv2.ORB_create(nfeatures=500,scoreType=cv2.ORB_HARRIS_SCORE),
        'AKAZE': cv2.AKAZE_create(),
        'KAZE' : cv2.KAZE_create(),
        'SIFT' : cv2.xfeatures2d.SIFT_create(),
        'SURF' : cv2.xfeatures2d.SURF_create()
    }.get(name, 0)  
```

[特徴ベースのテンプレートトラッキング](https://github.com/YoshiRi/TemplateTracker)で使用しました。

# プログラム例

以上の手法を用いて[こちらのブログ](https://ensekitt.hatenablog.com/entry/2017/12/21/200000)のテンプレートトラッキングの手法を分岐させます。大変参考になりました。


元のファイルに対する主な変更点として，

- 引数に「ビデオのファイル名」，「手法名」，「デフォルトのROI」を渡すことで選択可能にした
- 使える手法：Boosting,MIL,KCF,TLD,MedianFlow

があります。

```python
import cv2
import sys
import numpy as np

def get_tracker(name):
    """
    キーワードに応じてTrackerを選択
    """
    return {
        'Boosting': cv2.TrackerBoosting_create(),
        'MIL': cv2.TrackerMIL_create(),
        'KCF' : cv2.TrackerKCF_create(),
        'TLD' : cv2.TrackerTLD_create(),
        'MedianFlow' : cv2.TrackerMedianFlow_create()
    }.get(name, 0)  

def extractROI(frame,roi):
    return frame[int(roi[1]):int(roi[1]+roi[3]),int(roi[0]):int(roi[0]+roi[2])]


if __name__ == '__main__':
    """
    引数１：ファイル名，引数２：Method名，引数３：BoundingBox
    
    Method: Boosting, MIL, KCF, TLD, MedianFlow
    """
    ##---------- File name -----------##
    try:
        filename = sys.argv[1]
    except:
        filename = 'Videos/square50.avi'

    ##---------- Method ----------------##
    try:
        method = sys.argv[2]
    except:
        method = 'KCF'
    print('USE '+method+' Tracker!')
    ##----------  Tuple --------------- ##
    try:
        bbox = eval(sys.argv[3])
        print(bbox)
        hasframe = 1
    except:
        hasframe = 0

    cap = cv2.VideoCapture(filename)
    ret, frame = cap.read()
    if not ret:
        print('Can not open file:' + filename +'!')
        exit(-1)

    # capture the frame
    if not hasframe:
        bbox = cv2.selectROI(frame, False)
        print(bbox)
        cv2.destroyAllWindows()
    
    # Load tracker
    tracker = get_tracker(method)
    ok = tracker.init(frame, bbox)

    
    while True:
        # VideoCaptureから1フレーム読み込む
        ret, frame = cap.read()
        if not ret:
            k = cv2.waitKey(1)
            if k == 27 :
                break
            continue

        # Start timer
        timer = cv2.getTickCount()

        # トラッカーをアップデートする
        track, bbox = tracker.update(frame)

        # FPSを計算する
        fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)

        # 検出した場所に四角を書く
        if track:
            # Tracking success
            drawrect(frame,bbox)

        else :
            # トラッキングが外れたら警告を表示する
            cv2.putText(frame, "Failure", (10,50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1, cv2.LINE_AA)

        # FPSを表示する
        cv2.putText(frame, "FPS : " + str(int(fps)), (10,20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1, cv2.LINE_AA)

        # 加工済の画像を表示する
        cv2.imshow("Tracking", frame)

        # キー入力を1ms待って、k が27（ESC）だったらBreakする
        k = cv2.waitKey(1)
        if k == 27 :
            break

# キャプチャをリリースして、ウィンドウをすべて閉じる
cap.release()
cv2.destroyAllWindows()
```

環境はOpenCV3.4，Python3.5です。
雑ですがメモとして。