import cv2
import mediapipe as mp
import math

import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier

# 一些全局变量
label = [' ']  # 识别输出标签
posese = ''  # 视频输出标签
i = 0
t = 30  # 后处理帧数
posese_a = ''
posese_b = ''
version = 'V7.0'
a = 1.2  # 辅助拟合精度
distance_threshold = 121  # 设置KNN距离阈值
neighbors = 2  # 邻居
input_path = ''

# 初始化MediaPipe的人体姿势模型
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

# # 打开输入视频文件
# cap = cv2.VideoCapture('5.mp4')
import tkinter as tk
from tkinter import filedialog

# 修改distance_threshold
def set_distance_threshold(value):
    global distance_threshold
    distance_threshold = int(value)





# 创建窗口
root = tk.Tk()
root.withdraw()


# 显示使用说明信息
info = '欢迎使用击剑动作识别程序V6.2(作者:冯楠20201888)
请选择输入视频文件
支持格式:*.mp4, *.avi
点击确认选择文件'
tk.messagebox.showinfo('使用说明', info)

# 定义选择文件函数
def select_file():
    global input_path
    root3 = tk.Tk()
    root3.title('选择文件')
    input_path = filedialog.askopenfilename(title='选择输入视频文件', filetypes=[('视频文件', '*.mp4;*.avi'), ('所有文件', '*.*')])
    root3.destroy()
    if not input_path:
        tk.messagebox.showerror('错误', '未选择输入视频文件!')
        root3.destroy()
        return
    # 更新标签显示选择的文件路径
    file_label.config(text=input_path)
def closeit():
    root2.destroy()

# 创建窗口2
root2 = tk.Tk()
root2.title('选择文件,调整参数')
root2.geometry('400x600')

# 创建标题
file_titles = tk.Label(root2, text='击剑动作识别程序', font=('宋体', 18))
file_titles.pack(pady=20)
# 创建标签
file_label = tk.Label(root2, text='未选择文件')
file_label.pack(pady=20)
file_label.config(bg='#e9ccd3')

select_button = tk.Button(root2, text='选择文件', command=select_file)
select_button.pack(pady=10)
# 创建标题
file_titles = tk.Label(root2, text='参数调整', font=('微软雅黑', 13))
file_titles.pack(pady=20)
# 创建滑动条
scale = tk.Scale(root2, from_=0, to=200, orient=tk.HORIZONTAL, length=150, label='距离阈值', command=set_distance_threshold)
scale.set(distance_threshold)
scale.pack()



def set_neighbors(val):
    global neighbors
    neighbors = int(val)
# 创建滑动条
scale = tk.Scale(root2, from_=1, to=10, orient=tk.HORIZONTAL, length=150, label='邻居数量', command=set_neighbors)
scale.set(neighbors)
scale.pack()



# 创建按钮

run_button = tk.Button(root2, text='运行', command=closeit)
run_button.pack(pady=20)

# 创建标签
file_name = tk.Label(root2, text=f"作者:冯楠2020188 物联网2班\n指导教师:朱勇\n版本:{version}", font=("Arial", 14))
file_name.pack(pady=20)
# 关闭窗口
root.destroy()
# 运行窗口
root2.attributes('-topmost', True)  # 窗口在最前
root2.mainloop()



# 打开输入视频文件
print('打开输入视频文件')
cap = cv2.VideoCapture(input_path)


# 获取输入视频的帧率和分辨率
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 创建输出视频文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(f"{input_path}_OUT.mp4", fourcc, fps, (width, height))

# 加载动作数据集
warmup_df = pd.read_csv('dataset_warm-up.csv')
combat_df = pd.read_csv('dataset_SHIZHAN POSE.csv')
attack_df = pd.read_csv('dataset_hit.csv')
respect_df = pd.read_csv('dataset_respect.csv')
gongbu_df = pd.read_csv('dataset_gongbu.csv')


# 数据清洗
# 将每个小数据集中偏离平均值超过2倍标准差的样本删除
print('数据清洗')
for df in [warmup_df, combat_df, attack_df, respect_df, gongbu_df]:
    df.drop(df[(np.abs(df[['angle1', 'angle2', 'angle3', 'angle4', 'angle5', 'angle5_1', 'angle6', "angle7", "angle8", "angle9", "angle10", "angle11"]] - df[['angle1', 'angle2', 'angle3', 'angle4', 'angle5', 'angle5_1', 'angle6', "angle7", "angle8", "angle9", "angle10", "angle11"]].mean()) > 2 * df[['angle1', 'angle2', 'angle3', 'angle4', 'angle5', 'angle6', "angle7", "angle8", "angle9", "angle10", "angle11"]].std()).any(axis=1)].index, inplace=True)


# 将数据集合并为一个大的数据集
data = pd.concat([warmup_df, combat_df, attack_df, respect_df, gongbu_df], ignore_index=True)



# 训练KNN分类器
print('开始训练knn')
knn = KNeighborsClassifier(n_neighbors=neighbors, weights='distance', metric='manhattan')
knn.fit(data[['angle1', 'angle2', 'angle3', 'angle4', 'angle5', 'angle5_1', 'angle6', "angle7", "angle8", "angle9", "angle10", "angle11"]], data['label'])  # 将训练后的KNN可视化内容:# 定义一个函数,将训练后的KNN可视化
def knn_visualization(knn, data):
    # 获取数据集中的所有标签
    labels = data['label'].unique()
    # 创建一个空白图像
    img = np.zeros((500, 500, 3), np.uint8)
    # 遍历图像的所有像素点
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            # 获取当前像素点的坐标
            x = float(j) / img.shape[1]
            y = 1.0 - float(i) / img.shape[0]
            # 将坐标转换为特征向量
            features = np.array([x, y])
            # 使用KNN分类器对特征向量进行分类
            label = knn.predict([features])[0]
            # 将分类结果转换为颜色
            color = (0, 0, 0)
            for k in range(len(labels)):
                if label == labels[k]:
                    color = (int(255 * (k + 1) / len(labels)), int(255 * (k + 1) / len(labels)), int(255 * (k + 1) / len(labels)))
                    break
            # 将当前像素点的颜色设置为分类结果的颜色
            img[i, j] = color
    # 显示可视化结果
    cv2.imshow('KNN可视化', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 显示KNN分类器的可视化结果
knn_visualization(knn, data)

原文地址: https://www.cveoy.top/t/topic/gQ0M 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录