본문 바로가기

개발/Deep Learning

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

#1 얼굴 영역 탐지하기

from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.models import load_model
import numpy as np
import cv2

facenet = cv2.dnn.readNet('week3/models/deploy.prototxt', 'week3/models/res10_300x300_ssd_iter_140000.caffemodel')
model = load_model('week3/models/mask_detector.model')

cap = cv2.VideoCapture('week3/videos/04.mp4')

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

  if ret == False:
    break
    
  h, w, c = img.shape
   
  # 이미지 전처리하기
  blob = cv2.dnn.blobFromImage(img, size=(300, 300), mean=(104., 177., 123.))

  # 얼굴 영역 탐지 모델로 추론하기
  facenet.setInput(blob)
  dets = facenet.forward()

  # 각 얼굴에 대해서 반복문 돌기
  for i in range(dets.shape[2]):
      confidence = dets[0, 0, i, 2]

      if confidence < 0.5:
          continue

      # 사각형 꼭지점 찾기
      x1 = int(dets[0, 0, i, 3] * w)
      y1 = int(dets[0, 0, i, 4] * h)
      x2 = int(dets[0, 0, i, 5] * w)
      y2 = int(dets[0, 0, i, 6] * h)

      # 사각형 그리기
      cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), thickness=2, color=(0, 255, 0))

    cv2.imshow('result', img)

    if cv2.waitKey(1) == ord('q'):
        break

 

 

#2 마스크 착용 여부 판단

from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.models import load_model
import numpy as np
import cv2

facenet = cv2.dnn.readNet('week3/models/deploy.prototxt', 'week3/models/res10_300x300_ssd_iter_140000.caffemodel')
model = load_model('week3/models/mask_detector.model')

cap = cv2.VideoCapture('week3/videos/04.mp4')

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

    if ret == False:
        break
    
    h, w, c = img.shape
    # 이미지 전처리하기
    blob = cv2.dnn.blobFromImage(img, size=(300, 300), mean=(104., 177., 123.))

    # 얼굴 영역 탐지 모델로 추론하기
    facenet.setInput(blob)
    dets = facenet.forward()

    # 각 얼굴에 대해서 반복문 돌기
    for i in range(dets.shape[2]):
        confidence = dets[0, 0, i, 2]

        if confidence < 0.5:
            continue

        # 사각형 꼭지점 찾기
        x1 = int(dets[0, 0, i, 3] * w)
        y1 = int(dets[0, 0, i, 4] * h)
        x2 = int(dets[0, 0, i, 5] * w)
        y2 = int(dets[0, 0, i, 6] * h)

        face = img[y1:y2, x1:x2]

        face_input = cv2.resize(face, dsize=(224, 224))
        face_input = cv2.cvtColor(face_input, cv2.COLOR_BGR2RGB)
        face_input = preprocess_input(face_input)
        face_input = np.expand_dims(face_input, axis=0)

        mask, nomask = model.predict(face_input).squeeze()

        if mask > nomask:
            color = (0, 255, 0)
        else:
            color = (0, 0, 255)

        # 사각형 그리기
        cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), thickness=2, color=color)

    cv2.imshow('result', img)

    if cv2.waitKey(1) == ord('q'):
        break

 

 

#3 얼굴로 성별, 나이 예측하기

import numpy as np
import cv2

facenet = cv2.dnn.readNet('week3/models/deploy.prototxt', 'week3/models/res10_300x300_ssd_iter_140000.caffemodel')

img = cv2.imread('week3/images/02.jpg')

gender_list = ['Male', 'Female']
age_list = ['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']

gender_net = cv2.dnn.readNetFromCaffe('week3/models/deploy_gender.prototxt', 'week3/models/gender_net.caffemodel')
age_net = cv2.dnn.readNetFromCaffe('week3/models/deploy_age.prototxt', 'week3/models/age_net.caffemodel')

h, w, c = img.shape

# 이미지 전처리하기
blob = cv2.dnn.blobFromImage(img, size=(300, 300), mean=(104., 177., 123.))

# 얼굴 영역 탐지 모델로 추론하기
facenet.setInput(blob)
dets = facenet.forward()

# 각 얼굴에 대해서 반복문 돌기
for i in range(dets.shape[2]):
    confidence = dets[0, 0, i, 2]

    if confidence < 0.5:
        continue

    # 사각형 꼭지점 찾기
    x1 = int(dets[0, 0, i, 3] * w)
    y1 = int(dets[0, 0, i, 4] * h)
    x2 = int(dets[0, 0, i, 5] * w)
    y2 = int(dets[0, 0, i, 6] * h)

    face = img[y1:y2, x1:x2]

    blob = cv2.dnn.blobFromImage(face, size=(227, 227), mean=(78.4263377603, 87.7689143744, 114.895847746))

    # argmax는 confidence값이 가장 높은 값을 뽑아준다.
    gender_net.setInput(blob)
    gender_index = gender_net.forward().squeeze().argmax()
    gender = gender_list[gender_index]

    age_net.setInput(blob)
    age_index = age_net.forward().squeeze().argmax()
    age = age_list[age_index]

    cv2.putText(img, text='%s, %s' % (gender, age), org=(x1, y1), 
    fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(0, 255, 0), thickness=2)

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


cv2.imshow('result', img)
cv2.waitKey(0)

 

 

#4 Homework : Mask Confidence Text로 보여주기

from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.models import load_model
import numpy as np
import cv2

facenet = cv2.dnn.readNet('week3/models/deploy.prototxt', 'week3/models/res10_300x300_ssd_iter_140000.caffemodel')
model = load_model('week3/models/mask_detector.model')

cap = cv2.VideoCapture('week3/videos/04.mp4')

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

    if ret == False:
        break
    
    h, w, c = img.shape
    # 이미지 전처리하기
    blob = cv2.dnn.blobFromImage(img, size=(300, 300), mean=(104., 177., 123.))

    # 얼굴 영역 탐지 모델로 추론하기
    facenet.setInput(blob)
    dets = facenet.forward()

    # 각 얼굴에 대해서 반복문 돌기
    for i in range(dets.shape[2]):
        confidence = dets[0, 0, i, 2]

        if confidence < 0.5:
            continue

        # 사각형 꼭지점 찾기
        x1 = int(dets[0, 0, i, 3] * w)
        y1 = int(dets[0, 0, i, 4] * h)
        x2 = int(dets[0, 0, i, 5] * w)
        y2 = int(dets[0, 0, i, 6] * h)

        face = img[y1:y2, x1:x2]

        face_input = cv2.resize(face, dsize=(224, 224))
        face_input = cv2.cvtColor(face_input, cv2.COLOR_BGR2RGB)
        face_input = preprocess_input(face_input)
        face_input = np.expand_dims(face_input, axis=0)

        mask, nomask = model.predict(face_input).squeeze()

        if mask > nomask:
            color = (0, 255, 0)
            text = "Mask"
            mask_or_noMask = round(mask*100, 2)
        else:
            color = (0, 0, 255)
            text = "NoMask"
            mask_or_noMask = round(nomask*100, 2)

        # 확률 Text로 나타내기
        cv2.putText(img, text=text + ' : %s' % (str(mask_or_noMask)), org=(x1, y1), 
        fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=color, thickness=2)

        # 사각형 그리기
        cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), thickness=2, color=color)

    cv2.imshow('result', img)

    if cv2.waitKey(1) == ord('q'):
        break

 

 

#5 느낀 점

요즘같은 언택트 시대에 유용하게 쓰일 수 있을 것 같은 느낌이 들었다.

지하철역 같은 공공시설(?)에서 잘 사용하면 유용할 것 같다는 생각이 들었다.

 

argmax() 함수에 대해 강사분께서 잘 설명해주셔서 이해하기 수월했다.

argmax() 함수는 각 confidence 값들 중 가장 높은 값을 뽑아내는 함수이다.