Raspberry Piでカメラ映像の骨格検出をする方法 Part 1

  • URLをコピーしました!

※本ページはアフィリエイト広告を利用しています

今回から2回に分けて、Raspberry Piで撮影した映像に映った人物の骨格検出を行う方法を解説していきます。
Part 1ではOpenPoseを使って静止画に対して骨格検出を行うプログラムを作成していきます。

また、、OpenCVの活用事例についても以下の記事で解説していますので、あわせてご覧ください。

\OpenCVを使った画像処理を学びたい人には自宅で学べるUdemyがおすすめ!  /

講座単位で購入できます!

目次

openposeを入手する

今回、骨格検出するアプリケーションにはgithubで公開されているspmallick氏の「learnopencv」のプロジェクトを利用させて頂きました。以下のリポジトリをダウンロードします。

「Code」のプルダウンメニューの「Download ZIP」をクリックしてプロジェクトファイルをダウンロードしてください。

「(ダウンロードしたファイルのディレクトリパス)\learnopencv-master\OpenPose」にある「OpenPose_Notebook.ipynb」が骨格検出のプログラムになります。

著:小枝正直, 著:上田悦子, 著:中村恭之
¥3,080 (2024/04/13 09:15時点 | Amazon調べ)

モデルを入手する

骨格検出のための学習済みモデルをダウンロードします。

モデルのダウンロード

「(ダウンロードしたファイルのディレクトリパス)\learnopencv-master\OpenPose\getModels.sh」のファイルにモデルのダウンロード先が書かれています。「COCO」と「MPI」の2つのモデルファイルをダウンロードしてください。

# ------------------------- POSE MODELS -------------------------


# Downloading the pose-model trained on COCO
COCO_POSE_URL="https://www.dropbox.com/s/2h2bv29a130sgrk/pose_iter_440000.caffemodel"
COCO_FOLDER="pose/coco/"
wget -c ${COCO_POSE_URL} -P ${COCO_FOLDER}

# Downloading the pose-model trained on MPI
MPI_POSE_URL="https://www.dropbox.com/s/drumc6dzllfed16/pose_iter_160000.caffemodel"
MPI_FOLDER="pose/mpi/"
wget -c ${MPI_POSE_URL} -P ${MPI_FOLDER}

モデルを配置する

ダウンロードしたモデルファイルを配置します。
2つのモデルファイルをそれぞれ以下のディレクトリに配置してください。

pose_iter_440000.caffemodel

「(ダウンロードしたファイルのディレクトリパス)\learnopencv-master\learnopencv-master\OpenPose\pose\coco」

pose_iter_160000.caffemodel

「(ダウンロードしたファイルのディレクトリパス)\learnopencv-master\learnopencv-master\OpenPose\pose\mpi」

作成したソースコード

実際に骨格検出を行うプログラムを作成していきます。ダウンロードした「learnopencv」のソースコードはjupyter notebookファイルですので、Raspberry Piで実行するために必要な処理だけを実装します。

モデルの選択

ダウンロードした「COCO」と「MPI」のどちらのモデルを使用するかは、実際に読み込む画像によって使い分けてみてください。「MODE」という変数に使いたいモデルを指定することで切り替えることができます。
今回は「MPI」を使うことにしました。

#読み込むモデルを選択
MODE = "MPI"

if MODE is "COCO":
    protoFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/coco/pose_deploy_linevec.prototxt"
    weightsFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/coco/pose_iter_440000.caffemodel"
    nPoints = 18
    POSE_PAIRS = [ [1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]]

elif MODE is "MPI" :
    protoFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/mpi/pose_deploy_linevec_faster_4_stages.prototxt"
    weightsFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/mpi/pose_iter_160000.caffemodel"
    nPoints = 15
    POSE_PAIRS = [[0,1], [1,2], [2,3], [3,4], [1,5], [5,6], [6,7], [1,14], [14,8], [8,9], [9,10], [14,11], [11,12], [12,13] ]

全体のソースコード

以下が作成したコードの全体です。今回はRaspberry Piに実装する前に、PCで静止画で骨格検出ができるかテストするためのコードとなります。
画像はOpenPoseのディレクトリに最初から用意されている「single.jpeg」をそのまま使用します。
ディレクトリを指定している箇所は、環境に合わせてパスを変更して使ってください。

import cv2
import time
import numpy as np
import matplotlib.pyplot as plt


frame = cv2.imread(r"(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/single.jpeg")
frameCopy = np.copy(frame)
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]
threshold = 0.1

#読み込むモデルを選択
MODE = "MPI"

if MODE is "COCO":
    protoFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/coco/pose_deploy_linevec.prototxt"
    weightsFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/coco/pose_iter_440000.caffemodel"
    nPoints = 18
    POSE_PAIRS = [ [1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]]

elif MODE is "MPI" :
    protoFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/mpi/pose_deploy_linevec_faster_4_stages.prototxt"
    weightsFile = "(ダウンロードしたファイルのディレクトリパス)/learnopencv-master/OpenPose/pose/mpi/pose_iter_160000.caffemodel"
    nPoints = 15
    POSE_PAIRS = [[0,1], [1,2], [2,3], [3,4], [1,5], [5,6], [6,7], [1,14], [14,8], [8,9], [9,10], [14,11], [11,12], [12,13] ]


print("protoFile = ", protoFile)
print("weightsFile = ", weightsFile)
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)

inWidth = 368
inHeight = 368

inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
                          (0, 0, 0), swapRB=False, crop=False)

net.setInput(inpBlob)

output = net.forward()
H = output.shape[2]
W = output.shape[3]

points = []

for i in range(nPoints):
    # confidence map of corresponding body's part.
    probMap = output[0, i, :, :]

    # Find global maxima of the probMap.
    minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
    
    # Scale the point to fit on the original image
    x = (frameWidth * point[0]) / W
    y = (frameHeight * point[1]) / H

    if prob > threshold : 
        cv2.circle(frameCopy, (int(x), int(y)), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
        cv2.putText(frameCopy, "{}".format(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, lineType=cv2.LINE_AA)
        cv2.circle(frame, (int(x), int(y)), 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)

        # Add the point to the list if the probability is greater than the threshold
        points.append((int(x), int(y)))
    else :
        points.append(None)

# Draw Skeleton
for pair in POSE_PAIRS:
    partA = pair[0]
    partB = pair[1]

    if points[partA] and points[partB]:
        cv2.line(frame, points[partA], points[partB], (0, 255, 255), 3)

print("画像出力")

plt.figure(figsize=[10,10])
plt.imshow(cv2.cvtColor(frameCopy, cv2.COLOR_BGR2RGB))
plt.show()
plt.figure(figsize=[10,10])
plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
plt.show()
著:北山 直洋
¥3,630 (2024/04/16 18:36時点 | Amazon調べ)

実行結果

実行結果は以下の通りです。うまく骨格検出することができました。モデルを変更すると結果も変わりますので試してみてください。

まとめ

今回はOpenCVで骨格検出を行う方法を解説しました。次回はRaspberry Piに実装するためのコードを作成して、カメラで撮影した映像に対してリアルタイムに骨格検出します。

また、OpenCVをさらに詳しく学びたい方には、Udemyの以下の講座もお勧めです。

icon icon 【Pythonで学ぶ】OpenCVでの画像処理入門 icon

また、以下の記事で効率的にPythonのプログラミングスキルを学べるプログラミングスクールの選び方について解説しています。最近ではほとんどのスクールがオンラインで授業を受けられるようになり、仕事をしながらでも自宅で自分のペースで学習できるようになりました。

スキルアップや副業にぜひ活用してみてください。

スクールではなく、自分でPythonを習得したい方には、いつでもどこでも学べる動画学習プラットフォームのUdemyがおすすめです。

講座単位で購入できるため、スクールに比べ非常に安価(セール時1200円程度~)に学ぶことができます。私も受講しているおすすめの講座を以下の記事でまとめていますので、ぜひ参考にしてみてください。

それでは、また次の記事でお会いしましょう。

著:山内 直, 著:大久保 竣介, 著:森本 梨聖, 監修:太田 昌文
¥2,618 (2024/04/15 16:31時点 | Amazon調べ)

参考

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次