目錄
工具展示和使用說明
工具標注后文件展示說明
json轉換成單個npy文件
數據獲取補充
工具展示和使用說明
文件名labelV.py集于PySide6實現:
?
通過選擇視頻來選擇你要標注的視頻,然后選擇保存路徑:
然后視頻兩個類別。當你看見視頻中的人跳繩開始時,按鍵盤1或者點擊來標記開始幀號,按鍵盤左右鍵調轉上下幀,按e結束標記(這里我每一百幀標記一次)。
工具標注后文件展示說明
{"segments": [[36,140,1],[141,243,1],[255,360,1],[370,476,1],[477,590,1],[591,693,1],[706,776,1]]
}
保存后會得到這樣一個json文件,這里每一個列表中的內容分別代表開始事件幀數,結束事件幀數,事件類別。
json轉換成單個npy文件
代碼名jsonNpy.py,我這里用的時yolov8-pose模型,
def process_segment(video_path, start, end, label, output_name):cap = cv2.VideoCapture(video_path)T = end - start + 1skeleton = np.zeros((2, T, 17, 1), dtype=np.float32)valid = Truefor i, frame_idx in enumerate(range(start, end + 1)):cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx)ret, frame = cap.read()if not ret:print(f"[!] 無法讀取幀 {frame_idx} in {video_path}")valid = Falsebreakkeypoints = extract_keypoints(frame)if keypoints is None or keypoints.shape != (17, 2):print(f"[!] 關鍵點提取失敗 at frame {frame_idx}")valid = Falsebreakfor v in range(17):skeleton[0, i, v, 0] = keypoints[v][0]skeleton[1, i, v, 0] = keypoints[v][1]cap.release()if valid:out_path = os.path.join(OUTPUT_DIR, output_name)np.save(out_path, skeleton)label_list.append({"sample_name": output_name,"label": label})else:print(f"[?] 放棄片段: {start}-{end} in {video_path}")
通過opencv讀取視頻幀再根據標注文件json中的信息完成保存成npy文件,數組形狀[2, T, 17, 1],2代表存儲的關鍵點的x和y坐標,T代表幀數,這里我選擇的是100,17代表關鍵點數量是17(這里根據你選擇的模型來,比如openpose的話這里就是18)。1代表一個人。同時保存一個總的json文件,來記錄每一個npy的類別:
{"sample_name": "nojump_output_0189.npy","label": 0},{"sample_name": "nojump_output_0190.npy","label": 0},{"sample_name": "nojump_output_0191.npy","label": 0},
數據獲取補充
鑒于自己標準視頻實在是費時費力,本文提供了一個腳本autoLabel.py,
def main():# 加載現有 label.json(如果存在)label_list = []if os.path.exists(LABEL_JSON):with open(LABEL_JSON, "r") as f:label_list = json.load(f)# 處理 label1 文件夾(跳繩,類別 1)for video_file in os.listdir(LABEL1_DIR):if video_file.endswith((".mp4", ".avi", ".mov")):video_path = os.path.join(LABEL1_DIR, video_file)sample_prefix = f"jump_{Path(video_file).stem}"new_samples = extract_skeleton_from_video(video_path, label=1, output_dir=OUTPUT_DIR,sample_prefix=sample_prefix)label_list.extend(new_samples)# 處理 label0 文件夾(非跳繩,類別 0)for video_file in os.listdir(LABEL0_DIR):if video_file.endswith((".mp4", ".avi", ".mov")):video_path = os.path.join(LABEL0_DIR, video_file)sample_prefix = f"nojump_{Path(video_file).stem}"new_samples = extract_skeleton_from_video(video_path, label=0, output_dir=OUTPUT_DIR,sample_prefix=sample_prefix)label_list.extend(new_samples)# 保存 label.jsonwith open(LABEL_JSON, "w") as f:json.dump(label_list, f, indent=4)print(f"[?] 骨架數據提取完成,保存到 {OUTPUT_DIR},標簽更新到 {LABEL_JSON}")print(f"總樣本數: {len(label_list)}")
你可以將跳繩視頻和非跳繩視頻分別放到兩個文件夾中,配置好相關信息,然后會自動幫你生成npy文件。
后續更新數據匯總和預處理