스파르타 코딩클럽의 딥러닝 이미지 처리 수업을 기반으로 공부한 내용을 정리하고 있습니다.
얼굴의 랜드마크 탐지란, 얼굴 내의 눈코입을 탐지하는 것이다.
우선은 이미 정리해본 영상/이미지에서의 얼굴 영역 탐지하는 연습 코드를 활용해서 얼굴영역부터 탐지해 볼 것 이다.
얼굴의 랜드마크를 추론하는 모델을 로드하기
1
2
|
#얼굴의 랜드 마크를 추론하는 모델을 로드해온다
predictor = dlib.shape_predictor('models/shape_predictor_5_face_landmarks.dat')
|
cs |
-> 랜드마크 추론하는 것도 얼굴영역 탐지와 비슷하게 영상 내의 이미지 하나하나를 기준으로 추론하게 된다.
추론된 결과 즉 눈코입에 점과 글씨로 표기가 되도록 코드를 작성하기
1
2
3
4
|
for i, point in enumerate(shape.parts()):
cv2.circle(img, center=(point.x, point.y), radius=2, color=(0, 0, 255), thickness=-1)
cv2.putText(img, text=str(i), org=(point.x, point.y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.8, color=(255, 255, 255), thickness=2)
|
cs |
-> 위의 코드를 얼굴영역 탐지를 위한 for문 내에 작성해준다.
-> 또한 랜드마크 추론을 위해서 또 for 문을 쓰게된 이유는 찍힐 점이 여러개이기 때문이다. 여기서 enumerate를 통해 각 점의 index도 출력하게 되어 순서도 파악한다.
->이렇게 반복문을 돌면서 cv.circle로 점을 찍어주게 된다. point.x / potin.y로 해당 점의 좌표 위치를 알수 있다.
->또한 cy2.putText 로 점이 찍히는 순서를 알 수 있다.
아래와 같이 각 점의 index를 알 수 있고, 이를 활용해서 랜드마크에 적절한 스티커를 크기를 조절해서 붙여줄 수 있다.
안경 스티커 붙이기
-> 크기 조절와 위치 조절이 핵심이다
: 눈의 크기에 따라서 안경의 크기와 위치가 달라지기 때문이다.
우선 붙일 스티커를 로드하기
1
2
|
#합성할 이미지 이므로 투명한 배경의 이미지를 로드한다.
sticker_img = cv2.imread('imgs/glasses.png', cv2.IMREAD_UNCHANGED)
|
cs |
안경의 위치와 크기 계산하기
- 안경의 왼쪽 위 좌표: glasses_x1, glasses_y1
- 안경의 오른쪽 아래 좌표: glasses_x2, glasses_y2
- 안경의 너비와 높이: glasses_w, glasses_h
- 안경의 y축 중심 좌표: center_y
1
2
3
4
5
6
7
8
9
10
11
12
13
|
glasses_x1 = shape.parts()[2].x # 2번 인덱스 즉 왼쪽 눈꼬리
glasses_x2 = shape.parts()[0].x #0번 인덱스 즉 오른쪽 눈꼬리
h, w, c = sticker_img.shape
glasses_w = glasses_x2 - glasses_x1
#비례식을 통해서 이미 길이가 나온 너비 혹은 높이 값을 통해 나머지 값도 같은 비율로 된 길이를 구할 수 있다.
glasses_h = int(h / w * glasses_w)
#어떻게 보면 안경의 높이의 1/2 한 값.
center_y = (shape.parts()[0].y + shape.parts()[2].y) / 2
glasses_y1 = int(center_y - glasses_h / 2)
glasses_y2 = glasses_y1 + glasses_h
|
cs |
안경 스티커 붙여보고 위치와 크기 조정하기
1
2
3
4
5
6
7
8
|
overlay_img = sticker_img.copy()
overlay_img = cv2.resize(overlay_img, dsize=(glasses_w, glasses_h))
overlay_alpha = overlay_img[:, :, 3:4] / 255.0
background_alpha = 1.0 - overlay_alpha
img[glasses_y1:glasses_y2, glasses_x1:glasses_x2] = overlay_alpha * overlay_img[:, :, :3] + background_alpha * img[glasses_y1:glasses_y2, glasses_x1:glasses_x2]
|
cs |
1
2
3
|
#안경 스티커의 크기 조정해주기
glasses_x1 = shape.parts()[2].x - 20
glasses_x2 = shape.parts()[0].x + 20
|
cs |
돼지 코 붙여보기
다른 코드는 동일하며, 붙이고자 하는 스티커의 위치와 크기를 조정하는 코드에서 약간의 차이가 있다.
코의 랜드마크는 한개가 주어지는데 이런 경우, 위에서 안경 스티커를 붙일때 높이/ y좌표를 조정해주었을때의 코드를 활용하여
x와 y좌표를 구해주어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
center_x = shape.parts()[4].x
center_y = shape.parts()[4].y - 5
h, w, c = sticker_img.shape
pig_w = int((x2 - x1) / 2)
pig_h = int(h / w * pig_w)
pig_x1 = int(center_x - pig_w / 2)
pig_x2 = pig_x1 + pig_w
pig_y1 = int(center_y - pig_h / 2)
pig_y2 = pig_y1 + pig_h
|
cs |
'Data' 카테고리의 다른 글
[Practice]흑백사진 컬러처리 하기 (0) | 2020.12.25 |
---|---|
딥러닝 이해하기_GAN (0) | 2020.12.25 |
[Practice]스노우 앱처럼 얼굴에 스티커 붙이기 (0) | 2020.12.17 |
딥러닝 이해하기_컴퓨터비전(CV) (0) | 2020.12.17 |
[Practice]성별, 나이 예측하기 (0) | 2020.12.13 |