OpenCV_021_얼굴검출_스켈레톤(MediaPipe)

2024. 7. 11. 14:18Deep Learning

 

 

학습목표
○ Mediapipe 라이브러리를 활용할 수 있다

○ Mediapipe 라이브러리를 이용하여 얼굴 특성을 추출할 수 있다

○ Mediapipe 라이브러리를 이용하여 동작 특성을 추출할 수 있다

 

✅ Mediapipe 라이브러리를 이용한 얼굴 3D 데이터 추출

# 프롬프트 창에서 설치

!pip install mediapipe

from google.colab import drive

drive.mount('/content/drive')

%cd /content/drive/MyDrive/Colab Notebooks/Deep Learning

 

얼굴 메시 추출

import cv2
import mediapipe as mp

# 시각화 라이브러리 (점과 선 그리기)
mp_drawing = mp.solutions.drawing_utils

# 얼굴 메시 추출 라이브러리
mp_face_mesh = mp.solutions.face_mesh

# 점과 선 그리기 옵션 설정 (선 두께, 점의 크기)
draw_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)

# 사용할 영상 불러오기
cap = cv2.VideoCapture("./data/face1.mp4")

# 영상 파일 저장 옵션 설정 (크기, 속도, 코덱)
# 영상 크기 : 가져온 영상 크기 (실수 값으로 반환되므로 정수로 변환)
w = int(cap.get(3)) # w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(4)) # h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 속도 (초당 프레임 수)
fps = cap.get(5)

# 영상 코덱 (MP4V)
codec = cv2.VideoWriter_fourcc(*'MP4V')

# 저장할 파일명과 옵션 설정
out = cv2.VideoWriter("./data/result01.mp4", codec, fps, (w, h))
# 영상에서 프레임을 읽어서 얼굴의 메시를 추출하고 파일로 저장
# min_detection_confidence : 객체 검출 최소 정확도
# min_tracking_confidence : 객체 추적 최소 정확도

with mp_face_mesh.FaceMesh(min_detection_confidence=0.5,
                           min_tracking_confidence=0.5) as face_mesh:

    # 영상에서 프레임 이미지 읽기
    while cap.isOpened():

        # 영상에서 1 프레임 이미지를 읽어서 frame에 저장하고
        # 잘 읽었다면 ret에 True를 반환 그렇지 않으면 False를 반환
        ret, frame = cap.read()

        if not ret: # 이미지를 읽지 못했다면
            print("종료")
            break

        # 얼굴 메시 추출 (랜드마크 점 468개가 반환)
        frame.flags.writeable = False
        results = face_mesh.process(frame)
        frame.flags.writeable = True

        # 검출한 랜드마크 점을 그려주고 근처의 랜드마크 점을 선으로 연결해서 메시를 만듦
        # 랜드마크 점 468개를 하나씩 읽어온다
        for face_landmark in results.multi_face_landmarks:

            # 읽어온 랜드마크 점을 그려주고 연결
            mp_drawing.draw_landmarks(frame,                                # 프레임 이미지
                                      face_landmark,                        # 현재 랜드마크 좌표
                                      mp_face_mesh.FACEMESH_TESSELATION,    # 랜드마크 점 연결 설정
                                      draw_spec,                            # 랜드마크 그리기 옵션
                                      draw_spec)                            # 랜드마크 연결 선 그리기 옵션
            
        # 결과 영상 저장
        out.write(frame)

out.release()
cap.release()

  • 📌 결과 출력
from moviepy.editor import VideoFileClip

VideoFileClip("./data/result01.mp4").ipython_display(width=200)

 

✅ 얼굴, 왼손, 오른손, 동작 검출 (스켈레톤)

  • 얼굴, 몸, 손, 다리의 랜드마크 추출 - 33개 (3차원 좌표) -> 132개의 정보 추출
import cv2
import mediapipe as mp

# 시각화 라이브러리 (점과 선 그리기)
mp_drawing = mp.solutions.drawing_utils

# 스케레톤 추출 라이브러리
mp_holistic = mp.solutions.holistic

# 점 그리기 옵션 설정 (선 두께, 점의 크기, 색상)
draw_spec1 = mp_drawing.DrawingSpec(thickness=1, circle_radius=3, color=(109, 213, 250))

# 선 그리기 옵션 설정
draw_spec2 = mp_drawing.DrawingSpec(thickness=3, color=(41, 128, 185))

# 사용할 영상 불러오기
cap = cv2.VideoCapture("./data/face2.mp4")

# 영상 파일 저장 옵션 설정 (크기, 속도, 코덱)
# 영상 크기 : 가져온 영상 크기 (실수 값으로 반환되므로 정수로 변환)
w = int(cap.get(3)) # w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(4)) # h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 속도 (초당 프레임 수)
fps = cap.get(5)

# 영상 코덱 (MP4V)
codec = cv2.VideoWriter_fourcc(*'MP4V')

# 저장할 파일명과 옵션 설정
out = cv2.VideoWriter("./data/result02.mp4", codec, fps, (w, h))
# 영상에서 프레임을 읽어서 스켈레톤을 추출하고 파일로 저장
# min_detection_confidence : 객체 검출 최소 정확도
# min_tracking_confidence : 객체 추적 최소 정확도

with mp_holistic.Holistic(min_detection_confidence=0.5,
                           min_tracking_confidence=0.5) as holistic:

    # 영상에서 프레임 이미지 읽기
    while cap.isOpened():

        # 영상에서 1 프레임 이미지를 읽어서 frame에 저장하고
        # 잘 읽었다면 ret에 True를 반환 그렇지 않으면 False를 반환
        ret, frame = cap.read()

        if not ret: # 이미지를 읽지 못했다면
            print("종료")
            break

        # 얼굴 메시 추출 (랜드마크 점 468개가 반환)
        frame.flags.writeable = False
        results = holistic.process(frame)
        frame.flags.writeable = True

        # 랜드마크 점 33개를 읽어와서 몸통의 랜드마크만 그려준다
        # 읽어온 랜드마크 점을 그려주고 연결
        mp_drawing.draw_landmarks(frame,
                                  results.pose_landmarks,               # 몸통의 랜드마크
                                  mp_holistic.POSE_CONNECTIONS,            # 몸통 랜드마크 점 연결 설정
                                  draw_spec1,                            # 랜드마크 그리기 옵션
                                  draw_spec2)                            # 랜드마크 연결 선 그리기 옵션
            
        # 결과 영상 저장
        out.write(frame)

out.release()
cap.release()

from moviepy.editor import VideoFileClip

VideoFileClip("./data/result02.mp4").ipython_display(width=200)

import cv2
import mediapipe as mp

# 시각화 라이브러리 (점과 선 그리기)
mp_drawing = mp.solutions.drawing_utils

# 스케레톤 추출 라이브러리
mp_holistic = mp.solutions.holistic

# 점 그리기 옵션 설정 (선 두께, 점의 크기, 색상)
draw_spec1 = mp_drawing.DrawingSpec(thickness=1, circle_radius=3, color=(109, 213, 250))

# 선 그리기 옵션 설정
draw_spec2 = mp_drawing.DrawingSpec(thickness=3, color=(41, 128, 185))

# 사용할 영상 불러오기
cap = cv2.VideoCapture("./data/face2.mp4")

# 영상 파일 저장 옵션 설정 (크기, 속도, 코덱)
# 영상 크기 : 가져온 영상 크기 (실수 값으로 반환되므로 정수로 변환)
w = int(cap.get(3)) # w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(4)) # h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 속도 (초당 프레임 수)
fps = cap.get(5)

# 영상 코덱 (MP4V)
codec = cv2.VideoWriter_fourcc(*'MP4V')

# 저장할 파일명과 옵션 설정
out = cv2.VideoWriter("./data/result03.mp4", codec, fps, (w, h))
# 영상에서 프레임을 읽어서 스켈레톤을 추출하고 파일로 저장
# min_detection_confidence : 객체 검출 최소 정확도
# min_tracking_confidence : 객체 추적 최소 정확도

with mp_holistic.Holistic(min_detection_confidence=0.5,
                           min_tracking_confidence=0.5) as holistic:

    # 영상에서 프레임 이미지 읽기
    while cap.isOpened():

        # 영상에서 1 프레임 이미지를 읽어서 frame에 저장하고
        # 잘 읽었다면 ret에 True를 반환 그렇지 않으면 False를 반환
        ret, frame = cap.read()

        if not ret: # 이미지를 읽지 못했다면
            print("종료")
            break

        # 얼굴 메시 추출 (랜드마크 점 468개가 반환)
        frame.flags.writeable = False
        results = holistic.process(frame)
        frame.flags.writeable = True

        # 랜드마크 점 33개를 읽어와서 몸통의 랜드마크만 그려준다
        # 읽어온 랜드마크 점을 그려주고 연결
        mp_drawing.draw_landmarks(frame,                                # 프레임 이미지
                                  results.pose_landmarks,               # 몸통의 랜드마크
                                  mp_holistic.POSE_CONNECTIONS,         # 몸통 랜드마크 점 연결 설정
                                  draw_spec1,                           # 랜드마크 그리기 옵션
                                  draw_spec2)                           # 랜드마크 연결 선 그리기 옵션

        # 왼손 스켈레톤 출력
        mp_drawing.draw_landmarks(frame,
                                  results.left_hand_landmarks,          
                                  mp_holistic.HAND_CONNECTIONS,            
                                  draw_spec1,                         
                                  draw_spec2)                           

        # 오른손 스켈레톤 출력
        mp_drawing.draw_landmarks(frame,
                                  results.right_hand_landmarks,         
                                  mp_holistic.HAND_CONNECTIONS,          
                                  draw_spec1,                            
                                  draw_spec2)                          
            
        # 결과 영상 저장
        out.write(frame)

out.release()
cap.release()

from moviepy.editor import VideoFileClip

VideoFileClip("./data/result03.mp4").ipython_display(width=200)