Face Recognition (얼굴 인식) 개념 및 이미지 전처리를 배우다. (광주, 인공지능, 과학기술정보통신부, 광주광역시)
1. 얼굴 감지 vs 얼굴 인식
지금까지 배운 것은 얼굴 감지 기능이었다. 이제부터 배울 것은 얼굴 인식 기능인데, 얼굴 감지와 얼굴 인식은 들었을 때 비슷한 느낌일 것 같다. 하지만 다르게 말하는 이유가 있듯이 두 기능의 목적이 다르다.
얼굴 감지의 목적은 얼굴을 식별하고 얼굴 주위로 경계 상자를 그리는 것이다. 주로 사용되는 곳은 얼굴에 초점을 맞춰야 하는 디지털 카메라에서 주로 사용한다. 얼굴 인식의 목적은 얼굴을 감지하는 것에서 끝나는 것이 아니라 해당 얼굴의 인물이 누구인지 파악하는 것이다. 얼굴 인식이 얼굴 감지의 다음 단계라고 생각하면 편하다. 일단 얼굴을 감지해야 얼굴을 인식하든가 말든가 할 거 아닌가..
2. 얼굴 감지 방법 LBPH
얼굴 감지 방법에는 LBPH(지역 이진 패턴 히스토그램) 방법과 전에 사용했던 OpenCV 방법이 존재한다. 일단 처음보는 LBPH의 원리에 대해 설명하겠다.
이미지를 나타내는 행렬의 가장 가운데 픽셀 값을 기준으로 다른 픽셀에 조건을 적용한다. 가운데 픽셀값보다 값이 작으면 0, 크면 1이다. 내가 배울 때는 시계방향으로 0과 1을 붙여서 이진수를 생성한다. 그림 1을 보면 이해가 쉬울 것이다. 이진수가 생성되면 Decimal도 생성되는데, Decimal은 이진수를 10진수로 변환한 값이다. 이미지의 밝기가 어두워지거나 밝아지더라도 각 픽셀 값이 변화하는 비율은 동일하기 때문에 밝기의 변화 후에 이진수를 구하고 Decimal을 구하면, 밝기 변화와 상관없이 같다.
LBPH의 얼굴 감지 알고리즘 원리에 대해 요약 설명하겠다.
- 얼굴 이미지에 여러개의 정사각형 영역을 생성한다.
- 각각의 정사각형 영역 안에는 여러 픽셀 집합으로 이루어져 있다.
- 중앙 픽셀값 기준으로 조건 적용하면 히스토그램을 생성한다.
- 각각의 색깔이 각 정사각형에 몇번이나 나타내는지 센 후 히스토그램을 생성한다.
- 각 정사각형과 노드가 개별적으로 히스토그램을 갖는다.
- 각 히스토그램에 따라서 알고리즘은 Edge와 Corner를 식별할 수 있다.
- 얼굴의 각 부위 눈, 코, 입, 가장자리, 아무것도 없는 영역의 히스토그램이 모두 다르다.
- 어떤 히스토그램이 얼굴의 가장자리를 나타내고 얼굴의 주요부분을 나타내는지 히스토그램을 생성하고 비교하여 판단하는 알고리즘이다.
3. LBPH로 얼굴감지 과정
3 - 1. 데이터 셋 로드
# 파이썬에서 이미지 작업을 할 수 있도록 본 데이터셋의 이미지를 읽어 들일 수 있게 해준다.
from PIL import Image
import cv2
import numpy as np
from google.colab.patches import cv2_imshow
import zipfile
path = '/content/drive/MyDrive/Colab Notebooks/Udemy/Datasets/yalefaces.zip'
zip_object = zipfile.ZipFile(file=path, mode = 'r') # 파일 경로, r = read
zip_object.extractall('./') # 앞으로 모든 파일을 이 루트 디렉터리에 저장함
zip_object.close() # 메모리 해제
# test, train 데이터가 생김
# train 데이터를 보면 사람마다 여러 얼굴 표현의 얼굴 정보가 담겨있음
# 폴더에 식별 대상으로 15명의 얼굴이 있는 것처럼 또 다른 폴더 test 폴더에도 식별 대상이 되는 15명의 얼굴이 있다.
# 하지만 다른 이미지이다.
# 이미지를 학습시키고 테스트 해보기
강의에서 주어진 경로를 활용하여 폴더에 파일을 저장한다.
3 - 2. 이미지 전처리
# 이미지 읽어들이기
# LBPH 알고리즘에 전송하기 위해서 모든 이미지를 올바른 형식으로 변경
import os
# PIL 패키지 속 클래스로 gif 이미지를 읽기위함
print(os.listdir("/content/__MACOSX/yalefaces/train"))
이미지 읽어들이기 위해서 os.listdir( ) 함수로 해당 폴더 내부에 있는 이미지 파일들을 읽어들일 수 있다.
def get_image_data():
# for 루프로 각 파일을 읽어오고 목록형식으로 변환 후 이 루트 디렉터리로 목록을 합침
paths = [os.path.join("/content/yalefaces/train", f) for f in os.listdir('/content/yalefaces/train')]
# print(paths)
faces = [] # 이미지에 대한 정보를 저장, 이미지의 모든 픽셀을 저장하는 역할
ids = [] # 클래스의 이름을 저장
for path in paths:
# Image 클래스 사용
# 매개변수를 L로 지정해주는데 L은 이미지 모드를 뜻한다.
# L모드 이미지라고하면 단일 채널 이미지를 뜻하는데 => 흑백 이미지를 뜻한다.
image = Image.open(path).convert('L')
image_np = np.array(image, "uint8") # uint8 : 각 픽셀이 정수형 값을 갖도록 한다
id = int(os.path.split(path)[1].split(".")[0].replace('subject', "")) # 파일에서 숫자만 가져오기
ids.append(id)
faces.append(image_np)
return np.array(ids), faces
ids, faces = get_image_data()
# 결과 : 코드의 파일 이름만 표시되는 것이 아닌 각 이미지의 전체 경로를 알 수 있게된다. -> join 명령문의 역할
join 기능으로 인해 리스트 paths에 ' /content/yalefaces/train ' 디렉토리 내의 모든 파일과 디렉토리의 절대 파일 경로가 포함된다. 파일들의 절대경로와 파일명이 연결된 요소들을 담고있는 리스트를 활용하여 이미지의 정보와 이미지 파일 명에 존재하는 이미지의 id(클래스명)을 추출해야 한다. 현재 paths에 담겨있기 때문에 paths에 반복문을 걸어서 각 파일의 경로를 의미하는 path로 Image 클래스를 활용해서 컬러이미지를 흑백이미지로 변환해주는 covert("L")을 사용해준다. 부가 설명은 코드블럭의 주석을 참고하면 된다. 해당 파일이름의 숫자가 클래스명이기 때문에 split과 replace 함수를 사용해서 숫자만 추출하는 작업을 거쳐준다.
이미지의 모든 픽셀이 담겨있는 faces 리스트와 클래스 이름을 저장할 ids 리스트를 분석해보자. 일단 클래스명이 담긴 ids 리스트를 보면 1차원이고 길이가 135이다. 그럼 당연하게도 faces의 길이도 135이다. faces는 각 이미지의 픽셀값이 담겨 있다고 했다.
그림 5를 보면 faces의 리스트는 2차원형태이고 각각의 요소가 한 이미지의 전체 픽셀 정보이다. 픽셀 값의 범위는 0 ~ 255이다. 요소하나를 꺼내서 shape를 확인해보면 (243, 320)인 것을 볼 수 있는데 얼굴 인식 알고리즘을 사용할 때 모든 얼굴 face의 shape 형태가 동일한 형태여야 한다.
LBPH 분류기를 학습시키는 과정은 다음글에서 이어서 진행하겠다.
'딥러닝 > Computer vision' 카테고리의 다른 글
[Computer Vision] Dlib을 이용한 Face points 얼굴 포인트 감지 및 얼굴 기술자/ 인공지능사관학교 4기 (2) | 2023.11.09 |
---|---|
[Computer Vision] Face Recognition (얼굴 인식) LBPH 분류기 학습 / 인공지능사관학교 4기 (0) | 2023.10.31 |
[Computer Vision] Detecting faces with HOG / 인공지능사관학교 4기 (0) | 2023.10.16 |
[Computer Vision] Face Detection (얼굴 감지) / 인공지능사관학교 4기 (1) | 2023.10.10 |