Comments and readme update

This commit is contained in:
2022-02-08 20:02:14 +07:00
parent c6c2334d05
commit f73685fa55
6 changed files with 141 additions and 110 deletions

View File

@@ -2,7 +2,7 @@
import numpy as np import numpy as np
# element of json # create the element of json
def makexyzrotvis(x,y,z,rotx,roty,rotz,visible): def makexyzrotvis(x,y,z,rotx,roty,rotz,visible):
ret = {} ret = {}
translation = {} translation = {}

110
README.md
View File

@@ -1,5 +1,62 @@
# Human Pose Estimation with mediapipe # Human Pose Estimation with mediapipe
## Run with osc for UE4
```console
python3 hpe_win.py
```
The script accepts the following arguments in "config.yml" file:
* address_input - file path or webcam index
* scale_pose - shoulder width in metric system
* crop_image - coefficient if you need to resize the image
* osc_address - address for osc client
* osc_port - port for osc client
* osc_message_address - address for message output via osc client
* output_method (['file', 'osc']) - output type via file or osc client
* mirror_image - horizontal display of the output image
* show_image - output image output via opencv
* apose - send only APose coordinate
* world - world or local values of rotation and rotation
* old_world - old convrerting model (does not work anymore)
To test with matplotlib, you need to run a script (example with a webcam with index 0):
```console
python3 hpe_videocapture.py 0
```
## Dependencies
Python libraries:
* mediapipe
* numpy
* matplotlib (could be optional)
* opencv-python
* json
* python-osc
The mediapipe library requires the cuda toolkit and cudnn to work with the gpu.
## Interface for hpe_videocapture
For one-time rendering of points in 3D using matplotlib, you need to press the 'm' key.
To write the converted data to the UE4 model in the file 'hierarchy_data.json', you need to press the 'j' key.
To close the program, press the 'esc' key.
## Requirements for setting up an experiment
* There must be one person in the frame.
* The camera should be approximately at a 90 degree angle.
* The person must enter the frame entirely.
* It is desirable that the contours of the clothes on the person are clearly visible.
## Build on Windows
In development
## Запуск ## Запуск
Для тестового запуска через вебкамеру с индексом 0. Для тестового запуска через вебкамеру с индексом 0.
@@ -23,56 +80,3 @@ python3 hpe_json.py --address_input 0 --show_image True
```console ```console
python3 hpe_videocapture.py 0 python3 hpe_videocapture.py 0
``` ```
## Зависимости
Библиотеки python:
* mediapipe
* numpy
* matplotlib (можно сделать опциональной)
* opencv-python
* json
* python-osc
Библиотека mediapipe требует cudatoolkit и cudnn для работы с gpu.
## Интерфейс для hpe_videocapture
Для разовой отрисовки точек в 3D с помощью matplotlib необходимо нажать клавишу 'm'.
Чтобы записать сконвертированные данные в модель UE4 в файл 'hierarchy_data.json', нужно нажать клавишу 'j'.
Для закрытия программы нужно нажать клавишу 'esc'.
## Требования к постановке эксперимента
* Человек в кадре должен быть один.
* Камера примерно должна быть под углом 90 градусов.
* Человек должен входить в кадр целиком.
* Желательно, чтобы у одежда на человеке были хорошо видны контуры.
## Сборка на Windows
В разработке
## Config file
В разработке.
Предположительные переменные.
Параметры класса hpe_mp_class из hpe_mp_class.py:
* hands_static_image_mode = False
* hands_max_num_hands = 2
* hands_min_detection_confidence = 0.7
* hands_min_tracking_confidence = 0.5
* pose_static_image_mode = False
* pose_upper_body_only = False
* pose_smooth_landmarks = True
* pose_min_detection_confidence = 0.7
* pose_min_tracking_confidence = 0.5
* hol_static_image_mode = False
* hol_upper_body_only = False
* hol_smooth_landmarks = True
* hol_min_detection_confidence = 0.7
* hol_min_tracking_confidence = 0.5

17
check_stream.py Normal file
View File

@@ -0,0 +1,17 @@
import cv2
address_input = "http://localhost:8080"
cap = cv2.VideoCapture(address_input)
while True:
# Reading frame
success, img = cap.read()
if success:
cv2.imshow("Main", img)
else:
print("Frame not success read")
# Interface
key = cv2.waitKey(1)
if key == 27:
break

View File

@@ -1,5 +1,5 @@
# Input # Input
address_input: "1" # input video path or webcam index address_input: "0" # input video path or webcam index
# Image processing # Image processing
scale_pose: 35.4 # shoulder width scale_pose: 35.4 # shoulder width

View File

@@ -15,8 +15,8 @@ logger = logging.getLogger("hpe_mp_class_logger")
from ModelUE4 import * from ModelUE4 import *
from ModelUE4_apose import bodyaposelocal from ModelUE4_apose import bodyaposelocal
from ModelUE4_apose import bodyaposeworld from ModelUE4_apose import bodyaposeworld
from ModelUE4_old import bodyconvert #from ModelUE4_old import bodyconvert
from ModelUE4_old import bodyconvertlocal #from ModelUE4_old import bodyconvertlocal
class hpe_mp_class(): class hpe_mp_class():
@@ -169,13 +169,14 @@ class hpe_mp_class():
# try: # try:
if apose: if apose:
if world: if world:
bodyaposeworld(data) bodyaposeworld(data) # APose world
else: else:
bodyaposelocal(data) bodyaposelocal(data) # APose local
else: else:
if world: if world:
bodyaposeworld(data) bodyaposeworld(data)
if self.holistic_use: if self.holistic_use:
# body converting
poseslms = {} poseslms = {}
maxy = 0 maxy = 0
if self.results_hol.pose_landmarks: if self.results_hol.pose_landmarks:
@@ -184,6 +185,7 @@ class hpe_mp_class():
if lm.y > maxy: if lm.y > maxy:
maxy = lm.y maxy = lm.y
# only rotation method
bodyeuler(poseslms, data, self.coef) bodyeuler(poseslms, data, self.coef)
# if old_world: # if old_world:
@@ -191,11 +193,13 @@ class hpe_mp_class():
# else: # else:
# bodyconvertwithrot(poseslms, data, self.coef, maxy) # bodyconvertwithrot(poseslms, data, self.coef, maxy)
# right hand converting
rhandlms = {} rhandlms = {}
if self.results_hol.right_hand_landmarks: if self.results_hol.right_hand_landmarks:
for id, lm in enumerate(self.results_hol.right_hand_landmarks.landmark): for id, lm in enumerate(self.results_hol.right_hand_landmarks.landmark):
rhandlms[id] = lm rhandlms[id] = lm
# only rotation method
rhandeuler(rhandlms, data, self.coef) rhandeuler(rhandlms, data, self.coef)
# if old_world: # if old_world:
@@ -206,11 +210,13 @@ class hpe_mp_class():
# # else: # # else:
# # rhandconverttranslation(data) # # rhandconverttranslation(data)
# left hand converting
lhandlms = {} lhandlms = {}
if self.results_hol.left_hand_landmarks: if self.results_hol.left_hand_landmarks:
for id, lm in enumerate(self.results_hol.left_hand_landmarks.landmark): for id, lm in enumerate(self.results_hol.left_hand_landmarks.landmark):
lhandlms[id] = lm lhandlms[id] = lm
# only rotation method
lhandeuler(lhandlms,data,self.coef) lhandeuler(lhandlms,data,self.coef)
# if old_world: # if old_world:
@@ -222,18 +228,18 @@ class hpe_mp_class():
# lhandconverttranslation(data) # lhandconverttranslation(data)
else: else:
bodyaposelocal(data) bodyaposelocal(data)
if self.holistic_use: # if self.holistic_use:
poseslms = {} # poseslms = {}
maxy = 0 # maxy = 0
if self.results_hol.pose_landmarks: # if self.results_hol.pose_landmarks:
for id, lm in enumerate(self.results_hol.pose_landmarks.landmark): # for id, lm in enumerate(self.results_hol.pose_landmarks.landmark):
poseslms[id] = lm # poseslms[id] = lm
if lm.y > maxy: # if lm.y > maxy:
maxy = lm.y # maxy = lm.y
#
bodyconvert(poseslms, data, self.coef, maxy) # bodyconvert(poseslms, data, self.coef, maxy)
#
bodyconvertlocal(poseslms, data, self.coef, maxy) # bodyconvertlocal(poseslms, data, self.coef, maxy)
# except Exception as err: # except Exception as err:
# logger.exception("Error json converting hpe class: " + str(err)) # logger.exception("Error json converting hpe class: " + str(err))

View File

@@ -51,50 +51,54 @@ mp_cl = hpe_mp_class()
while True: while True:
# Reading frame # Reading frame
success, img = cap.read() success, img = cap.read()
if success:
# Image preprocessing
if crop != 1.0:
img = cv2.resize(img, (frame_width, frame_height))
# Image preprocessing # # Mediapipe
if crop != 1.0: mp_cl.process(img, scale_pose=scale_pose)
img = cv2.resize(img, (frame_width, frame_height)) mp_cl.show(img)
# Mediapipe # FPS
mp_cl.process(img, scale_pose=scale_pose) cTime = time.time()
mp_cl.show(img) fps = 1. / (cTime - pTime)
pTime = cTime
# FPS # Showing
cTime = time.time() if show_image:
fps = 1. / (cTime - pTime) if mirror_image:
pTime = cTime img = cv2.flip(img, 1) # mirror
cv2.putText(img, str(int(fps)), (22, 32), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2)
cv2.putText(img, str(int(fps)), (20, 30), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
cv2.imshow("Main", img)
# Showing # Output
if show_image: if output_method == 'file':
if mirror_image: # JSON
img = cv2.flip(img, 1) # mirror res = mp_cl.getJSON(apose=apose, world=world, old_world=old_world)
cv2.putText(img, str(int(fps)), (22, 32), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2) with open('hierarchy_data.json', 'w', encoding='utf-8') as f:
cv2.putText(img, str(int(fps)), (20, 30), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2) json.dump(res, f, ensure_ascii=False, indent=4)
cv2.imshow("Main", img) else:
# OSC
# Output res = mp_cl.getJSON(apose=apose, world=world, old_world=old_world) # convering model
if output_method == 'file': res_list = []
# JSON # for values parsing on UE4
res = mp_cl.getJSON(apose=apose, world=world, old_world=old_world) for val in res.keys():
with open('hierarchy_data.json', 'w', encoding='utf-8') as f: stroka = str(val)
json.dump(res, f, ensure_ascii=False, indent=4) for val2 in res[val]:
if val2 == 'visible':
stroka += " " + str(val2) + " " + str(res[val][val2])
# res_list.append(str(val) + " " + str(val2) + " " + str(res[val][val2]))
else:
for val3 in res[val][val2]:
stroka += " " + str(val2) + "_" + str(val3) + " " + str(res[val][val2][val3])
# res_list.append(str(val) + " " + str(val2) + " " + str(val3) + " " + str(res[val][val2][val3]))
res_list.append(stroka)
# message sending
client.send_message(osc_message_address, res_list)
else: else:
# OSC print("Frame not success read")
res = mp_cl.getJSON(apose=apose, world=world, old_world=old_world)
res_list = []
for val in res.keys():
stroka = str(val)
for val2 in res[val]:
if val2 == 'visible':
stroka += " " + str(val2) + " " + str(res[val][val2])
# res_list.append(str(val) + " " + str(val2) + " " + str(res[val][val2]))
else:
for val3 in res[val][val2]:
stroka += " " + str(val2) + "_" + str(val3) + " " + str(res[val][val2][val3])
# res_list.append(str(val) + " " + str(val2) + " " + str(val3) + " " + str(res[val][val2][val3]))
res_list.append(stroka)
client.send_message(osc_message_address, res_list)
# Interface # Interface
key = cv2.waitKey(1) key = cv2.waitKey(1)