과정/2차 AI프로젝트(해커톤참가)
MediaPipe를 이용한 간단한 앉은 자세 인식하기
줘요
2023. 9. 26. 20:14
이전에 했던 MediaPipe를 이용한 실시간 랜드마크 생성글에서 했던 코드
+ 앉은 자세를 보여주는 코드를 작성해보자
먼저 추가된 코드를 적은 후 완성된 코드를 뒤에 첨부하겠습니당
# 앉은 자세의 임계값을 설정해준다.
YOUR_SITTING_THRESHOLD = 0.7
먼저 앉은 자세에 대한 기준점을 잡기 위해 임계값을 설정해줍니다.
#기본값으로 앉은게 아닌 것으로 표시해준다.
sitting = False
기본 값으로는 앉지 않을 것으로 인식하게 설정
# 왼쪽 어깨와 오른쪽 어깨에 대한 랜드마크 위치를 검색
left_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
right_shoulder= results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
저는 어깨를 기준으로 설정하였습니다. (엉덩이를 기준으로 하실 분들은 따로 만드시면 됩니다!)
웹캠이 가까이 있어서 어깨 아래로는 보여주기 힘들어 어깨로 선정하였습니다.
[mp_pose.PoseLandmark.LEFT_SHOULDER] 여기서 나오는 LEFT_SHOUDER는 이미 정의된 값을 넣어주었습니다.
#왼쪽 어깨와 오른쪽 어깨가 설정해 놓은 임계값보다 크다면 앉은 것으로 인식
if (left_shoulder and right_shoulder).y > YOUR_SITTING_THRESHOLD:
sitting = True
양쪽 어깨의 Y 좌표가 '0.7'(프레임 높이의 70%)보다 큰 경우 코드는 'sitting' 변수를 'True'로 설정하여 사람이 앉아 있는 것으로 인식되었음을 나타냄
print(left_shoulder)
하지만 정확히 값이 어떻게 찍히는지 몰라서 print를 통해 left_shoulder 값을 찍어보았다.
찍어보니 화면상에서 어깨라인이 내려가면 y값이 커졌고 반대로 올라가면 y값이 작아졌다.
# 앉은 상태를 보여준다.
status_text = "Sitting" if sitting else "Not Sitting"
cv2.putText(frame, status_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
이제 화면왼쪽 상단에 텍스트를 보여준다.
추가된 코드는 여기까지입니다!
마지막으로 실습한 이미지와 완성된 코드를 보여드리겠습니당
#먼저 MediaPipe 및 OpenCV를 포함하여 필요한 라이브러리를 가져옵니다.
import cv2
import mediapipe as mp
#신체 랜드마크 감지를 위해 MediaPipe 포즈 모델을 초기화합니다.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
#mp_drawing 변수를 초기화하고 이를 mp.solutions.raw_utils 클래스와 연결
mp_drawing = mp.solutions.drawing_utils
#실시간 비디오를 캡처하려면 웹캠 피드를 엽니다.
cap = cv2.VideoCapture(1)
# 앉은 자세의 임계값을 설정해준다.
YOUR_SITTING_THRESHOLD = 0.7
#비디오 프레임을 지속적으로 처리하고 신체 랜드마크를 오버레이하는 루프를 만들자
while True:
#웹캠에서 프레임을 읽는다.
ret, frame = cap.read()
if not ret:
break
#프레임을 RGB로 변화해준다.
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
#MediaPipe Pose로 프레임을 처리한다.
results = pose.process(frame_rgb)
#기본값으로 앉은게 아닌 것으로 표시해준다.
sitting = False
#랜드마크가 감지되었는지 확인
if results.pose_landmarks:
# 왼쪽 어깨와 오른쪽 어깨에 대한 랜드마크 위치를 검색
left_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
right_shoulder= results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
#왼쪽 어깨와 오른쪽 어깨가 설정해 놓은 임계값보다 크다면 앉은 것으로 인식
if (left_shoulder and right_shoulder).y > YOUR_SITTING_THRESHOLD:
sitting = True
print(left_shoulder)
#프레임에 랜드마크를 렌더링한다.
mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
# 앉은 상태를 보여준다.
status_text = "Sitting" if sitting else "Not Sitting"
cv2.putText(frame, status_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# 랜드마크가 있는 프레임을 보여준다.
cv2.imshow('Pose Estimation', frame)
# q를 누르면 while문 종료됨.
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#프로그램 작업을 마친 후 할당된 리소르를 남기거나 열어두지 않게 함
#비디오 캡처 리소스를 해제
cap.release()
#모든 OpenCV 표시 창을 닫습니다.
cv2.destroyAllWindows()