Thực tế những lý thuyết trên, các tính toán thư viện OpenCV đã làm hết
hộ ta. Thuật toán máy học thường chia làm hai quá trình, một là quá trình học,
hai là quá trình chạy. Quá trình học sẽ thực hiện offline với nhiều các mẫu và
thường là quá trình lặp. Kết thúc quá trình học thông thường cho ra kết quả là một bộ tham số, một mô hình (model), ... Trong thư viện OpenCV có các tập tin
xml chính là dữ liệu lưu trữ thông tin này. Trong quá trình chạy, quá trình sẽ gần như tương tự quá trình học nhưng có điều là sẽ cho ra kết quả trực tiếp căn cứ
vào giá trị mô hìnhđã có.
* Tạo một hàm nhận dạng khuôn mặt như sau
int DetectFaceHaar( IplImage *imgSrc,
IplImage **imgFaceDetected,
bool isDraw = false, char *winSrc\ = NULL );
Mô tả :
Hàm này đọc một ảnh nguồn là một ảnh khoảng phần trên của người. Hàm trả lại giá trị kiểu nguyên là số lượng mặt người nhận dạng được (nếu không tìm
được sẽ trả lại giá trị0).
Đầu vào :
imgFace : ảnh nguồn cần được nhận dạng.
isDraw : có kiểu lô-gíc. Nếu là đúng hàm sẽ vẽ vào ảnh nguồn imgSrc mỗi
khuôn mặt đãđược nhận dạng một hình hình chữ nhật bao quanh.
winSrc : tên cửa sổ nếu muốn hiển thị ảnh nguồn lên đó. Nên sử dụng tham số này kèm tham số isDraw = true để hàm thể hiện được hình bao khuôn mặt đã vẽ vào cửa sổ đó.
Đầu ra :
imgFaceDetected : trích ảnh khuôn mặt đãđược nhận dạng.
* Mã nguồn hàm như sau
int DetectFaceHaar(
IplImage *imgSrc, IplImage **imgFaceDetected, bool isDraw = false, char *winSrc = NULL) {
IplImage *imgGray = cvCreateImage(
cvSize(imgSrc->width, imgSrc->height), IPL_DEPTH_8U, 1 ); cvCvtColor( imgSrc, imgGray, CV_BGR2GRAY );
cvSmooth( imgGray, imgGray, CV_GAUSSIAN, 11, 11 ); //--- có thể phát hiện nhiều khuôn mặt trong một ảnh
CvSeq *facesDetected = cvHaarDetectObjects( imgGray,
g_cascadeFace, g_storageFace, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(60, 60)
);
//--- tạo 2 biến để đánh dấu hình chữ nhật bao khuôn mặt
CvPoint ptFace1, ptFace2; CvRect *rectFace;
//--- mỗi khuôn mặt nhận dạng, vẽ một hình chữ nhật
int iNumOfHaarFacesDetected = \
(facesDetected ? facesDetected->total : 0); for( int i = 0; i < iNumOfHaarFacesDetected; i++ ) {
//--- tạo hình chữ nhật
rectFace = (CvRect*) cvGetSeqElem( facesDetected, i ); //--- xác định 2 điểm
ptFace1.x = (rectFace->x) ; ptFace1.y = (rectFace->y) ; ptFace2.x = (rectFace->x + rectFace->width) ; ptFace2.y = (rectFace->y + rectFace->height); //--- vẽ hình chữ nhật đó lên ảnh gốc if( isDraw ) cvRectangle( imgSrc, cvPoint(ptFace1.x - 1, ptFace1.y - 1), ptFace2, CV_RGB(0,255,0), // màu sắc hình chữ nhật 1, 8, 0 // độ dày hình chữ nhật );
//--- chỉ lấy ảnh khuôn mặt đầu tiên if( i == 0 )
{
//--- always check for allocmem if( (!(*imgFaceDetected)) \ || ((*imgFaceDetected)->width != rectFace->width) || ((*imgFaceDetected)->height!=rectFace->height) ) { if( *imgFaceDetected ) cvReleaseImage( imgFaceDetected ); *imgFaceDetected = cvCreateImage( cvSize(rectFace->width,rectFace->height), IPL_DEPTH_8U, 3 ); }
cvSetImageROI( imgSrc, *rectFace );
cvCopy( imgSrc, *imgFaceDetected, NULL ); cvResetImageROI( imgSrc );
} }
if( winSrc ) {
cvShowImage( winSrc, imgSrc ); }
//---
if( imgGray ) cvReleaseImage( &imgGray ); //---
return iNumOfHaarFacesDetected; }
* Mã nguồn chương trình như sau
#include "stdafx.h" #include "cv.h" #include "highgui.h"
//=========================[ GLOBAL VAR ]=========================// static CvHaarClassifierCascade *g_cascadeFace;
static CvMemStorage *g_storageFace; const char *szHaarFaceFilename =
"C:\\OpenCV2.1\\data\\haarcascades\\haarcascade_frontalface_alt.xml" ;
//============================================================// int DetectFaceHaar(
IplImage *imgSrc, IplImage **imgFaceDetected, bool isDraw = false, char *winSrc = NULL) {
... }
//=========================[ MAIN PROG ]=========================// int main(int argc, char *argv[])
{
//--- kiểm tra có nạp được tệp tin dữ liệu Haar không
if( !(g_cascadeFace = (CvHaarClassifierCascade*) \ cvLoad( szHaarFaceFilename, 0, 0, 0 )) ) {
fprintf( stderr, "\nERROR: Could not load c.c file.\n" ); return -1;
}
//--- kiểm tra bộ nhớ có đủ không
if( !(g_storageFace = cvCreateMemStorage(0)) ) {
fprintf( stderr, "\nERROR: Could not create memsto.\n" ); return -1;
}
//====================
char *winSrc = "ATP Eye :: Demo face detect"; IplImage *imgSrc = NULL;
IplImage *imgFaceDetected = NULL; //---
imgSrc = cvLoadImage( "C:\\lena.jpg" );
DetectFaceHaar( imgSrc, &imgFaceDetected, true, winSrc ); cvWaitKey( 0 ); //--- giải phóng bộ nhớ những gì đã cấp phát if( g_cascadeFace ) cvReleaseHaarClassifierCascade( &g_cascadeFace ); if( g_storageFace ) cvReleaseMemStorage( &g_storageFace ); if( imgSrc ) cvReleaseImage( &imgSrc );
cvDestroyAllWindows(); cvDestroyWindow( winSrc ); //==================== return 0;
}
* Kết quả nhận dạng khuôn mặt người
Hình 5.7 : Kết quả nhận dạng khuôn mặt người(demo)