Tạo file đường dẫn đến cơ sở dữ liệu khuôn mặt (CSV-file)

Một phần của tài liệu Nghiên cứu xây dựng phần mềm nhận dạng mặt người theo thời gian thực (Trang 41)

Mỗi ảnh trong một phân lớp sẽ được đặt ở một thư mục khác nhau và sẽ được gán một trọng số để tiến hành nhận dạng sau này

Chương trình tạo file CSV: Phụ lục 2

27

Hình 3. 5 Nội dung file CSV 3.4 Lưu đồ giải thuật tổng quát 3.4 Lưu đồ giải thuật tổng quát

Yêu cầu của đề tài là xây dựng một hệ thống chạy trên thời gian thực, hoạt động 24/24, có thể nhận dạng được một hoặc nhiều người cùng lúc.

Trong đề tài này sử dụng 2 cơ sở dữ liệu về đặc trưng gương mặt người được huấn luyện theo thuật toán AdaBoost được OpenCV cung cấp là:

 Haarcascade_frontalface_alt2.xml: Đặc trưng gương mặt theo hướng nhiền chính diện.

 Haarcascade_profileface.xml: Đặc trưng gương mặt theo hướng nhìn từ cạnh bên.

Để tăng độ chính xác của việc nhận diện gương mặt, ta có thể thu thập thêm các mẫu ảnh về gương mặt người ở các góc nhìn khác nhau. Sau đó huấn luyện các mẫu ảnh đó để được các tập tin dữ liệu *.xml của các đặc trưng gương mặt từ nhiều góc nhìn.

Việc tạo được đữ liệu chính xác cần số lượng mẫu huấn luyện phải nhiều và ở các điều kiện môi trường ngoại cảnh khác nhau. Và để huấn luyện được số lượng lớn mẫu đó thì cần một máy tính có cấu hình mạnh để việc huấn luyện có thể hồn thành nhanh chóng.

28 Chuẩn hóa khn mặt

Load file CSV

Huấn luyện đặc trưng khuôn mặt Load đặc trưng khn

mặt

Chuyển sang ảnh xám

Dị tìm đặc trưng khn mặt

Chuyển về kich thước khuôn mặt huấn luyện Nhận ảnh từ camera Phát hiện khn mặt Tính Eigenvalue và EigenVector Tính khoảng cách so với tập mẫu So sánh khoảng cách với ngưỡng Đóng khung và hiển thị tên Đóng khung và hiển thị “Unknow” N Y Nhỏ hơn Lớn hơn

29

3.5 Chương trình thực hiện

30

Chương 4

KẾT QUẢ THỰC HIỆN

Chương trình được ứng dụng chạy thử nghiệm trong nhiều điều kiện ánh sáng khác nhau, từ mơi trường có ánh sáng yếu cho đến môi trường đủ sáng ở các khoảng cách khác nhau, nhận dạng một hoặc nhiều người xuất hiện cùng lúc, và đạt được các kết quả như sau:

4.1 Kết quả nhận dạng một người

Trong môi trường ánh sáng phù hợp với môi trường ánh sáng khi lấy mẫu khn mặt thì chương trình có tỷ lệ nhận dạng chính xác cao. Khi thay đổi mơi trường sáng thì chỉ có phân lớp thứ 3 (ảnh lấy mẫu trực tiếp từ camera), cho tỷ lệ nhận dạng cao, còn phân lớp 1, 2 (ảnh lấy mẫu từ internet) khi thay đổi mơi trường sáng thì hầu như khơng nhận dạng được.

31

Hình 4. 2 Ảnh nhận dạng diễn viên Leonardo Decapiro - phân lớp thứ 2

32

4.2 Kết quả nhận dạng hai người

Trong môi trường ánh sáng phù hợp với môi trường ánh sáng tạo tập mẫu huấn luyện thì chương trình cho kết quả nhận dạng tốt. Khi có ánh sáng chói hoặc khơng đủ sáng thì chương trình chỉ cho kết quả nhận dạng đúng ở phân lớp 3.

Hình 4. 4 Nhận dạng khi xuất hiện mặt người ở phân lớp 1,3

33

4.3 Kết quả nhận dạng khi có người lạ xuất hiện

Trong mơi trường ánh sáng phù hợp với môi trường ánh sáng tạo tập mẫu huấn luyện thì chương trình cho kết quả nhận dạng tốt ở phân lớp 3. Ở phân lớp 1,2 chương trình cho kết quả nhận dạng thấp.

Hình 4. 6 Phân loại được khi có người lạ xuất hiện

34

35

Chương 5

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

5.1 Kết luận.

- Trên cơ sở nghiên cứu lý thuyết tổng quan về các phương pháp nhận dạng mặt người trong thời gian thực. Đặc biệt là thuật toán PCA, các đặc trưng Eigenfaces và Eigenvector kết hợp với kỹ thuật lập trình C++. Tơi đã áp dụng thành cơng thuật tốn nhận dạng phân tích thành phần chính PCA vào bài tốn nhận dạng mặt người trong thời gian thực. Xây dựng thành công phần mềm nhận dạng được một hoặc nhiều người xuất hiện trong khung ảnh. Đặc biệt chương trình xử lý ảnh động, lấy trực tiếp từ camera. Bên cạnh đó, trong q trình xây dựng chương trình ,tơi đã tìm hiểu về thư viện mã nguồn mở OpenCV, qua đó biết cách sử dụng các hàm trong thư viện OpenCV để xây dựng chương trình nhận dạng mặt người trên kit nhúng sau này.

- Về chương trình demo, chương trình được chạy thử nghiệm trên máy tính có bộ xử lý Core i7, thế hệ 4, tốc độ 2,4GHz; RAM 8GB. Tốc độ xử lý của chương trình khoảng 5 khung hình/s, khi ép xung lên 3,2Ghz thì có thể xử lý được khoảng 8 khung hình/s. Hiệu xuất của chương trình cịn tùy theo chất lượng của loại webcam được sử dụng, tập cơ sở dữ liệu lấy mẫu, và điều kiện ánh sáng khi lấy mẫu. Trong điều kiện ánh sáng phù hợp với môi trường ánh sáng khi lấy mẫu thì chương trình cho kết quả nhận dạng tốt, nhưng khi điều kiện ánh sáng thay đổi thì chương trình hay cho kết quả lẫn lộn giữa các phân lớp. Điều này cho thấy thuật toán PCA rất dễ bị ảnh hưởng của nhiễu do gương mặt bị nghiêng, hay mặt có râu, mặt cười, và đặc biệt là nhiễu do ánh sáng.

5.2 Hướng phát triển.

- Về cơ bản đã hoàn thành các yêu cầu mà ban đầu đề tài đề ra. Tuy nhiên, để ứng dụng vào thực tế thì thuật tốn PCA vẫn cịn nhiều điểm hạn chế, mà cụ thể đó là ảnh hưởng từ nhiễu. Do đó, hướng phát triển tiếp theo của đề tài sẽ tập trung vào phần xử lý nhiễu, hoặc kết hợp với các thuật toán nhận dạng khác để xây dựng một hệ thống nhận dạng chính xác hơn ở những mơi trường khác nhau, ở các góc nhìn gương mặt khác nhau...Từ đó áp dụng vào thực tế như hệ thống giám sát, kiểm tra an ninh, điểm danh học sinh tự động, kiểm tra một người có phải là cán bộ, giảng viên, cơng nhân viên của trường hay không….

- Kết nối với hệ thống Camera IP để có thể xây dựng 1 trung tâm giám sát an ninh cho công ty, chung cư…

36

- Tăng khả năng phát hiện của camera bằng cách sử dụng camera hồng ngoại hoặc sử dụng loại camera có độ phân giải cao

37

TÀI LIỆU THAM KHẢO

TIẾNG VIỆT

[1]. PGS.TS Nguyễn Quang Hoan, Xử Lý Ảnh, Học Viện Cơng Nghệ Bưu Chính

Viễn Thơng, 2006.

[2]. Trương Công Lợi, Nhận dạng khuôn mặt sử dung phương pháp biến đổi

Eigenfaces và mạng Nowrron, Đại học Đà Nẵng, 2013

[3]. Nguyễn Thành Thái, Nhận dạng mặt người dùng SVM và mạng nơron, Đại học CNTT Tp.HCM, 2006

[4]. Mạch Thị Kim Hạnh, Xác thực sinh trắc học khuôn mặt trên thiết bị di động, Đại học Lạc Hồng, 2013

[5]. PGS.TS. Nguyễn Thị Hồng Lan – Hệ thống an ninh thơng tin dựa trên sinh trắc học - PKI (Bio-PKI Based Information Security System), 2009

TIẾNG NƯỚC NGOÀI

[6]. M. A. Turk và A. P. Pentland - Face Recognition Using Eigenfaces, Proc. of IEEE Conf. on Computer Vision and Pattern Recognition, 1991.

[7]. Viola, P. and Jones, Rapid object detection using a boosted cascade of simple

features, Proc. IEEE Conf. on Computer Vision and Pattern Recognition, Dec. 2001.

[8]. Jolliffe, I.T. Principal Component Analysis, second edition (Springer), 2008. [9]. Timo Ahonen, Abdenour Hadid, and Matti Pietikăainen, Face Recognition with

Local Binary Patterns, 2004

[10]. Nefian, Hayes, Face detection and recognition using hidden Markov models,

1998

[11]. Douc, R. and Cappe, O. and Moulines, E., "Comparison of Resampling Schemes

for Particle Filtering", Image and Signal Processing and Analysis, 2005.

[12]. Michael Isard and Andrew Blake, “Conditional Density Propagation for Visual

Tracking”, 1997.

[13]. Shai Avidan, MobilEye Vision Technologies, 24 Mishol Hadkalim, Jerusalem, Israel, “Support Vector Tracking”, 2008

[14]. Michael Isard, Andrew Blake, “Condensation – conditional density

PHỤ LỤC

1. Đoạn chương trình lấy mẫu khn mặt

import sys, math, Image def Distance(p1,p2): dx = p2[0] - p1[0] dy = p2[1] - p1[1]

return math.sqrt(dx*dx+dy*dy)

def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None, resample=Image.BICUBIC): if (scale is None) and (center is None):

return image.rotate(angle=angle, resample=resample) nx,ny = x,y = center

sx=sy=1.0

if new_center:

(nx,ny) = new_center if scale:

(sx,sy) = (scale, scale) cosine = math.cos(angle) sine = math.sin(angle) a = cosine/sx b = sine/sx c = x-nx*a-ny*b d = -sine/sy e = cosine/sy f = y-nx*d-ny*e

return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)

def CropFace(image, eye_left=(0,0), eye_right=(0,0), offset_pct=(0.2,0.2), dest_sz = (70,70)):

# calculate offsets in original image

offset_h = math.floor(float(offset_pct[0])*dest_sz[0]) offset_v = math.floor(float(offset_pct[1])*dest_sz[1]) # get the direction

eye_direction = (eye_right[0] - eye_left[0], eye_right[1] - eye_left[1])

# calc rotation angle in radians rotation = -

math.atan2(float(eye_direction[1]),float(eye_direction[0])) # distance between them

dist = Distance(eye_left, eye_right) # calculate the reference eye-width reference = dest_sz[0] - 2.0*offset_h # scale factor

scale = float(dist)/float(reference) # rotate original around the left eye

image = ScaleRotateTranslate(image, center=eye_left, angle=rotation)

# crop the rotated image

crop_xy = (eye_left[0] - scale*offset_h, eye_left[1] - scale*offset_v)

crop_size = (dest_sz[0]*scale, dest_sz[1]*scale)

image = image.crop((int(crop_xy[0]), int(crop_xy[1]),

int(crop_xy[0]+crop_size[0]), int(crop_xy[1]+crop_size[1]))) # resize it

image = image.resize(dest_sz, Image.ANTIALIAS) return image

if __name__ == "__main__":

image = Image.open("tin8.png")

#CropFace(image, eye_left=(311,283), eye_right=(416,282), offset_pct=(0.1,0.1),

dest_sz=(200,200)).save("phat1_10_10_200_200.jpg")

CropFace(image, eye_left=(334,100), eye_right=(375,99), offset_pct=(0.2,0.2),

dest_sz=(200,200)).save("tin8_20_20_200_200.jpg")

#CropFace(image, eye_left=(311,283), eye_right=(416,282), offset_pct=(0.3,0.3),

dest_sz=(200,200)).save("phat1_30_30_200_200.jpg")

#CropFace(image, eye_left=(311,283), eye_right=(416,282), offset_pct=(0.2,0.2)

2. Đoạn chương trình tạo file CSV

if __name__ == "__main__": if len(sys.argv) != 2:

print "usage: create_csv <base_path>" sys.exit(1)

BASE_PATH=sys.argv[1] SEPARATOR=";"

label = 0

for dirname, dirnames, filenames in os.walk(BASE_PATH): for subdirname in dirnames:

subject_path = os.path.join(dirname, subdirname) for filename in os.listdir(subject_path):

abs_path = "%s/%s" % (subject_path, filename) print "%s%s%d" % (abs_path, SEPARATOR, label) label = label + 1

3. Đoạn chương trình phát hiện và nhận dạng khuôn mặt

#include "opencv2/core/core.hpp" #include "opencv2/contrib/contrib.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <fstream> #include <sstream> using namespace cv;

using namespace std;

static Mat norm_0_255(InputArray _src) { Mat src = _src.getMat(); Mat dst; switch(src.channels()) { case 1: cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1); break; case 3: cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3); break; default: src.copyTo(dst); break; } return dst; }

static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {

std::ifstream file(filename.c_str(), ifstream::in); if (!file) {

string error_message = "No valid input file was given, please check the given filename.";

CV_Error(CV_StsBadArg, error_message); }

string line, path, classlabel; while (getline(file, line)) { stringstream liness(line);

getline(liness, path, separator); getline(liness, classlabel);

if(!path.empty() && !classlabel.empty()) { images.push_back(imread(path, 0));

labels.push_back(atoi(classlabel.c_str())); }

} }

int main(int argc, const char *argv[]) { if (argc < 2) {

cout << "usage: " << argv[0] << " <csv.ext> <output_folder> " << endl; exit(1); } string output_folder = "."; if (argc == 3) { output_folder = string(argv[2]); }

string fn_csv = string(argv[1]); vector<Mat> images;

vector<int> labels; try {

read_csv(fn_csv, images, labels); } catch (cv::Exception& e) {

cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;

exit(1); }

if(images.size() <= 1) {

string error_message = "Chuong trinh can it nhat 2 anh de chay, vui long them anh vao tap du lieu!";

CV_Error(CV_StsError, error_message); }

int height = images[0].rows;

Mat testSample = images[images.size() - 1]; int testLabel = labels[labels.size() - 1]; images.pop_back();

labels.pop_back();

Ptr<FaceRecognizer> model = createEigenFaceRecognizer(); model->train(images, labels);

int predictedLabel = model->predict(testSample);

string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);

cout << result_message << endl;

Mat eigenvalues = model->getMat("eigenvalues"); Mat W = model->getMat("eigenvectors");

Mat mean = model->getMat("mean"); if(argc == 2) { imshow("mean", norm_0_255(mean.reshape(1, images[0].rows))); } else { imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(1, images[0].rows))); }

for (int i = 0; i < min(10, W.cols); i++) {

string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));

cout << msg << endl;

Mat ev = W.col(i).clone();

Mat grayscale = norm_0_255(ev.reshape(1, height)); Mat cgrayscale;

applyColorMap(grayscale, cgrayscale, COLORMAP_JET); if(argc == 2) {

imshow(format("eigenface_%d", i), cgrayscale); } else {

imwrite(format("%s/eigenface_%d.png", output_folder.c_str(), i), norm_0_255(cgrayscale)); }

}

for(int num_components = min(W.cols, 10); num_components < min(W.cols, 300); num_components+=15) {

Mat evs = Mat(W, Range::all(), Range(0, num_components));

Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1));

Mat reconstruction = subspaceReconstruct(evs, mean, projection); reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows)); if(argc == 2) { imshow(format("eigenface_reconstruction_%d", num_components), reconstruction); } else { imwrite(format("%s/eigenface_reconstruction_%d.png", output_folder.c_str(), num_components), reconstruction); } } if(argc == 2) { waitKey(0); } return 0; }

Một phần của tài liệu Nghiên cứu xây dựng phần mềm nhận dạng mặt người theo thời gian thực (Trang 41)

Tải bản đầy đủ (PDF)

(57 trang)