미디어파이프란 구글에서 제공하는 AI 오픈소스이다
미디어파이프 설치
pip install mediapipe
필요 라이브러리 임포트
import mediapipe as mp
import cv2
mp.solutions: 미디어파이프 솔루션들이 포함되어 쉽게 사용할 수 있다
- 얼굴 인식
mp.solutions.face_detection
- 얼굴 메시
mp.solutions.face_mesh
- 손 추적
mp.solutions.hands
- 포즈 추정
mp.solutions.pose
- 신체 전체 추적
mp.solutions.holistic
- 랜드마크 시각화 툴
mp.solutions.drawing_utils
- 미리 정의된 스타일 툴
mp.solutions.drawing_styles
- 인물과 배경 분리
mp.solutions.selfie_segmentation
https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md
얼굴 인식
face_detection을 사용합니다
mp_facedetection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils
face_detection = mp_facedetection.FaceDetection()
미디어파이프에 적용하기 위해 이미지를 rgb로 변환해줍니다
그 후 face_detection.process(이미지) 를 하여 결과를 반환합니다.
img = cv2.imread('data/karina.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 결과
result = face_detection.process(img_rgb) # rgb로 넣어줘야 한다
print(result.detections)
출력 결과
6개의 좌표를 인식합니다.
['LEFT_EAR_TRAGION', 'LEFT_EYE', 'MOUTH_CENTER', 'NOSE_TIP', 'RIGHT_EAR_TRAGION', 'RIGHT_EYE']
[label_id: 0
score: 0.943828046
location_data {
format: RELATIVE_BOUNDING_BOX
relative_bounding_box {
xmin: 0.362439603
ymin: 0.277495772
width: 0.291663319
height: 0.233330518
}
relative_keypoints {
x: 0.437948346
y: 0.357101202
}
relative_keypoints {
x: 0.558209419
y: 0.346372902
}
relative_keypoints {
x: 0.500902534
y: 0.416154385
}
relative_keypoints {
x: 0.512111783
y: 0.45437628
}
relative_keypoints {
x: 0.38407588
y: 0.36842072
}
relative_keypoints {
x: 0.638756156
y: 0.34334442
}
}
]
drawing_utils를 사용해서 시각화를 해보겠습니다
# 얼굴 인식이 됐다면
if result.detections:
for detection in result.detections:
# 그려라
mp_drawing.draw_detection(img, detection)
이제 이미지 출력을 해보겠습니다.
cv2.imshow('face_detection', img)
cv2.waitKey()
cv2.destroyAllWindows()
저는 drawing_utils를 사용해서 시각화의 바운딩 박스를 이용해서 새롭게 표시를 해보고 싶은데요
그럴 때
detection.location_data.relative_bounding_box
를 사용하면 됩니다.
출력해보니
xmin: 0.362439603
ymin: 0.277495772
width: 0.291663319
height: 0.233330518
이렇게 나오는데요.
width와 height를 1로 봤을 때 얼만큼 위치했는지, 얼만큼 차지하는지 비율로 나오는 것이기 때문에
*width, *height하면 실제 좌표가 나옵니다.
# 얼굴 인식이 됐다면
if result.detections:
for detection in result.detections:
# bbox 알려줌: 좌표가 width와 height를 1로 봤을 때 얼만큼 위치했는지, 얼만큼 차지하는지(*width, *height하면 실제 좌표 나온다)
# print(detection.location_data.relative_bounding_box)
img_height, img_width, _ = img.shape
bbox = detection.location_data.relative_bounding_box # xmin: 0.362439603 ymin: 0.277495772 width: 0.291663319 height: 0.233330518
xmin = int(bbox.xmin * img_width)
ymin = int(bbox.ymin * img_height)
width = int(bbox.width * img_width)
height = int(bbox.height * img_height)
cv2.rectangle(img, (xmin,ymin,width,height), (0,0,255), 3)
이미지 출력을 하면
cv2.imshow('face_detection', img)
cv2.waitKey()
cv2.destroyAllWindows()
이쁘게 됐습니다~
이제 좌표를 받아보겠습니다.
# 얼굴 인식이 됐다면
if result.detections:
for detection in result.detections:
# 두 방식이 같다
print(detection.location_data.relative_keypoints[mp_facedetection.FaceKeyPoint.NOSE_TIP])
print(mp_facedetection.get_key_point(
detection, mp_facedetection.FaceKeyPoint.NOSE_TIP))
이 좌표는 좌표가 width와 height를 1로 봤을 때 얼만큼 위치했는지 보여주기 때문에 width와 height를 곱하면 실제 좌표 나옵니다.
코의 좌표를 받아볼게요
nose = detection.location_data.relative_keypoints[mp_facedetection.FaceKeyPoint.NOSE_TIP]
# 실제 좌표
nose_x = int(nose.x * img_width)
nose_y = int(nose.y * img_height)
그리고 이미지에 nose라고 텍스트를 넣어주겠습니다
cv2.putText(img, 'nose', (nose_x, nose_y), cv2.FONT_HERSHEY_COMPLEX, 2, (0,0,0), 2)
cv2.imshow('face_detection', img)
cv2.waitKey()
cv2.destroyAllWindows()
웹캠에서도 해볼까요??
# 웹캠
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame.flags.writeable = False
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 얼굴 인식 결과
result = face_detection.process(frame_rgb) # rgb로 넣어줘야 한다
# print(result.detections)
frame.flags.writeable = True
# 얼굴 인식이 됐다면
if result.detections:
for detection in result.detections:
# 그려라
mp_drawing.draw_detection(frame, detection)
cv2.imshow('face_detection', frame)
if cv2.waitKey(1) == 27:
break
이미지 처리와 똑같지만
상태가 바뀌지 않도록
frame.flags.writeable = False
체크를 해줘야 합니다.
https://github.com/stonegyoung/OpenCV/blob/main/mp_face_detection_video.py
'비전' 카테고리의 다른 글
[MediaPipe] 얼굴 매쉬1 (1) | 2024.09.02 |
---|---|
[MediaPipe] 포즈 인식 (0) | 2024.08.25 |
[OpenCV] 특정 색 검출 (0) | 2024.08.20 |
[OpenCV] 그리기 함수 (0) | 2024.08.19 |
[OpenCV] 마스킹 (0) | 2024.08.18 |