728x90

스파르타 코딩클럽의 딥러닝 이미지 처리 수업을 기반으로 공부한 내용을 정리하고 있습니다.

 

얼굴의 랜드마크 탐지란, 얼굴 내의 눈코입을 탐지하는 것이다.

우선은 이미 정리해본 영상/이미지에서의 얼굴 영역 탐지하는 연습 코드를 활용해서 얼굴영역부터 탐지해 볼 것 이다.

 

얼굴의 랜드마크를 추론하는 모델을 로드하기

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=(00255), thickness=-1)
          cv2.putText(img, text=str(i), org=(point.x, point.y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.8, color=(255255255), 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

 

728x90

+ Recent posts