人間の姿勢認識は、コンピュータビジョンの分野における重要なアプリケーションであり、人体の主要なポイントや関節の位置を識別することで、人体の姿勢や動きを正確に判断できます。この技術はスポーツトレーニング、医療リハビリテーション、セキュリティ監視など多くの分野に応用でき、人々の生活や仕事に大きな利便性と利益をもたらします。
Pythonと深層学習技術に基づく人間のジェスチャ認識
この記事では、Python とディープラーニング技術をベースにした人体の姿勢認識手法を紹介しますカメラで撮影した写真やビデオストリームを読み込むことで、OpenCV と Tensorflow モデルを使用して画像中の人体の姿勢を検出し、最終的に画像を出力します、体の各キーポイントと関節の位置、および関節間の接続をマークします。
準備
人間のジェスチャ認識の実装を開始する前に、必要なツールと材料を準備する必要があります。まず、Python 環境と、OpenCV、Tensorflow、Numpy などの関連ライブラリをインストールする必要があります。次に、画像内の人間のポーズを検出するために、事前トレーニングされた Tensorflow モデルをダウンロードする必要があります。最後に、カメラでキャプチャされた画像またはビデオ ストリームが入力データとして必要になります。
モデルをロードしてパラメータを定義する
モデルをロードする前に、ボディパーツの数やジョイントの接続など、いくつかの定数とパラメータを定義する必要があります。具体的なコードは次のとおりです。
import cv2
import numpy as np
# 定义身体部位编号
body_parts = {
0: "Nose",
1: "Neck",
2: "Right Shoulder",
3: "Right Elbow",
4: "Right Wrist",
5: "Left Shoulder",
6: "Left Elbow",
7: "Left Wrist",
8: "Right Hip",
9: "Right Knee",
10: "Right Ankle",
11: "Left Hip",
12: "Left Knee",
13: "Left Ankle",
14: "Right Eye",
15: "Left Eye",
16: "Right Ear",
17: "Left Ear"
}
# 定义关节连线
pose_parts = [
[0, 1], [1, 2], [2, 3], [3, 4], [1, 5], [5, 6],
[6, 7], [1, 8], [8, 9], [9, 10], [1, 11], [11, 12], [12, 13],
[0, 14], [14, 16], [0, 15], [15, 17]
]
# 加载预训练的 Tensorflow 模型
net = cv2.dnn.readNetFromTensorflow("graph_opt.pb")
写真やビデオストリームを読む
次に、カメラでキャプチャされた画像またはビデオ ストリームを入力データとして読み取る必要があります。具体的なコードは次のとおりです。
# 读取图片或者视频流
image = cv2.imread("test.jpg")
# cap = cv2.VideoCapture(0)
ビデオ ストリームを読みたい場合は、コメントをキャンセルし、パラメータを対応するカメラ番号に設定します。
画像データを処理する
画像データをモデルに入力する前に、画像に対して何らかの処理を行って、ニューラル ネットワークが必要とする入力形式に変換する必要があります。具体的なコードは次のとおりです。
python
# 处理图像数据
blob = cv2.dnn.blobFromImage(image, 1.0, (368, 368), (0, 0, 0), swapRB=False, crop=False)
net.setInput(blob)
output = net.forward()
このうち、cv2.dnn.blobFromImage 関数は、画像をニューラル ネットワークに必要な入力形式に変換するために使用されます。つまり、画像を指定したサイズに拡大縮小し、平均値を減算し、正規化やその他の操作を実行します。net.setInput 関数は、ニューラル ネットワークの入力データを設定するために使用されます。net.forward 関数は、キーポイントの座標を取得するための順伝播計算に使用されます。
キーポイントとジョイントラインを描く
キーポイントの座標を取得したら、観察と分析のためにそれらを描画する必要があります。具体的なコードは次のとおりです。
# 绘制关键点和关节连线
points = []
for i in range(len(body_parts)):
# 获取可信度
prob = output[0, i, 2]
# 判断可信度是否达到阈值
if prob > 0.5:
# 获取关键点坐标
x = int
完全なコード
import cv2
# 关节标识
body_parts={
"Nose":0,"Neck":1,
"RShoulder":2,"RElbow":3,"RWrist":4,
"LShoulder": 5, "LElbow": 6, "LWrist": 7,
"RHip":8,"RKnee":9,"RAnkle":10,
"LHip":11,"LKnee":12,"LAnkle":13,
"REye":14,"LEye":15,
"REar":16,"LEar":17
}
#关节连线
pose_parts=[
["Neck","RShoulder"],["Neck","LShoulder"],
["RShoulder","RElbow"],["RElbow","RWrist"],
["LShoulder","LElbow"],["LElbow","LWrist"],
["Neck","RHip"],["RHip","RKnee"],["RKnee","RAnkle"],
["Neck","LHip"], ["LHip","LKnee"], ["LKnee","LAnkle"],
["Neck","Nose"],
["Nose","REye"], ["REye","REar"],
["Nose","LEye"], ["LEye","LEar"]
]
cap=cv2.VideoCapture("a2.jpg")
# cap=cv2.VideoCapture(0,cv2.CAP_DSHOW)
# 加载模型
net=cv2.dnn.readNetFromTensorflow("pose.pb")
while cv2.waitKey(1)<0:
ok,frame=cap.read()
if not ok:
cv2.waitKey()
break
width=frame.shape[1]
height=frame.shape[0]
net.setInput(cv2.dnn.blobFromImage(
frame,1.0,(368,368),(127,127,127),swapRB=True,crop=False
))
out=net.forward()
out=out[:,:19,:,:]
# print(out)
points=[]
for i in range(len(body_parts)):
heatmap=out[0,i,:,:]
_,conf,_,point=cv2.minMaxLoc(heatmap)
x=(width*point[0])/out.shape[3]
y=(height*point[1])/out.shape[2]
points.append((int(x),int(y))if conf>0.2 else None)
# print(points)
for p in pose_parts:
partfrom = p[0]
partto=p[1]
idfrom=body_parts[partfrom]
idto=body_parts[partto]
if points[idfrom] and points[idto]:
# 画线
cv2.line(frame,points[idfrom],points[idto],(0,200,0),3)
# 画点
cv2.ellipse(frame,points[idfrom],(3,3),0,0,360,(0,0,200),cv2.FILLED)
cv2.ellipse(frame, points[idto], (3, 3), 0, 0, 360, (0, 0, 200), cv2.FILLED)
cv2.imshow("",frame)