본문 바로가기

개발/Deep Learning

스파르타 코딩클럽 - 4주차 [이미지 처리로 시작하는 딥러닝]

#1 필요한 Library 및 Model, Image, Video Load

import cv2
import dlib

# 정면 얼굴 탐지 모델 
detector = dlib.get_frontal_face_detector()

# 영상 Load
cap = cv2.VideoCapture('week4/videos/01.mp4')

# 투명도 포함 이미지 Load
sticker_img = cv2.imread('week4/imgs/sticker01.png', cv2.IMREAD_UNCHANGED)

while True:
    ret, img = cap.read()

    if ret == False:
        break

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#2 얼굴 영역 탐지

import cv2
import dlib

# 정면 얼굴 탐지 모델 
detector = dlib.get_frontal_face_detector()

# 영상 Load
cap = cv2.VideoCapture('week4/videos/01.mp4')

# 투명도 포함 이미지 Load
sticker_img = cv2.imread('week4/imgs/sticker01.png', cv2.IMREAD_UNCHANGED)

while True:
    ret, img = cap.read()

    if ret == False:
        break
    
    # 정면 얼굴 탐지하여 좌표 저장
    dets = detector(img)
    print("number of faces detected:", len(dets))

    for det in dets:
        print(det)
    
    # 탐지된 얼굴의 좌표 뽑아내기
    for det in dets:
        x1 = det.left()
        y1 = det.top()
        x2 = det.right()
        y2 = det.bottom()
        
        # 탐지된 얼굴 영역 사각형으로 표시
        cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), color=(255, 0, 0), thickness=2)

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#3 탐지된 얼굴에 스티커 합성

import cv2
import dlib

# 정면 얼굴 탐지 모델 
detector = dlib.get_frontal_face_detector()

# 영상 Load
cap = cv2.VideoCapture('week4/videos/01.mp4')

# 투명도 포함 이미지 Load
sticker_img = cv2.imread('week4/imgs/sticker01.png', cv2.IMREAD_UNCHANGED)

while True:
    ret, img = cap.read()

    if ret == False:
        break
    
    # 정면 얼굴 탐지하여 좌표 저장
    dets = detector(img)
    print("number of faces detected:", len(dets))

    for det in dets:
        print(det)
    
    # 탐지된 얼굴의 좌표 뽑아내기
    for det in dets:
        x1 = det.left() - 40
        y1 = det.top() - 50
        x2 = det.right() + 40
        y2 = det.bottom() + 30
        
        # 탐지된 얼굴 영역 사각형으로 표시
        # cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), color=(255, 0, 0), thickness=2)

        try:
            # 얼굴 위에 합성할 이미지
            overlay_img = sticker_img.copy()

            # 얼굴 크기에 맞게 이미지 크기 resizing
            overlay_img = cv2.resize(overlay_img, dsize=(x2 - x1, y2 - y1))

            overlay_alpha = overlay_img[:, :, 3:4] / 255.0
            background_alpha = 1.0 - overlay_alpha

            img[y1:y2, x1:x2] = overlay_alpha * overlay_img[:, :, :3] + background_alpha * img[y1:y2, x1:x2]
        except:
            pass

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#4 랜드마크 모델로 눈, 코 추론하기

import cv2
import dlib

# 정면 얼굴 탐지 모델
detector = dlib.get_frontal_face_detector()

# 랜드마크 모델(눈, 코 추론)
predictor = dlib.shape_predictor('week4/models/shape_predictor_5_face_landmarks.dat')

# 영상 Load
cap = cv2.VideoCapture('week4/videos/01.mp4')

while True:
    ret, img = cap.read()

    if ret == False:
        break

    # 정면 얼굴 탐지하여 좌표 dets에 저장
    dets = detector(img)

    for det in dets:
        # 탐지된 얼굴에서 랜드마크 모델을 이용해 눈, 코 추론
        shape = predictor(img, det)

        # 눈, 코 위치에 점과 글씨 입력
        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)
        try:
            x1 = det.left()
            y1 = det.top()
            x2 = det.right()
            y2 = det.bottom()

            cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), color=(255, 0, 0), thickness=2)
        except:
            pass

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#5 눈, 코 위치를 이용해 안경 씌워보기

import cv2
import dlib

# 정면 얼굴 탐지 모델
detector = dlib.get_frontal_face_detector()

# 랜드마크 모델(눈, 코 추론)
predictor = dlib.shape_predictor('week4/models/shape_predictor_5_face_landmarks.dat')

# 영상 Load
cap = cv2.VideoCapture('week4/videos/01.mp4')

# Overlay 이미지 Load
sticker_img = cv2.imread('week4/imgs/glasses.png', cv2.IMREAD_UNCHANGED)

while True:
    ret, img = cap.read()

    if ret == False:
        break

    # 정면 얼굴 탐지하여 좌표 dets에 저장
    dets = detector(img)

    for det in dets:
        # 탐지된 얼굴에서 랜드마크 모델을 이용해 눈, 코 추론
        shape = predictor(img, det)

        # 눈, 코 위치에 점과 글씨 입력
        # 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)
        
        # 왼쪽 눈꼬리 x좌표
        glasses_x1 = shape.parts()[2].x - 20
        # 오른쪽 눈꼬리 x좌표
        glasses_x2 = shape.parts()[0].x + 20

        h, w, c = sticker_img.shape

        # 이미지 크기 resizing
        glasses_w = glasses_x2 - glasses_x1
        glasses_h = int(h / w * glasses_w)

        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

        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]

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#6 Homework 돼지코 붙이기

import cv2
import dlib

# 정면 얼굴 탐지 모델
detector = dlib.get_frontal_face_detector()

# 랜드마크 모델(눈, 코 추론)
predictor = dlib.shape_predictor('week4/models/shape_predictor_5_face_landmarks.dat')

# 영상 Load
cap = cv2.VideoCapture('week4/videos/02.mp4')

# Overlay 이미지 Load
sticker_img = cv2.imread('week4/imgs/pig.png', cv2.IMREAD_UNCHANGED)

while True:
    ret, img = cap.read()

    if ret == False:
        break

    # 정면 얼굴 탐지하여 좌표 dets에 저장
    dets = detector(img)

    for det in dets:
        # 탐지된 얼굴에서 랜드마크 모델을 이용해 눈, 코 추론
        shape = predictor(img, det)
        
        # 왼쪽 눈 안쪽 x좌표
        pig_x1 = shape.parts()[3].x - 15
        # 오른쪽 눈 안쪽 x좌표
        pig_x2 = shape.parts()[1].x + 15

        h, w, c = sticker_img.shape

        center_y = int((shape.parts()[0].y + shape.parts()[2].y) / 2)
        nose_y = shape.parts()[4].y + 10

        # 이미지 크기 resizing
        pig_w = pig_x2 - pig_x1
        pig_h = int(h / w * pig_w)

        pig_y2 = nose_y
        pig_y1 = pig_y2 - pig_h

        overlay_img = sticker_img.copy()
        overlay_img = cv2.resize(overlay_img, dsize=(pig_w, pig_h))

        overlay_alpha = overlay_img[:, :, 3:4] / 255.0
        background_alpha = 1.0 - overlay_alpha

        img[pig_y1:pig_y2, pig_x1:pig_x2] = overlay_alpha * overlay_img[:, :, :3] + background_alpha * img[pig_y1:pig_y2, pig_x1:pig_x2]

    cv2.imshow('result', img)
    if cv2.waitKey(1) == ord('q'):
        break

 

 

#7 느낀점

SNOW나 TICTOCK같은 어플에서 사용하는 얼굴에 스티커 합성하는 방식을 직접 구현해보니 신기하고 좋았다.

배운 것들을 토대로 재밌는 토이프로젝트를 하나 진행하면 좋을 것 같다.