作業手順

1. それぞれの画像から対応する四点を取得する
2. 対応する四点から変換行列を作成する
3. 元の画像から選手の座標を取得する
4. 変換行列を使い選手の座標を変換する
5. 変換した座標の地点に円を描画する

※ Pythonで座標を扱う際は、x軸もy軸も左上から数えることに注意してください!
※ また、ここどうなってんの?となった時はprint()などで出力して確認してみてください。

1.それぞれの画像から対応する四点を取得する。

setMouseCallback()を使用することで、マウスでクリックした場所の座標を取得することができます。
引数: ウィンドウ名, コールバック関数

コールバック関数として onMouse()を用意しています。左クリックに反応して座標を返します。

Practice!: setMouseCallbackを利用して画像から四点を取得してみてください。

サンプルコードはsample_code.ipynbにあります

取得出来たらそれぞれの座標を下の [corners] 配列に代入して実行してください。(左上 → 右上 → 右下 → 左下 の座標の順で格納します)
下のコードでは、赤線を引いて、取得した座標が正しいかどうか確認しています。

[corners] 配列に四点の座標を設定することができました。
同じようにしてフィールドの画像でも四点の座標を取得しますが、今回はあらかじめ用意していた座標を使用します。

after_corner = [[1185, 28], [1860, 28], [1788, 1050], [1365, 1050]]

2.対応する四点から変換行列を作成する

これをすることで、beforeの四角形をafterの四角形に変換する際の変換行列が作成されます。

3.元の画像から選手の座標を取得する

practice_exercise_yolov5で .xyxy[0]を使用して選手を囲ったバウンティボックスの座標を取得することができました。
今回はバウンティボックスの下辺の中央(選手の足元)をその選手の座標として扱います。

yolov5.loadで作成したモデルの.classesに値を指定することで、検知するクラスを絞り込むことができます。

以下のクラスが用意されています。

names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
        'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
        'hair drier', 'toothbrush']  # class names

personのみを検知してほしい場合

model.classes = 0

選手一人の座標が取得できたので、その地点に円を描画して座標がどこなのか確認します。
円の描画はcircleメソッドを使用します。

OpenCVの描画系メソッドをまとめたサイトがあったのでここに貼っておきます

4.変換行列を使い選手の座標を変換する

前回使用したwarpPerspectiveは変換行列に応じて画像を変形させることができました。
しかし今回は選手の座標のみを変換するため、違うメソッドを使用します。

perspectiveTransform() を使用することで、変換前の座標を変換行列をもとに変換することができます。 引数: 変換するもの, 変換行列

ここでようやく、変換後の座標を取得することができました。

5.変換した座標の地点に円を描画する

circleを使用し、変換した座標がfield画像上のどこに対応しているのか確認します。

今ままでの技術を応用すると、以下のようなものを作ることができます。

2Dマッピングの資料は以上となります。
僕らが実際に書いたコードをsample_code.ipynbに配置しておくので、気になった方は見てみてください。

お疲れさまでした!