해파리냉채무침 2023. 8. 10. 21:57
import numpy as np
import cv2 
import matplotlib.pyplot as plt
%matplotlib inline
nadia = cv2.imread('../DATA/Nadia_Murad.jpg',0)
denis = cv2.imread('../DATA/Denis_Mukwege.jpg',0)
solvay = cv2.imread('../DATA/solvay_conference.jpg',0)

plt.imshow(nadia,cmap='gray')

plt.imshow(denis,cmap='gray')

plt.imshow(solvay,cmap='gray')

이렇게 3개의 사진을 각각 불러옴. 우선 필요한 것은 classifier를 만들고 XML classifier를 진행하는것이다

face_cascade = cv2.CascadeClassifier('../DATA/haarcascades/haarcascade_frontalface_default.xml')

xml파일을 cascadeclassifer로 분류를 해줌. 6000개의 classifier 리스트, 이미지를 통해 이동되는 기능들이어서 모든 기능에 적합한지 알 수 있다

def detect_face(img):
    
  
    face_img = img.copy()
  
    face_rects = face_cascade.detectMultiScale(face_img) 
    
    for (x,y,w,h) in face_rects: 
        cv2.rectangle(face_img, (x,y), (x+w,y+h), (255,255,255), 10) #x,y,높이 넓이 두께10
        
    return face_img

detectMultiscale을 이용해서 얼굴탐지에 필요한 사각형을 정의해준다. 

result = detect_face(denis)
plt.imshow(result,cmap='gray')

result = detect_face(nadia)
plt.imshow(result,cmap='gray')

result = detect_face(solvay)
plt.imshow(result,cmap='gray')

데니스와 나디아는 잘 탐지했지만, 마지막의 군중의 얼굴을 완벽하게 탐지하는데 뒤에 얼굴이 아닌것까지 탐지함

def adj_detect_face(img):
    
    face_img = img.copy()
  
    face_rects = face_cascade.detectMultiScale(face_img,scaleFactor=1.2, minNeighbors=5) 
    #스케일 비율, 최소 이웃
    for (x,y,w,h) in face_rects: 
        cv2.rectangle(face_img, (x,y), (x+w,y+h), (255,255,255), 10) 
        
    return face_img

스케일 비율(scale factor)은 이미지 크기가 각 이미지 스케일에서 얼마나 줄어드는지 명시하는 변수
최소 이웃(minNeighbor)은 얼마나 많은 이웃을 각 사각형이 보유해야 하는지 명시하는 변수
훨씬 좋고 선명하게 얼굴을 감지하게 한다

result = adj_detect_face(solvay)
plt.imshow(result,cmap='gray')

위의 기둥?은 감지하지 않았지만 너무 많은 얼굴을 감지하면서 생기는 상충, sideface 감지 못함
스케일 비율과 최소 이웃 사이의 균형을 찾을 수 있는지 보기 위해 그 둘을 조정해야함

eye_cascade = cv2.CascadeClassifier('../DATA/haarcascades/haarcascade_eye.xml')
def detect_eyes(img):
    
    face_img = img.copy()
  
    eyes = eye_cascade.detectMultiScale(face_img) 
    #눈 한 쌍을 찾으면 이게 사각형 2개가 됨
    
    for (x,y,w,h) in eyes: 
        cv2.rectangle(face_img, (x,y), (x+w,y+h), (255,255,255), 10) 
        
    return face_img

콧구멍도 눈이라고 감지하면 detect MultiScale 조정해야함 scaleFactor=1.2, minNeighbors=5 이렇게 설정하면 콧구멍 없어진다.

result = detect_eyes(nadia)
plt.imshow(result,cmap='gray')

나디아의 두눈은 잘 감지하였다

eyes = eye_cascade.detectMultiScale(denis) 
result = detect_eyes(denis)
plt.imshow(result,cmap='gray')

cascade를 쓸 때 보이는 문제점이 눈이 흰자가 안보여서 눈 탐지를 하지 못함

 

출처: Udemy X KMOOC OpenCV 및 딥러닝을 이용한 Computer Vision 파이썬