전체 요약
12.16(월)
- YOLOv8-pose와 미디어파이프 두가지 모델을 비교하여 낙상감지 프로젝트 구상
- 우선 YOLOv8n-pose로 관절값(코, 양쪽 어깨)을 json파일로 뽑아서 속도 임계값을 구해보려고 함
- 그런데 속도값이 너무 높게나와 시각화를 해보니
- 한 사람에게 바운딩 박스가 2개 잡히고(심지어 틀리게 잡힌것이 conf값이 더 높게 나옴)
- 순간 잡히는 정확도가 떨어짐
➡ json파일 뽑는 코드는 확정됨
🚩
현재 이상이 생긴 박스플롯(아래 영상)의 문제 해결 후 위와 다른 박스플롯이 나오면 문제 해결된 것으로 판단예정입니다.
yolov8n-pose에서 두 바운딩 박스가 잡히는건 (값을 출력해 봐야겠지만) 한 명만 고정해서 트랙커하는걸로하려고 합니다.
YOLOv8n-pose관절값(코, 양쪽 어깨)을 json파일로 뽑아서 속도 임계값을 구해보려고 함
import cv2
import json
import numpy as np
from ultralytics import YOLO
yolo_model = YOLO('yolov8n-pose.pt')
# 동영상 경로
input_video = '/content/drive/MyDrive/PJ/00014_H_A_FY_C4.mp4'
output_video = '/content/output_yolo.mp4'
json_output = '/content/output_yolo.json'
# 동영상 읽기 및 저장 설정
cap = cv2.VideoCapture(input_video)
out = cv2.VideoWriter(
output_video,
cv2.VideoWriter_fourcc(*'mp4v'),
int(cap.get(cv2.CAP_PROP_FPS)),
(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
)
# 랜드마크 정의 (코, 왼쪽 어깨, 오른쪽 어깨)
INTERESTED_LANDMARKS = [0, 5, 6]
landmarks_data = []
frame_idx = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = yolo_model(frame)
for result in results:
# JSON저장 파일 양식
frame_data = {"frame_idx": frame_idx}
if result.keypoints is not None and result.keypoints.xyn.numpy().size > 0:
for idx in INTERESTED_LANDMARKS:
frame_data[f'landmark_{idx}_x'] = float(result.keypoints.xyn[0][idx][0])
frame_data[f'landmark_{idx}_y'] = float(result.keypoints.xyn[0][idx][1])
landmarks_data.append(frame_data)
out.write(frame)
frame_idx += 1
cap.release()
out.release()
with open(json_output, 'w') as f:
json.dump(landmarks_data, f)
print(f"처리가 완료되었습니다! 결과 파일: {output_video}, 랜드마크 데이터: {json_output}")
box plot 구현
↑ 코드
낙상 임계값 추출 코드
import json
import pandas as pd
# JSON 파일 로드
data = json.load(open('/content/output_yolo.json'))
df = pd.json_normalize(data)
# df.head()
df['center_x'] = (df['landmark_0_x'] + df['landmark_5_x'] + df['landmark_6_x']) / 3
df['center_y'] = (df['landmark_0_y'] + df['landmark_5_y'] + df['landmark_6_y']) / 3
# df.head()
df['speed'] = (df['center_x'].diff()**2 + df['center_y'].diff()**2)**0.5
# df.head()
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 박스플롯 그리기
plt.figure(figsize=(7, 5))
sns.boxplot(x=df['speed'])
plt.title('Boxplot of Speed')
plt.xlabel('Speed')
plt.show()
너무 이상치가 커서 미리 확인해봐야할 영상 자료를 뒤늦게 확인해보았다 만약 미리 봤었더라면 해결점을 좀 더 넓고 빨리 찾을 수 있었을것같았다.
그래서 왜 순서가 있는지 다시한번 깨달았다.
영상확인
import cv2
from ultralytics import YOLO
# YOLO 모델 로드
yolo_model = YOLO('yolov8n-pose.pt')
# 동영상 경로
input_video = '/content/drive/MyDrive/PJ/00014_H_A_FY_C4.mp4'
output_video = '/content/output_yolo.mp4'
# 동영상 읽기 및 저장 설정
cap = cv2.VideoCapture(input_video)
out = cv2.VideoWriter(
output_video,
cv2.VideoWriter_fourcc(*'mp4v'),
int(cap.get(cv2.CAP_PROP_FPS)),
(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
)
# 동영상 처리
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 모델로 프레임 분석
results = yolo_model(frame)
# 결과를 프레임에 시각화
for result in results:
# 시각화된 결과를 가져옴
frame = result.plot(
conf=True, # 신뢰도 표시
kpt_radius=5, # 키포인트 반지름
kpt_line=True, # 키포인트 간 선 그리기
boxes=True, # 박스 표시
color_mode='instance' # 색상 모드 설정
)
# 결과를 동영상 파일에 저장
out.write(frame)
cap.release()
out.release()
print(f"처리가 완료되었습니다! 결과 파일: {output_video}")
'Project > 낙상' 카테고리의 다른 글
[낙상 감지 프로젝트] 2025년 2월 22일 (토) _프로젝트 완성 (0) | 2025.02.22 |
---|---|
[낙상 감지 프로젝트] 2025년 2월 15일 (토) (0) | 2025.02.15 |
[낙상 감지 프로젝트] 2024년 12월 31일(화) (1) | 2024.12.31 |
[낙상 감지 프로젝트] 2024년 12월 20일(금) (3) | 2024.12.20 |
[낙상 감지 프로젝트] 2024년 12월 17일(화) (1) | 2024.12.17 |