과정/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()