4번째 줄:
4번째 줄:
단순히 찾는 것 뿐이라면 cv2만으로도 가능하지만, 매끄럽게 처리하려면 dlib이 있어야 좋다.
단순히 찾는 것 뿐이라면 cv2만으로도 가능하지만, 매끄럽게 처리하려면 dlib이 있어야 좋다.
−
== 방법 ==
+
= 방법 =
−
=== 준비 ===
+
== 준비 ==
+
+
=== 공통과정 ===
+
아래에 이어질 모든 과정 이전에 사용될 준비과정을 여기에 담는다.
{| class="wikitable"
{| class="wikitable"
!과정
!과정
15번째 줄:
18번째 줄:
|-
|-
|사용할 모듈 설치 및 불러오기
|사용할 모듈 설치 및 불러오기
−
|pip install CMake dlib opencv-python numpy
+
|pip install cmake dlib opencv-python numpy
* 윈도우에선 visual studio 설치가 선행되어야 한다.(설치 옵션에서 C++ 모듈을 포함하게 하면 관련 컴파일러 등이 함께 설치된다.)
* 윈도우에선 visual studio 설치가 선행되어야 한다.(설치 옵션에서 C++ 모듈을 포함하게 하면 관련 컴파일러 등이 함께 설치된다.)
−
+
* cmake는 dlib를 설치하기 위해 필요하다.
−
cmake는 dlib를 설치하기 위해 필요하다.<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python">
import dlib # 얼굴인식
import dlib # 얼굴인식
import cv2 # 이미지처리
import cv2 # 이미지처리
30번째 줄:
33번째 줄:
|-
|-
|모델객체 생성
|모델객체 생성
−
|<syntaxhighlight lang="python">
+
|이미 학습된 bat파일을 불러오는데, 이는 [https://github.com/davisking/dlib-models/blob/master/shape_predictor_68_face_landmarks.dat.bz2 링크]에서 다운받을 수 있다.<syntaxhighlight lang="python">
detector = dlib.get_frontal_face_detector() # 얼굴탐지모델
detector = dlib.get_frontal_face_detector() # 얼굴탐지모델
−
predictor = dlib.shape_predictor('models/shape_predictor_68_face_landmarks.dat') # 얼굴 랜드마크 탐지 모델. 학습된 모델을 가져온다.
+
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # 얼굴 랜드마크 탐지 모델. 학습된 모델을 가져온다.
−
+
cap = cv2.VideoCapture(0) # 영상 캡쳐. 경로 대신 0을 넣으면 웹캠이 켜진다.
</syntaxhighlight>
</syntaxhighlight>
|}
|}
−
=== 얼굴 찾기 ===
+
== 얼굴 찾기 ==
−
<syntaxhighlight lang="python">
+
얼굴을 찾아 네모칸으로 표시한다.(필요에 따라 변형하여 사용하면 될듯.)
−
# 영상 캡쳐
+
{| class="wikitable"
−
cap = cv2.VideoCapture('영상경로') # 경로 대신 0을 넣으면 웹캠이 켜진다.
+
!과정
−
+
!코드 및 설명
−
def find_face(cap)
+
|-
−
ret, img = cap.read() # 캡처한 영상을 프레임 단위로 읽는다.
+
|함수 정의
−
if not ret:
+
|코드를 파편화 하기 위해 함수를 정의하여 사용한다.<syntaxhighlight lang="python">
−
break # 프레임이 없다면 종료.
+
def find_face(img):
+
'''이미지를 받아 해당 얼굴을 찾는다.'''
faces = detector(img) # 디텍터에 이미지를 넣어주어 얼굴을 찾는다.
faces = detector(img) # 디텍터에 이미지를 넣어주어 얼굴을 찾는다.
−
face = faces[0] # 인식된 얼굴 중 첫번째.
+
try:
−
+
face = faces[0] # 인식된 얼굴 중 첫번째.
−
# 인식이 잘 되었는지 확인. 네모 그리기.
+
# 인식이 잘 되었는지 확인. 네모 그리기. 기존 이미지에 덧씌워 보여준다.
−
# 기본 이미지에 덧씌워 보여준다.
+
img = cv2.rectangle(img, pt1=(face.left(), face.top()), pt2=(face.right(), face.bottom()),
−
# 좌 상단과 우 하단을 잡아준다.
+
color=(255, 255, 255), # 색 지정이 가능하다.
−
img = cv2.rectangle(img, pt1=(face.left(), face.top()), pt2=(face.right(), face.bottom)
+
thickness=2, # 두께지정
−
color=(255,255,255), # 색 지정이 가능하다.
+
lineType=cv2.LINE_AA # 선의 타입 지정
−
thickness=2, # 두께지정
+
)
−
lineType=cv2.LINE_AA # 선의 타입 지정
+
except: # 얼굴이 없으면 faces[0]에서 인덱스 에러가 뜬다. 그럴 땐 그냥 패스!
−
)
+
pass
−
+
cv2.imshow('window', img) # 창에 해당하는 이미지를 띄운다.
−
−
−
cv2.imshow('창이름', img) # 창에 해당하는 이미지를 띄운다.
cv2.waitKey(1) # 1ms만큼 대기 해야 창이 제대로 열린다.
cv2.waitKey(1) # 1ms만큼 대기 해야 창이 제대로 열린다.
−
+
</syntaxhighlight>
−
+
|-
−
+
|실행
−
+
|다음과 같이 실행한다.<syntaxhighlight lang="python">
while True: # 기본적으로 계속 진행
while True: # 기본적으로 계속 진행
−
find_face(cap=cap)
+
ret, img = cap.read() # 캡처한 영상을 프레임 단위로 읽는다.
+
if not ret: # 잘 찍히면 ret은 True를 반환한다.
+
break # 프레임이 없다면 종료.
+
find_face(img)
</syntaxhighlight>
</syntaxhighlight>
+
|}
−
=== 얼굴 특징점 찾기 ===
+
== 얼굴 특징점 찾기 ==
−
얼굴 찾기를 진행한 후 진행한다.<syntaxhighlight lang="python">
+
위에서 함수만 바꾸어주면 얼굴의 특징점을 찾아준다.<syntaxhighlight lang="python">
−
def find_shape(img, face) # img가 꼭 필요할까?
+
def find_shape(img):
−
dlib_shape = predictor(img, face) # 특징점을 리턴받는다.
+
'''이미지를 받아 얼굴의 특징점을 찾는다.'''
−
+
faces = detector(img) # 디텍터에 이미지를 넣어주어 얼굴을 찾는다.
−
shape_2d = np.array([[p.x, p.y] for p in dlib_shape.parts()]) # 연산을 위해 배열로 저장.
+
try:
−
for s in shape_2d: # 해당 좌표에 원 그리기. 68개의 특징점을 찾는다.
+
face = faces[0] # 인식된 얼굴 중 첫번째.
−
cv2.circle(img, center=tuple(s), radius=1, color=(255, 255, 255), thickness=2, lineType=cv2.LINE_AA)
+
dlib_shape = predictor(img, face) # 특징점을 리턴받는다.
+
shape_2d = np.array([[p.x, p.y] for p in dlib_shape.parts()]) # 연산을 위해 배열로 저장.
+
for s in shape_2d: # 해당 좌표에 원 그리기. 68개의 특징점을 찾는다.
+
cv2.circle(img, center=tuple(s), radius=1, color=(255, 255, 255), thickness=2, lineType=cv2.LINE_AA)
+
except:
+
pass
+
cv2.imshow('window', img) # 창에 해당하는 이미지를 띄운다.
+
cv2.waitKey(1) # 1ms만큼 대기 해야 창이 제대로 열린다.
+
</syntaxhighlight>앞으로의 목표는 많은 얼굴에 대해서도 찾는 것...
+
+
== 얼굴을 특정 이미지로 가리기 ==
+
{| class="wikitable"
+
!과정
+
!코드 및 설명
+
|-
+
|함수 정의
+
|코드를 파편화 하기 위해 함수를 정의하여 사용한다.<syntaxhighlight lang="python">
+
def blind_face(img, address='test_image.png'):
+
'''1. 이미지를 받아 얼굴의 중심점을 찾는다. 2. 그 지점에 이미지를 불러온다.'''
+
faces = detector(img) # 디텍터에 이미지를 넣어주어 얼굴을 찾는다.
+
try:
+
face = faces[0] # 인식된 얼굴 중 첫번째.
+
dlib_shape = predictor(img, face) # 특징점을 리턴받는다.
+
shape_2d = np.array([[p.x, p.y] for p in dlib_shape.parts()]) # 연산을 위해 배열로 저장.
+
center_x, center_y = np.mean(shape_2d, axis=0).astype(np.int) # 중심점을 찾는다.
+
overlay = cv2.imread(address, cv2.IMREAD_UNCHANGED) # 이미지를 불러온다. 알파채널까지 읽기 위한 옵션.
+
# 얼굴 경계 찾기.
+
min_coords = np.min(shape_2d, axis=0) # 각 열에 대해 가장 작은 값들.
+
max_coords = np.max(shape_2d, axis=0)
+
face_size = max(max_coords - min_coords)
+
# 덮을 이미지가 얼굴 인식에 따라 급격하게 변하기 때문에, 이를 중화하기 위한 코드.
+
face_sizes.append(face_size)
+
if len(face_sizes) > 10:
+
del face_sizes[0]
+
mean_face_size = int(np.mean(face_sizes) * 2.0) # 얼굴을 적절히 덮기 위한 숫자보정.
+
origin_image = img.copy()
+
# 다음 사용하는 함수는 아랫쪽에 정의되어 있다.
+
result = overlay_transparent(x=center_x, y=center_y - 25, # 얼굴의 중심을 찾고 숫자로 보정해준다.
+
background_img=origin_image, # 기존 이미지.
+
img_to_overlay_t=overlay, # 덮을 이미지.
+
overlay_size=(mean_face_size, mean_face_size))
+
cv2.imshow('window', result) # 창에 해당하는 이미지를 띄운다.
+
except:
+
cv2.imshow('window', img) # 얼굴 인식이 안되면 이미지를 그냥 띄우기
+
pass
+
cv2.waitKey(1) # 1ms만큼 대기 해야 창이 제대로 열린다.
</syntaxhighlight>
</syntaxhighlight>
−
+
|-
−
=== 얼굴을 특정 이미지로 가리기 ===
+
|이미지로 덮기
−
<syntaxhighlight lang="python">
+
|위에서 사용하는, 이미지로 덮는 함수는 다음과 같다.<syntaxhighlight lang="python">
−
def blind_face(img, address='파일경로.png')
−
dlib_shape = predictor(img, face) # 특징점을 리턴받는다.
−
shape_2d = np.array([[p.x, p.y] for p in dlib_shape.parts()]) # 연산을 위해 배열로 저장.
−
−
center_x, center_y = np.mean(shape_2d, axis=0).astype(np.int)
−
overlay = cv2.imread(address, cv2.IMREAD_UNCHANGED) # 알파채널까지 읽기 위한 옵션.
−
−
# compute face size
−
face_size = max(max_coords - min_coords)
−
face_sizes.append(face_size)
−
if len(face_sizes) > 10: # 덮을 이미지가 얼굴 인식에 따라 급격하게 변하기 때문에, 이를 중화하기 위한 코드.
−
del face_sizes[0]
−
mean_face_size = int(np.mean(face_sizes) * 1.8) # 얼굴을 적절히 덮기 위한 보정.
−
ori = img.copy()
−
# 다음 사용하는 함수는 아랫쪽에 정의되어 있다.
−
result = overlay_transparent(background_img=ori, # 기존 이미지.
−
img_to_overlay_t=overlay, # 덮을 이미지.
−
center_x + 8, center_y - 25, # 얼굴의 중심을 찾고 숫자로 보정해준다.
−
overlay_size=(mean_face_size, mean_face_size))
−
−
def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):
def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):
bg_img = background_img.copy()
bg_img = background_img.copy()
129번째 줄:
158번째 줄:
return bg_img
return bg_img
</syntaxhighlight>
</syntaxhighlight>
+
|-
+
|실행
+
|맨 위의 과정에서 face_size들을 담는 리스트가 추가된다.<syntaxhighlight lang="python">
+
while True: # 기본적으로 계속 진행
+
ret, img = cap.read() # 캡처한 영상을 프레임 단위로 읽는다.
+
if not ret: # 잘 찍히면 ret은 True를 반환한다.
+
break # 프레임이 없다면 종료.
+
face_sizes = [] # 얼굴 크기를 자연스럽게 변형하기 위한 리스트.
+
blind_face(img)
+
</syntaxhighlight>
+
|}
[[분류:딥러닝 트래킹]]
[[분류:딥러닝 트래킹]]