TỔNG QUAN PHÁT HIỆN MẶT NGƯỜI
Tổng quan
Lĩnh vực nhận dạng đang dành được nhiều sự quan tâm trong giai đoạn hiện nay.
Nó được ứng dụng trong các hệ thống giám sát, an ninh, trong các máy tính thế hệ mới mà con người có thể tương tác với máy tính qua cử chỉ hoặc lời nói,… Nhận dạng mặt người là một trong số đó Và phát hiện mặt người là một khâu tiền xử lý cho nhận dạng mặt người Ý tưởng của nó là: từ một ảnh chụp cảnh đám đông, ta phải tách ra được các khuôn mặt trong đó Các khuôn mặt được tách ra sẽ được chuyển cho khâu nhận dạng.
Có nhiều hướng tiếp cận và các phương pháp khác nhau trong phát hiện mặt người. Cũng có nhiều cách phân chia, gom nhóm khác nhau Sau đây la một số hướng tiếp cận:
Giải pháp dựa trên mô hình (top-down model-based approach): trong hướng tiếp cận này, người ta sử dụng các mô hình mặt người khác nhau có tỉ lệ khác nhau từ thô nhất đến tốt nhất Đầu tiên, ảnh sẽ được quét bởi mô hình có tỉ lệ thô nhất Sau đó ảnh được quét với mô hình có tỉ lệ tốt hơn Và cuối cùng được quét với mô hình có tỉ lệ tốt nhất Ứng với mỗi tỉ lệ chỉ có 1 mô hình khuôn mặt Mà 1 mô hình khuôn mặt ứng với 1 góc nhìn khuôn mặt cụ thể.
Do đó, nhìn chung, phương pháp này khó khăn trong việc đưa vào nhiều góc nhìn khuôn mặt khác nhau.
Giải pháp dựa trên đặc trưng (bottom-up feature-based approach): trong hướng tiếp cận này, người ta sẽ tiến hành tìm kiếm trong ảnh các đặc trưng của khuôn mặt (như mắt, mũi, miệng,…), sau đó gom nhóm chúng lại với nhau (dựa trên mối quan hệ hình học giữa chúng) tạo thành các ứng cử viên cho khuôn mặt Giải pháp này có thể dễ dàng mở rộng cho nhiều góc nhìn khuôn mặt khác nhau.
Giải pháp dựa trên bề mặt (texture-based approach): trong hướng tiếp cận này, các khuôn mặt được phát hiện dựa trên sự phân bố không gian các mức xám của các điểm trong ma trận ảnh con Phương pháp này khó mở rộng cho nhiều góc nhìn. khuôn mặt Sau khi huấn luyện xong, sẽ được dùng vào nhận ra khuôn mặt. Ảnh sẽ được quét bằng 1 cửa sổ Tại mỗi vị trí cửa sổ, nội dung ảnh được lấy ra (có thể phải thay đổi tỉ lệ (co, giãn) vì các ảnh được huấn luyện có kích thước như nhau và xác định) và được cho qua bộ lọc mạng nơron Nhìn chung, phương pháp này cho kết quả tốt Tuy nhiên tốn thời gian huấn luyện và sưu tầm mẫu.
Giải pháp dựa trên màu sắc (color-based approach): trong giải pháp này, đầu tiên người ta xác định các điểm trong ảnh có màu giống màu da mặt Sau đó, người ta khoanh vùng các điểm đó lại Các vùng này có thể là khuôn mặt hoặc không Để xác định có phải là mặt không, có thể dựa vào tỉ lệ kích thước của vùng có tương tự tỉ lệ khuôn mặt không, hoặc dựa vào tỉ lệ số điểm màu da trong hình chữ nhật bao vùng đó,…
Giải pháp dựa trên chuyển động (motion-based approach): ngay cái tên của nó cũng cho thấy giải pháp này chỉ áp dụng phát hiện mặt người trong phim, không áp dụng cho ảnh tĩnh Từ các đối tượng chuyển động trong ảnh, dựa trên một số tiêu chí, người ta sẽ xác định được vùng mặt Ví dụ như một cái lắc đầu, hay nháy mắt sẽ là cơ sở để phát hiện khuôn mặt.
Trong thực tế, ngoài những phương pháp đơn thuần đi theo một hướng tiếp cận, thì cũng có những phương pháp kết hợp nhiều hướng tiếp cận để cho ra kết quả chính xác hơn, tuy nhiên cũng phải trả giá về thời gian Trong đồ án này, em chỉ đi vào tìm hiểu các phương pháp phát hiện mặt người theo hướng dựa trên đặc trưng và dựa trên màu sắc.
Trong các phương pháp phát hiện mặt người, các tác giả thường sử dụng nhiều hệ màu khác nhau Do đó, đầu tiên em xin trình bày về một số hệ màu được sử dụng trong các phương pháp phát hiện mặt người.
Giới thiệu về một số hệ màu
Trong phát hiện mặt người, người ta thường không sử dụng hệ màu RGB, mà thường sử dụng các hệ màu khác như: HSV, HSL, YCrCb Vì những hệ màu này biểu diễn màu sắc giống với quan điểm nhìn màu sắc của con người Sau đây, ta sẽ đi vào diễn đạt chi tiết một số hệ màu cụ thể.
HSV (còn có tên gọi khác là HSB) là viết tắt của Hue, Saturation, Value Hệ màu gồm 3 thành phần H, S, V Trong hệ màu này, các màu đều được biểu diễn dựa trên
H là viết tắt của Hue, nghĩa là màu sắc Thành phần này biểu diễn màu sắc vốn có của màu như: đỏ, xanh da trời, da cam,… Nó có giá trị từ 0 đến 360 o Hình sau minh họa giá trị của H và màu tương ứng:
Hình 1.1: Mô hình biểu diễn 2 thành phần màu H,S trong HSV Ở trong hình, các giá trị của H đã được quy về dải [0,6), tương ứng với chia các góc cho 60 độ Việc biểu diễn H trong dải giá trị nào không thành vấn đề.
S là viết tắt của Saturation, nghĩa là độ bão hòa Ta có thể hiểu nó giống như khái niệm nồng độ trong hóa học, với dung môi là màu trắng và chất tan là màu S có giá trị nằm trong đoạn [0,1] Khi giá trị của S lớn, lượng màu hòa trong màu trắng nhiều lên, màu sẽ đậm hơn S=1, màu đậm nhất, chiếm hoàn toàn màu trắng Và ngược lại, khi giá trị S nhỏ, lượng màu hòa trong màu trắng ít đi, màu sẽ nhạt hơn. S=0 tương ứng với không có một chút màu nào pha trong màu trắng, kết quả sẽ không có màu (cũng không khẳng định ngay kết quả là màu trắng, vì nó còn phụ thuộc vào thành phần V nữa, nhưng có thể khẳng định nó là màu xám) Ví dụ: khi H=0, ta có màu đỏ Nhưng không phải cứ H=0 là ta có được 1 màu đỏ đậm đà, nó còn phụ thuộc vào S (tức là phụ thuộc vào lượng màu đỏ hòa trong màu trắng) Khi
S nhỏ, ta có màu đỏ nhạt Khi S lớn ta có màu đỏ đậm hơn S=1 màu đỏ đậm nhất. Khi S=0, giá trị của H bằng bao nhiêu là vô nghĩa, kết quả cũng chỉ là 1 màu trắng (giả sử V=max).
Thành phần V là viết tắt của value, nó biểu thị thành phần độ sáng V có giá trị nằm trong đoạn [0,1] Bạn mặc 1 chiếc áo hồng, nhưng nếu bạn đứng trong bóng tối, mọi người sẽ chỉ nhìn thấy chiếc áo màu đen Vai trò của V là như vậy Với 1 giá trị H xác định, ta có 1 màu xác định Với giá trị S, ta có được độ đậm nhạt cho màu đó. Nhưng ta sẽ không thể cảm nhận đúng màu đó với độ đậm nhạt đó, nếu độ sáng không chuẩn Khi V=1 ta mới cảm nhận được đúng bản chất vốn có của màu Khi V tăng tương ứng với độ sáng tăng dần V=0: không có ánh sáng, tất cả chỉ là 1 màu đen với mọi H và S Như ở trên, ta đã nói, khi S=0 thì màu kết quả không phụ thuộc vào H, nhưng chưa thể nói ngay ta có màu trắng vì còn phụ thuộc vào V Nếu V=0 ta có màu đen, V=1 ta có màu trắng, còn nếu 0” nằm dưới khung ảnh. Hoặc có thể sử dụng các phím mũi tên trái, phải trên bàn phím File nào không phải là file ảnh thì sẽ hiện thị 1 ảnh thông báo lỗi:
Hình 3.3: Ảnh báo lỗi khi mở file không phải là file ảnh Để lấy khuôn mặt, ta dùng chuột khoanh vùng khuôn mặt:
Hình 3.4: Minh họa khoanh vùng mặt
Sau khi khoanh vùng rồi, ta nhấn vào nút “Lưu khuôn mặt”, khuôn mặt đó sẽ được lưu vào file (đuôi bmp, ảnh bitmap 24bpp) ở một thư mục xác định Sau khi nhấn nút đó xong, khung xanh bao khuôn mặt sẽ biến mất, thể hiện việc lưu thành công.Thay vì nhấn nút lưu khuôn mặt, ta có thể nhấn phím Enter trên bàn phím để thực hiện chức năng tương đương Về thư mục chứa file khuôn mặt, vị trí của nó như sau: khi chọn 1 thư mục ảnh để duyệt, ta sẽ tạo ra trong thư mục đó một thư mục con có tên là CacKhuonMat Các khuôn mặt sẽ được cất trong đây, mỗi khuôn mặt
1 file Tên các file khuôn mặt được đặt theo quy cách: tên file ảnh chứa khuôn mặt + chỉ số của khuôn mặt trong file
Trong tổng hợp histogram, để đảm bảo sự ngẫu nhiên, khách quan thì ta cần tránh sự trùng lặp ảnh Trong 1 thư mục ảnh với số lượng ảnh lớn, ta có thể không duyệt hết được trong 1 ngày làm việc, mà phải thực hiện tiếp vào hôm sau Sang ngày hôm sau, khi mở lại thư mục ảnh đó, rất khó có thể nhớ được file ảnh nào ta đã lấy khuôn mặt rồi, file ảnh nào chưa Ta có thể nghĩ đến giải pháp như ghi lại tên các file đã duyệt rồi, nhưng như vậy danh sách có thể dài, ghi rất mệt và mỗi lần nghi ngờ 1 file nào đó, lại phải đối chiếu lại danh sách dài đó Rõ ràng là không hợp lý. Hoặc ta có thể thực hiện cách đơn giản hơn là mỗi file duyệt xong, ta sẽ vào thư mục đó và thực hiện chuyển nó sang một thư mục khác Và thư mục sẽ chỉ còn lại các file chưa duyệt Ý tưởng là hợp lý nhưng thao tác “Cut” từng file một rất vất vả khi số lượng nhiều Do đó, chương trình đưa thêm chức năng cất file ảnh, thực hiện chuyển file ảnh đã duyệt sang 1 thư mục khác, để tránh duyệt lại Để thực hiện chức năng này, sau khi lấy hết các khuôn mặt trong ảnh rồi, chỉ việc nhấn nút “Cất ảnh” (hoặc nhấn phím Delete trên bàn phím), file ảnh đang làm việc sẽ tự động được chuyển đến 1 thư mục xác định Nếu lưu thành công, form sẽ hiển thị ảnh khác trong danh sách.
Về thư mục chứa các file ảnh đã duyệt: khi chọn 1 thư mục ảnh, ta sẽ tạo ra trong thư mục đó 1 thư mục con có tên là “DaDuyet” Đây chính là thư mục sẽ chứa các file đã duyệt sau khi nhấn nút “Cất ảnh”.
3.1.4.2 Lấy khuôn mặt từ file phim Đầu tiên ta sẽ phải mở 1 file phim bằng cách nhấn nút “Mở file phim” Sẽ có 1 hộp thoại bật ra cho ta chọn file phim Sau khi file phim được chọn, sẽ hiển thị frame đầu tiên của phim Chỉ số frame được ghi trên thanh tiêu đề của form. Để di chuyển qua các frame, ta cũng sử dụng các phím mũi tên “” và “ >” như đối với duyệt thư mục ảnh Tuy nhiên chương trình cũng cung cấp thêm một bộ điều khiển hỗ trợ duyệt file phim đó là nhảy đến vị trí 1 frame xác định.
Hình 3.5: Các điều khiển trên form dùng cho di chuyển frame trong phim
Ta nhập chỉ số frame muốn đến vào ô text box, rồi nhấn nút “Đi”, chương trinh sẽ hiển thị frame có chỉ số đó Lý do của việc đưa ra chức năng này là: trong 1 file phim thường có rất nhiều frame, hàng trăm frame Trong 1 buổi làm việc, có thể ta không di chuyển qua hết được các frame để lấy các khuôn mặt Công việc được tiếp tục vào ngày hôm sau, nếu chỉ có các mũi tên, ta sẽ phải nhấn nhiều lần để di chuyển đến frame kết thúc của ngày hôm qua, vì vậy chức năng này được xây dựng để thuận tiện trong tình huống này (ta có thể nhập chỉ số frame dừng của ngày hôm qua, và nhấn nút “Đi”, lập tức sẽ nhảy ngay đến vị trí đã dừng của ngày hôm qua). Để lưu các khuôn mặt, ta cũng thực hiện như đối với file ảnh, cũng dùng chuột khoanh vùng khuôn mặt, rồi nhấn nút “Lưu khuôn mặt” hoặc nhấn phím Enter trên bàn phím để thực hiện lưu nó Vị trí đặt các khuôn mặt như sau: khi ta chọn 1 file phim, chương trình sẽ tạo 1 thư mục trong cùng thư mục chứa file phim đó có tên là: CacKhuonMat Các khuôn mặt được lấy ra sẽ được lưu trong này.
Vì chỉ có 1 file phim, nên không có chức năng cất file phim như đối với duyệt thư mục.
Công cụ tổng hợp histogram
Công cụ này được xây dựng để tổng hợp và chuẩn hóa histogram từ một tập ảnh màu da được chuẩn bị trước, để phục vụ cho công tác phát hiện màu da sau này.
Công cụ này có chức năng giống như một bộ soạn thảo histogram Nó cho phép:
Mở 1 histogram đã tồn tại (đã được tổng hợp một phần từ lần trước, nay mở ra để tổng hợp tiếp).
Thêm các ảnh vào histogram.
Lưu và lưu mới histogram.
Giao diện của chương trình như sau:
Giao diện khi mới chạy chương trình:
Hình 3.6: Giao diện công cụ tổng hợp histogram khi khởi động chương trình
Giao diện khi đang soạn thảo 1 histogram:
Phía bên phải là dãy các button thực hiện các chức năng Cửa sổ trắng ở giữa là list box dùng hiển thị danh sách các file ảnh đã duyệt qua trong quá trình tổng hợp histogram Dòng text bên dưới cửa sổ cho biết histogram đang xây dựng đã có bao nhiêu điểm ảnh rồi (đó là tổng số điểm của tất cả các file ảnh đã duyệt qua khi tổng hợp histogram).
3.2.4 Chi tiết các chức năng Để tạo mới 1 histogram, nhấn vào nút “Tạo mới” Khi đó, chương trình sẽ bật hộp thoại Save file để chọn nơi chứa và đặt tên file chứa histogram File này có đuôi là hir Về bản chất, file này chỉ là 1 file text Dòng đầu tiên trong file text là tổng số điểm ảnh đã duyệt qua Sau dòng này là một ma trận lưu kết quả tổng hợp histogram Cuối cùng là các dòng lưu đường dẫn đến các nơi chứa các file ảnh đã duyệt rồi.
Nếu ta đã sẵn có 1 file histogram rồi, bây giờ muốn mở ra để tổng hợp tiếp thì nhấn vào nút “Mở” Chương trình sẽ mở 1 hộp thoại cho ta chọn file đó. Để thêm các ảnh vào histogram (duyệt qua các ảnh khác), ta nhấn nút “Thêm vào”. Chương trình sẽ bật ra 1 hộp thoại cho ta chọn thư mục chứa các file ảnh Tại sao lại là thư mục chứa ảnh mà không phải là các file ảnh riêng rẽ? Vì nếu cứ mở từng file ảnh riêng rẽ một sẽ rất mất thời gian vì số lượng ảnh của ta nhiều (trên 200 file). Đồng thời ở bước trước (lấy các khuôn mặt) ta đã đặt tập trung các khuôn mặt vào 1 thư mục rồi.
Sau khi chọn xong, chương trình sẽ thực hiện duyệt qua các file ảnh trong thư mục để thêm vào histogram Mỗi file được duyệt sẽ được hiện lên trên form, trong list box Nếu file được duyệt không phải là file ảnh sẽ có dòng thông báo lỗi ngay bên dưới dòng hiện tên file đó trong list box.
Hình 3.8: Giao diện khi thêm ảnh vào histogram
Như ta đã biết trong file chứa histogram có lưu cả các thư mục đã duyệt rồi Bởi vì như đã nói, khi tổng hợp histogram cần tránh trùng lặp file Do đó, ta lưu lại đường dẫn đến các thư mục đã duyệt để hạn chế sự trùng lặp này Khi chọn 1 thư mục, nếu nó trùng với 1 trong các thư mục đã duyệt rồi, chương trình sẽ hiện thị thông báo hỏi ý kiến xem có muốn tiếp tục tổng hợp không? (phải hỏi vì có thể vẫn là thư mục đó, nhưng nội dung có thể đã khác rồi) Nếu câu trả lời là KHÔNG thì sẽ bỏ qua, không làm gì cả Nếu là CÓ thì sẽ tiến hành duyệt qua các file trong thư mục để đưa vào histogram.
Dấu * ở trên list box (góc trái), cho ta biết rằng histogram đang mở chưa được lưu. Để lưu histogram đang mở, ta nhấn vào nút “Lưu” Sau khi lưu xong, dấu * sẽ mất đi Quá trình lưu là quá trình ghi lại histogram từ bộ nhớ vào file.
Tổng hợp histogram là thao tác rất tốn kém và không phải chất lượng tốt dần lên, vì nó còn phụ thuộc vào ảnh mẫu Do đó, histogram hiện tại tốt cho phát hiện màu da, nhưng sau khi tổng hợp thêm một số ảnh màu da nữa, histogram thu được có thể lại phát hiện màu da kém đi Điều này là có thể nếu các ảnh được tổng hợp tiếp là không tốt Vì thế để an toàn ta có thể phải lưu bản histogram cũ ra 1 file khác rồi sau đó mới thêm các ảnh mới vào Để hỗ trợ điều này, chương trình có đưa thêm chức năng “Lưu mới” để lưu histogram đang tổng hợp thành 1 file khác, không xóa mất kết quả tổng hợp trước đó.
Histogram được sử dụng trong phát hiện màu da không phải là histogram với các cột là các số nguyên, mà là histogram được chuẩn hóa, tức là chia số điểm trong mỗi cột cho tổng số điểm ảnh đã duyệt Khi đó, các cột có giá trị là các số thực có giá trị trong dải [0; 1) Để thực hiện chuẩn hóa histogram, nhấn vào nút “Chuẩn hóa” trên form Chương trình sẽ tiến hành chuẩn hóa histogram hiện hành.Histogram được chuẩn hóa sẽ được lưu trong 1 file có đuôi là hin Vị trí và tên của file ta sẽ được yêu cầu nhập vào sau khi nhấn “Chuẩn hóa” Sau khi chuẩn hóa xong, sẽ hiện hộp thoại thông báo thành công hoặc thất bại.
XÂY DỰNG CHƯƠNG TRÌNH VÀ MỘT SỐ KẾT QUẢ
Mục đích
Mục đích của chương trình này là phát hiện ra các mặt người trong ảnh hoặc trong các frame (từ camera hoặc file phim) rồi lưu chúng vào một nơi xác định để phục vụ cho các công tác sau này (nhận dạng hoặc học khuôn mặt, ).
Các chức năng
Chương trình hỗ trợ phát hiện mặt người trong các nguồn sau:
Với đầu vào file ảnh, chương trình có các chức năng:
Tìm các khuôn mặt trong ảnh.
Lưu các khuôn mặt tìm được vào 1 thư mục xác định.
Với đầu vào file phim, chương trình có các chức năng:
Các chức năng cho chạy, tạm dừng và stop file phim Cho phép di chuyển ngẫu nhiên đến các vị trí bất kì trong phim bằng thanh trượt giống như trong các công cụ media như Window Mediaplayer chẳng hạn.
Cho phép vừa phát phim vừa tìm mặt hoặc thực hiện tìm mặt trong một frame cụ thể.
Thực hiện lưu mặt tự động khi phát hiện được mặt Chức năng này có thể được bật tắt để linh hoạt khi không muốn lưu mặt.
Trong trường hợp đầu vào là camera (xử lý online, các frame được thu về được xử lý ngay, được dò mặt ngay), chương trình có các chức năng sau:
Cũng như file phim, nó cũng cho phép vừa phát camera vừa tìm mặt, hoặc tìm mặt trên 1 frame khi camera đang dừng Mặt tìm được có thể được lưu tự động vào một nơi xác định hoặc không lưu, tùy theo ta thiết lập.
Trong trường hợp nhiều camera, chương trình cho phép chọn camera đầu vào Camera được chọn, hình ảnh thu được của nó sẽ được phát lên form và được tìm mặt.
Trong thuật toán phát hiện mặt người có sử dụng nhiều tham số Không có bộ tham số tốt trong mọi trường hợp Do đó, trong các trường hợp khác nhau cần thay đổi tham số để đạt kết quả tốt nhất có thể Vì vậy, chương trình có chức năng cho phép thiết lập các tham số đó, để linh hoạt trong các trường hợp khác nhau Các tham số cần thiết lập như: file histogram, các tham số trong tiêu chuẩn màu da, tỉ lệ khuôn mặt, thư mục lưu trữ các khuôn mặt tìm được,
Giao diện chương trình
Từ các chức năng được yêu cầu ở trên, ta tiến hành xây dựng giao diện chương trình Vì chương trình có 3 đầu vào, và với các đầu vào khác nhau, chương trình có các chức năng khác nhau phù hợp với từng loại đầu vào, do đó giao diện cũng khác nhau với từng đầu vào.
Giao diện với đầu vào file ảnh:
Hình 4.2: Giao diện chương trình với đầu vào là file phim
Giao diện ứng với đầu vào là camera:
Hình4.3: Giao diện chương trình với đầu vào camera
Các kĩ thuật xử lý
Ta sử dụng thư viện sẵn có là Aforge.Net để thực hiện thu hình từ camera vào máy tính Thư viện này chỉ điều khiển được các camera local, tức là các camera nối trực tiếp với máy tính chạy chương trình này, chứ không điều khiển được các camera nối với các máy tính khác trong mạng máy tính (remote camera). Đây là thư viện viết trên C# Trong C# có một khái niệm là namespace, nó chứa một tập các lớp có liên quan hoặc các namespace khác AForge là 1 namespace như vậy Nó chứa nhiều namespace trong nó như: AForge.Imaging, AForge.Video.DirectShow, AForge.Video, … dùng cho xử lý ảnh và video (mở file video hoặc thu từ camera).
Trong thư viện này, để thực hiện thu hình từ camera, ta sử dụng thư viện AForge.Video.DirectShow Trong thư viện này có các lớp phục vụ cho việc phát hiện ra các thiết bị camera gắn vào máy tính, thực hiện khởi động và tắt các camera. Các lớp đó như sau:
FilterInfoCollection: dùng phát hiện ra các thiết bị camera gắn với máy tính Nó là một mảng các đối tượng FilterInfo, mỗi đối tượng này chứa thông tin về 1 thiết bị camera được phát hiện ra.
VideoCaptureDevice: đây là lớp trực tiếp điều khiển thiết bị camera, như cho chạy, dừng, lấy về các frame.
FilterCategory: lớp này định nghĩa các nguồn video khác nhau như từ file hay từ thiết bị camera.
Trình tự thực hiện thu hình từ camera khi sử dụng thư viện này như sau:
1 Dò xét xem có thiết bị camera được gắn với máy tính không.
FilterInfoCollection videoDevices = new FilterInfoCollection( FilterCategory.VideoInputDevice );
Thuộc tính videoDevices.Count cho biết có bao nhiêu thiết bị camera đang được nối với máy tính Nếu nó bằng 0 có nghĩa là không có thiết bị nào cả.
2 Tạo 1 đối tượng VideoCaptureDevice gắn với 1 camera được chọn, để điều khiển nó.
VideoCaptureDevice videoSource = new VideoCaptureDevice( videoDevices[0].MonikerString );
Trong ví dụ này ta đã chọn điều khiển camera số 0 MonikerString là xâu đặc tả về thiết bị camera được chọn.
3 Cho chạy camera. Đơn giản chỉ cần gọi phương thức Start của đối tượng VideoCaptureDevice vừa tạo. videoSource.Start( );
Khi gọi phương thức này, hệ thống sẽ sinh ra 1 tiến trình ngầm Tiến trình này sẽ liên tục gửi các frame hình ảnh thu được từ camera cho chương trình.
Sau 2 lời gọi này, tiến trình ngầm sẽ chấm dứt hoạt động và camera cũng dừng hoạt động.
5 Nhận về các frame khung hình Đây là điều mà chúng ta quan tâm nhất Khi có được frame chúng ta có thể làm bất kì điều gì chúng ta muốn lên frame đó Để thực hiện điều này, ta cần đăng kí sự kiện NewFrame của đối tượng VideoCaptureDevice Thực hiện như sau: videoSource.NewFrame += new NewFrameEventHandler( video_NewFrame ); private void video_NewFrame( object sender, NewFrameEventArgs eventArgs )
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone();
// xử lý frame nhận được tại đây
Kiểu delegate NewFrameEventHandler và lớp NewFrameEventArgs được khai báo trong thư viện AForge.Video (một phần của AForge, đã nói qua ở trên), chứ không có trong AForge.Video.DirectShow.
4.4.2 Phát 1 file phim Để phát một file phim đầu tiên cần lấy ra các frame, sau đó phát các frame tuần tự lên form, mỗi frame duy trì trong 1 khoảng thời gian xác định.
Ta có thể dùng lớp FileVideoSource của AForge để phát file phim Nó cũng tương tự như thu hình từ camera, có sự kiện NewFrame, ta sẽ đăng kí một hàm cho sự kiện này Trong hàm xử lý của sự kiện này, ta sẽ lấy về các frame và xử lý nó Tuy nhiên, nó có nhược điểm là không truy nhập được ngẫu nhiên lên các frame, mỗi lần chạy là chạy từ đầu, không tạm dừng được Vì vậy ta chuyển sang sử dụng thư viện DirectShow để có thể truy nhập ngẫu nhiên lên các frame Tuy nhiên, nó cũng có nhược điểm là ta phải tự làm quá trình phát phim, vì các frame do ta lấy ra một cách thủ công Việc thực hiện phát phim cũng không phức tạp, ta chỉ cần dùng 1 timer với thuộc tính Interval thích hợp, và xử lý sự kiện Tick của nó (trong chương trình, khoảng thời gian timer là 35ms).
Trước khi lấy frame trong file phim dùng DirectShow, ta phải khởi tạo cho phim đó. Quá trình khởi tạo nhằm mục đích kiểm tra xem file đưa vào có dòng video không (có phải là file phim không) và lấy về các thông tin của phim như kích thước các frame trong phim.
Ta sử dụng interface IMediaDet (thuộc namespace DirectShowLib.DES) Từ Det là viết tắt của Detector Quá trình khởi tạo thực hiện các bước sau:
Tạo 1 đối tượng MediaDet và cho một tham chiếu kiểu interface IMediaDet tham chiếu đến nó.
Gán tên file cần phát vào trong đối tượng đó.
Kiểm tra xem trong file đó có dòng video không (video stream).
Lấy về thông tin về dòng video đó như kích thước thực của các frame.
Thực hiện cụ thể các bước như sau:
* Tạo đối tượng MediaDet: Để có thể sử dụng lớp MediaDetm cần using namespace: DirectShowLib.DES: using DirectShowLib.DES;
Sau đó tạo một thể hiện của lớp MediaDet bằng hàm tạo không đối và cho 1 tham chiếu có kiểu interface IMediaDet tham chiếu đếnn nó:
IMediaDet imd; imd = (IMediaDet)new MediaDet();
Muốn giải phóng đối tượng MediaDet, thực hiện như sau: if (imd != null)
Marshal.ReleaseComObject(imd); imd = null;
(lớp Marshal nằm trong namespace System.Runtime.InteropServices).
* Đặt tên file cần phát vào trong đối tượng:
Gọi phương thức put_Filename của interface IMediaDet: imd.put_Filename(tenfile);
(tenfile là đường dẫn đến file phim muốn phát).
* Kiểm tra xem trong file có dòng video không: Đầu tiên cần lấy về số lượng dòng (stream) có trong file: int sodong;//so stream trong file kq = imd.get_OutputStreams(out sodong);
Sau đó, duyệt qua các dòng, thực hiện truy vấn trên các dòng để xem có dòng nào có thông tin video không: Để lấy thông tin về một dòng thì đầu tiên phải đưa dòng đó trở thành dòng hiện hành: imd.put_CurrentStream(i); với i là chỉ số dòng đang xét.
Lấy thông tin về dòng như sau:
* Lấy về thông tin video (kích thước frame):
Lúc này, dòng hiện tại đang là dòng video, vì khi kiểm tra xem có dòng video trong file không, nếu thấy có dòng video thì ta dừng luôn, không kiểm tra nữa Thực hiện lấy thông tin như sau:
AMMediaType amkieu = new AMMediaType(); imd.get_StreamMediaType(amkieu);
Mã nguồn đầy đủ cho khởi tạo phim: private void KhoiTaoPhim(string tenfile)
{ //thuc hien cac buoc can thiet de khoi
//thuc hien tao ra mediadet moi int kq;
//kiem tra xem da co the hien cua imd chua, neu roi
//thi giai phong no truoc if (imd != null)
Marshal.ReleaseComObject(imd); imd = null;
//tao lai imd = (IMediaDet)new MediaDet(); if (imd == null)
Exception("Không tạo được đối tượng
//dua file vua nhan duoc vao doi tuong do kq = imd.put_Filename(tenfile); if (kq != 0) //co loi
{ throw new Exception("file phim không hợp lệ!");
//kiem tra xem no co phai la file video khong int sodong;//so stream trong file kq = imd.get_OutputStreams(out sodong); if (kq != 0)
Exception("Không đếm được số stream trong file!");
//chay qua cac dong de xem co dong video khong int i; bool co = false; //cho biet co video stream khong Guid kieu; for (i = 0; i < sodong; i++)
{ kq = imd.put_CurrentStream(i); if (kq != 0)
Exception("Không chọn được stream!"); }
//nhan ve kieu media cua dong hien tai kq = imd.get_StreamType(out kieu); if (kq != 0)
Exception("Không lấy được kiểu stream!");
//kiem tra kieu vua nhan ve if (kieu == MediaType.Video)
//kiem tra ket qua thu duoc if (!co)
{ throw new Exception("Trong file không có video");
//luc nay dang dung o stream video
//nhan ve chieu rong, cao cua cac frame
AMMediaType amkieu = new AMMediaType(); rong_video = cao_video = 0; kq = imd.get_StreamMediaType(amkieu); if (kq != 0)
Exception("Không lấy được nội dung
//kiem tra kieu co chuan khong if (amkieu.formatType == FormatType.VideoInfo
//chuyen thanh doi tuong lop videoinfoheader Marshal.PtrToStructure(amkieu.formatPtr, vih); rong_video = vih.BmiHeader.Width; cao_video = vih.BmiHeader.Height; if (cao_video < 0) cao_video = -cao_video;
Marshal.FreeCoTaskMem(amkieu.formatPtr); amkieu.formatPtr = IntPtr.Zero;
{ throw new Exception("MediaType không chuẩn!"); }
4.4.2.2 Lấy frame Để lấy frame, ta dùng hàm GetBitmapBits của IMediaDet Hàm này có 5 tham số là:
Vị trí frame Hàm này coi toàn bộ phim là 1 dòng thời gian, là một dãy các frame liên tục điền vào khoảng thời gian đó (chứ không phải là 1 tập các frame rời rạc lưu trong file), và ta sẽ lấy ra 1 frame tại 1 thời điểm nào đó Vì vậy nó có kiểu thực chứ không phải kiểu nguyên Đây là thời điểm (tính theo giây), chứ không phải là chỉ số frame.
Kích thước của bộ đệm chứa frame Khi con trỏ tới bộ đệm là NULL thì tham số này là đầu ra cho biết cần bao nhiêu bộ nhớ để chứa được frame đó.
Con trỏ đến bộ đệm chứa frame.
Chiều rộng, cao của frame lấy ra Nếu ta đặt kích thước này khác với kích thước thực của frame trong file thì frame sẽ bị co giãn cho vừa với kích thước đưa ra đó.
Các lớp được xây dựng
Lớp này được xây dựng là để chuyển đổi qua lại giữa các hệ màu YCrCb và RGB, phục vụ cho thực hiện công thức xác định màu da trên hệ màu YCrCb như đã trình bày ở chương 2 Như đã nói YPrPb là hình thức analog của hệ màu YCrCb YPrPb là các số thực, còn YCrCb là các số nguyên được rời rạc hóa từ YPrPb. Để chuyển từ RGB sang YPrPb theo chuẩn BT601, chỉ cần tạo 1 đối tượng YPrPb với hàm tạo có đối là các giá trị r, g, b:
Sau đó truy vấn các thuộc tính Y, Pr, Pb để lấy ra các thành phần màu tương ứng được chuyển đổi.
Lớp này chỉ có 3 thuộc tính là Y, Pr, Pb, đều có kiểu là kiểu số thực, tương ứng với
3 thành phần màu của hệ YPrPb.
Thực hiện gán 0 cho cả 3 thuộc tính y, pr, pb.
* YPrPb(double gt_y, double gt_pr, double gt_pb)
Thực hiện gán cho các thuộc tính y, pr, pb các giá trị tương ứng: gt_y, gt_pr, gt_pb.
* YPrPb(int r, int g, int b,double kb,double kr)
Trong hàm tạo này thực hiện luôn việc chuyển đổi hệ màu từ RGB (với các giá trị r, g, b đầu vào) sang YPrPb và gán lại cho các thuộc tính y, pr, pb Các tham số kb, kr là các tham số trong công thức chuyển đổi hệ màu giữa RGB và YPrPb Giá trị của các tham số này tùy thuộc vào chuẩn được chọn Do đó, hàm này có tính linh động, cho phép chuyển từ RGB sang YPrPb theo bất kì chuẩn nào.
Cũng tương tự như hàm tạo trên, nó thực hiện luôn việc chuyển đổi sang hệ màu YPrPb rồi gán lại cho các thuộc tính Nó khác ở chỗ, chuẩn chuyển đổi là ngầm định (khác với hàm tạo trên, chuẩn chuyển đổi phải nhập vào qua các giá trị kr, kb) Chuẩn được dùng ở đây là: BT601 với kb=0,114; kr=0,299 Tại sao dùng chuẩn này vì trong công thức màu da ta dùng chuẩn này, nên xây dựng hàm này cho thuận tiện.
* static void TinhPrPb(int r, int g, int b, out double _pb, out double _pr)
Phương thức tĩnh (gắn với lớp, gọi từ lớp mà không cần tạo bất kì đối tượng nào của lớp).
Dùng tính giá trị pr, pb từ giá trị r, g, b đưa vào theo chuẩn BT601.
* void RGB(double kb,double kr,out int r, out int g, out int b)
Dùng chuyển đổi từ YPrPb trở lại RGB.
Các giá trị kb, kr đưa vào để xác định chuẩn sử dụng trong công thức chuyển đổi.
* void RGB(out int r, out int g, out int b)
Cũng tương tự như trên, chỉ có điều chuẩn tính là xác định (không có kb, kr trong tham số của hàm) Đó là chuẩn BT601.
Lớp này được xây dựng với mục đích chuyển đổi qua lại giữa 2 hệ màu RGB vàHSV Cần chuyển đổi sang hệ màu HSV là để phục vụ cho công tác tổng hợp histogram trên nền HS và để tính trong chương trình khi xác định màu da.
Lớp này cũng chỉ có 3 thuộc tính là H, S, V tương ứng với các thành phần của hệ màu HSV Chúng đều có kiểu giá trị là kiểu thực: H có giá trị trong đoạn [0; 360), S và V có giá trị trong đoạn [0; 1].
Thực hiện gán cho các thuộc tính h, s, v của lớp các giá trị 0.
* HSV(double gt_h, double gt_s, double gt_v)
Thực hiện gán cho các thuộc tính h, s, v các giá trị tương ứng gt_h, gt_s, gt_v được truyền vào.
Trong hàm tạo này thực hiện luôn việc chuyển đổi các giá trị màu r, g, b trong hệ màu RGB sang HSV và gán kết quả chuyển đổi cho các thuộc tính tương ứng.
* static void TinhHS(int r, int g, int b, out int gt_h, out double gt_s)
Phương thức tĩnh của lớp.
Thực hiện tính các giá trị H, S trong hệ màu HSV tương ứng với màu (r, g, b) đưa vào Nó thực hiện chuyển đổi từ RGB sang HSV, rồi trả về 2 thành phần H và S trong kết quả chuyển đổi.
Mục đích xây dựng hàm này là để thuận lợi trong tổng hợp histogram và trong xác định màu da dựa trên histogram Như đã biết, ta xây dựng histogram trên nền HS, tức là ta chỉ cần tính 2 thành phần H, S này là đủ. Dùng hàm này giúp ta tránh phải tạo đi, tạo lại đối tượng HSV với mỗi lần tính, giúp tăng tốc chương trình.
* void RGB(out int r, out int g, out int b)
Thực hiện chuyển đổi ngược lại từ hệ màu HSV sang RGB.
Lớp này được xây dựng để lưu trữ các thông tin về mỗi vùng trắng tìm được khi duyệt ảnh nhị phân, và cung cấp các phương thức thao tác trên nó như: tính tỉ lệ kích thước cao/rộng, tỉ lệ số điểm trắng, Tên của nó trong chương trình là: VungTrang.
Lớp có 2 thuộc tính là:
int SoDiem: dùng lưu trữ số điểm trắng trong vùng.
Rectangle ToaDo: dùng lưu trữ tọa độ của vùng trắng (là tọa độ của hình chữ nhật bao vùng trắng.
Dùng tạo ra 1 vùng trắng rỗng Nó gán cho thuộc tính SoDiem = 0 và các kích thước rộng, cao trong thuộc tính ToaDo bằng 0.
Dùng tạo 1 vùng trắng với 1 điểm trắng khởi đầu trong vùng Điểm này có tọa độ (x, y) đưa vào qua đối của hàm.
Phương thức này thực hiện thêm 1 điểm trắng vào trong vùng trắng.
Khi thêm 1 điểm trắng, thuộc tính SoDiem chắc chắn sẽ tăng lên 1, còn thuộc tính ToaDo có thay đổi hay không và thay đổi thành phần tọa độ nào trong nó còn phụ thuộc vào vị tương đối của điểm đó với vùng trắng Nếu nó nằm trong khung hình chữ nhật bao vùng trắng thì không cần phải thay đổi.
Phương thức trả về tỉ lệ số điểm trắng trong vùng so với tổng số điểm của vùng (chính là toàn bộ số điểm nằm trong hình chữ nhật bao vùng và bằng rộng x cao).
Phương thức xác định xem tỉ lệ điểm trắng trong vùng có lớn hơn hoặc bằng
1 giá trị ngưỡng đưa ra hay không? Nếu đúng, nó trả về TRUE, nếu sai trả về FALSE.
Đây là phương thức xác định xem tỉ lệ kích thước của vùng trắng có xấp xỉ tỉ lệ vảng với 1 sai số cho phép hay không.
Đầu vào của phương thức là giá trị sai số cho phép.
Đầu ra: phương thức trả về TRUE nếu tỉ lệ kích thước của nó xấp xỉ tỉ lệ vàng, và trả về FALSE nếu sai.
Phương thức tính tỉ số giữa chiều cao và chiều rộng của vùng trắng Nó trả về tỉ số này.
* DLL: đây là lớp xây dựng trong chương trình nên nó không nằm trong dll nào cả.
Mục đích xây dựng lớp này là để xác định các vùng trắng trong ảnh nhị phân Các vùng trắng được xác định bằng thuật toán phân vùng nâng cao Trong lớp này cũng cài đặt cả thuật toán phân vùng bình thường Tên trong chương trình của nó là: BoLocPhanVung.
Lớp có 2 thuộc tính là:
int ChieuDaiCua: dùng để thiết lập ngưỡng kích thước của liên kết yếu.
ArrayList DSVung: dùng trả về danh sách vùng trắng đã tìm được trong ảnh Mỗi phần tử trong danh sách này là 1 đối tượng của lớp VungTrang.
Dùng gán các giá trị mặc định cho các biến.
* unsafe void XDVungNC(byte* p0, int x, int y)
Dùng xác định 1 vùng trắng khi phát hiện ra nó và thêm vùng trắng này vào danh sách vùng trắng.
Thuật toán phân vùng được áp dụng là phân vùng nâng cao, tức là có cài đặt để loại bỏ các liên kết yếu.
p0 là con trỏ đến điểm đầu tiên trong ảnh (điểm có tọa độ (0,0)) x, y là tọa độ của điểm bắt đầu vùng trắng này.
* unsafe void KT_HangXomNC(byte* p0, int x2, int y2,
Dùng kiểm tra xem hàng xóm của điểm đang xét có thỏa mãn điều kiện để đưa vào vùng trắng đang xây dựng không Khi ta lấy 1 điểm ra khỏi hàng đợi, ta sẽ phải duyệt qua các hàng xóm của nó (4 hàng xóm trên, dưới, trái, phải) Với mỗi hàng xóm, ta phải xác định xem có thể đưa nó vào vùng trắng đang xây dựng không Điều kiện để đưa vào là: là điểm trắng, chưa gán nhãn và không nằm trên liên kết yếu Phương thức này sẽ giúp ta thực hiện điều đó.
* unsafe void XDVung(byte* p0, int x, int y)
Phương thức này tương tự phương thức XDVungNC như ở trên Chỉ khác ở chỗ nó bỏ qua việc kiểm tra điều kiện liên kết yếu.
* unsafe void KT_HangXom(byte* p0, int x2, int y2,
Cũng như KT_HangXomNC, khác ở chỗ, trong các điều kiện kiểm tra hàng xóm không có điều kiên kiểm tra có thuộc liên kết yếu không, chỉ kiểm tra xem có phải là điểm trắng và đã gán nhãn chưa thôi.
Việc giảm bớt điều kiện kiểm tra sẽ tăng tốc xử lý.
* unsafe void XetCuaNgang(byte* p0, int x, int y)
Phương thức kiểm tra liên kết yếu theo phương ngang.
Quá trình thực hiện của phương thức này như trình bày trong thuật toán xác định liên kết yếu được trình bày trong chương 2.
* unsafe void XetCuaDoc(byte* p0, int x, int y)
Phương thức kiểm tra liên kết yếu theo phương thẳng đứng.
Phương thức thực hiện duyệt trên 1 ảnh nhị phân vào, để tìm ra các vùng trắng.
Thuật toán phân vùng được cài đặt trong phương thức này là thuật toán phân vùng nâng cao (loại bỏ liên kết yêu).
Nội dung thuật toán phân vùng nâng cao được trình bày trong chương 2.
* DLL: lớp này được xây dựng trong chương trình nên không nằm trong dll nào cả.
Lớp này được xây dựng để cung cấp các phương thức cho tìm ra các khuôn mặt trong ảnh Việc xác định các khuôn mặt trong ảnh được thực hiện theo thuật toán đã trình bày trong chương 2 Xây dựng thành 1 lớp riêng để dễ quản lý và có thể sử dụng lại. Để tìm ra các khuôn mặt với 1 ảnh đưa vào, đầu tiên ta phải tạo ra 1 thể hiện của lớp, sau đó khởi gán các thuộc tính phục vụ quá trình phát hiện mặt là: Histogram và các tham số trong xác định màu da và tính chất khuôn mặt Sau khi mọi thứ thiết lập xong, ta gọi phương thức TimMat, phương thức sẽ trả về danh sách các tọa độ các khuôn mặt tìm kiếm được.
Lớp có 2 thuộc tính là:
Các kết quả thí nghiệm
Trong thử nghiệm, ta đã tổng hợp histogram xác định màu da trên hơn 200 ảnh màu da vàng Các ảnh này được lấy ra nhờ công cụ lấy khuôn mặt đã trình bày ở trên. Các ảnh phần lớn được lấy từ Internet, một phần được xin từ bạn bè hoặc của cá nhân
Như đã trình bày ở trên, phương pháp được dựa trên một bộ các tham số Giá trị tốt nhất của bộ tham số được đưa ra qua thực nghiệm (không có giá trị tốt cho mọi trường hợp) Nếu ta lấy giá trị ngưỡng thấp thì phát hiện được nhiều khuôn mặt hơn nhưng hậu quả là phát hiện nhầm (những cái không phải là mặt nhưng lại bị phát hiện là mặt) cũng tăng lên Qua thực nghiệm, giá trị của bộ tham số thu được là:
Sai số tỉ lệ khuôn mặt so với tỉ lệ vàng: 0,6.
Kích thước khuôn mặt nhỏ nhất: 20 pixel.
Ngưỡng histogram xác định màu da: 0,0002 File histogram được dùng là: his090408.hin
Tỉ lệ số điểm màu da trong vùng mặt: [0,6; 0,9].
Giá trị ngưỡng trong xác định liên kết yếu là 7 điểm.
Kết quả thử nghiệm trên bộ tham số này được cho trong bảng sau:
STT Tên file Kích thước Số khuôn mặt
Pháthiện nhầm thựcTg hiện (ms)
3 asian-businessman- posing-~- dl_k34_0031.jpg
5 asian-girl-sitting-on- floor-smiling-~- lw_s05_008_04.jpg
8 asian-grandparents-with- grandson-~-BPH134.jpg 300 x 223 3 0 0 80
9 asian-male-waiter-at- upscale-restaurant-~-
10 asian-man-and-woman- in-modern-residence-~-
11 asian-man-in-turtleneck- sweater-~-bxp66169.jpg 200 x 300 1 1 0 90
12 asian-mother-and- daughter-~-OFM060.jpg 221 x 300 2 2 0 60
13 asian-woman-with- basket-of-dirty-laundry-
15 boy-in-playground- looking-at-camera- people-in-the- background-~-
17 close-up-of-asian- woman-smiling-indoors-
18 close-up-portrait-of- young-asian-man-~-
21 four-young-people- sitting-in-a-park-~- b03717.jpg
27 group-of-asian-office- people-looking-at-the- camera-smiling-~-
41 occidental-man-and- asian-man-shouting-~- u18926904.jpg
42 office-people-smiling- with-laptop-at-desk-~- u19664126.jpg
43 older-asian-woman- talking-on-phone-~-
55 portrait-of-a-teenage- asian-girl-in-a-multi- colored-sweater-as-she-
56 portrait-of-a-young- asian-boy-in-a-light-blue- shirt-as-he-looks-~-
57 portrait-of-a-young- asian-boy-in-a-red-shirt- as-he-smiles-and-laughs-
58 portrait-of-a-young- asian-woman-in-a-black- coat-with-a-blue- backgound-~-
59 portrait-of-a-young- asian-woman-in-a-black- shirt-turns-her-head-and-
60 portrait-of-five-people- smiling-~-u13036865.jpg 300 x 200 5 4 0 40
61 portrait-of-three-young- people-~-u10517981.jpg 300 x 240 3 0 0 50
62 portrait-of-two-business- people-~- cb0503bdh_0365.jpg
63 portrait-of-two-young- people-~-u17615797.jpg 240 x 300 2 2 0 50
64 portrait-of-two-young- people-~-u18797712.jpg 300 x 240 2 2 3 80
65 portrait-of-two-young- people-~-u30393442.jpg 300 x 240 2 1 0 40
66 senior-asian- businessman-smiling-~- dl_k34_0301.jpg
68 senior-asian-man-giving- senior-asian-woman-a- neck-massage-san-~- pl060231.jpg
69 senior-asian-man-with- newspaper-outdoors-~-
72 three-business-people- with-asian-man-up-front-
80 young-asian-female- model-with-light-blue- winter-parka-~- u21658553.jpg
81 young-asian-female- model-with-white- winter-parka-and- woolen-hat-~- u26145533.jpg
82 young-asian-people- wearing-casual-and- sports-clothing-~- u23413817.jpg
Thử nghiệm trên hơn 82 file ảnh, với 244 khuôn mặt Kết quả phát hiện được 120
Hình 4.4: Một số kết quả minh họa phát hiện mặt người
Phương pháp có ưu điểm là có thể phát hiện được những khuôn mặt mờ (nhưng vẫn rõ màu da) Điều này không thể thực hiện được với các phương pháp học máy, vì nó học trên các ảnh chuẩn Việc phát hiện các ảnh mờ không có ý nghĩa lắm trong nhận dạng, nhưng có ý nghĩa trong đếm số người chẳng hạn.
Những trường hợp không phát hiện được là do nhiễu màu da ở xung quanh làm mở rộng vùng trắng của khuôn mặt (sự dính líu) làm cho tính chất của vùng trắng không còn thỏa mãn khuôn mặt nữa, hoặc do các khuôn mặt dính vào nhau, hoặc tay dính vào mặt, hoặc do cởi trần, Tóm lại phương pháp không phát hiện tốt khi có nhiều vùng da, ngoài vùng mặt, được lộ ra như: cổ, tay, chân, Như vậy,phương pháp phát hiện tốt vào mùa đông không phát hiện tốt vào mùa hè.
KẾT LUẬN VÀ PHƯƠNG HƯỚNG PHÁT TRIỂN
Phát hiện mặt người là một lĩnh vực đang dành được nhiều sự quan tâm hiện nay.
Có rất nhiều bài báo, các công trình nghiên cứu thử nghiệm về lĩnh vực này đã được công bố và có những thành công nhất định Phát hiện mặt người là khâu tiền xử lý cho khâu nhận dạng mặt người, hướng tới xây dựng một hệ thống nhận dạng mặt người tự động Nó còn được ứng dụng vào đếm số người (có ý nghĩa trong giao thông, thương mại, ) và nhiều lĩnh vực khác nữa.
Có rất nhiều các phương pháp, kĩ thuật khác nhau trong phát hiện màu da, như: các phương pháp dựa trên học máy, các phương pháp dựa trên đặc trưng, các phương pháp dựa trên mô hình, Mỗi phương pháp đều có những ưu nhược riêng của nó, không có phương pháp nào hoàn hảo cả Có phương pháp phát hiện tốt trong trường hợp này, nhưng lại phát hiện kém trong những tình huống khác Với những tình huống khác đó, lại đòi hỏi phương pháp khác phù hợp với nó.
* Trong đồ án này, đã làm được:
Trình bày được một số phương pháp phát hiện mặt người dựa trên đặc trưng Các phương pháp được trình bày ở mức độ chi tiết vừa phải, chưa chi tiết đến mức cài đặt.
Đưa ra một phương pháp phát hiện mặt người dựa trên màu da Trình bày một cách chi tiết, rõ ràng các bước trong thuật toán.
Xây dựng được ứng dụng phát hiện mặt người với các đầu vào: file ảnh, file phim, camera Ứng dụng cài đặt thuật toán phát hiện mặt người dựa trên màu da ở trên Ứng dụng có tốc độ phát hiện nhanh, có thể thực hiện trong các hệ thống thời gian thực Nó có thể phát hiện được các khuôn mặt có kích thước khác nhau, hướng khác nhau và độ sáng khác nhau.
* Những điều đồ án chưa làm được:
Phương pháp đưa ra có kĩ thuật có thể nói là đơn giản Vì vậy mà tỉ lệ phát hiện đúng không cao, và còn phát hiện nhầm nhiều.
Ứng dụng được xây dựng, ban đầu mới chỉ thử phát hiện mặt người trên chủng tộc người da vàng Tuy vẫn có thể phát hiện trên các màu da khác (do vùng màu da trong không gian màu là nhỏ gọn, các màu da khác nhau vẫn có những điểm chung), nhưng chất lượng không tốt.
* Hướng phát triển của đồ án:
Đưa thêm một số kĩ thuật khác nữa vào trong phương pháp, để nâng cao tính chính xác của phương pháp Các kĩ thật dự kiến đưa vào như: bộ lọc Gabor.
Phát triển ứng dụng để có thể phát hiện mặt người trên mọi loại da: da đen, da trắng, da vàng, da đỏ.