Utilisez openpose pour extraire les points osseux de l'ensemble de données auto-construit pour former st-gcn et reproduire st-gcn

Utilisez openpose pour extraire les points osseux de l'ensemble de données auto-construit pour former st-gcn et reproduire st-gcn

0. Télécharger st-gcn

Référence :
Il est plus rapide d'importer vers gitee après fork sur gitbub : téléchargement st-gcn
Vous pouvez aussi directement télécharger le fichier zip et le décompresser

1. Traitez et préparez votre propre ensemble de données

  • L'ensemble de données nécessite que les vidéos de la même catégorie soient placées dans le même dossier. J'utilise ici un ensemble de données plus ancien : training_lib_KTH.zip, et six comportements sont placés dans six dossiers différents.
    insérez la description de l'image ici
    Le nombre d'images vidéo de l'ensemble de données utilisé pour la formation st-gcn ne doit pas dépasser 300 images, et la durée de la vidéo de 5-6s est meilleure, pas plus de 10s. index 300 is out of bounds for axis 1 with size 300Sinon, cette erreur sera signalée . Par conséquent, l'ensemble de données ci-dessus est encore recadré à environ 150 images de 6s (la fréquence d'images vidéo est de 25, et lorsque la fréquence d'images est à nouveau modifiée à 30 à l'aide de FFmpeg, la durée sera étendue à 8s). Le fichier vidéo recadré est le suivant :
    insérez la description de l'image ici
    l'ensemble de données d'origine et l'ensemble de données recadrées 6s sont placés dans le lien :
    Lien : https://pan.baidu.com/s/1oHQyo-c3e5YXb52b-O0STQ?pwd=x166
    Code d'extraction : x166

2. Préparer l'environnement et créer l'environnement openpose

  • Le but de la configuration de l'environnement openpose est d'utiliser la pose ouverte pour extraire les points du squelette de la vidéo knetics-skeleton. Pour la construction de l'environnement openpose, veuillez vous référer à la vidéo suivante : Construction de l'environnement openpose et blog de référence :
    Windows
    10 , code openpose auto-compilé
  • Notez ici que si vous utilisez cuda, il est préférable de télécharger vs avant de télécharger cuda

3. Utilisez openpose pour extraire vos propres données d'os vidéo

Les auteurs de st-gcn leur ont fourni l'ensemble de données de squelette cinétique qu'ils ont organisé et utilisé. Le format de leur ensemble de données est illustré
insérez la description de l'image ici
dans la figure ci-dessous : L'ensemble de données de reconnaissance du comportement cinétique-squelette construit La partie 2 redimensionne les données vidéo à une taille de 340x256 et une fréquence d'images de 30 ips. Appelez ensuite openpose pour détecter et générer les données de point d'os.

#!/usr/bin/env python
# coding:gbk
import os
import argparse
import json
import shutil

import numpy as np
import torch
import skvideo.io

#from processor.io import IO
import tools
import tools.utils as utils


# if __name__ == '__main__':
#class PreProcess(IO):
class PreProcess():
    def start(self):

        work_dir = 'D:/st-gcn'
        type_number = 6
        action_filename_list = ['boxing', 'handclapping', 'handwaving', 'jogging', 'running', 'walking']


        for process_index in range(type_number):

            action_filename = action_filename_list[process_index]
            # 标签信息
            labelAction_name = '{}_{}'.format(action_filename,process_index)
            #labelAction_name = 'xxx_{}'.format(process_index)
            label_no = process_index

            # 视频所在文件夹
            originvideo_file = 'D:/dataSet/training_lib_KTH_cut_6s/{}/'.format(action_filename)
            # resized视频输出文件夹 需要自己创建几个动作的文件夹
            resizedvideo_file = './mydata/training_lib_KTH_cut_6s/resized/{}/'.format(action_filename)

            videos_file_names = os.listdir(originvideo_file)

            # 1. Resize文件夹下的视频到340x256 30fps
            for file_name in videos_file_names:
                video_path = '{}{}'.format(originvideo_file, file_name)
                outvideo_path = '{}{}'.format(resizedvideo_file, file_name)
                writer = skvideo.io.FFmpegWriter(outvideo_path,
                                                 outputdict={
    
    '-f': 'mp4','-vcodec': 'libx264', '-s': '340x256',
                                                             '-r': '30'})
                reader = skvideo.io.FFmpegReader(video_path)
                for frame in reader.nextFrame():
                    writer.writeFrame(frame)
                writer.close()
                print('{} resize success'.format(file_name))

            # 2. 利用openpose提取每段视频骨骼点数据
            resizedvideos_file_names = os.listdir(resizedvideo_file)
            for file_name in resizedvideos_file_names:
                outvideo_path = '{}{}'.format(resizedvideo_file, file_name)

                # openpose = '{}/examples/openpose/openpose.bin'.format(self.arg.openpose)
                #openpose = '{}/OpenPoseDemo.exe'.format(self.arg.openpose)
                openpose = 'D:/openpose-master/build/x64/Release/OpenPoseDemo.exe'

                video_name = file_name.split('.')[0]
                output_snippets_dir = './mydata/training_lib_KTH_cut_6s/resized/snippets/{}'.format(video_name)
                output_sequence_dir = './mydata/training_lib_KTH_cut_6s/resized/data'
                output_sequence_path = '{}/{}.json'.format(output_sequence_dir, video_name)

                #label_name_path = '{}/resource/kinetics_skeleton/label_name_action.txt'.format(work_dir)
				#自己创建好标签文档,里面文档内写好动作名称
                label_name_path = '{}/resource/kinetics_skeleton/label_name_action{}.txt'.format(work_dir,process_index)
                with open(label_name_path) as f:
                    label_name = f.readlines()
                    label_name = [line.rstrip() for line in label_name]

                # pose estimation
                openpose_args = dict(
                    video=outvideo_path,
                    write_json=output_snippets_dir,
                    display=0,
                    render_pose=0,
                    model_pose='COCO')
                command_line = openpose + ' '
                command_line += ' '.join(['--{} {}'.format(k, v) for k, v in openpose_args.items()])
                shutil.rmtree(output_snippets_dir, ignore_errors=True)
                os.makedirs(output_snippets_dir)
                os.system(command_line)

                # pack openpose ouputs
                video = utils.video.get_video_frames(outvideo_path)

                height, width, _ = video[0].shape

                # 这里可以修改label, label_index
                video_info = utils.openpose.json_pack(
                    output_snippets_dir, video_name, width, height, labelAction_name, label_no)

                if not os.path.exists(output_sequence_dir):
                    os.makedirs(output_sequence_dir)

                with open(output_sequence_path, 'w') as outfile:
                    json.dump(video_info, outfile)
                if len(video_info['data']) == 0:
                    print('{} Can not find pose estimation results.'.format(file_name))
                    return
                else:
                    print('{} pose estimation complete.'.format(file_name))

if __name__ == '__main__':
    p=PreProcess()
    p.start()

Avant d'exécuter le code, créez à l'avance le dossier /mydata/training_lib_KTH_cut_6s_resized dans st-gcn et créez les dossiers pour les six comportements dans le dossier, 'boxing', 'handclapping', 'handwaving', 'jogging', 'running' , 'marche'. Avant l'exécution, vous devez également créer des documents d'étiquettes 0 à 5 :
document d'étiquette
chaque document contient 100 étiquettes d'action. Après
l'exécution, il est affiché comme suit :
insérez la description de l'image ici
ouvrez les données à ce moment pour voir les données osseuses de toutes les vidéos, et chaque fichier json dans les extraits stockent une seule image squelette de données, chaque fichier json dans les données est toutes les données de point d'os d'une vidéo. Le fichier json dans les données est ouvert comme illustré dans la figure suivante :
insérez la description de l'image ici

4. Organiser les données de point d'os et générer le format de l'opération st-gcn

Divisez d'abord les données dans les données en ensemble d'entraînement, ensemble de vérification et ensemble de test selon 6: 2: 2. Copiez
insérez la description de l'image ici
kinetics_train de 01 à 15, mettez 16-20 dans val et mettez 21-25 dans test.

import json
import os

if __name__ == '__main__':
    train_json_path = './mydata/kinetics-skeleton/kinetics_train'
    val_json_path = './mydata/kinetics-skeleton/kinetics_val'
    test_json_path = './mydata/kinetics-skeleton/kinetics_test'

    output_train_json_path = './mydata/kinetics-skeleton/kinetics_train_label.json'
    output_val_json_path = './mydata/kinetics-skeleton/kinetics_val_label.json'
    output_test_json_path = './mydata/kinetics-skeleton/kinetics_test_label.json'
    #
    train_json_names = os.listdir(train_json_path)
    val_json_names = os.listdir(val_json_path)
    test_json_names = os.listdir(test_json_path)

    train_label_json = dict()
    val_label_json = dict()
    test_label_json = dict()


    for file_name in train_json_names:
        name = file_name.split('.')[0]
        json_file_path = '{}/{}'.format(train_json_path, file_name)
        json_file = json.load(open(json_file_path))

        file_label = dict()
        if len(json_file['data']) == 0:
            file_label['has_skeleton'] = False
        else:
            file_label['has_skeleton'] = True
        file_label['label'] = json_file['label']
        file_label['label_index'] = json_file['label_index']

        train_label_json['{}'.format(name)] = file_label

        print('{} success'.format(file_name))

    with open(output_train_json_path, 'w') as outfile:
        json.dump(train_label_json, outfile)

    for file_name in val_json_names:
        name = file_name.split('.')[0]
        json_file_path = '{}/{}'.format(val_json_path, file_name)
        json_file = json.load(open(json_file_path))

        file_label = dict()
        if len(json_file['data']) == 0:
            file_label['has_skeleton'] = False
        else:
            file_label['has_skeleton'] = True
        file_label['label'] = json_file['label']
        file_label['label_index'] = json_file['label_index']

        val_label_json['{}'.format(name)] = file_label

        print('{} success'.format(file_name))

    with open(output_val_json_path, 'w') as outfile:
        json.dump(val_label_json, outfile)

    for file_name in test_json_names:
        name = file_name.split('.')[0]
        json_file_path = '{}/{}'.format(test_json_path, file_name)
        json_file = json.load(open(json_file_path))

        file_label = dict()
        if len(json_file['data']) == 0:
            file_label['has_skeleton'] = False
        else:
            file_label['has_skeleton'] = True
        file_label['label'] = json_file['label']
        file_label['label_index'] = json_file['label_index']

        test_label_json['{}'.format(name)] = file_label

        print('{} success'.format(file_name))

        with open(output_test_json_path, 'w') as outfile:
            json.dump(test_label_json, outfile)

La génération est la suivante :
insérez la description de l'image ici
utilisez ensuite le code de conversion de données tools/kinetics_gendata.py fourni avec le code d'entraînement stgcn, et utilisez ce script pour convertir l'ensemble de données kinetics-skleton en fichiers npy et pkl pour l'entraînement.
Voici une référence au blog : Three data conversions in data conversion . Les endroits suivants doivent être modifiés :

        num_person_in=1,  #observe the first 5 persons
        num_person_out=1,  #then choose 2 persons with the highest score
    part = ['train', 'val','test']

La vidéo précédente a été recadrée sans modifier le cadre.
Après avoir exécuté le script :
insérez la description de l'image ici

5. Formation réseau st-gcn

Pour cette partie, reportez-vous aux parties 5 et 6 de l'ensemble de données de reconnaissance de comportement auto-construit de la formation st-gcn
Mon train.yaml est modifié comme ceci :

work_dir: ./work_dir/recognition/kinetics_skeleton/ST_GCN

# feeder
feeder: feeder.feeder.Feeder
train_feeder_args:
  random_choose: True
  random_move: True
  window_size: 150 
#  data_path: ./data/Kinetics/kinetics-skeleton/train_data.npy
#  label_path: ./data/Kinetics/kinetics-skeleton/train_label.pkl
  data_path: ./mydata/kinetics-skeleton/train_data.npy
  label_path: ./mydata/kinetics-skeleton/train_label.pkl

test_feeder_args:
#  data_path: ./data/Kinetics/kinetics-skeleton/val_data.npy
#  label_path: ./data/Kinetics/kinetics-skeleton/val_label.pkl
  data_path: ./mydata/kinetics-skeleton/val_data.npy
  label_path: ./mydata/kinetics-skeleton/val_label.pkl

# model
model: net.st_gcn.Model
model_args:
  in_channels: 3
  num_class: 6
  edge_importance_weighting: True
  graph_args:
    layout: 'openpose'
    strategy: 'spatial'

# training
#device: [0,1,2,3]
device: [0]
batch_size: 32
test_batch_size: 32

#optim
base_lr: 0.1
step: [20, 30, 40, 50]
num_epoch: 50

Exécutez le code d'entraînement :

python main.py recognition -c config/st_gcn/kinetics-skeleton/train.yaml

6. Testez

Vous pouvez modifier test.yaml pour tester avec votre propre jeu de test tout à l'heure

weights: ./work_dir/recognition/kinetics_skeleton/ST_GCN/epoch50_model.pt
#weights: ./models/st_gcn.kinetics.pt

# feeder
feeder: feeder.feeder.Feeder
test_feeder_args:
#  data_path: ./data/Kinetics/kinetics-skeleton/val_data.npy
#  label_path: ./data/Kinetics/kinetics-skeleton/val_label.pkl

#  data_path: ./mydata/kinetics-skeleton/val_data.npy
#  label_path: ./mydata/kinetics-skeleton/val_label.pkl
  data_path: ./mydata/kinetics-skeleton/test_data.npy
  label_path: ./mydata/kinetics-skeleton/test_label.pkl

# model
model: net.st_gcn.Model
model_args:
  in_channels: 3
  num_class: 6
  edge_importance_weighting: True
  graph_args:
    layout: 'openpose'
    strategy: 'spatial'

# test 
phase: test
device: 0
test_batch_size: 32

puis exécutez

python main.py recognition -c config/st_gcn/kinetics-skeleton/test.yaml

Remarque : L'auteur est également un débutant. Cet article est à titre de référence et de discussion. Si vous avez des questions, n'hésitez pas à discuter et à donner des conseils !

おすすめ

転載: blog.csdn.net/qq_41131123/article/details/127164293