6강 OpenCV 딥러닝 활용과 얼굴검출

양말신은도비·2022년 7월 2일
0

딥러닝 활용과 얼굴 검출

OpenCV에서 지원하는 얼굴 검출 기법

  1. Haar Cascade 방법
    • 2001년 Viola와 Jones에 의해 제안된 방법
    • Haar-like 특징과 Adaboost 알고리즘, Cascade 구조를 사용하여 빠르고 정확한 얼굴 검출을 수행
  2. DNN 방법
    • OpenCV 3.3.1부터 DNN모듈을 사용한 얼굴 검출을 기본 예제로 제공
    • RssNet-10과 SSD를 기반으로 학습된 얼굴 검출 네트워크 사용

딥러닝 이란?

2000년대부터 사용되고 있는 심층 신경망의 또 다른 이름

Deep learning is part of a broader family of machine learning methods
based on artificial neural networks. - WikiPedia

딥러닝의 활용

  1. Image Recognition
  2. Object Detection
  3. Object Segmentation
  4. Super-Resolution
  5. Image to Image Translation
  6. Image Inpainting

OpenCV DNN API

  • 네트워크 불러오기
    cv2.dnn.readNet(model, config=None, framework=None) -> retval
    • model: 훈련된 가중치를 저장하고 있는 이진 파일 이름
    • config: 네트워크 구성을 저장하고 있는 텍스트 파일 이름
    • framework: 명시적인 딥러닝 프레임워크 이름
    • retval: cv2.dnn_Net 클래스 객체

  • 네트워크 입력 블롭(blob) 만들기

    cv2.dnn.blobFromImage(image, scalefactor=None, size=None,
    											mean=None, swapRB=None, crop=None,
    											ddepth=None) -> retval
    • image: 입력 영상
    • scalefactor: 입력 영상 픽셀 값에 곱할 값. 기본값은 1.
    • size: 출력 영상의 크기. 기본값은 (0, 0).
    • mean: 입력 영상 각 채널에서 뺄 평균 값. 기본값은 (0, 0, 0, 0).
    • swapRB: R과 B 채널을 서로 바꿀 것인지를 결정하는 플래그. 기본값은 False
    • crop: 크롭(crop) 수행 여부. 기본값은 False.
    • ddepth: 출력 블롭의 깊이. CV_32F 또는 CV_8U. 기본값은 CV_32F.
    • retval: 영상으로부터 구한 블롭 객체.
  • 네트워크 입력 설정하기

    cv2.dnn_Net.setInput(blob, name=None, scalefactor=None, mean=None)
    • blob: 블롭 객체
    • name: 입력 레이어 이름
    • scalefactor: 추가적으로 픽셀 값에 곱할 값
    • mean: 추가적으로 픽셀 값에서 뺄 평균 값
  • 네트워크 순방향 실행 (추론)

    cv2.dnn_Net.forward(outputName=None) -> retval
    • outputName: 출력 레이어 이름
    • retval: 지정한 레이어의 출력 블롭. 네트워크마다 다르게 결정됨.

실습

  • Classify
    • 코드
      import sys
      import numpy as np
      import cv2
      img = cv2.imread('beagle.jpg')
      
      if img is None:
          print('Image load failed!')
          exit()
      # Load network
      
      net = cv2.dnn.readNet('bvlc_googlenet.caffemodel', 'deploy.prototxt')
      
      if net.empty():
          print('Network load failed!')
          exit()
      # Load class names
      
      classNames = None
      with open('classification_classes_ILSVRC2012.txt', 'rt') as f:
          classNames = f.read().rstrip('\n').split('\n')
      # Inference
      
      inputBlob = cv2.dnn.blobFromImage(img, 1, (224, 224), (104, 117, 123))
      net.setInput(inputBlob, 'data')
      prob = net.forward()
      # Check results & Display
      
      out = prob.flatten()
      classId = np.argmax(out)
      confidence = out[classId]
      
      text = '%s (%4.2f%%)' % (classNames[classId], confidence * 100)
      cv2.putText(img, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 1, cv2.LINE_AA)
      cv2.imshow('img', img)
      cv2.waitKey()
      cv2.destroyAllWindows()
    • 결과
  • DnnFace
    • 코드
      import cv2
      model = 'res10_300x300_ssd_iter_140000_fp16.caffemodel'
      config = 'deploy.prototxt'
      #model = 'opencv_face_detector_uint8.pb'
      #config = 'opencv_face_detector.pbtxt'
      
      cap = cv2.VideoCapture(0)
      
      if not cap.isOpened():
          print('Camera open failed!')
          exit()
      net = cv2.dnn.readNet(model, config)
      
      if net.empty():
          print('Net open failed!')
          exit()
      # while True:
      # _, frame = cap.read()
      # if frame is None:
      #     break
      
      frame = cv2.imread('mask.jpg')
      
      if frame is None:
          print('Image load failed!')
          exit()
      
      blob = cv2.dnn.blobFromImage(frame, 1, (300, 300), (104, 177, 123))
      net.setInput(blob)
      detect = net.forward()
      
      detect = detect[0, 0, :, :]
      (h, w) = frame.shape[:2]
      
      for i in range(detect.shape[0]):
          confidence = detect[i, 2]
          if confidence < 0.5:
              break
      
          x1 = int(detect[i, 3] * w)
          y1 = int(detect[i, 4] * h)
          x2 = int(detect[i, 5] * w)
          y2 = int(detect[i, 6] * h)
      
          cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0))
      
          label = 'Face: %4.3f' % confidence
          cv2.putText(frame, label, (x1, y1 - 1), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 1, cv2.LINE_AA)
      cv2.imshow('frame', frame)
      cv2.waitKey()
      cv2.destroyAllWindows()
    • 결과
  • Catcam
    • 코드

0개의 댓글