Python과 컴퓨터 카메라를 사용하여 팔굽혀펴기 횟수 세기

Python과 컴퓨터 카메라를 사용하여 팔굽혀펴기 횟수 세기

많은 프로젝트를 사용하여 컴퓨터 비전 및 Python 기술을 강화할 수 있습니다. 이러한 프로젝트 중 하나는 Python을 사용하여 간단한 푸시업 카운터를 만드는 것입니다. 이 프로젝트의 프로그램을 단일 파일에 작성할 수 있습니다.

이 프로그램은 비디오 입력 또는 카메라의 실시간 입력을 받아 입력에 대해 사람의 자세 추정을 수행하고 사람이 하는 팔굽혀펴기 횟수를 계산합니다. 인간 포즈 추정을 수행하기 위해 프로그램은 MediaPipe 인간 포즈 추정 모델을 사용합니다.

MediaPipe 인간 포즈 추정 모델이란 무엇입니까?

인체의 33개 랜드마크를 추적하는 Google에서 개발한 모델입니다. 또한 2등급 분할로 나타내는 전신 분할을 예측합니다. 다음 이미지는 모델이 식별할 수 있는 모든 랜드마크를 보여줍니다. 번호가 매겨진 포인트는 각 랜드마크를 식별하고 선으로 서로 연결됩니다.

MediaPipe 인간 포즈 추정 랜드마크
이미지 크레디트: MediaPipe/ GitHub

푸시업 카운터 프로그램은 어깨와 팔꿈치의 위치를 ​​활용합니다. 위의 이미지에서 어깨 랜드마크는 11과 12이고 팔꿈치 랜드마크는 13과 14입니다.

환경 설정

Python의 기본 사항에 이미 익숙해야 합니다. Python IDE를 열고 새 Python 파일을 만듭니다. 터미널에서 다음 명령을 실행하여 환경에 해당 패키지를 설치합니다.

pip install OpenCV-Python

OpenCV-Python 을 사용하여 프로그램에서 비디오 입력을 가져와 처리합니다. 이 라이브러리는 프로그램 컴퓨터 비전 기능을 제공합니다.

pip install MediaPipe

MediaPipe를 사용하여 입력에서 사람 포즈 추정을 수행합니다.

pip install imutils

imutils를 사용하여 비디오 입력의 크기를 원하는 너비로 조정합니다.

터미널에 Python 라이브러리 설치

가져오기 및 MediaPipe 초기화

이전에 환경에 설치한 세 개의 라이브러리를 가져오십시오. 이렇게 하면 프로젝트에서 해당 종속성을 사용할 수 있습니다.

import cv2
import imutils
import mediapipe as mp

그런 다음 3개의 MediaPipe 객체를 생성하고 각각의 함수를 사용하여 초기화합니다. mp.solutions.drawing_utils 함수를 사용하여 입력에 다양한 랜드마크를 그립니다. mp.solutions.drawing_styles는 랜드마크의 그림이 나타나는 스타일을 변경하고 이러한 랜드마크를 식별하는 데 사용할 모델인 mp.solutions.pose를 변경합니다.

mp_draw = mp.solutions.drawing_utils
mp_draw_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose

인간 포즈 추정 수행

사람의 포즈 감지는 관절을 식별하고 분류하여 신체 방향을 식별하는 프로세스입니다.

변수 선언

푸시업 횟수, 어깨와 팔꿈치의 위치, 비디오 입력을 저장하는 데 사용할 변수를 선언합니다.

count = 0
position = None
cap = cv2.VideoCapture("v4.mp4")

위치 변수를 없음으로 초기화합니다. 프로그램은 팔꿈치와 어깨의 위치에 따라 업데이트합니다.

MediaPipe 포즈 추정 모델 호출

입력에서 사람의 포즈를 감지할 MediaPipe 포즈 추정 모델을 호출합니다.

with mp_pose.Pose(
    min_detection_confidence = 0.7,
    min_tracking_confidence = 0.7) as pose:

탐지 신뢰도 및 추적 신뢰도의 초기화는 모델에서 필요한 정확도 수준을 나타냅니다. 0.7은 70% 정확도와 비슷합니다. 원하는 수준으로 변경할 수 있습니다.

입력 가져오기 및 전처리

나중에 포즈 추정 모델에 전달할 입력을 받습니다. imutils 라이브러리를 사용하여 비디오 입력의 너비를 조정합니다. MediaPipe는 RGB 입력에서만 작동하므로 입력을 BGR에서 RGB로 변환합니다 . 마지막으로 변환된 입력을 인간 포즈 추정 모델에 전달하여 랜드마크를 식별합니다.

while cap.isOpened():
    success, image=cap.read()

    if not success:
        print("empty camera")
        break


    image = imutils.resize(image, width=500)
    image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
    result = pose.process(image)

입력을 처리한 후 입력에서 랜드마크를 식별했습니다.

입력에 식별된 랜드마크 그리기

각 랜드마크의 좌표를 저장할 빈 목록을 만듭니다. draw_landmarks 클래스를 사용하여 각 랜드마크와 그 사이의 연결에 점을 그립니다. for 루프를 사용하여 랜드마크를 반복하고 생성한 목록에 각 랜드마크의 ID와 좌표를 저장합니다. image.shape 클래스를 사용하여 비디오 입력의 너비와 높이를 계산합니다.

lmList = []

if result.pose_landmarks:
    # Draws the landmarks' points and connects them
    mp_draw.draw_landmarks(image, result.pose_landmarks,
                               mp_pose.POSE_CONNECTIONS)

    for id, im in enumerate(result.pose_landmarks.landmark):
        # Finding the length and width of the video input
        h, w, _ = image.shape

        # Finding the exact coordinates of the body points
        X, Y = int(im.x * w), int(im.y * h)
        lmList.append([id, X, Y])

ID는 MediaPipe 포즈 추정 모델에 의해 특정 랜드마크에 부여된 번호입니다. 입력에서 사람의 포즈를 식별한 후에는 팔굽혀펴기 횟수를 세어야 합니다.

푸쉬업 횟수 세기

팔꿈치의 위치에 대해 어깨의 위치를 ​​확인하는 조건을 만듭니다. 입력에 있는 사람의 어깨가 팔꿈치보다 높으면 사람이 위로 있는 것입니다. 어깨가 팔꿈치보다 낮으면 그 사람은 아래에 있습니다. 어깨 랜드마크의 ID와 팔꿈치 랜드마크의 ID를 비교하여 이를 확인합니다.

# Checking whether there are any identified landmarks
if len(lmList)! = 0:
    # Condition that identifies the down position
    if (lmList[12][2] and lmList[11][2] >= lmList[14][2] and lmList[13][2]):
        position = "down"

    # Condition that identifies the up position
    if (lmList[12][2] and lmList[11][2] <= lmList[14][2] and lmList[13][2])
    and position == "down":
         position = "up"
         count +=1

풀 푸쉬업 1회를 완료하려면 아래 자세를 취한 다음 다시 위 자세로 돌아와야 합니다. 푸쉬업을 완료한 후 프로그램은 카운트를 하나씩 업데이트할 수 있습니다.

출력 표시

프로그램이 계산한 팔 굽혀 펴기의 수를 표시해야 합니다. 사용자가 푸시업을 완료할 때마다 카운트 값을 터미널에 인쇄합니다. 마지막으로 팔굽혀펴기를 하는 사람의 몸에 랜드마크가 그려진 출력물을 표시합니다.

            print(count)

    cv2.imshow("Push-up counter", cv2.flip(image, 1))
    key = cv2.waitKey(1)

    # Program terminates when q is pressed
    if key == ord('q'):
        break

cap.release()

출력은 다음과 같아야 합니다.

사람이 팔굽혀펴기를 하는 프로그램의 출력

출력의 사람이 완전한 푸시업을 수행하므로 터미널에서 업데이트를 관찰해야 합니다.

컴퓨터 비전 기술 강화

컴퓨터 비전은 광범위합니다. 팔 굽혀 펴기 카운터는 컴퓨터 비전 기술을 실제로 적용하는 데 사용할 수 있는 많은 프로젝트 중 하나입니다. 이러한 기술을 강화하는 가장 좋은 방법은 컴퓨터 비전과 관련된 더 많은 프로젝트를 구축하는 것입니다.

더 많은 프로젝트를 구축할수록 더 많은 것을 배우게 됩니다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다