데이터분석/Python
머신러닝 Example by Python - 주성분 분석을 이용한 사람 얼굴 인식 (이미지 인식 시스템)
버섯도리
2022. 1. 14. 15:00
### 주성분 분석을 이용한 사람 얼굴 인식
## 2. 사이킷런을 이용한 고유 얼굴 검출
import cv2
import sys
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.decomposition import PCA
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
def read_data(fin):
""" 이미지 파일을 읽어 들여 이미지 데이터, 이미지 얼굴 번호, 사람 이름을 리턴합니다.
fin 파일은 각 이미지 데이터의 경로를 포함하고 있습니다.
"""
target_li = []
data_li = []
for line in open(fin):
#working_dir = fin.split('/')[:-1]
image_path, face_id = line.strip().split(';')
#image_path = '/'.join(working_dir) + '/' + image_path
#target_name = image_path.split('/')[1]
image_data = cv2.imread(image_path, cv2.COLOR_BGR2GRAY)
data_li.append(image_data)
target_li.append(int(face_id))
return(np.array(data_li), np.array(target_li))
def create_train_test_data(image_data, label_li):
# 이미지 데이터 수, 이미지 세로 픽셀 크기, 이미지 가로 픽셀 크기
n_samples, image_h, image_w = image_data.shape
# 가로 픽셀 강도 벡터와 세로 픽셀 강도 벡터를 이어서 하나의 벡터로 만듭니다.
# 길이는 image_h x image_w가 되겠죠. 그리고 이 벡터가 피처 벡터가 됩니다.
X = image_data.reshape(n_samples, -1)
n_features = X.shape[1] # 피처 크기
y = label_li # 학습 레이블
n_classes = len(set(y)) # 클래스(인물) 수
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
print("n_classes: %d" % n_classes)
# 사이킷런의 함수 train_test_split을 이용하여 학습셋과 평가셋을 나눕니다.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
return(X_train, X_test, y_train, y_test)
def extract_features(X_train, X_test, n_components, image_h, image_w):
print("Extracting the top %d eigenfaces from %d faces"
% (n_components, X_train.shape[0]))
pca = PCA(n_components=n_components, svd_solver='randomized', whiten=True).fit(X_train)
# 고유 얼굴 추출
eigenfaces = pca.components_.reshape((n_components, image_h, image_w))
# 주성분을 원래 이미지와 같은 차원으로 바꿉니다.
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
return(X_train_pca, X_test_pca, eigenfaces)
def train_test_classifier(X_train_pca, X_test_pca, y_train, y_test):
print("Fitting the classifier to the traing set")
param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
clf = clf.fit(X_train_pca, y_train)
print("Best estimator found by grid search:")
print(clf.best_estimator_)
print("Predictiong people's names on the test set")
y_pred = clf.predict(X_test_pca)
print(classification_report(y_test, y_pred))
# 플롯 함수
from matplotlib import pyplot as plt
def plot_gallery(images, n_col=5):
""" 한 줄에 5개의 이미지를 플롯합니다. """
n_row = round(images.shape[0] / n_col)
plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
plt.subplots_adjust(bottom=0.1, left=0.01, right=0.99, top=0.90, hspace=0.35)
for i in range(n_row * n_col):
plt.subplot(n_row, n_col, i + 1)
# cmap을 gray로 설정하여 흑백 이미지로 플롯합니다.
# imshow는 플롯할 값의 최대치를 흰색으로, 최소치를 검은색으로 변환합니다.
plt.imshow(images[i], cmap='gray')
# X축과 Y축의 눈금을 없앱니다.
plt.xticks(())
plt.yticks(())
if __name__ == '__main__':
argv = sys.argv
image_data, label = read_data('faces.csv')
n_eigenface = 10 # 추출할 고유 얼굴 수
X_train, X_test, y_train, y_test = create_train_test_data(image_data, label)
X_train_pca, X_test_pca, eigenfaces = extract_features(X_train, X_test, n_eigenface,
image_data.shape[1], image_data.shape[2])
train_test_classifier(X_train_pca, X_test_pca, y_train, y_test)
plot_gallery(eigenfaces)
plt.show()
출처 : 처음 배우는 머신러닝 : 기초부터 모델링, 실전 예제, 문제 해결까지