{"id":389721,"date":"2024-06-29T08:47:07","date_gmt":"2024-06-29T08:47:07","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=389721"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T08:47:07","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=389721","title":{"rendered":"<span>Blender, \u0437\u0430\u0445\u0432\u0430\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f, \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>Blender \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 3d \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, \u0443\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0430\u043d\u0442\u0430\u0437\u0438\u0439. \u0411\u043e\u043b\u044c\u0448\u0430\u044f &#171;\u0444\u0430\u043d\u0430\u0442\u0441\u043a\u0430\u044f \u0431\u0430\u0437\u0430&#187; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0443\u0441\u043a\u043e\u0440\u044f\u044f \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u044e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442\u0430 \u0432 Blender, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0432 \u0441\u0430\u043c\u043e\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435, \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0435\u043b\u044c c \u0436\u0435\u043b\u0430\u0435\u043c\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c, \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438\u0437 \u0443\u0440\u043e\u043a\u043e\u0432 \u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u043c\u0435\u043d\u044f. \u0412\u044b\u0431\u0438\u0440\u0430\u044e \u0446\u0435\u043b\u044c, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u043b\u0438\u0448\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u044d\u0442\u0430\u043f\u043e\u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f. \u041c\u043e\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 &#8212; \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0432 Blender, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432\u0438\u0434\u0435\u043e, \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u043e \u043d\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043c\u043d\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0438 \u0433\u043e\u043b\u043e\u0432\u043e\u043b\u043e\u043c\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c.<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c:<\/h4>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0438\u0437 \u0432\u0438\u0434\u0435\u043e, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440 \u041a\u0430\u043b\u043c\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442 \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 Blender.<\/p>\n<\/li>\n<li>\n<p>\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0412\u0410\u0416\u041d\u041e! <\/strong>\u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0430\u0447\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0445\u043e\u0434\u0443 \u043c\u043e\u0438\u0445 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439<\/p>\n<p>\u0417\u0430\u0445\u0432\u0430\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439, \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438. \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0443\u043f\u043e\u0440 \u043c\u043e\u0435\u0433\u043e \u043f\u043e\u0432\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432 Blender, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u043a\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0432\u0430\u0436\u043d\u043e. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0437\u043b\u043e\u0432 \u043c\u043e\u0435\u0439 \u043c\u043e\u0437\u0430\u0438\u043a\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435  <a href=\"https:\/\/github.com\/haryo-s\/blender_lifting\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/haryo-s\/blender_lifting<\/a>, \u0430\u0432\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0442\u0430\u0442\u044c\u044e CVPR 2017 \u0433\u043e\u0434\u0430 <a href=\"http:\/\/openaccess.thecvf.com\/content_cvpr_2017\/papers\/Tome_Lifting_From_the_CVPR_2017_paper.pdf\" rel=\"noopener noreferrer nofollow\">Lifting from the Deep: Convolutional 3D Pose Estimation from a Single Image<\/a>. Haryo Sukmawanto, \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043b \u043e\u0442\u043b\u0438\u0447\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043b\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u043f\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0431\u0435\u0437 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u043d\u0435, \u0432\u043d\u0435\u0441 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"python\">import bpy from mathutils import Vector, Matrix import numpy as np import math from math import radians, ceil  # Importing global modules import time import subprocess import sys import json import pickle import os, random import numpy as np  def create_armature(coordinates, name, scale=1.0):     \"\"\"     Creates an armature skeleton data object from the input coordinates acquired from lift_image().      The skeleton's bones will have been appropriately labelled and parented.     The skeleton data object will be implemented into the scene as well.     :param coordinates: List of vertex coordinates from lifter     :param name: Base name of the bezier_curves      :param scale: Scale of the skeleton      \"\"\"     # Setting the scale to a hundredth already as the distances from lifting are considerably large.     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     arm_dat = bpy.data.armatures.new(arm_dat_name)     arm_obj = bpy.data.objects.new(arm_obj_name, arm_dat)              bpy.context.scene.collection.objects.link(arm_obj)     bpy.context.view_layer.objects.active = arm_obj          bpy.ops.object.mode_set(mode='EDIT', toggle=False)          edit_bones = bpy.data.armatures[arm_dat_name].edit_bones     b = edit_bones.new('base')     b.head = [coordinates[0][0]*scale, coordinates[0][1]*scale + 100*scale, coordinates[0][2]*scale]     b.tail = [coordinates[0][0]*scale, coordinates[0][1]*scale,             coordinates[0][2]*scale]     bone_nr = 0     for conn in CONNECTIONS:                 b = edit_bones.new(LIFTING_BONE_NAMES[bone_nr])         b.head = [scale*item for item in coordinates[conn[0]]]         b.tail = [scale*item for item in coordinates[conn[1]]]         b.parent = edit_bones[LIFTING_BONE_PARENTS[str(LIFTING_BONE_NAMES[bone_nr])]]         b.use_connect = True         bone_nr += 1              bpy.ops.object.mode_set(mode='OBJECT')     return arm_obj       <\/code><\/pre>\n<p>Haryo, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/DenisTome\/Lifting-from-the-Deep-release\/\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/DenisTome\/Lifting-from-the-Deep-release\/<\/a> &#8212; \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432\u0438\u0434\u0435\u043e.<\/p>\n<pre><code class=\"python\">import cv2 import json from lifting import PoseEstimator  \"\"\" \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e numpy, \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e. \"\"\" cap = cv2.VideoCapture(\"test_video.mp4\") h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) pose_estimator = PoseEstimator((h,w,3), SESSION_PATH, PROB_MODEL_PATH) pose_estimator.initialise() outfile = open('data_c.txt', 'w') while True:     ret, image = cap.read()     if ret == False:         break      pose_2d, visibility, pose_3d = pose_estimator.estimate(image)     try:       for ii in pose_3d:           coordinates = []           for i in range(len(ii[0])):               coordinates.append([ii[0][i], ii[1][i], ii[2][i]])           outfile.write(str(json.dumps(coordinates))+\"\\n\")       except Exception as e:       print (e) outfile.close() cap.release() cv2.destroyAllWindows()<\/code><\/pre>\n<p>\u0418\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0437\u0434\u0430\u044e \u0441\u043a\u0435\u043b\u0435\u0442.<\/p>\n<pre><code class=\"python\"># \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b def get_c(returned_val):     with open(returned_val) as f:          f = f.readlines()          ls = []                   for i in f:             ls.append(json.loads(i))          return ls  coordinates = get_c(\"data_c.txt\") scene.frame_start = 0 scene.frame_end = len(coordinates) ARM = create_armature(coordinates[0], \"A\")<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8a\/4e9\/54b\/a8a4e954b7b7c2a5fa5144fbeea33ee1.png\" alt=\"\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0441\u0442\u0438\" title=\"\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0441\u0442\u0438\" width=\"1254\" height=\"1073\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a8a\/4e9\/54b\/a8a4e954b7b7c2a5fa5144fbeea33ee1.png\"\/><figcaption>\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0441\u0442\u0438<\/figcaption><\/figure>\n<p><strong>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f<\/strong>. \u041d\u0430\u0438\u0432\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b head \u0438 tail \u043a\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>keyframe_insert<\/code>, \u0440\u043e\u0442\u0430\u0446\u0438\u044e \u0438 \u043b\u043e\u043a\u0430\u0446\u0438\u044e. \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, <code>keyframe_insert<\/code> \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437, \u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f head \u0438 tail \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u043e\u0433\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f head \u0438 tail \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437, \u043d\u043e \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u043c\u043e\u0433\u0443. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f Blender, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 Stack Exchange,  \u0441\u0442\u0430\u0442\u044c\u0438&#8230;  \u041f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0434\u0432\u0435 \u0438\u0434\u0435\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e \u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><em>\u0434\u0432\u043e\u0439\u043d\u0438\u043a \u0441\u043a\u0435\u043b\u0435\u0442\u0430;<\/em><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.blender.org\/manual\/en\/latest\/animation\/constraints\/introduction.html\" rel=\"noopener noreferrer nofollow\"><em>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435<\/em><\/a><em> \u043a\u043e\u0441\u0442\u0435\u0439 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438.<\/em><\/p>\n<\/li>\n<\/ul>\n<p><em>\u0414\u0432\u043e\u0439\u043d\u0438\u043a \u0441\u043a\u0435\u043b\u0435\u0442\u0430<\/em>. \u0421\u043e\u0437\u0434\u0430\u044e \u0434\u0432\u0430 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u044e \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0448\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437\u044b.<\/p>\n<pre><code class=\"python\"># \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f - \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u043e\u0437\u044b def get_pose(ARM, ARM2):     for bone in ARM.pose.bones:              ARM.pose.bones[bone.name].matrix = ARM2.pose.bones[bone.name].matrix                    ARM.pose.bones[bone.name].rotation_mode = 'XYZ'             ARM.pose.bones[bone.name].keyframe_insert(data_path='rotation_euler', frame=frame)             scene.frame_set(frame)     scene.frame_set(frame)  # \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f - \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u0438 \u043f\u043e\u0437\u044b, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 def snap_rotation(source, target):     Ms = source.id_data.convert_space(         pose_bone=source,         matrix=source.matrix,         from_space='POSE',         )     Mt = target.id_data.convert_space(         pose_bone=target,         matrix=target.matrix,         from_space='POSE',         )                _, q, _ = Ms.decompose()     t, _, s = Mt.decompose()     M = (         Matrix.Translation(t) @         q.to_matrix().to_4x4() @          Matrix.Diagonal(s.to_4d())         )     target.matrix = target.id_data.convert_space(         pose_bone=target,         matrix=M,         to_space='POSE',         )  def change_arm(coordinates, name, scale=1.0):     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     bpy.ops.object.mode_set(mode='EDIT', toggle=False)     edit_bones = bpy.data.armatures[arm_dat_name].edit_bones     bone_nr = 0     for conn in CONNECTIONS:                 b = edit_bones[LIFTING_BONE_NAMES[bone_nr]]         b.head = [scale*item for item in coordinates[conn[0]]]         b.tail = [scale*item for item in coordinates[conn[1]]]         bone_nr += 1     bpy.ops.object.mode_set(mode = 'POSE')     # \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f     # get_pose(ARM, ARM2)          # \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f     for bone in ARM.pose.bones:         ARM.pose.bones[bone.name].rotation_mode = 'QUATERNION'         snap_rotation(bpy.data.objects[arm_obj_name].pose.bones[bone.name],                       ARM.pose.bones[bone.name])                     ARM.pose.bones[bone.name].keyframe_insert(data_path='rotation_quaternion', frame=frame)         scene.frame_set(frame)      ARM = create_armature(coordinates[0], \"A\") ARM2 = create_armature(coordinates[0], \"B\") for frame in range(len(coordinates)):             scene.frame_set(frame)             COR = coordinates[frame]             change_arm(COR, \"B\") <\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/22f\/c53\/59a\/22fc5359a9a3d783240f00bed7ec80b7.gif\" alt=\"\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" title=\"\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" width=\"600\" height=\"750\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/22f\/c53\/59a\/22fc5359a9a3d783240f00bed7ec80b7.gif\"\/><figcaption>\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430<\/figcaption><\/figure>\n<p>\u0418\u0434\u0435\u044f \u0441 \u0434\u0432\u043e\u0439\u043d\u0438\u043a\u043e\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0440\u0430\u0431\u043e\u0447\u0435\u0439, \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u044f\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 &#8212; \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432 \u043e\u0441\u0438 \u043a\u043e\u0441\u0442\u0438. \u041f\u0440\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 head \u0438 tail \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u0441\u0442\u044c (\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll), \u044d\u0442\u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437\u044b, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0434\u0435\u0444\u0435\u043a\u0442.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/00c\/bf5\/f26\/00cbf5f26659cbd5ae858d938f93462d.png\" alt=\"\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll\" title=\"\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll\" width=\"196\" height=\"335\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/00c\/bf5\/f26\/00cbf5f26659cbd5ae858d938f93462d.png\"\/><figcaption>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll<\/figcaption><\/figure>\n<p><a href=\"https:\/\/docs.blender.org\/manual\/en\/latest\/animation\/constraints\/introduction.html\" rel=\"noopener noreferrer nofollow\"><em>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435<\/em><\/a><em> \u043a\u043e\u0441\u0442\u0435\u0439 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438<\/em>. \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442,  \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0441\u0442\u0438 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0434\u0440\u043e\u0432, \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u043a\u043e\u0441\u0442\u0438, \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u0441\u0442\u0438 <code>keyframe_insert<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0435 \u043e\u0442 \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<pre><code class=\"python\">def create_armature(coordinates, name, scale=1.0):     \"\"\"     Creates an armature skeleton data object from the input coordinates acquired from lift_image().      The skeleton's bones will have been appropriately labelled and parented.     The skeleton data object will be implemented into the scene as well.     :param coordinates: List of vertex coordinates from lifter     :param name: Base name of the bezier_curves      :param scale: Scale of the skeleton      \"\"\"     # Setting the scale to a hundredth already as the distances from lifting are considerably large.     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     arm_dat = bpy.data.armatures.new(arm_dat_name)     arm_obj = bpy.data.objects.new(arm_obj_name, arm_dat)     bpy.context.scene.collection.objects.link(arm_obj)     bpy.context.view_layer.objects.active = arm_obj     bpy.ops.object.mode_set(mode='EDIT', toggle=False)     edit_bones = bpy.data.armatures[arm_dat_name].edit_bones     b = edit_bones.new('base')     b.head = [coordinates[0][0]*scale, coordinates[0][1]*scale + 100*scale, coordinates[0][2]*scale]     b.tail = [coordinates[0][0]*scale, coordinates[0][1]*scale,             coordinates[0][2]*scale]     bone_nr = 0     for conn in CONNECTIONS:                 b = edit_bones.new(LIFTING_BONE_NAMES[bone_nr])         b.head = [scale*item for item in coordinates[conn[0]]]         b.tail = [scale*item for item in coordinates[conn[1]]]         b.parent = edit_bones[LIFTING_BONE_PARENTS[str(LIFTING_BONE_NAMES[bone_nr])]]         b.use_connect = True         bone_nr += 1     bpy.ops.object.mode_set(mode='POSE')     bone_nr = 0     for conn in CONNECTIONS:             b = arm_obj.pose.bones[LIFTING_BONE_NAMES[bone_nr]]             v1 = Vector(coordinates[conn[0]])         v2 = Vector(coordinates[conn[1]])          # \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0435\u043a\u0442\u043e\u0440         v = v2 - v1          v.normalize()          vGoal = v + b.tail          # \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442         bpy.ops.object.mode_set(mode='OBJECT')         bpy.ops.object.empty_add(type='PLAIN_AXES', location= vGoal)          target_axis = bpy.context.active_object         temp_list.append(target_axis.name)         # \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435         neckCopyRot = arm_obj.pose.bones[LIFTING_BONE_NAMES[bone_nr]].constraints.new('DAMPED_TRACK')          neckCopyRot.target = target_axis          target_axis.select_set(False)          bpy.context.view_layer.objects.active = arm_obj         bpy.ops.object.mode_set(mode='POSE')            bone_nr += 1      # \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0437\u0443 \u0438\u0437 \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u043e\u0437         bpy.context.view_layer.objects.active = arm_obj     bpy.data.objects['Armature_obj_A'].select_set(True)     bpy.ops.object.mode_set(mode = 'POSE')     bpy.ops.pose.select_all(action='SELECT')     bpy.ops.pose.armature_apply(selected=False)     bpy.ops.object.mode_set(mode = 'OBJECT')             return arm_obj    def change_arm(coordinates, scale=1.0):     bpy.ops.object.mode_set(mode='POSE', toggle=False)         RIG = bpy.context.active_object.id_data     bone_nr = 0     for conn in CONNECTIONS:         v1 = Vector(coordinates[conn[0]])         v2 = Vector(coordinates[conn[1]])               v = v2 - v1          v.normalize()          vGoal = v + ARM.pose.bones[LIFTING_BONE_NAMES[bone_nr]].tail                bpy.ops.object.mode_set(mode='OBJECT')         J = bpy.data.objects[temp_list[bone_nr]]         J.location = vGoal         ARM.select_set(True)         bpy.context.view_layer.objects.active = ARM         bpy.ops.object.mode_set(mode='POSE')         RIG.data.bones[LIFTING_BONE_NAMES[bone_nr]].select = True         bpy.ops.pose.visual_transform_apply()         # \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043b\u043e\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430         J.keyframe_insert(data_path=\"location\", frame=frame)         # \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u0441\u0442\u0438         ARM.pose.bones[LIFTING_BONE_NAMES[bone_nr]].keyframe_insert(data_path=\"rotation_quaternion\", frame=frame)         bone_nr += 1                                                                   scene.frame_set(frame)  <\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f28\/269\/fff\/f28269fff84382c587419f1e2d3edb07.gif\" alt=\"\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" title=\"\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" width=\"350\" height=\"715\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f28\/269\/fff\/f28269fff84382c587419f1e2d3edb07.gif\"\/><figcaption>\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430<\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0439 \u043a \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u043c\u0443, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0412 \u0433\u043b\u0430\u0437\u0430 \u0431\u0440\u043e\u0441\u0430\u044e\u0442\u0441\u044f \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u0430\u0434\u0440\u043e\u043c, \u043d\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f. \u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u0440\u0435\u0448\u0430\u044e\u0442 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438, \u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%B8%D0%BB%D1%8C%D1%82%D1%80_%D0%9A%D0%B0%D0%BB%D0%BC%D0%B0%D0%BD%D0%B0\" rel=\"noopener noreferrer nofollow\">\u0444\u0438\u043b\u044c\u0442\u0440 \u041a\u0430\u043b\u043c\u0430\u043d\u0430<\/a>. \u042d\u0442\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0432 \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430, \u0434\u043e\u043b\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447\u0430\u0445.<\/p>\n<pre><code class=\"python\">class KalmanFilter:     def __init__(self):         # \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438         self.x_P = 0.9         self.x_Q = 0.08                  self.y_P = 0.9         self.y_Q = 0.08                  self.z_P = 0.9         self.z_Q = 0.08                  self.x_priori_estimated_covariance = 1          self.y_priori_estimated_covariance = 1         self.z_priori_estimated_covariance = 1         # X          self.x_estimated_value_dict = {'base': 0, 'pelvis_r': 0, 'thigh_r': 0, 'calf_r': 0, 'pelvis_l': 0,                                         'thigh_l': 0, 'calf_l': 0, 'waist': 0, 'chest': 0,                                         'neck': 0, 'head': 0, 'shoulder_l': 0, 'arm_l': 0,                                         'forearm_l': 0, 'shoulder_r': 0, 'arm_r': 0, 'forearm_r': 0}          self.x_post_estimated_covariance_dict = {'base': 1, 'pelvis_r': 1, 'thigh_r': 1, 'calf_r': 1, 'pelvis_l': 1,                                                   'thigh_l': 1, 'calf_l': 1, 'waist': 1, 'chest': 1,                                                   'neck': 1, 'head': 1, 'shoulder_l': 1, 'arm_l': 1,                                                   'forearm_l': 1, 'shoulder_r': 1, 'arm_r': 1, 'forearm_r': 1}         # Y          self.y_estimated_value_dict = {'base': 0, 'pelvis_r': 0, 'thigh_r': 0, 'calf_r': 0, 'pelvis_l': 0,                                         'thigh_l': 0, 'calf_l': 0, 'waist': 0, 'chest': 0,                                         'neck': 0, 'head': 0, 'shoulder_l': 0, 'arm_l': 0,                                         'forearm_l': 0, 'shoulder_r': 0, 'arm_r': 0, 'forearm_r': 0}          self.y_post_estimated_covariance_dict = {'base': 1, 'pelvis_r': 1, 'thigh_r': 1, 'calf_r': 1, 'pelvis_l': 1,                                                   'thigh_l': 1, 'calf_l': 1, 'waist': 1, 'chest': 1,                                                   'neck': 1, 'head': 1, 'shoulder_l': 1, 'arm_l': 1,                                                   'forearm_l': 1, 'shoulder_r': 1, 'arm_r': 1, 'forearm_r': 1}                                                           # Z                                                  self.z_estimated_value_dict = {'base': 0, 'pelvis_r': 0, 'thigh_r': 0, 'calf_r': 0, 'pelvis_l': 0,                                         'thigh_l': 0, 'calf_l': 0, 'waist': 0, 'chest': 0,                                         'neck': 0, 'head': 0, 'shoulder_l': 0, 'arm_l': 0,                                         'forearm_l': 0, 'shoulder_r': 0, 'arm_r': 0, 'forearm_r': 0}          self.z_post_estimated_covariance_dict = {'base': 1, 'pelvis_r': 1, 'thigh_r': 1, 'calf_r': 1, 'pelvis_l': 1,                                                   'thigh_l': 1, 'calf_l': 1, 'waist': 1, 'chest': 1,                                                   'neck': 1, 'head': 1, 'shoulder_l': 1, 'arm_l': 1,                                                   'forearm_l': 1, 'shoulder_r': 1, 'arm_r': 1, 'forearm_r': 1}      # \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439     def x_reset(self, P, Q):          self.x_P = P         self.x_Q = Q      def y_reset(self, P, Q):         self.y_P = P         self.y_Q = Q      def z_reset(self, P, Q):         self.z_P = P         self.z_Q = Q      # \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0432 \u0444\u0438\u043b\u044c\u0442\u0440        def cal_X(self, current_value, label):           self.current_value = current_value         self.x_priori_estimated_covariance = self.x_post_estimated_covariance_dict[label]         x_kalman_gain = self.x_priori_estimated_covariance \/ (self.x_priori_estimated_covariance + self.x_P)           output = self.x_estimated_value_dict[label] + x_kalman_gain * (                     current_value - self.x_estimated_value_dict[label])           self.x_estimated_value_dict[label] = output         self.x_post_estimated_covariance_dict[label] = (1 - x_kalman_gain) * self.x_priori_estimated_covariance + self.x_Q         self.x_priori_estimated_covariance = self.x_post_estimated_covariance_dict[label]         return output        def cal_Y(self, current_value, label):           self.current_value = current_value         self.y_priori_estimated_covariance = self.y_post_estimated_covariance_dict[label]         y_kalman_gain = self.y_priori_estimated_covariance \/ (self.y_priori_estimated_covariance + self.y_P)           output = self.y_estimated_value_dict[label] + y_kalman_gain * (                     current_value - self.y_estimated_value_dict[label])           self.y_estimated_value_dict[label] = output         self.y_post_estimated_covariance_dict[label] = (1 - y_kalman_gain) * self.y_priori_estimated_covariance + self.y_Q         self.y_priori_estimated_covariance = self.y_post_estimated_covariance_dict[label]         return output      def cal_Z(self, current_value, label):          self.current_value = current_value         self.z_priori_estimated_covariance = self.z_post_estimated_covariance_dict[label]         z_kalman_gain = self.z_priori_estimated_covariance \/ (self.z_priori_estimated_covariance + self.z_P)           output = self.z_estimated_value_dict[label] + z_kalman_gain * (                     current_value - self.z_estimated_value_dict[label])           self.z_estimated_value_dict[label] = output         self.z_post_estimated_covariance_dict[label] = (1 - z_kalman_gain) * self.z_priori_estimated_covariance + self.z_Q         self.z_priori_estimated_covariance = self.z_post_estimated_covariance_dict[label]         return output   class KalmanProcess():     def __init__(self):         self.kalman_filter_X = KalmanFilter()         self.kalman_filter_Y = KalmanFilter()         self.kalman_filter_Z = KalmanFilter()      def reset_kalman_filter_X(self, P, Q):         self.kalman_filter_X.x_reset(P, Q)      def reset_kalman_filter_Y(self, P, Q):         self.kalman_filter_Y.y_reset(P, Q)      def reset_kalman_filter_Z(self, P, Q):         self.kalman_filter_Z.z_reset(P, Q)       def do_kalman_filter(self, X, Y, Z, label):         X_cal = self.kalman_filter_X.cal_X(X, label)         Y_cal = self.kalman_filter_Y.cal_Y(Y, label)         Z_cal = self.kalman_filter_Z.cal_Z(Z, label)         return X_cal, Y_cal, Z_cal        kalman_process = KalmanProcess() _dict = {'base': 0, 'pelvis_r': 0, 'thigh_r': 0, 'calf_r': 0, 'pelvis_l': 0,           'thigh_l': 0, 'calf_l': 0, 'waist': 0, 'chest': 0,           'neck': 0, 'head': 0, 'shoulder_l': 0, 'arm_l': 0,           'forearm_l': 0, 'shoulder_r': 0, 'arm_r': 0, 'forearm_r': 0}  list_dict = list(_dict.keys())    # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b def lift_image(returned_val):     with open(returned_val) as f:          f = f.readlines()          ls = []                   for i in f:             ls.append(json.loads(i))          return ls           returned_val = \"data_c.txt\" coordinates = lift_image(returned_val) _file = open(\"data_c_kalman.txt\",\"w\") for i in coordinates:     coordinates = []     for iz, z in enumerate(i):         out_kalman_x, out_kalman_y, out_kalman_z = kalman_process.do_kalman_filter(z[0], z[1], z[2], list_dict[iz])         coordinates.append([out_kalman_x, out_kalman_y, out_kalman_z])     _file.write(str(coordinates)+\"\\n\")   _file.close()    <\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb8\/8a2\/3b9\/eb88a23b99f8e5f2506ad3e6925a8288.gif\" alt=\"\u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" title=\"\u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u041a\u0430\u043b\u043c\u0430\u043d\u0430\" width=\"400\" height=\"750\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb8\/8a2\/3b9\/eb88a23b99f8e5f2506ad3e6925a8288.gif\"\/><figcaption>\u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u041a\u0430\u043b\u043c\u0430\u043d\u0430<\/figcaption><\/figure>\n<p><a href=\"https:\/\/github.com\/naturalkind\/natural-motion\" rel=\"noopener noreferrer nofollow\"><strong>https:\/\/github.com\/<\/strong>naturalkind\/natural-motion<\/a><\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u043b\u0443\u0447\u0448\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0440\u0430\u0431\u043e\u0442\u044b Blender. \u0420\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u0446\u0438\u0444\u0440\u043e\u0432\u044b\u0445 \u0432\u0441\u0435\u043b\u0435\u043d\u043d\u044b\u0445, \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u044f, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0441\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0437 \u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0432 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u043c\u0438\u0440, \u0437\u0430\u0432\u0442\u0440\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0441\u043e\u0437\u043d\u0430\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0435 \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u043e\u0437\u043d\u0430\u043d\u0438\u044f \u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d, \u0434\u043e\u043a\u0430\u0436\u0438\u0442\u0435.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/684284\/\"> https:\/\/habr.com\/ru\/articles\/684284\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>Blender \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 3d \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, \u0443\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0430\u043d\u0442\u0430\u0437\u0438\u0439. \u0411\u043e\u043b\u044c\u0448\u0430\u044f &#171;\u0444\u0430\u043d\u0430\u0442\u0441\u043a\u0430\u044f \u0431\u0430\u0437\u0430&#187; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0443\u0441\u043a\u043e\u0440\u044f\u044f \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u044e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442\u0430 \u0432 Blender, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0432 \u0441\u0430\u043c\u043e\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435, \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0435\u043b\u044c c \u0436\u0435\u043b\u0430\u0435\u043c\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c, \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438\u0437 \u0443\u0440\u043e\u043a\u043e\u0432 \u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u043c\u0435\u043d\u044f. \u0412\u044b\u0431\u0438\u0440\u0430\u044e \u0446\u0435\u043b\u044c, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u043b\u0438\u0448\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u044d\u0442\u0430\u043f\u043e\u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f. \u041c\u043e\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 &#8212; \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0432 Blender, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432\u0438\u0434\u0435\u043e, \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u043e \u043d\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043c\u043d\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0438 \u0433\u043e\u043b\u043e\u0432\u043e\u043b\u043e\u043c\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c.<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c:<\/h4>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0438\u0437 \u0432\u0438\u0434\u0435\u043e, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440 \u041a\u0430\u043b\u043c\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442 \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 Blender.<\/p>\n<\/li>\n<li>\n<p>\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0412\u0410\u0416\u041d\u041e! <\/strong>\u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0430\u0447\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0445\u043e\u0434\u0443 \u043c\u043e\u0438\u0445 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439<\/p>\n<p>\u0417\u0430\u0445\u0432\u0430\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439, \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438. \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0443\u043f\u043e\u0440 \u043c\u043e\u0435\u0433\u043e \u043f\u043e\u0432\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432 Blender, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u043a\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0432\u0430\u0436\u043d\u043e. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0437\u043b\u043e\u0432 \u043c\u043e\u0435\u0439 \u043c\u043e\u0437\u0430\u0438\u043a\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435  <a href=\"https:\/\/github.com\/haryo-s\/blender_lifting\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/haryo-s\/blender_lifting<\/a>, \u0430\u0432\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0442\u0430\u0442\u044c\u044e CVPR 2017 \u0433\u043e\u0434\u0430 <a href=\"http:\/\/openaccess.thecvf.com\/content_cvpr_2017\/papers\/Tome_Lifting_From_the_CVPR_2017_paper.pdf\" rel=\"noopener noreferrer nofollow\">Lifting from the Deep: Convolutional 3D Pose Estimation from a Single Image<\/a>. Haryo Sukmawanto, \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043b \u043e\u0442\u043b\u0438\u0447\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043b\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u043f\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0431\u0435\u0437 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u043d\u0435, \u0432\u043d\u0435\u0441 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"python\">import bpy from mathutils import Vector, Matrix import numpy as np import math from math import radians, ceil  # Importing global modules import time import subprocess import sys import json import pickle import os, random import numpy as np  def create_armature(coordinates, name, scale=1.0):     \"\"\"     Creates an armature skeleton data object from the input coordinates acquired from lift_image().      The skeleton's bones will have been appropriately labelled and parented.     The skeleton data object will be implemented into the scene as well.     :param coordinates: List of vertex coordinates from lifter     :param name: Base name of the bezier_curves      :param scale: Scale of the skeleton      \"\"\"     # Setting the scale to a hundredth already as the distances from lifting are considerably large.     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     arm_dat = bpy.data.armatures.new(arm_dat_name)     arm_obj = bpy.data.objects.new(arm_obj_name, arm_dat)              bpy.context.scene.collection.objects.link(arm_obj)     bpy.context.view_layer.objects.active = arm_obj          bpy.ops.object.mode_set(mode='EDIT', toggle=False)          edit_bones = bpy.data.armatures[arm_dat_name].edit_bones     b = edit_bones.new('base')     b.head = [coordinates[0][0]*scale, coordinates[0][1]*scale + 100*scale, coordinates[0][2]*scale]     b.tail = [coordinates[0][0]*scale, coordinates[0][1]*scale,             coordinates[0][2]*scale]     bone_nr = 0     for conn in CONNECTIONS:                 b = edit_bones.new(LIFTING_BONE_NAMES[bone_nr])         b.head = [scale*item for item in coordinates[conn[0]]]         b.tail = [scale*item for item in coordinates[conn[1]]]         b.parent = edit_bones[LIFTING_BONE_PARENTS[str(LIFTING_BONE_NAMES[bone_nr])]]         b.use_connect = True         bone_nr += 1              bpy.ops.object.mode_set(mode='OBJECT')     return arm_obj       <\/code><\/pre>\n<p>Haryo, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/DenisTome\/Lifting-from-the-Deep-release\/\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/DenisTome\/Lifting-from-the-Deep-release\/<\/a> &#8212; \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432\u0438\u0434\u0435\u043e.<\/p>\n<pre><code class=\"python\">import cv2 import json from lifting import PoseEstimator  \"\"\" \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e numpy, \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e. \"\"\" cap = cv2.VideoCapture(\"test_video.mp4\") h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) pose_estimator = PoseEstimator((h,w,3), SESSION_PATH, PROB_MODEL_PATH) pose_estimator.initialise() outfile = open('data_c.txt', 'w') while True:     ret, image = cap.read()     if ret == False:         break      pose_2d, visibility, pose_3d = pose_estimator.estimate(image)     try:       for ii in pose_3d:           coordinates = []           for i in range(len(ii[0])):               coordinates.append([ii[0][i], ii[1][i], ii[2][i]])           outfile.write(str(json.dumps(coordinates))+\"\\n\")       except Exception as e:       print (e) outfile.close() cap.release() cv2.destroyAllWindows()<\/code><\/pre>\n<p>\u0418\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0437\u0434\u0430\u044e \u0441\u043a\u0435\u043b\u0435\u0442.<\/p>\n<pre><code class=\"python\"># \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b def get_c(returned_val):     with open(returned_val) as f:          f = f.readlines()          ls = []                   for i in f:             ls.append(json.loads(i))          return ls  coordinates = get_c(\"data_c.txt\") scene.frame_start = 0 scene.frame_end = len(coordinates) ARM = create_armature(coordinates[0], \"A\")<\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0441\u0442\u0438<\/figcaption><\/figure>\n<p><strong>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f<\/strong>. \u041d\u0430\u0438\u0432\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b head \u0438 tail \u043a\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>keyframe_insert<\/code>, \u0440\u043e\u0442\u0430\u0446\u0438\u044e \u0438 \u043b\u043e\u043a\u0430\u0446\u0438\u044e. \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, <code>keyframe_insert<\/code> \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437, \u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f head \u0438 tail \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u043e\u0433\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f head \u0438 tail \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437, \u043d\u043e \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u043c\u043e\u0433\u0443. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f Blender, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 Stack Exchange,  \u0441\u0442\u0430\u0442\u044c\u0438&#8230;  \u041f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0434\u0432\u0435 \u0438\u0434\u0435\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e \u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><em>\u0434\u0432\u043e\u0439\u043d\u0438\u043a \u0441\u043a\u0435\u043b\u0435\u0442\u0430;<\/em><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.blender.org\/manual\/en\/latest\/animation\/constraints\/introduction.html\" rel=\"noopener noreferrer nofollow\"><em>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435<\/em><\/a><em> \u043a\u043e\u0441\u0442\u0435\u0439 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438.<\/em><\/p>\n<\/li>\n<\/ul>\n<p><em>\u0414\u0432\u043e\u0439\u043d\u0438\u043a \u0441\u043a\u0435\u043b\u0435\u0442\u0430<\/em>. \u0421\u043e\u0437\u0434\u0430\u044e \u0434\u0432\u0430 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u044e \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0448\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437\u044b.<\/p>\n<pre><code class=\"python\"># \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f - \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u043e\u0437\u044b def get_pose(ARM, ARM2):     for bone in ARM.pose.bones:              ARM.pose.bones[bone.name].matrix = ARM2.pose.bones[bone.name].matrix                    ARM.pose.bones[bone.name].rotation_mode = 'XYZ'             ARM.pose.bones[bone.name].keyframe_insert(data_path='rotation_euler', frame=frame)             scene.frame_set(frame)     scene.frame_set(frame)  # \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f - \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u0438 \u043f\u043e\u0437\u044b, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 def snap_rotation(source, target):     Ms = source.id_data.convert_space(         pose_bone=source,         matrix=source.matrix,         from_space='POSE',         )     Mt = target.id_data.convert_space(         pose_bone=target,         matrix=target.matrix,         from_space='POSE',         )                _, q, _ = Ms.decompose()     t, _, s = Mt.decompose()     M = (         Matrix.Translation(t) @         q.to_matrix().to_4x4() @          Matrix.Diagonal(s.to_4d())         )     target.matrix = target.id_data.convert_space(         pose_bone=target,         matrix=M,         to_space='POSE',         )  def change_arm(coordinates, name, scale=1.0):     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     bpy.ops.object.mode_set(mode='EDIT', toggle=False)     edit_bones = bpy.data.armatures[arm_dat_name].edit_bones     bone_nr = 0     for conn in CONNECTIONS:                 b = edit_bones[LIFTING_BONE_NAMES[bone_nr]]         b.head = [scale*item for item in coordinates[conn[0]]]         b.tail = [scale*item for item in coordinates[conn[1]]]         bone_nr += 1     bpy.ops.object.mode_set(mode = 'POSE')     # \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f     # get_pose(ARM, ARM2)          # \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f     for bone in ARM.pose.bones:         ARM.pose.bones[bone.name].rotation_mode = 'QUATERNION'         snap_rotation(bpy.data.objects[arm_obj_name].pose.bones[bone.name],                       ARM.pose.bones[bone.name])                     ARM.pose.bones[bone.name].keyframe_insert(data_path='rotation_quaternion', frame=frame)         scene.frame_set(frame)      ARM = create_armature(coordinates[0], \"A\") ARM2 = create_armature(coordinates[0], \"B\") for frame in range(len(coordinates)):             scene.frame_set(frame)             COR = coordinates[frame]             change_arm(COR, \"B\") <\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u041a\u0430\u043b\u043c\u0430\u043d\u0430<\/figcaption><\/figure>\n<p>\u0418\u0434\u0435\u044f \u0441 \u0434\u0432\u043e\u0439\u043d\u0438\u043a\u043e\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0440\u0430\u0431\u043e\u0447\u0435\u0439, \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u044f\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 &#8212; \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432 \u043e\u0441\u0438 \u043a\u043e\u0441\u0442\u0438. \u041f\u0440\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 head \u0438 tail \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u0441\u0442\u044c (\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll), \u044d\u0442\u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u043e\u0437\u044b, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0434\u0435\u0444\u0435\u043a\u0442.<\/p>\n<figure class=\"\"><figcaption>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 roll<\/figcaption><\/figure>\n<p><a href=\"https:\/\/docs.blender.org\/manual\/en\/latest\/animation\/constraints\/introduction.html\" rel=\"noopener noreferrer nofollow\"><em>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435<\/em><\/a><em> \u043a\u043e\u0441\u0442\u0435\u0439 \u0441\u043a\u0435\u043b\u0435\u0442\u0430, \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438<\/em>. \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442,  \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0441\u0442\u0438 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0434\u0440\u043e\u0432, \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432 \u043a\u043e\u0441\u0442\u0438, \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u0441\u0442\u0438 <code>keyframe_insert<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0435 \u043e\u0442 \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<pre><code class=\"python\">def create_armature(coordinates, name, scale=1.0):     \"\"\"     Creates an armature skeleton data object from the input coordinates acquired from lift_image().      The skeleton's bones will have been appropriately labelled and parented.     The skeleton data object will be implemented into the scene as well.     :param coordinates: List of vertex coordinates from lifter     :param name: Base name of the bezier_curves      :param scale: Scale of the skeleton      \"\"\"     # Setting the scale to a hundredth already as the distances from lifting are considerably large.     scale = scale * 0.01       arm_dat_name = 'Armature_dat_' + name     arm_obj_name = 'Armature_obj_' + name     arm_dat = bpy.data.armatures.new(arm_dat_name)     arm_obj = bpy.data.objects.new(arm_obj_name, arm_dat)     bpy.context.scene.collection.objects.link(arm_obj)     bpy.context.view_layer.objects.active = arm_obj<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-389721","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/389721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=389721"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/389721\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=389721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=389721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=389721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}