Mục lục
1. Giới thiệu về OpenCV 3
1.1. Tổng quan OpenCV 3
1.1.1. Các tính năng. 3
1.1.2. Tổ chức. 3
1.2. Cài đặt OpenCV 3
1.2.1. Cài đặt cơ bản. 3
1.2.2. Tùy chỉnh khi cài đặt Windows. 3
1.2.3. Sau khi cài đặt. 3
1.3. Lập trình với OpenCV: Một số vấn đề cơ bản. 3
1.3.1. Về tiêu đề và thư viện. 3
1.3.2. Đọc và Ghi ảnh. 3
1.3.3. Live Video nhập vào. 3
1.3.4. Chuyển đổi Color. 3
1.3.5. OpenCV Iplimage. 3
1.3.6. Truy cập giá trị Pixel 3
2. Face Detection. 3
2.1. Background and Preliminaries. 3
2.2. Thực hiện nhận diện khuôn mặt, từng bước. 3
3. Nhận dạng khuôn mặt 3
3.1. Introduction PCA. 3
3.2. Mathematics of PCA 3
3.3. Nhận dạng khuôn mặt. 3
4. Giải thuật phân nhóm khuôn mặt. 3
5. Chương trình. 3
5.1. Chương trình có các hàm xử lý sau: 3
5.2. Các lớp xử lý với ảnh: 3
5.3. Chức năng chương trình. 3
5.4. Chi tiết chương trình. 3
6. Đánh giá chương trình. 3
7. Tài liệu tham khảo. 3
1.Giới thiệu về OpenCVOpenCV là mã nguồn mở của Intel, nó là một thư viện có khả năng nhúng vào trong các chương trình có khả năng nhận diện hình ảnh của máy tính .Nó bao gồm khả năng tiên tiến như phát hiện khuôn mặt, theo dõi khuôn mặt, nhận diện khuôn mặt Ngoài ra, nó cung cấp rất nhiều các thuật toán xử lý ảnh thông qua các hàm API.
1.1. Tổng quan OpenCVIntel phát hành phiên bản đầu tiên của OpenCV vào năm 1999. Ban đầu, nó yêu cầu như là thư viện xử lý hình ảnh của Intel. Nhưng các vấn đề phụ thuộc đã được gỡ bỏ và bây giờ bạn có thể sử dụng OpenCV là một thư viện độc lập.
OpenCV hỗ trợ đa nền tảng. Nó hỗ trợ cả Windows và Linux, và gần đây hơn là MacOSX. Với giao diện của nó là nền tảng độc lập.
32 trang |
Chia sẻ: lvcdongnoi | Lượt xem: 3808 | Lượt tải: 3
Bạn đang xem trước 20 trang tài liệu Bài tập lớn môn xử lý ảnh: Extract face sequences from video, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Trường đại học Bách Khoa Hà Nội
Viện công nghệ thông tin và truyền thông
Bộ môn kĩ thuật máy tính
Bài tập lớn môn xử lý ảnh:
Extract face sequences from video
Nhóm thực hiện:
Lê Xuân Bách Kĩ thuật máy tính K52
Phạm Kiên Giang Kĩ thuật máy tính K52
Nguyễn Đình Nam Kĩ thuật máy tính K52
Đồng Thị Tâm Kĩ thuật máy tính K52
Giáo viên hướng dẫn : Gv. Hoàng Văn Hiệp.
Mục lục
Giới thiệu về OpenCV
OpenCV là mã nguồn mở của Intel, nó là một thư viện có khả năng nhúng vào trong các chương trình có khả năng nhận diện hình ảnh của máy tính .Nó bao gồm khả năng tiên tiến như phát hiện khuôn mặt, theo dõi khuôn mặt, nhận diện khuôn mặt….. Ngoài ra, nó cung cấp rất nhiều các thuật toán xử lý ảnh thông qua các hàm API.
Tổng quan OpenCV
Intel phát hành phiên bản đầu tiên của OpenCV vào năm 1999. Ban đầu, nó yêu cầu như là thư viện xử lý hình ảnh của Intel. Nhưng các vấn đề phụ thuộc đã được gỡ bỏ và bây giờ bạn có thể sử dụng OpenCV là một thư viện độc lập.
OpenCV hỗ trợ đa nền tảng. Nó hỗ trợ cả Windows và Linux, và gần đây hơn là MacOSX. Với giao diện của nó là nền tảng độc lập.
Hình 1. Các khả năng của OpenCV có thể là nhận diện khuôn mặt (trên cùng bên trái), phát hiện đường đồng mức (trên bên phải), và phát hiện cạnh (phía dưới)
Các tính năng
Dưới đây là một bản tóm tắt của các loại chức năng quan trọng trong OpenCV, phiên bản 1.0:
General computer-vision and image-processing algorithms (mid- and low-level APIs).
Sử dụng các interface này, bạn có thể thử nghiệm nhiều tiêu chuẩn thuật toán tầm nhìn máy tính mà không cần phải code chúng. Bao gồm các việc như : phát hiện cạnh, đường, và phát hiện góc, hình elip, kim tự tháp ….và nhiều hơn nữa .
High-level computer-vision modules
OpenCV bao gồm một số khả năng cao cấp. Ngoài việc phát hiện khuôn mặt, nhận diện, và theo dõi, nó còn bao gồm dòng chảy quang học (bằng cách sử dụng máy ảnh chuyển động để xác định cấu trúc 3D), hiệu chuẩn máy ảnh.
AI and machine-learning methods.
Ứng dụng tầm nhìn máy tính thường đòi hỏi máy học hoặc sử dụng phương thức AI khác. Một số trong số này là có sẵn trong gói phần mềm OpenCV's Machine Learning
Image sampling and view transformations.
Thường hữu ích để xử lý một nhóm các điểm ảnh như một khối . OpenCV bao gồm giao diện cho tiểu vùng trích xuất hình ảnh, lấy mẫu ngẫu nhiên, thay đổi kích thước, cong vênh, xoay, và các hiệu ứng quan điểm áp dụng .
Methods for creating and analyzing binary (two-valued) images
Ảnh nhị phân thường được sử dụng trong các hệ thống kiểm tra mà quét phát hiện các khuyết tật hoặc trong các bộ đếm. Ảnh nhị phân cũng thuận tiện khi định vị trí một đối tượng để nắm bắt .
Methods for computing 3D information.
Các chức năng này rất hữu ích để lập bản đồ và nội địa hoá hoặc với nhiều quan góc nhìn từ một máy ảnh.
Math routines for image processing, computer vision, and image interpretation.
OpenCV bao gồm các thuật toán toán học thường được sử dụng trong đại số tuyến tính, thống kê, và hình học tính toán.
Graphics.
Các interface này cho phép bạn viết văn bản và vẽ trên hình ảnh. Ngoài ra, các chức năng này rất hữu ích cho việc ghi nhãn và đánh dấu . Ví dụ, nếu bạn viết một chương trình phát hiện đối tượng, nó rất hữu ích để nhãn hình ảnh với kích cỡ và vị trí của họ.
GUI methods
OpenCV bao gồm các interface windown riêng của nó. Trong khi đây là những hạn chế so với những gì có thể được thực hiện trên các nền tảng khác, họ cung cấp một đơn giản, đa nền tảng API để hiển thị hình ảnh, chấp nhận đầu vào người dùng thông qua con chuột hoặc bàn phím, và thực hiện kiểm soát thanh trượt .
Datastructures and algorithms
Với các interface, bạn có thể thực hiệu quả hơn các việc như: tìm kiếm, lưu, và thao tác các danh sách lớn, bộ sưu, đồ thị và cây .
Data persistence
Những phương pháp này cung cấp giao diện thuận tiện để lưu trữ các loại dữ liệu vào ổ lưu trữ và lấy chúng sau này .
Tổ chức
Chức năng OpenCV được chứa trong một số module:
CXCORE chứa các định nghĩa kiểu dữ liệu cơ bản. Ví dụ, cấu trúc dữ liệu điểm cho hình ảnh, hình chữ nhật và được quy định tại cxtypes.h.
CV bao gồm xử lý hình ảnh và các phương pháp hiệu chỉnh máy ảnh. Các chức năng tính toán hình học cũng nằm ở đây.
CVAUX được mô tả trong tài liệu hướng dẫn của OpenCV có chứa mã thử nghiệm và thực nghiệm.Tuy nhiên, các giao diện đơn giản nhất để nhận dạng khuôn mặt trong mô-đun này.
ML chứa machine-learning interfaces.
Các chức năng còn lại được chứa trong HighGUI và CVCAM. Cả hai đều nằm trong một thư mục có tên là "otherlibs. Nó chứa các cửa sổ đa nền tảng, đa chức năng.
CVCAM chứa các giao diện để truy cập video thông qua DirectX trên nền tảng Windows 32-bit. Tuy nhiên, HighGUI cũng chứa các giao diện video.
Cài đặt OpenCV
Cài đặt cơ bản
OpenCV cho Linux hoặc MacOSX là các bản đóng gói như là một kho lưu trữ mã nguồn. Bạn sẽ cần phải xây dựng các thư viện tĩnh và thư viện chia sẻ đối tượng. Bạn có thể xây dựng một RPM đầu tiên, và cài đặt từ đó, hoặc biên dịch và cài đặt nó trực tiếp.
Với Windows thì được đóng gói như là một thực thi cài đặt OpenCV và bạn cần chạy nó. Nó đặt các file OpenCV vào một thư mục tùy bạn chọn, thay đổi đường dẫn hệ thống của bạn để có thể include những chương trình OpenCV.
Tùy chỉnh khi cài đặt Windows
Kể từ khi OpenCV là một bộ công cụ nhà phát triển, không phải là một chương trình, bạn có thể muốn xác định vị trí nó ở đâu đó khác hơn so với thư mục Program Files của bạn. Nếu bạn thích để xác định vị trí nó ở nơi khác, quyết định rằng trước khi bạn chạy trình cài đặt, và nhập vào vị trí đó khi được hỏi.
Bạn có thể thay đổi các biến PATH hệ thống của bạn bao gồm vị trí của họ, hoặc bạn có thể di chuyển chúng, sau khi cài đặt, từ thư mục "bin" của OpenCV vào thư mục SYSTEM_ROOT của bạn.
Nếu bạn muốn di chuyển các file dll, nhưng không chắc chắn thư mục SYSTEM_ROOT của bạn, bạn có thể xác định vị trí nó bằng cách chạy các tiện ích có sẵn ở www.cognotics.com/utilities.
Nếu bạn muốn thay đổi PATH, chứ không phải là di chuyển các fiel dll, bạn có thể cài đặt làm điều đó cho bạn bằng cách chọn hộp kiểm tra "Thêm thư mục bin vào PATH."
Sau khi cài đặt
OpenCV chứa nhiều thư mục con. Các tài liệu thư mục chứa tài liệu html cho tất cả các chức năng và kiểu dữ liệu OpenCV.
Các tập tin tiêu đề bạn sẽ cần phải bao gồm khi bạn biên dịch chương trình sử dụng OpenCV được phân phối giữa các mô-đun OpenCV.
Trên cả hai Linux và Windows, bạn có thể xác định vị trí các tiêu đề bằng cách tìm kiếm thư mục cài đặt và thư mục con cho tên tập tin phù hợp với mô hình *. h, *. HPP.
Lập trình với OpenCV: Một số vấn đề cơ bản
Về tiêu đề và thư viện
Hầu hết các chương trình OpenCV cần bao gồm cv.h và highgui.h. Sau đó, nhận diện khuôn mặt, chúng tôi cũng sẽ bao gồm cvaux.h. Các tập tin tiêu đề còn lại được bao gồm bởi những tiêu đề cấp cao nhất.
Mối liên kết của bạn sẽ cần cả hai con đường thư viện và tên của các thư viện tĩnh để sử dụng. Các thư viện tĩnh, bạn cần phải liên kết với file thư viện cxcore.lib, cv.lib, và highgui.lib. Sau đó, nhận diện khuôn mặt, bạn cũng sẽ liên kết cvaux.lib. Đây là những file trong thư mục "lib" của OpenCV.
Đọc và Ghi ảnh
Hình ảnh I / O dễ dàng với OpenCV.Chương trình dưới đây là để đọc một hình ảnh từ tập tin và viết nó như là một tập tin thứ hai, trong một định dạng nén khác nhau .
// ImageIO.c
// Example showing how to read and write images
#include "cv.h"
#include "highgui.h"
#include
int main(int argc, char** argv)
{
IplImage * pInpImg = 0;
// Load an image from file
pInpImg = cvLoadImage("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!pInpImg)
{
fprintf(stderr, "failed to load input image\n");
return -1;
}
// Write the image to a file with a different name,
// using a different image format -- .png instead of .jpg
if( !cvSaveImage("my_image_copy.png", pInpImg) )
{
fprintf(stderr, "failed to write image file\n");
}
// Remember to free image memory after using it!
cvReleaseImage(&pInpImg);
return 0;
}
Để đọc một tập tin hình ảnh, chỉ cần gọi cvLoadImage (), và truyền vào trong hàm đường dẫn fle.OpenCV hỗ trợ các định dạng hình ảnh phổ biến nhất, bao gồm JPEG, PNG, và BMP. Bạn không cần phải cung cấp thông tin định dạng. cvLoadImage () xác định định dạng tập tin bằng cách đọc phần đầu tập tin.
Để viết một hình ảnh tập tin, hãy gọi cvSaveImage (). Chức năng này quyết định định dạng tập tin để sử dụng từ phần mở rộng tập tin.
Cả hai cvLoadImage () và cvSaveImage () trong module HighGUI.
Live Video nhập vào
// Capture.c
// Example showing how to connect to a webcam and capture
// video frames
#include "stdio.h"
#include "string.h"
#include "cv.h"
#include "highgui.h"
int main(int argc, char ** argv)
{
CvCapture * pCapture = 0;
IplImage * pVideoFrame = 0;
int i;
char filename[50];
// Initialize video capture
pCapture = cvCaptureFromCAM( CV_CAP_ANY );
if( !pCapture )
{
fprintf(stderr, "failed to initialize video capture\n");
return -1;
}
// Capture three video frames and write them as files
for(i=0; i<3; i++)
{
pVideoFrame = cvQueryFrame( pCapture );
if( !pVideoFrame )
{
fprintf(stderr, "failed to get a video frame\n");
}
// Write the captured video frame as an image file
sprintf(filename, "VideoFrame%d.jpg", i+1);
if( !cvSaveImage(filename, pVideoFrame) )
{
fprintf(stderr, "failed to write image file %s\n", filename);
}
// IMPORTANT: Don't release or modify the image returned
// from cvQueryFrame() !
}
// Terminate video capture and free capture resources
cvReleaseCapture( &pCapture );
return 0;
}
Giao diện chụp được khởi tạo bằng cách gọi cvCaptureFromCAM(). Chức năng này trả về một con trỏ đến một cấu trúc CvCapture. Bạn sẽ lưu trữ con trỏ để sử dụng cvQueryFrame () để lấy frame.
Khi bạn hoàn tất bằng cách sử dụng đầu vào video, gọi cvReleaseCapture() để giải phóng tài nguyên. Với cvReleaseImage (), bạn thông qua địa chỉ của con trỏ CvCapture để cvReleaseCapture ().
Ảnh (IplImage) bạn nhận được từ cvQueryFrame()! Nếu bạn cần phải sửa đổi dữ liệu hình ảnh, tạo một bản sao để làm việc với:
//Sao chép các khung hình video:
IplImage * pImgToChange = cvCloneImage (pVideoFrame);
/ / Chèn mã xử lý hình ảnh của bạn ở đây ... / / sao chép sau khi sử dụng cvReleaseImage (& pImgToChange );
Chuyển đổi Color
// ConvertToGray.c
// Example showing how to convert an image from color
// to grayscale
#include "stdio.h"
#include "string.h"
#include "cv.h"
#include "highgui.h"
int main(int argc, char** argv)
{
IplImage * pRGBImg = 0;
IplImage * pGrayImg = 0;
// Load the RGB image from file
pRGBImg = cvLoadImage("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!pRGBImg)
{
fprintf(stderr, "failed to load input image\n");
return -1;
}
// Allocate the grayscale image
pGrayImg = cvCreateImage
( cvSize(pRGBImg->width, pRGBImg->height), pRGBImg->depth, 1 );
// Convert it to grayscale
cvCvtColor(pRGBImg, pGrayImg, CV_RGB2GRAY);
// Write the grayscale image to a file
if( !cvSaveImage("my_image_gray.jpg", pGrayImg) )
{
fprintf(stderr, "failed to write image file\n");
}
// Free image memory
cvReleaseImage(&pRGBImg);
cvReleaseImage(&pGrayImg);
return 0;
}
Lưu ý rằng chức năng chuyển đổi, cvCvtColor (), yêu cầu hai hình ảnh trong danh sách đầu vào của nó. Đầu tiên, pRGBImg, là hình ảnh nguồn. Thứ hai, pGrayImg, là hình ảnh đích. Nó sẽ chứa kết quả chuyển đổi khi cvCvtColor () trả về.
OpenCV Iplimage.
OpenCV lưu trữ hình ảnh như là một cấu trúc C, IplImage. IPL là viết tắt của Thư viện xử lý hình ảnh.
Các kiểu dữ liệu IplImage được định nghĩa trong CXCORE. Ngoài dữ liệu pixel liệu, nó có chứa một số lĩnh vực mô tả, gọi chung là Header Image. Chúng bao gồm
Chiều rộng - chiều rộng hình ảnh theo pixel.
Chiều cao – hình ảnh chiều cao tính bằng pixel.
Chiều sâu - một trong những hằng số được xác định trước cho biết số bit cho mỗi điểm ảnh trên một kênh
nChannels - số lượng của các kênh dữ liệu (1-4). Mỗi kênh có chứa một loại dữ liệu pixel.Ví dụ, hình ảnh RGB có ba kênh màu đỏ, màu xanh lá cây, và cường độ màu xanh.
Truy cập giá trị Pixel
Nó có thể tạo ra nhiều loại chức năng sử dụng OpenCV mà không trực tiếp truy cập vào các dữ liệu pixel liệu. Ví dụ, các chương trình nhận diện khuôn mặt, theo dõi, và công nhận không bao giờ thao tác dữ liệu pixel liệu trực tiếp. Tuy nhiên, nếu bạn viết các thuật toán xử lý hình ảnh của riêng bạn, bạn có thể cần truy cập vào các giá trị pixel liệu. Dưới đây là hai cách để làm điều đó:
Pixel truy cập đơn giản
Cách dễ nhất để đọc điểm ảnh cá nhân với cvGet2D ():
CvScalar cvGet2D (const CvArr *, int row, int col);Chức năng này có ba thông số: một con trỏ đến một thùng chứa dữ liệu (CVArr *) và mảng chỉ số hàng và vị trí cột. Các thùng chứa dữ liệu có thể là một cấu trúc IplImage. Hàng trên cùng của điểm ảnh là hàng = 0, và dưới cùng là = chiều cao-1 hàng.
CvGet2D () chức năng trả về một cấu trúc C, CvScalar, được định nghĩa là:
CvScalar typedef struct
{
double val [4];
}
CvScalar;
Các giá trị pixel cho mỗi kênh trong val [i]. Đối với màu xám hình ảnh, val [0] chứa độ sáng điểm ảnh. Ba giá trị khác được thiết lập là 0. Đối với một kênh ba, BGR hình ảnh, màu xanh = val [0], xanh lá cây = val [1], và màu đỏ = val [2].
Các chức năng bổ sung, cvSet2D () cho phép bạn chỉnh sửa các giá trị pixel. Đó là định nghĩa: cvSet2D khoảng trống (CvArr *, int row, int col, CvScalar);
Truy cập nhanh Pixel
Mặc dù cvGet2D () và cvSet2D () là dễ sử dụng, nếu bạn muốn truy cập nhiều hơn một vài giá trị pixel, và các vấn đề hiệu suất, bạn sẽ muốn đọc các giá trị trực tiếp từ bộ đệm dữ liệu thô, IplImage.imageData.
Đối với lý do hiệu suất, dữ liệu pixel được liên kết, và đệm nếu cần thiết, sao cho mỗi hàng bắt đầu vào ngày một nhiều bốn-byte. Một lĩnh vực thứ hai, IplImage.widthStep, cho biết số lượng các byte giữa sự bắt đầu của dữ liệu mỗi điểm ảnh của hang: IplImage.imageData +i*IplImage.widthStep.
IplImage.imageData được định nghĩa là kiểu char *, vì vậy bạn có thể cần phải bỏ kiểu dữ liệu.Ví dụ, nếu dữ liệu của bạn hình ảnh byte unsigned (các loại đầu vào phổ biến nhất), bạn muốn bỏ mỗi giá trị để * char unsigned trước khi giao, hoặc sử dụng nó.
Nếu bạn đang truy cập dữ liệu từ một màu xám (một kênh) hình ảnh, và độ sâu dữ liệu là tám bit (một byte cho mỗi điểm ảnh), bạn muốn truy cập điểm ảnh [hàng] [col] với:
pixel [row] [col] = (uchar *) (pImg-> imageData + row * pImg-> widthStep + col);
Cuối cùng, nếu chiều sâu hình ảnh lớn hơn tám bit (ví dụ, IPL_DEPTH_32S), bạn sẽ cần phải chuyển các byte nhiều, hoặc diễn viên đệm để một kiểu dữ liệu đa-byte. Bạn cũng sẽ cần phải nhân bước rộng bằng số lượng các byte dữ liệu để tạo độ sâu hình ảnh của bạn. (Ví dụ, IPL_DEPTH_32S bạn muốn bỏ bộ đệm (int *) và nhân widthStep.)
Face Detection.
Background and Preliminaries.
OpenCV sử dụng một loại phát hiện khuôn mặt được gọi là Haar Cascade classifie.Sidebar "nhận diện khuôn mặt hoạt động như thế nào" giải thích miếng này có nghĩa là gì. Hình 1 cho thấy một ví dụ về phát hiện phải đối mặt với hành động của OpenCV.
Phân loại giả định một tỷ lệ cố định cho khuôn mặt, nói rằng các điểm ảnh 50x50. Kể cả khi các khuôn mặt trong một hình ảnh có thể là nhỏ hơn hoặc lớn hơn, phân loại chạy trên hình ảnh nhiều lần, để tìm kiếm các khuôn mặt trên một loạt các quy mô. Điều này có vẻ là một số lượng lớn xử lý, nhưng nhờ thuật toán nên đã phân loại là rất nhanh, ngay cả khi nó áp dụng ở quy mô lớn hơn.
Hình 1. Phát hiện khuôn mặt với OpenCV, bằng cách sử dụng các thông số mặc định.
Phân loại này sử dụng các dữ liệu được lưu trữ trong một tập tin XML để quyết định làm thế nào để phân loại từng vị trí hình ảnh. Trong bản OpenCv tải bao gồm bốn loại dữ liệu XML nhận diện khuôn mặt phía trước, và một cho khuôn mặt hồ sơ cá nhân. Nó cũng bao gồm ba file phát hiện khuôn mặt dạng XML - một cho phát hiện cơ thể , một cho phần trên cơ thể, và một cho cơ thể thấp hơn.
Bạn cần xác định loại tập tin dữ liệu mà bạn muốn chương trình sử dụng. Ví dụ là haarcascade_frontalface_default.xml.
Bạn cũng sẽ cần một hình ảnh để xử lý. Lena.jpg là một ảnh tốt để thử nghiệm.
Thực hiện nhận diện khuôn mặt, từng bước
Initializing the detector.
Biến CvHaarClassifierCascade * pCascade (2) nắm giữ các dữ liệu từ file XML bạn đặt trước đó. Để tải dữ liệu XML vào pCascade, bạn có thể sử dụng cvLoad(). cvLoad () là một chức năng có mục đích chung để tải dữ liệu từ các tập tin.Phải mất đến ba thông số đầu vào. Đối với ví dụ này, bạn sẽ chỉ cần tham số đầu tiên. Đây là đường dẫn đến một file XML có chứa một Cascade Haar hợp lệ.
Trước khi phát hiện khuôn mặt trong hình ảnh, bạn cũng sẽ cần phải tạo một đối tượng CvMemStorage. Đây là một bộ nhớ đệm mở rộng tự động, khi cần thiết. Phát hiện khuôn mặt sẽ đưa danh sách các khuôn mặt vào bộ đệm này. Kể từ khi bộ đệm được mở rộng, bạn sẽ không cần phải lo lắng về tràn bộ nhớ.
Running the detector.
Phương thức cvHaarDetectObjects() để dò khuôn mặt.Chức năng này có đến bảy thông số . Đầu tiên là con trỏ hình ảnh, dữ liệu XML, và bộ nhớ đệm. Bốn thông số còn lại được thiết lập để C + + mặc định .
Show Result.
Một cách nhanh chóng để kiểm tra xem chương trình của bạn hoạt động là để hiển thị các kết quả trong một cửa sổ OpenCV. Bạn có thể tạo ra một cửa sổ hiển thị bằng cách sử dụng cvNamedWindow () chức năng,
Để một hình ảnh cho màn hình hiển thị, hãy gọi cvShowImage () với tên trước đây bạn chỉ định cửa sổ, và hình ảnh mà bạn muốn nó để hiển thị. Gọi cvWaitKey() để tạm dừng việc áp dụng cho đến khi bạn đóng cửa sổ. Ngoài ra, hãy chắc chắn rằng chương trình của bạn gọi cvDestroyWindow () để đóng cửa sổ.
Phát hiện khuôn mặt được lưu trữ như một danh sách các CvRect con trỏ struct.
Releasing resources.
Bạn cần trả tài nguyên khi sau khi sử dụng các biến và không cần sử dụng lại nữa.
Nhận dạng khuôn mặt
Introduction PCA.
Phân tích phần chính (PCA) là một trong những kỹ thuật thành công nhất đã được sử dụng trong nhận dạng hình ảnh và nén. PCA là một phương pháp thống kê theo tiêu đề factor analysis. Mục đích của PCA là giảm số chiều lớn của không gian dữ liệu (các biến quan sát) các chiều nhỏ hơn nội tại của không gian tính năng (biến độc lập), đó là cần thiết để mô tả các dữ liệu kinh tế.Đây là trường hợp khi có một sự tương quan mạnh mẽ giữa các biến quan sát.
Các công việc mà PCA có thể làm là dự đoán, loại bỏ dư thừa, khai thác tính năng nén dữ liệu…. Bởi vì PCA là một kỹ thuật cổ điển mà có thể làm một cái gì đó trong lĩnh vực tuyến tính, các ứng dụng có mô hình tuyến tính phù hợp, chẳng hạn như xử lý tín hiệu, xử lý hình ảnh, hệ thống và lý thuyết điều khiển, truyền thông, .v.v..
Nhận dạng khuôn mặt có nhiều điểm áp dụng. Hơn nữa, nó có thể được phân loại vào nhận diện khuôn mặt, phân loại khuôn mặt, hoặc xác định giới tính. Các ứng dụng hữu ích nhất bao gồm giám sát đám đông, lập chỉ mục nội dung video, nhận dạng cá nhân (ví dụ: lái xe giấy phép), lối vào an ninh…. Ý tưởng chính của việc sử dụng PCA cho nhận dạng khuôn mặt là thể hiện vector 1-D lớn các điểm ảnh xây dựng từ 2-D hình ảnh khuôn mặt vào các thành phần chủ yếu nhỏ gọn của khoảng tính năng. Điều này có thể được gọi là eigenspace .Eigenspace được tính bằng cách xác định các vector riêng của ma trận hiệp phương sai bắt nguồn từ một tập hợp các hình ảnh trên khuôn mặt (vector).
Mathematics of PCA
Bước 1: Tập hợp các bức ảnh mẫu: I1, I2,..., IM.
Bước 2: coi các bức ảnh Ii như các vector Γi
Bước 3: Tính vector trung bình:
Bước 4: Tính vector lệch của mỗi bức ảnh so với vector trung bình.
Φi=Γi−Ψ
Bước 5: Tính ma trận hiệp phương sai :
Bước 6: tính vector riêng ui của ma trận hiệp phương sai AAT.
Do ma trận hiệp phương sai có kích thước lớn nên ra không tính trực tiếp mà thông qua ma trận dảo của ma trận hiệp phương sai là
Tính vector riêng vi của ma trận .
Chú ý:
Ma trận có NxN trị riêng và vector riêng.
Ma trận có M trị riêng và vector riêng.
M trị riêng,vector riêng của ma trận tương ứng là M trị riêng và vector riêng của .
Tính M vector riêng:
Bước 7: Giữ lại K vector riêng (có trị riêng lớn nhất)
Mỗi ảnh khuôn mặt(sau khi đã trừ đi giá trị trung bình ) Φi có thể được biểu diễn như là một sự kết hợp tuyến tính của K vector riêng tốt nhất.
Mỗi ảnh khuôn mặt Φi được thể hiển bởi vector:
Nhận dạng khuôn mặt.
Bước 1: Tính: Φ= Γ− Ψ
Bước 2: dự đoán không gian riêng:
Bước 3: thể hiện Φ là vector :
Bước 4: tìm
Bước 5: Nếu er < Tr thì Γ là nhận dạng như là khuôn mặt l trong số ảnh mẫu.
Chú ý:
Giải thuật phân nhóm khuôn mặt.
Mặc định đầu vào ta có một số bức ảnh(có thể là danh sách các file ảnh, hoặc ảnh trích từ video, từu camera.. ).
Chú ý: ta chỉ xét các bức ảnh có mặt người, những bức ảnh ko có mặt người sẽ ko xử lý.
Bước 1: Đưa một khuôn mặt vào làm mẫu nhận dạng.
Bước 2: Phân tích PCA đối với các ảnh khuôn mặt mẫu.
Bước 3: Xét một khuôn mặt bất kì, dự đoán theo phân tích PCA xem nó gần với ảnh khuôn mặt mẫu nào nhất(nearest), tính toán độ tin cậy của dự đoán theo trị riêng(confidence)
Bước 4:
nếu confidence>Tngưỡng thì đưa ảnh vừa xét vào nhóm với ảnh dự đoán gần nhất vừa tìm được, quay trở lại bước 3 xét ảnh tiếp theo.
nếu không thì khuôn mặt trên chưa có trong tập hợp ảnh mẫu, đưa ảnh khuôn mặt xét vào tập ảnh khuôn mặt mẫu và tạo cho nó một nhóm mới. quay trở lại bước 2 để phân tích lại tập ảnh mẫu. sau đó xét ảnh tiếp theo.
Chương trình.
Chương trình có các hàm xử lý sau:
void learn(); // chuẩn bị dữ liệu cho việc chuẩn đoán
void doPCA(); // phân tích dữ liệu chuẩn đoán
int findNearestNeighbor(float * projectedTestFace, float *pConfidence);
// xác định khuôn mặt gần đúng nhất, với độ tin cậy
void getArrayImageFromListTrainHistrogram() // load ảnh từ list sang array
int defindFaceTrainFormCamera ();
// Xác định dữ liệu ảnh mẫu từ camera
void showCameraRecogniton ();
// Nhận dạng trực tiếp từ camera
void createFaceAndImageFromCamera(const char * fileListFrame);
// Tạo dữ liệu ảnh cần gom nhóm từ camera
void createFaceAndImageFormVideo();
// Xác định dữ liệu ảnh cần xử lý từ video
void groupFace();// Gom nhóm ảnh có cùng khuôn mặt.
void initGroup ();//Khởi tạo dữ liệu mẫu
void addNewFaceInListTrain(IplImage *face,int indexImage);
// Thêm ảnh mới vào dữ liệu mẫu, tạo nhóm mới
void addFaceInListTrain(IplImage *face,int indexImage);
// Thêm ảnh đã gom nhóm ảnh vào dữ liệu mẫu
void initShowGroup();
// Thực hiện việc xem ảnh từng nhóm.
Các lớp xử lý với ảnh:
class ImageProcess
{
public:
ImageProcess(void); //hàm tạo
~ImageProcess(void); //Hàm hủy
void showImage(IplImage * img); // Xem ảnh trên của sổ
char *saveImage(const char *folder,int index,IplImage *img);
//Save image vào thư mục có tên tương ứng với vị trí
IplImage*convertFloatImageToUcharImage(const IplImage *srcImg);
// Conver image sang dữ liệu float
IplImage*rotateImage(const IplImage *src, float angleDegrees);
// xoay ảnh theo góc
IplImage*cropImage(const IplImage *img, const CvRect region);
// cắt ảnh theo khung
IplImage*resizeImage(const IplImage *origImg, int newWidth,int newHeight); // thay đổi kích thước ảnh
CvSeq *detectFace(IplImage* img); // phát hiện danh sách khuôn mặt
IplImage*detect_and_draw(IplImage* img); // Xác định và vẽ khuôn mặt
IplImage*histogram(IplImage *imageSrc); //Tính histrogram ảnh
IplImage*convertImageToGreyscale(const IplImage *imageSrc);
// convert image sang dữ liệu Greyscale
};
Thực hiện việc xử lý, các thao tác với ảnh.
class MyImage
{
public:
IplImage * image;
MyImage(void);
MyImage(IplImage * img);
};
Tạo đối tượng để xử lý với List.
Chức năng chương trình.
Chương trình gồm có 3 chức năng chính:
Chức năng 1: nhận dạng trực tiếp từ camera.
Chức năng 2: gom nhóm từ video.
Chức năng 3: gom nhóm trực tiếp từ camera.
Chức năng 1: nhận dạng trực tiếp từ camera:
Bước 1: thiết lập dữ liệu mẫu cho chương trình
void defindFaceTrainFormCamera () Thực hiện xác định ảnh khuôn mặt mẫu.
Với mỗi ảnh mẫu sẽ được đặt tên theo thứ tự ảnh khuôn mặt được nhận biết.
Bước 2: Nhận dạng ảnh từ camera:
showCameraRecogniton ();thực hiện việc nhận dạng ảnh trực tiếp từ camera:
chứa hàm int defindFaceTrainFormCamera () ở bước 1
chưa hàm void learn() để phân tích dữ liệu mẫu
Chứa hàm int findNearestNeighbor(float * projectedTestFace, float *pConfidence) để xác định ảnh gần đúng nhât trong dữ liệu mẫu và trả về độ chính xác tương ứng.
Với mỗi ảnh cần xác định sẽ tính toán đưa ra giá trị dự đoán, sau đó xác định ảnh mẫu gần đúng nhất và hiển thị kết quả cùng độ chính xác đạt được.
Chức năng 2 :gom nhóm từ video.
Bước 1: Thực hiện dọc video:
void createFaceAndImageFormVideo(char* fileNameVideo); đọc dữ liệu từ file video truyền vào, trả về danh sách các ảnh(frame) đọc từ video có chưa mặt người, và danh sách các ảnh khuôn mặt người trong toàn video.
Bước 2:Thực hiện khởi tạo mẫu ảnh.
initGroup (); Khởi tạo ban đầu có ít nhất 3 nhóm để phân biệt.
Ban đầu mỗi nhóm chỉ có 1 ảnh duy nhất, 3 ảnh khuôn mặt đầu tiên sẽ tương ứng với 3 nhóm đầu tiên(có thể 3 ảnh khuôn mặt có thể là 1 người).
Bước 3: Thực hiện việc nhóm ảnh:
void groupFace(); gom nhóm các ảnh khuôn mặt lại với nhau, thực hiện xác định ảnh khuôn mặt tương ứng với ảnh frame của video.
Thực hiện trình tự xử lý giống bước 2 của chức năng 1, tuy nhiên với mỗi bức ảnh sau khi xác định được ảnh mẫu gần đúng và độ chính xác tương ứng thì sẽ được so sánh với độ chính xác Tngưỡng . Nếu độ chính xác >Tngưỡng thì xác nhận ảnh vào nhóm với ảnh gần nhất tìm được, nếu không thì xác nhận ảnh này là thuộc 1 nhóm mới, thêm ảnh này vào bộ dữ liệu mẫu và tính toán lại dữ liệu mẫu.
Bước 4: thực hiện show các bức ảnh (frame) có khuôn mặt trong cùng 1 nhóm :
Với mỗi nhóm ta thực hiện void initShowGroup() để show ảnh từng nhóm theo chỉ số, trả về số ảnh có trong nhóm.
Chức năng 3 :gom nhóm từ camera.
Giống như chức năng 2; chỉ khác ở bước thứ 1: thay vì đọc các ảnh (frame) từ video ta đọc các ảnh(frame) trực tiếp thu từ camera.
Chi tiết chương trình.
Nhận dạng trực tiếp từ camera:
Gom nhóm từ video:
Gom nhóm trực tiếp từ camera:
Đánh giá chương trình.
Sau khi chạy thử chương trình với dữ liệu vào là 1 đoạn video chúng ta có kết quả sau:
Input : Video
Đọc được 51 frame
Nhận diện được 103 face trong 51 fram trên.
Thực tế có 4 khuôn mặt được nhận biết
.
Output: Group Face
Nhận biết được 6 group
Trong đó có 2 nhóm group giống khuôn mặt
Thời gian chạy lâu ~ 2ph đối với video trên.
Đánh giá :
Mới chỉ thực hiện nhận diện qua file haarcascade_frontalface_alt.xml nên chỉ đưa ra kết quả không thực sự chuẩn xácè có thể kết hợp với việc nhận diện mắt, mắt có kính…..
Do việc thực hiện lâu nên chưa thực hiện quay ảnh nên sai lệch bị lớn.
Thực tế cho thấy việc phân nhóm chưa thực sự chuẩn xác với độ tin cậy 40%;
Hàm findNearestNeighbor(…..) chưa thực sự cho độ tin cậy như mong muốn.
Thực tế OpenCV cung cấp file haarcascade_frontalface_alt.xml cho việc nhận diện khuôn mặt chưa thực sự phù hợp vì thỉnh thoảng vẫn nhận diện lỗi khuôn mặt.
Tài liệu tham khảo
Bài giảng xử lý ảnh – gv Hoàng Văn Hiệp
ww.codeproject.com/KB/audio-video.
Các file đính kèm theo tài liệu này:
- Bài tập lớn môn xử lý ảnh- Extract face sequences from video.docx