LoginSignup
4
3

More than 1 year has passed since last update.

[2022年]MediaPipeで取得した座標データの統一化の方法[CSVファイル]

Last updated at Posted at 2022-06-08

MediaPipeで取得した座標データの統一化

手の座標の見本です。
aa.jpg

2つのポイントを決定する。具体的にはP0(WRIST)を絶対動かない基準として設定する。それとP9(MIDDLE_FINGER_MCP)からP0までの距離が1になるように大きさを揃える。(P9以外でも大丈夫です。)
※z軸はあってもなくても大丈夫です。

まず全体のソースコードです。

normalize.py
import csv
import numpy as np
import math

with open("landmark.csv") as file_name:
    array = np.loadtxt(file_name, delimiter=",").ravel()
    #print(array)
    
x1 = array[::3]
y1 = array[1::3]
z1 = array[2::3]
    
x2 = []
y2 = []
z2 = []
for i in range(0,21):
    a = x1[i] - x1[0]
    x2.append(a)
    b = y1[i] - y1[0]
    y2.append(b)
    c = z1[i] - z1[0]
    z2.append(c)
#print(x2, y2, z2)

#k = math.sqrt((x2[1] - x2[0])**2 + (y2[1] - y2[0])**2)
k = math.sqrt((x2[1] - x2[0])**2 + (y2[1] - y2[0])**2 + (z2[1] - z2[0])**2)
print(k)

x = []
y = []
z = []
for i in range(20):
    d = x2[i] / k
    x.append(d)
    e = y2[i] / k
    y.append(e)
    f = z2[i] / k
    z.append(f)
#print(x, y, z)

"""
#xy = []
xy.extend(x)
xy.extend(y)
np.savetxt('distance.csv', xy, delimiter=',')
"""

xyz = [] 
xyz.extend(x)
xyz.extend(y)
xyz.extend(z)

np.savetxt('distance.csv', xyz, delimiter=',')

読込用の座標データです。

landmark.csv
#0_x,0_y,0_z,1_x,1_y,1_z,2_x,2_y,2_z,3_x,3_y,3_z,4_x,4_y,4_z,5_x,5_y,5_z,6_x,6_y,6_z,7_x,7_y,7_z,8_x,8_y,8_z,9_x,9_y,9_z,10_x,10_y,10_z,11_x,11_y,11_z,12_x,12_y,12_z,13_x,13_y,13_z,14_x,14_y,14_z,15_x,15_y,15_z,16_x,16_y,16_z,17_x,17_y,17_z,18_x,18_y,18_z,19_x,19_y,19_z,20_x,20_y,20_z

0.451469481,0.652247429,3.88E-07,0.39776203,0.594621599,-0.000152903,0.373409241,0.51929009,-0.019663431,0.377043515,0.45223251,-0.03330189,0.396842062,0.40474093,-0.041340236,0.401626706,0.50286001,-0.103324965,0.408331186,0.379671395,-0.116982467,0.409053624,0.395460844,-0.100276023,0.411410362,0.427753359,-0.084593035,0.451683015,0.509396553,-0.106109776,0.444376409,0.365016639,-0.143135041,0.440043449,0.294116557,-0.147520944,0.442870706,0.250151962,-0.149211541,0.494813234,0.521774828,-0.095909588,0.484428912,0.393632114,-0.10612002,0.467082083,0.414141715,-0.072775304,0.458774358,0.449492723,-0.049317408,0.530400872,0.536703229,-0.083674148,0.512897849,0.439408749,-0.077969834,0.497577071,0.452368796,-0.045357663,0.494336367,0.482049167,-0.020433536

読み込んだ座標をx, y, z軸でそれぞれ分けます。

x1 = array[::3]
y1 = array[1::3]
z1 = array[2::3]

>>print(x1, y1, z1)
x1 = [0.45146948, 0.39776203, 0.37340924, 0.37704351, 0.39684206, 0.40162671, 0.40833119, 0.40905362, 0.41141036, 0.45168302, 0.44437641, 0.44004345, 0.44287071, 0.49481323, 0.48442891, 0.46708208, 0.45877436, 0.53040087, 0.51289785, 0.49757707, 0.49433637]
y1 = [0.65224743, 0.5946216, 0.51929009, 0.45223251, 0.40474093, 0.50286001, 0.3796714, 0.39546084, 0.42775336, 0.50939655, 0.36501664, 0.29411656, 0.25015196, 0.52177483, 0.39363211, 0.41414172, 0.44949272, 0.53670323, 0.43940875, 0.4523688 , 0.48204917]
z1 = [3.88000000e-07, -1.52903000e-04, -1.96634310e-02, -3.33018900e-02, -4.13402360e-02, -1.03324965e-01, -1.16982467e-01, -1.00276023e-01, -8.45930350e-02, -1.06109776e-01, -1.43135041e-01, -1.47520944e-01, -1.49211541e-01, -9.59095880e-02, -1.06120020e-01, -7.27753040e-02, -4.93174080e-02, -8.36741480e-02, -7.79698340e-02, -4.53576630e-02, -2.04335360e-02]

以下の配列は、それぞれの点(P1~20)のxyz座標の値を点0の座標で引いたものを表します。

x2 = []
y2 = []
z2 = []

>>print(x2, y2, z2)
x2 = [0.0, -0.05370745100000002, -0.07806024, -0.07442596600000001, -0.05462741900000001, -0.049842775000000006, -0.04313829499999999, -0.042415857, -0.04005911900000003, 0.0002135340000000152, -0.007093071999999978, -0.01142603200000003, -0.008598775000000003, 0.043343752999999985, 0.032959430999999983, 0.015612601999999975, 0.007304876999999987, 0.07893139099999996, 0.06142836800000001, 0.046107589999999976, 0.04286688599999999]
y2 = [0.0, -0.05762582999999999, -0.13295733899999995, -0.200014919, -0.247506499, -0.14938741899999997, -0.27257603399999997, -0.256786585, -0.22449407, -0.14285087600000002, -0.28723079, -0.358130872, -0.402095467, -0.13047260100000002, -0.258615315, -0.23810571399999997, -0.202754706, -0.11554419999999999, -0.21283868, -0.19987863299999997, -0.170198262]
z2 = [0.0, -0.000153291, -0.019663819, -0.033302278, -0.041340624, -0.10332535300000001, -0.11698285500000001, -0.10027641100000001, -0.084593423, -0.106110164, -0.14313542899999998, -0.14752133199999998, -0.149211929, -0.09590997600000001, -0.106120408, -0.072775692, -0.049317796, -0.08367453600000001, -0.077970222, -0.045358050999999996, -0.020433924]

以下でP0からP9の距離を求める。

k = math.sqrt((x2[9] - x2[0])**2 + (y2[9] - y2[0])**2 + (z2[9] - z2[0])**2)

>>print(k)
k = 0.177948827686061

次に手のサイズを揃える。
||点9 - 点0|| =1 となるようにする。
つまりk = sqrt((x9-x0)^2 + (y9-y0)^2 + (z9-z0)^2) として、
すべての点0〜点20の座標値をkで割る。
割られた後の座標値をP0〜P20とする。
これを学習データとする。(ただしP0=(0,0,0)なのでP0は使わない)

以下でx,y,zをそれぞれ配列として表す。

x = []
y = []
z = []

>>print(x, y, z)
x = [-0.30181401978523403, -0.43866678423818906, -0.41824364323041796, -0.3069838655884501, -0.28009611329349754, -0.24241966390531655, -0.23835985632246176, -0.22511594777501265, 0.0011999741879543816, -0.03986017830088571, -0.06420965031676379, -0.04832161645464753, 0.24357425425958662, 0.18521859024633378, 0.08773647010220194, 0.04105043621241113, 0.44356229836619926, 0.3452024315011084, 0.2591058935288038]
y = [-0.32383371528394683, -0.747166141687455, -1.1240024539687794, -1.3908858081192494, -0.8394965054984833, -1.5317663934312689, -1.4430361151523028, -1.2615653214420415, -0.8027637937127571, -1.614120158783711, -2.0125497686998974, -2.2596129023641596, -0.7332029252262399, -1.453312833598722, -1.3380572218214797, -1.1393989420245116, -0.649311386326434, -1.1960667724964844, -1.1232365821067827]
z = [-0.0008614330422588534, -0.11050266110598433, -0.18714525087376352, -0.2323174844002542, -0.580646438324885, -0.6573960420036162, -0.5635126249716498, -0.4753806141911793, -0.5962959429392846, -0.8043628657813968, -0.8290098559135131, -0.8385103231095239, -0.5389750370775429, -0.5963535100507581, -0.40896977488602265, -0.2771459449398954, -0.4702168431680787, -0.43816091970864685, -0.2548937893539883]

以下でx,y,zの配列を1つの配列にまとめ、CSVファイルに出力する。

xyz = [] 
xyz.extend(x)
xyz.extend(y)
xyz.extend(z)
np.savetxt('distance.csv', xyz, delimiter=',')

出力されたCSVファイルです

xyz.csv
-0.30181402,-0.438666784,-0.418243643,-0.306983866,-0.280096113,-0.242419664,-0.238359856,-0.225115948,0.001199974,-0.039860178,-0.06420965,-0.048321616,0.243574254,0.18521859,0.08773647,0.041050436,0.443562298,0.345202432,0.259105894,0.240894456,-0.323833715,-0.747166142,-1.124002454,-1.390885808,-0.839496505,-1.531766393,-1.443036115,-1.261565321,-0.802763794,-1.614120159,-2.012549769,-2.259612902,-0.733202925,-1.453312834,-1.338057222,-1.139398942,-0.649311386,-1.196066772,-1.123236582,-0.956444975,-0.000861433,-0.110502661,-0.187145251,-0.232317484,-0.580646438,-0.657396042,-0.563512625,-0.475380614,-0.596295943,-0.804362866,-0.829009856,-0.838510323,-0.538975037,-0.59635351,-0.408969775,-0.277145945,-0.470216843,-0.43816092,-0.254893789,-0.114830338

SVMに使用するときは、「点1から点20」を説明変数とし、21番目に「pose」の変数を加え、画像データに該当する手の形の値を加える。それを目的変数とする。

poseの値 手の形
0 手を挙げている
1 goodのポーズ
2 中指立てる
3 口に人差し指をあてるポーズ

他の記事
[2022年]SVMの学習セットのフォーマット(CSVファイル)
[2022年]MediaPipeで取得した座標データの統一化の方法[CSVファイル]
[2022年]PythonのMediaPipeを使い、動画ファイルの手を認識し、CSVファイルに座標データを保存する方法
[2022年]PythonのOpenCVを使って動画を録画する方法

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3