OpenCV를 활용한 얼굴 감지를 배우다. (광주, 인공지능, 과학기술정보통신부, 광주광역시)
- 사용언어 : Python
- 환경 : Colab
- 강의 : Computer Vision (Udemy)
Udemy의 유료강의를 볼 수 있는 기회가 생겨서 딥러닝의 한 분야인 Computer Vision 강의를 선택했다.
1. OpenCV
OpenCV란 이미지나 동영상 처리에 사용되는 라이브러리이다. 이미지, 동영상에서 물체 감지, 추적, 특징추출, 패턴인식, 얼굴인식 등의 작업 수행을 할 수 있다. OpenCV는 무료로 제공되고 딥러닝과 결합해서 데이터 처리를 빠르고 쉽게 처리할 수 있게 되었다.
2. OpenCV를 활용한 얼굴 감지 (Haarcascade)
1. 이미지 불러오기
이미지자료나 캐스케이드 분류기등의 자료는 Udemy 강의 자료이다.
import cv2
image = cv2.imread("/content/drive/MyDrive/Colab Notebooks/Udemy/Images/people1.jpg")
cv2_imshow(image)
이미지를 불러오기 위해서 cv2를 불러와야 한다. 이제 이미지를 읽을 수 있는 imread( ) 함수를 사용해서 이미지의 경로를 매개변수로 주면 이미지가 불러와진다. 불러온 이미지를 화면에 보이게 하기 위해서 imshow( ) 함수를 사용해서 불러온 이미지가 담긴 변수를 매개변수로 받는다. 결과로 그림 1과 같이 불러온 이미지가 화면에 보인다.
2. 이미지 흑백화
# 흑백화
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# BGR인 이유는 OpenCV를 사용하면 순서를 반대로 적어야한다.
# 채널 순서를 반대로
OpenCV를 사용해서 얼굴 특징을 추출하기 위해서는 이미지를 흑백화 한 후에 특징 추출을 해야 한다. 얼굴을 감지할 때만 흑백화된 이미지가 필요한 것이지 얼굴을 감지한 결과의 이미지가 흑백일 필요는 없다. 얼굴을 감지할 때만 흑백 이미지를 사용하고 감지된 얼굴을 사각형으로 감지할 건데, 그 사각형을 컬러 이미지 위에 나타내는 것일 뿐이다.
컬러를 변환한다는 의미에서 cvt(convert)Color 함수를 사용하면 된다. 매개변수로 변화시킬 이미지, 어떻게 변화시킬 것인지를 받는다. 일반적인 컬러 이미지의 채널은 RGB이지만 OpenCV를 통해서 불러온 이미지의 채널은 RGB에서 BGR로 순서가 바뀐다. RGB를 보면 각 색깔 채널이 같은 선상에 위치한 게 아니라 R 채널, G 채널, B 채널이 겹쳐있는 구조이다.
아무튼 흑백화 하는 이유는 컬러 이미지일 때는 각 채널의 값이 제각각인데 RGB채널일 때의 흑백이미지는 각 채널의 값이 모두 같다. 그럼 채널이 3개에서 1개로 줄어드는 것과 같으니까 이미지의 크기가 작아진다. 메모리 확보가 되기 때문에 흑백화를 해야 한다.
3. 이미지 특징 추출
face_detector = cv2.CascadeClassifier("/content/drive/MyDrive/Colab Notebooks/Udemy/Cascades/haarcascade_frontalface_default.xml")
detections = face_detector.detectMultiScale(image_gray)
detections # 각 열은 감지된 얼굴임
# 앞에 2개 얼굴의 위치, 뒤 2개 얼굴의 크기
# [x좌표, y좌표, 얼굴의 크기, 얼굴의 크기]
# y좌표는 위에서 아래로 잰것 top to bottom
# x, y, w, h 정보를 기반으로 사진에 직사각형을 그리기
for (x, y, w, h) in detections:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) # 이미지, 사각형 시작점, 끝나는 점, BGR 형식의 색상 = 선의 색상, 선의 두께
cv2_imshow(image)
이미지에서 특징을 추출해 주는 하르 캐스케이드 분류기의 파일을 가져와야 한다. 그러기 위해서 CascadeClassifier 함수를 사용해서 캐스케이드 분류기의 경로를 지정해 주면 된다. 하르 캐스케이드 분류기를 불러왔으면, OpenCV를 활용해서 이미지 특징추출할 때는 이미지 흑백화가 필요하니까 흑백화한 이미지를 하르 캐스케이드 분류기의 변수로 주면 감지된 특징(여기서는 얼굴이니까 얼굴로 말하겠음)의 x좌표, y좌표, 너비, 높이를 반환한다. 반환된 x, y좌표와 너비와 높이를 사용해서 이미지에 띄울 사각형의 틀을 잡고 그린다.
# x, y, w, h 정보를 기반으로 사진에 직사각형을 그리기
for (x, y, w, h) in detections:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) # 이미지, 사각형 시작점, 끝나는 점, BGR 형식의 색상 = 선의 색상, 선의 두께
cv2_imshow(image)
cv2의 rectangle 함수로 사각형을 그릴 수 있는데, 매개변수로 그려질 이미지와 x좌표 y좌표(하나의 점), x에 너비를 더하고 y에 높이를 더한 것, 사각형의 색깔 (RGB채널), 사각형 선의 굵기를 매개변수로 받는다.
결과(그림 3)를 보면 녹색 사각형이 얼굴에 그려진 것을 볼 수 있다. x좌표와 y좌표로 한 점을 그리고 너비와 높이로 점에서 선을 이어나가서 사각형을 그리는 것이다. 하지만 얼굴이 아닌 곳에 사각형이 그려지는 '긍정 오류'가 발생한 것을 볼 수 있다.
우리는 얼굴이 아닌데 얼굴로 인식되는 오류, 얼굴인데 얼굴이 아닌 것으로 인식되는 오류를 해결해서 더 신뢰도가 높은 모델을 만들 필요가 있다. 이 모델도 다른 인공지능 모델처럼 파라미터 조정이 가능하다. 파리미터 조정을 해서 긍정오류를 없애보겠다.
4. 하르 캐스케이드 파라미터 조정 (오류 없애기)
detections = face_detector.detectMultiScale(image_gray, scaleFactor = 1.08)
우리의 목적은 올바른 결과에 영향이 가지 않는 선에서 긍정오류를 없애는 것이다. 나머지 코드는 동일하고 하르케스케이드 분류기를 만들고 for 문 과정을 하기 전에 해당 코드를 작성해서 파라미터를 조정할 수 있다.
지금 사용된 'scaleFactor' 매개변수는 영상 축소비율로 이미지가 얼마나 축소되었는지 알려준다. 이미지의 크기에 맞게 설정해서 큰 얼굴을 작게, 작은 얼굴을 크게 인식하게 한다. default 값은 1.1이고 항상 1보다 커야 한다.
나머지 파라미터는 간략하게 설명하겠다.
- minNeighbors : 입력한 수만큼의 이웃 사각형이 검출되어야 최종 검출 영역으로 설정할지 (default = 3)
- minSize : 얼굴의 최소 크기이다. ex) minSize = (30, 30) 너비와 높이이다.
- maxSize : 얼굴의 최대 크기이다.
매개변수를 조절할 때 주의사항이 있다. 매개변수를 조절하면 결과의 품질이 달라지는데, 결과의 품질을 향상할지? 결과 감지 범위를 늘릴지 선택해야 한다. 왜냐하면 감지 범위를 늘려서 모든 얼굴을 감지하게 하면 긍정오류가 발생하기 때문이다.