90452216-hệ-điều-hanh-android-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-android

64
ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ Trần Thị Hợp HỆ ĐIỀU HÀNH ANDROID VÀ THỰC THI ỨNG DỤNG PHÁT HIỆN KHUÔN MẶT TRÊN ANDROID KHOÁ LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY Ngành: Công Nghệ Điện Tử Viễn Thông HÀ NỘI - 2011

Upload: ba-vuvan

Post on 29-Jul-2015

2.343 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

a

ĐẠI HỌC QUỐC GIA HÀ NỘI

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

Trần Thị Hợp

HỆ ĐIỀU HÀNH ANDROID VÀ THỰC THI ỨNG

DỤNG PHÁT HIỆN KHUÔN MẶT TRÊN ANDROID

KHOÁ LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY

Ngành: Công Nghệ Điện Tử Viễn Thông

HÀ NỘI - 2011

Page 2: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

ĐẠI HỌC QUỐC GIA HÀ NỘI

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

Trần Thị Hợp

HỆ ĐIỀU HÀNH ANDROID VÀ THỰC THI ỨNG

DỤNG PHÁT HIỆN KHUÔN MẶT TRÊN ANDROID

KHOÁ LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY

Ngành: Công Nghệ Điện Tử Viễn Thông

Cán bộ hướng dẫn: TS. Nguyễn Linh Trung

Cán bộ đồng hướng dẫn: TS. Nguyễn Thái Hà

HÀ NỘI - 2011

Page 3: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

VIETNAM NATIONAL UNIVERSITY, HANOI

UNIVERSITY OF ENGINEERING AND TECHNOLOGY

Tran Thi Hop

ANDROID OPERATING SYSTEM AND

IMPLEMENTATION OF FACE DETECTION

APPLICATION ON ANDROID

Major: Faculty of Electronics and Telecommunications

Supervisor: Ph.D Nguyen Linh Trung

Co-Supervisor: Ph.D Nguyen Thai Ha

HÀ NỘI-2011

Page 4: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

LỜI CẢM ƠN

Để hoàn thành khóa luận này, em đã nhận được sự giúp đỡ nhiệt tình của TS.

Nguyễn Linh Trung, TS. Nguyễn Thái Hà và các anh chị bên công ty Techburg, Hà

Nội.

Trước hết em xin bày tỏ lòng biết ơn sâu sắc tới TS. Nguyễn Linh Trung, Giảng

viên khoa Điện Tử Viễn Thông, Trường Đại học Công Nghệ, ĐHQG Hà Nội, người

đã hướng dẫn và chỉ bảo nhiệt tình cho em trong suốt quá trình học, nghiên cứu và

hoàn thành khóa luận.

Em xin trân trọng cảm ơn sự nhiệt tình hướng dẫn và giúp đỡ tận tình của TS.

Nguyễn Thái Hà, Tổng giám đốc Công ty Techburg và các anh chị thuộc công ty đã

nhiệt tình giúp đỡ và tạo điều kiện cho em học tập và hoàn thành khóa luận này.

Cuối cùng, em xin gửi lời biết ơn tới gia đình và bạn bè đã giúp đỡ và động viên

em rất nhiều để em có thể hoàn thành khóa luận này. Đặc biệt là gia đình, nơi đã

sinh thành, nuôi dưỡng và động viên em rất nhiều trong thời gian qua.

Hà Nội , ngày 20 tháng 5 năm 2011

Sinh viên:

Trần Thị Hợp

Page 5: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

TÓM TẮT

Android là hệ điều hành cho thiết bị di động được phát triển bởi Google. Android

dựa trên nhân Linux 2.6 và các ứng dụng Android được viết bằng ngôn ngữ lập trình

Java. Khóa luận này tôi trình bày tổng quan về Android, kiến trúc Android, Android

SDK, Android NDK, các thành phần tạo nên một ứng dụng Android và trình bày hai

phương pháp phát hiện khuôn mặt sử dụng thư viện OpenCV và framework API của

Android. Đồng thời khóa luận cũng trình bày sự khác nhau giữa máy ảo Java và máy ảo

Dalvik. Dalvik là máy ảo thực thi các ứng dụng Android.

Trong khóa luận này tôi trình bày quy trình xây dựng và thực thi một ứng dụng với

Android NDK. Quy trình này sẽ được sử dụng để xây dựng ứng dụng phát hiện khuôn

mặt sử dụng OpenCV. OpenCV là một thư viện hỗ trợ cho xử lý ảnh do Intel phát triển,

bao gồm khoảng 500 hàm viết bằng các ngôn ngữ C và C++. Để sử dụng được thư viện

này thì đầu tiên phải porting được thư viện OpenCV vào Android. Khóa luận cũng trình

bày cách porting thư viện và trình bày thuật toán phát hiện khuôn mặt do Viola và Jones

đưa ra. Để sử dụng thư viện OpenCV thì cần một giao diện để chương trình ứng dụng

Android viết bằng Java có thể gọi được các hàm viết bằng C/C++ của OpenCV. Giao

diện đó là JNI (Java Native Interface). Trong khóa luận tôi cũng đưa ra một demo với

“Hello World” sử dụng Android NDK mà có hỗ trợ JNI. Từ đó đưa được giải pháp để

phát triển ứng dụng phát hiện khuôn mặt sử dụng OpenCV.

Phương pháp thứ hai để phát hiện khuôn mặt là sử dụng framework API của

Android. API là giao diện lập trình ứng dụng (Application Programming Interface).

Android cung cấp một framework API bao gồm các gói và các lớp giúp cho các nhà

phát triển có thể sử dụng để phát triển nhiều ứng dụng hấp dẫn. Khóa luận trình bày về

các gói và các lớp sử dụng framework API của Android để xây dựng ứng dụng phát hiện

khuôn mặt trên Android và khóa luận đưa ra được kết quả khi tiến hành thực nghiệm.

Với phương pháp này chỉ cần có kỹ năng lập trình Java tốt là có thể xây dựng được ứng

dụng.

i

Page 6: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

LỜI CAM ĐOAN

Tôi xin cam đoan đề tài “Hệ điều hành Android và thực thi ứng dụng phát hiện

khuôn mặt trên Android ” là kết quả tìm hiểu của riêng tôi với sự hướng dẫn của TS.

Nguyễn Linh Trung và TS. Nguyễn Thái Hà. Trong khóa luận có sử dụng một số tài

liệu và kết quả nghiên cứu như đã nêu trong phần tài liệu tham khảo. Các kết quả, số

liệu sử dụng trong khóa luận là chính xác và trung thực.

Khóa luận được hoàn thành trong thời gian tôi là sinh viên tại Bộ môn thông tin vô

tuyến, Khoa điện tử viễn thông, Trường Đại học Công Nghệ, ĐHQG Hà Nội.

Hà Nội, ngày 20 tháng 5 năm 2011

Sinh viên:

Trần Thị Hợp

ii

Page 7: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

MỤC LỤC

Trần Thị Hợp ................................................................................................................................... 1

Trần Thị Hợp ................................................................................................................................... 2

Tran Thi Hop .................................................................................................................................... 3

Danh sách hình vẽ ........................................................................................................................... iv

CHƯƠNG 1. HỆ ĐIỀU HÀNH ANDROID..................................................................................1

1.1.Android là gì? ............................................................................................................................ 1

1.2.Máy ảo Dalvik ........................................................................................................................... 1

1.3.Kiến trúc Android ...................................................................................................................... 3

1.4.Android emulator ....................................................................................................................... 5

1.5. Android SDK ............................................................................................................................ 6

1.6.Android NDK ............................................................................................................................ 8

1.7. Porting OpenCV vào Android ................................................................................................ 10

1.8. Các thành phần tạo nên một ứng dụng Android .................................................................... 12

1.9. Phát triển ứng dụng Android và DVM ................................................................................... 19

1.10. Tạo và demo ứng dụng “Hello World” sử dụng Android NDK .......................................... 20

CHƯƠNG 2 .CÁC PHƯƠNG PHÁP PHÁT HIỆN KHUÔN MẶT TRÊN ANDROID............27

2.1. Thuật toán của Viola – Jones trong OpenCV ........................................................................ 27

2.2. Phát hiện khuôn mặt sử dụng framework API của Android .................................................. 31

2.3. Xây dựng chương trình phát hiện khuôn mặt trên Android .................................................. 36

CHƯƠNG 3. KẾT QUẢ ĐẠT ĐƯỢC.........................................................................................48

3.1. Kết quả phát hiện khuôn mặt sử dụng framework API của Android .................................. 48

3.2. Khó khăn và hướng giải quyết ............................................................................................... 49

KẾT LUẬN....................................................................................................................................50

TÀI LIỆU THAM KHẢO.............................................................................................................50

iii

Page 8: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Danh sách hình vẽ

Hình 1. Qúa trình thực thi ứng dụng Java và ứng dụng Android [4].............................................2

Hình 2.Qúa trình biến đổi file mã Java thành file (.dex)................................................................2

Hình 3.Kiến trúc Android [9]..........................................................................................................3

Hình 4.Android Emulator................................................................................................................6

Hình 5.Các ứng dụng Android trong API Demos..........................................................................7

iv

Page 9: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 6.Vai trò của JNI [7]...............................................................................................................9

Hình 7.Mô hình xây dựng và chạy code JNI [7]...........................................................................10

Hình 8.Mô hình porting OpenCV vào Android............................................................................11

Hình 9.Qúa trình porting OpenCV vào Android...........................................................................12

Hình 10.Ngăn xếp Activity............................................................................................................13

Hình 11.Chu kỳ sống của Activity [4]..........................................................................................14

Hình 12.Chu kỳ sống của Service [4]...........................................................................................17

Hình 13.Truyền thông giữa hai tiến trình......................................................................................17

Hình 14.Broadcast receiver...........................................................................................................17

Hình 15.Content Provider [4]........................................................................................................18

Hình 16.Ứng dụng Contacts sử dụng Contacts Provider để lấy dữ liệu......................................18

Hình 17.Intent [4]..........................................................................................................................19

Hình 18.Qúa trình tạo file APK.....................................................................................................20

Hình 19.Quá trình truy cập mã gốc qua JNI [4]............................................................................21

Hình 20.Demo ứng dụng Hello World dùng Android NDK........................................................26

Hình 21.Các đặc trưng Haar-like cơ bản [7].................................................................................27

Hình 22.Các đặc trưng Haar-like mở rộng [6]..............................................................................27

Hình 23.Cách tính Integral Image [8]............................................................................................28

Hình 24.Ví dụ cách tính nhanh các giá trị mức xám [7]...............................................................28

Hình 25.Mô hình cascade kết hợp với các bộ phân loại yếu [7]..................................................29

Hình 26.Kết hợp các bộ phân loại yếu thành bộ phân loại mạnh.................................................30

Hình 27. Hệ thống phát hiện khuôn mặt.......................................................................................30

Hình 28.Các gói Android cung cấp trong framework API...........................................................36

Hình 29.Mô hình phát hiện khuôn mặt trên Androi......................................................................36

Hình 30.Các góc Euler- hệ tọa độ xyz (cố định), hệ tọa độ XYZ (quay).....................................37

Hình 31.Các thành phần trong một Android Project....................................................................40

Hình 32. Các tệp trong thư mục bin của Android Project............................................................46

Hình 33.Hình ảnh gốc ban đầu......................................................................................................48

Hình 34.Kết quả phát hiện khuôn mặt trên Android.....................................................................48

v

Page 10: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

vi

Page 11: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

THUẬT NGỮ VIẾT TẮT SỬ DỤNG TRONG BÀI

ADB Android Debug Bridge

ADT Android Development Tools

AVD Android Virtual Devices

API Application Programming Interface

BSD Berkeley Software Distribution

DVM Dalvik Virtual Machine

GPS Global Positioning System

JNI Java Native Interface

JVM Java Virtual Machine

NDK Native Development Kit

OS Operating System

OpenCV OpenSource Computer Vision

SDK Software Development Kit

UI User Interface

VM Virtual Machine

vii

Page 12: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

LỜI MỞ ĐẦU

Android là một hệ điều hành cho điện thoại di động do Google phát triển dựa trên

nền tảng Linux 2.6. Android đang từng bước thống trị thị trường di động nhờ vào những

ưu điểm vượt trội của nó. Không như iPhone của Apple người dùng dường như bị cột

chặt với những gì hãng này cho phép thì Android được kế thừa tính mở từ Linux hay nói

cụ thể hơn là Google và Android mang đến một thế giới hoàn toàn mở. Người dùng

được tự do với những gì họ muốn và các nhà phát triển có được sự tự do hơn để tạo ra

các ứng dụng. Ngoài ra với Android người tiêu dùng có thể có nhiều sự lựa chọn. Chẳng

hạn như hãng LG tung ra trên thị trường 20 sản phẩm chạy nền Android năm 2010. Bên

cạnh các tính năng đó thì Android sẽ từng bước thống trị thị trường di động nhờ vào ưu

điểm hướng đến người dùng và với thương hiệu của Google đứng sau lưng nó. Đây là

một thương hiệu đáng giá.

Hiện nay Android không chỉ được dùng cho điện thoại di động mà còn được các

nhà sản xuất điện tử trên thế giới sử dụng Android như là một nền tảng cho các sản

phẩm nhúng, ví dụ như nhà thông minh, hệ thống thông tin giải trí ô tô, … Ngoài ra

trong tương lai Google sẽ sớm tung ra một hệ điều hành cho tivi, đầu thu kỹ thuật số

(set-top-box).

Trong khóa luận này tôi sẽ trình bày tổng quan về hệ điều hành Android và trình

bày hai hướng để phát triển ứng dụng phát hiện khuôn mặt trên Android đó là sử dụng

OpenCV và framework API của Android. OpenCV là một thư viện hỗ trợ mạnh cho xử

lý ảnh do Intel phát triển bao gồm các hàm được viết bằng ngôn ngữ C và C++ trong đó

có hỗ trợ phát hiện khuôn mặt. Thuật toán phát hiện khuôn mặt của Viola – Jones được

đưa vào OpenCV vì với tốc độ gấp 15 lần so với các thuật toán hiện tại [7]. Hướng thứ

hai tôi sẽ trình bày trong khóa luận để xây dựng một ứng dụng phát hiện khuôn mặt với

framework API của Android. API là giao diện lập trình ứng dụng, viết tắt của

Application Programming Interface. Nền tảng Android cung cấp một framework API

mà các ứng dụng có thể tương tác với hệ thống Android. Framework API bao gồm một

lõi thiết lập các gói và các lớp. Trong ứng dụng phát hiện khuôn mặt tôi sử dụng lớp

FaceDetector trong gói android.media của framework API do Android cung cấp để xây

dựng ứng dụng. Với hướng thứ hai này chỉ cần kỹ năng lập trình Java tốt là có thể xây

dựng được ứng dụng.

Nội dung của khóa luận gồm 3 chương:

viii

Page 13: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Chương 1: Trình bày tổng quan về hệ điều hành Android, kiến trúc Android,

Android SDK, Android NDK, porting OpenCV vào Android và quy trình xây dựng và

thực thi một ứng dụng Android. Bản chất của việc Porting OpenCV vào Android là

thêm một thư viện chia sẻ vào tầng thư viện của Android để từ đó có thể dùng thư viện

này để phát triển nhiều ứng dụng khác không chỉ là phát hiện khuôn mặt. Chẳng hạn

như dùng OpenCV có thể phát triển thêm các ứng dụng phân tích chuyển động, nhận

dạng khuôn mặt. Chương này cũng đưa ra sự khác nhau giữa máy ảo Java và máy ảo

Dalvik. Dalvik là máy ảo để thực thi các ứng dụng Android.

Chương 2: Trình bày hai phương pháp phát hiện khuôn mặt trên Android sử dụng

OpenCV và framework API của Android trong tầng applications framework của kiến

trúc Android. Trong chương này tôi sẽ trình bày thuật toán của Viola – Jones sử dụng

trong OpenCV và xây dựng chương trình phát hiện khuôn mặt với framework API của

Android.

Chương 3: Trình bày các kết quả đạt được và những khó khăn gặp phải từ đó đưa

ra hướng giải quyết khó khăn.

ix

Page 14: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

CHƯƠNG 1. HỆ ĐIỀU HÀNH ANDROID

1.1.Android là gì?

Android là một ngăn xếp phần mềm cho các thiết bị di động bao gồm một hệ

điều hành, middleware và các ứng dụng khóa được phát triển bởi Google. Android

được dựa trên nhân Linux 2.6 và các ứng dụng cho Android sử dụng ngôn ngữ lập

trình Java.

Android là một hệ điều hành mã nguồn mở, các nhà phát triển có thể tạo ra các

ứng dụng cho Android và bất kỳ ai cũng có thể lấy và sửa đổi theo ý thích. Tuy nhiên

các thiết bị Android cũng chứa một số phần mềm độc quyền mà các nhà phát triển

không thể tiếp cận được những phần mềm này. Ví dụ: hệ thống định vị toàn cầu

(GPS). Android cũng hỗ trợ nhiều tính năng như: Wi-fi, Bluetooth, các mạng 3G và

4G, …

1.2.Máy ảo Dalvik

Dalvik là máy ảo để thực thi các ứng dụng Android. Dalvik chạy các file ở định

dạng (.dex). Từ góc nhìn của một nhà phát triển Dalvik giống như máy ảo Java nhưng

thực tế thì hoàn toàn khác. Khi các nhà phát triển viết một ứng dụng Android thì đều

phải thực hiện các đoạn mã trong Java. Sau đó các file mã Java sẽ được biên dịch

sang mã bytecode. Sau đó để thực thi được các ứng dụng Android thì ta phải dùng

một công cụ tên là dx để chuyển đổi mã bytecode của Java sang một file có định dạng

dex (dex là viết tắt của Dalvik excutable), đóng vai trò như cơ chế ảo để thực thi các

ứng dụng Android. Hình 1 mô tả sự khác nhau giữa giữa quá trình thực thi một ứng

dụng Java và quá trình thực thi một ứng dụng Android:

1

Page 15: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 1. Qúa trình thực thi ứng dụng Java và ứng dụng Android [4]

Hình 1 thể hiện hai sự khác biệt giữa máy ảo Java (JVM: Java Virtual Machine)

và máy ảo Dalvik (DVM: Dalvik Virtual Machine). Sự khác biệt đầu tiên là các mã

bytecode mà JVM hoạt động là Java bytecode còn DVM hoạt động trên định dạng

đặc biệt của nó (định dạng .dex). Sự khác biệt thứ hai là các lớp Java trong chương

trình Java SE được biên dịch vào một hay nhiều file (.class) và nén vào file(.jar), sau

đó JVM có được các file bytecode từ các file (.class) và file (.jar). Mặc dù các ứng

dụng Android cũng được biên dịch trong ngôn ngữ lập trình Java nhưng sau khi các

ứng dụng này được biên dịch thành các file (.class) thì một công cụ dx sẽ biến đổi tất

cả các file (.class) thành file (.dex). Từ đó DVM đọc các chỉ dẫn và dữ liệu. Hình vẽ

dưới đây thể hiện quá trình biến đổi đó:

Hình 2.Qúa trình biến đổi file mã Java thành file (.dex)

2

Page 16: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

1.3.Kiến trúc Android

Hình 3.Kiến trúc Android [9]

Android là một ngăn xếp phần mềm, bao gồm các tầng như trên hình 3. Trong

đó các hàm thực thi các ứng dụng trong hai tầng Applications và Applications

framework được viết bằng ngôn ngữ lập trình Java. Còn các hàm thực thi các ứng

dụng ở các tầng dưới: Libraries, Android runtime, Linux kernel được viết bằng mã

gốc hay native code được viết bằng ngôn ngữ C/C++. Khi cần xây dựng một ứng

dụng Android mà cần phải sử dụng một đoạn mã viết bằng C/C++ ở các tầng bên

dưới thì ta sẽ sử dụng JNI (Java Native Interface) để giúp ứng dụng Android viết bằng

Java có thể truy cập được các hàm viết bằng C/C++. Ta sẽ nói rõ hơn về quá trình sử

dụng JNI trong phần demo ứng dụng “Hello World” ở phần sau. Dưới đây ta sẽ tìm

hiểu chức năng của từng tầng trong kiến trúc Android:

Tầng Applications

Android được tích hợp sẵn một số ứng dụng cần thiết cơ bản như: calendar,

maps, contacts, brower, camera, phone, … Tất cả các ứng dụng này đều được viết

bằng ngôn ngữ Java.

Tầng Applications framework

3

Page 17: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Bằng cách cung cấp một nền tảng phát triển mở Android cung cấp cho các nhà

phát triển khả năng xây dựng các ứng dụng cực kỳ phong phú và sáng tạo. Nhà phát

triển được tự do tận dụng các thiết bị phần cứng, thông tin địa điểm truy cập, các dịch

vụ chạy nền, thiết lập hệ thống báo động, và cộng thêm các cảnh báo đến các thanh

trạng thái, và nhiều hơn nữa.

Nhà phát triển có thể truy cập vào các API cùng một framework được xây dựng

bởi các ứng dụng lõi. Kiến trúc ứng dụng được thiết kế để đơn giản hóa việc sử dụng

lại các thành phần; bất kỳ ứng dụng nào cũng có thể công bố khả năng của nó và bất

kỳ ứng dụng nào khác cũng có thể sử dụng những khả năng này(có thể hạn chế bảo

mật được thực thi bởi framework). Tất cả các ứng dụng cơ bản là một bộ dịch vụ và

các hệ thống, bao gồm:

• Một tập hợp phong phú và mở rộng các View có khả năng kế thừa lẫn nhau

dùng để thiết kế phần giao diện ứng dụng như : gridview, tableview, linearlayout, …

• Trình cung cấp nội dung (Content Providers): Cho phép các ứng dụng có thể

truy xuất dữ liệu từ các ứng dụng khác (chẳng hạn như contacts) hoặc là chia sẻ dữ

liệu giữa các ứng dụng đó.

• Quản lý tài nguyên (Resource Manager): Cung cấp truy xuất tới các tài

nguyên không phải là mã nguồn, chẳng hạn như graphics, và các file layout.

• Quản lý thông báo (Notification Manager): Cho phép tất cả các ứng dụng hiển

thị các cảnh báo trong thanh trạng thái.

• Quản lý hoạt động (Activity Manager): Quản lý chu trình sống của ứng dụng

và điều hướng các Activity.

Tầng Libraries

Android bao gồm một tập hợp các thư viện C/C++ được sử dụng bởi nhiều

thành phần khác nhau trong hệ thống Android. Điều này được thể hiện thông qua nền

tảng ứng dụng Android. Một số các thư viện cơ bản được liệt kê dưới đây:

• System C library – Thực hiện triển khai BSD của thư viện hệ thống C chuẩn

(libc) và chỉnh cho các thiết bị nhúng dựa trên Linux. BSD là giấy phép nguồn mở,

cho phép mọi người sử dụng chương trình, mã nguồn của nó và các dẫn xuất.

• Media Libararies – Dựa trên PacketVideo’s OpenCORE; các thư viện hỗ trợ

phát và ghi âm với nhiều định dạng audio và video, cũng như đối với các file ảnh tĩnh

bao gồm: MPEG4, H.264, MP3, AAC, ARM, JPG, và PNG.

4

Page 18: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

• Surface Manager- Quản lý truy cập vào hệ thống hiển thị.

• LibWebCore- Một công cụ trình duyệt web hiện đại.

• SGL – Công cụ đồ họa 2D cơ sở.

• 3D libraries – Sự thực hiện dựa trên OpenGL ES 1.0 APIs.

• Free Type- Biểu diễn font véc-tơ và bitmap.

• QLite –Cơ sở dữ liệu.

• Webkit – Thư viện cho việc biểu diễn HTML

Tầng Android runtime

Tầng này bao gồm các thư viện lõi và máy ảo Dalvik. Các thư viện lõi bao gồm

các thư viện lớp cơ bản nhất như: cấu trúc dữ liệu, mạng, các tiện ích, hệ thống file.

DVM được thiết kế để đạt được các chức năng quản lý chu kỳ sống của đối tượng,

quản lý ngăn xếp, quản lý luồng, bảo mật, …DVM là lý tưởng để sử dụng với yêu

cầu về không gian bộ nhớ và CPU thấp so với các máy ảo chạy trên các máy tính để

bàn và hệ thống máy chủ. Theo tính toán của Google thì cần 64M RAM cho phép hệ

thống hoạt động tốt, 24M RAM được sử dụng để khởi tạo và bắt đầu hệ thống cơ bản,

và 20M RAM được sử dụng cho các dịch vụ cấp cao.

Linux kernel

Android được xây dựng trên nhân Linux, nhưng Android không phải là Linux.

Android dựa trên Linux phiên bản 2.6 cho các hệ thống dịch vụ cốt lõi như an ninh,

quản lý bộ nhớ, quản lý quá trình, ngăn xếp mạng, và mô hình điều khiển. Hạt nhân

cũng hoạt động như một lớp trừu tượng giữa phần cứng và phần còn lại của ngăn xếp

phần mềm. Linux kernel hỗ trợ các thư viện chia sẻ (shared libraries) và nó còn là một

mã nguồn mở.

1.4.Android emulator

Android SDK và Plugin Eclipse được gọi là Android Development Tools

(ADT). Trình giả lập Android ( Android Emulator) được tích hợp với Eclipse, sử

dụng ADT plug-in cho Eclipse IDE. Trình giả lập điện thoại Android hay còn gọi là

AVD (Android Virtual Device) trên đó các ứng dụng có thể chạy và được thử

nghiệm. Một khi AVD được khởi chạy, có thể triển khai một số lượng ứng dụng bất

kỳ trong khi nó vẫn còn đang chạy và thậm chí có thể sử dụng nó để gỡ rối ứng dụng.

Hình dưới đây mô tả một trình giả lập Android:

5

Page 19: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 4.Android Emulator

Các trình giả lập Android là một công cụ tiện lợi nhưng nó có một số hạn chế đó

là: các trình giả lập không phải là một thiết bị nói chung nó mô phỏng hành vi của

chiếc điện thoại, không hỗ trợ các chức năng nghe nhạc, quay phim, chụp ảnh, USB,

Bluetooth, …

1.5. Android SDK

Android SDK cung cấp nhiều tập tin và các công cụ đặc biệt nhằm mục đích

giúp cho việc thiết kế và phát triển các ứng dụng chạy trên nền tảng Android.

Android SDK cũng chứa các thư viện để buộc các ứng dụng vào trong các đặc tính

lõi của Android, chẳng hạn như những thư viện này được kết hợp với các chức năng

của điện thoại di động (thực hiện và nhận cuộc gọi), các chức năng GPS, và nhắn tin

văn bản. Những thư viện này tạo nên lõi của SDK và sẽ được sử dụng thường xuyên

nhất.

Phần lớn Android SDK bao gồm các tập tin, tài liệu, với lập trình API, các công

cụ, và các ví dụ. Trong Android SDK có một vài tập tin trong thư mục gốc giống như

android.jar (một ứng dụng Java được biên dịch có chứa các thư viện lõi SDK và API),

một số ghi chú, phần còn lại của Android SDK được chia thành ba thư mục chính:

• Docs: Chứa tất cả các tài liệu đi kèm với Android.

• Samples: Bao gồm các ví dụ, có thể được biên dịch và kiểm tra bên trong của

Eclipse.

6

Page 20: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

• Tools: Chứa tất cả các công cụ gỡ lỗi, biên dịch, và phát triển mà ta cần trong

suốt quá trình phát triển một ứng dụng Android.

Trong mục Samples của Android SDK có chứa 6 ví dụ mẫu cho ứng dụng

Android. Những ví dụ này cung cấp bởi Google để cung cấp cho ta một ý tưởng

nhanh chóng về làm cách nào để phát triển một ứng dụng Android. Mỗi ứng dụng

mẫu thể hiện mỗi phần khác nhau về chức năng của Android. Chúng ta có thể mở và

chạy các ứng dụng này từ bên trong của Eclipse.

Ứng dụng API Demos là một ứng dụng chủ (host application) mô tả nhiều hàm

API trong một Activity đơn lẻ. Một Activity là một ứng dụng Android. Ứng dụng API

Demos như chỉ ra hình dưới bao gồm nhiều ví dụ khác nhau về chức năng của

Android:

Hình 5.Các ứng dụng Android trong API Demos

Giao diện lập trình ứng dụng API (Application Programming Interface) là phần

lõi của Android SDK. API là tập hợp các hàm, phương thức, đặc tính, lớp và các thư

viện được sử dụng bởi các nhà phát triển ứng dụng để tạo ra các chương trình làm

việc trên nền tảng cụ thể. Các Android API chứa tất cả các thông tin cụ thể mà ta cần

để tạo ra ứng dụng có thể làm việc và tương tác với một ứng dụng trên nền Android.

Android SDK cũng chứa hai bộ APIs bổ sung là Google APIs và Optional APIs:

• Google APIs

7

Page 21: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Nằm trong tập tin android.jar, các API của Google được chứa trong gói

com.google.*. Có một vài gói đi kèm với các API của Google. Một số gói được vận

chuyển trong các API của Google bao gồm các gói cho đồ họa, tính khả chuyển, địa

chỉ liên hệ và các tiện ích về lịch. Chẳng hạn như với gói cho Google Maps. Sử dụng

gói com.google.android.maps. Trong gói này có chứa các thông tin cho bản đồ

Google (Google Maps) ta có thể tạo các ứng dụng tương tác liên tục với giao diện

quen thuộc của Google Maps.

• Optional APIs

Các Optional APIs bao gồm các tùy chọn chương trình khi cố gắng sử dụng các

tính năng này trong các ứng dụng Android. Một trong những tính năng tùy chọn là

một điện thoại di động dựa trên GPS. Android LBS (Location-Based Services) API

giải quyết việc tiếp nhận và sử dụng thông tin từ GPS của điện thoại. (Kết hợp thông

tin trong LBS Android API với GPS trong Google Maps API có thể tạo ra một ứng

dụng rất hữu ích có thể tự động hiển thị một bản đồ định vị trí ). Một số Optional

APIs khác bao gồm các tùy chọn cho việc sử dụng Bluetooth, Wi-Fi, chơi nhạc MP3

và truy cập phần cứng 3-D-OpenGL.

1.6.Android NDK

Như tôi đã đề cập trong phần kiến trúc của Android. Khi ta viết một ứng dụng

cho Android sử dụng ngôn ngữ lập trình Java mà cần phải sử dụng một đoạn mã nào

đó ở các tầng bên dưới (chẳng hạn tầng Libraries) viết bằng các ngôn ngữ C/C++. Để

Java có thể truy cập được các hàm C/C++ thì ta cần một giao diện để chúng có thể

tương tác với nhau. Giao diện đó là JNI (Java Native Interface).

Android NDK là một công cụ đồng hành với Android SDK cho phép xây dựng

các phần quan trọng thực hiện các ứng dụng trong mã gốc (native code). Nó cung cấp

các headers và các thư viện cho phép xây dựng các activities khi lập trình bằng C

hoặc C++. Nếu ta viết mã máy, các ứng dụng vẫn được đóng gói vào một file .apk và

chúng vẫn chạy bên trong máy ảo trên thiết bị. Sử dụng mã gốc không dẫn đến tăng

hiệu suất tự động, nhưng luôn luôn tăng độ phức tạp ứng dụng.

Android NDK là một bộ công cụ cho phép nhúng các thành phần sử dụng mã

gốc trong các ứng dụng Android. Các ứng dụng Android chạy trong máy ảo Dalvik.

NDK (Native Development Kit) cho phép thực hiện các phần của ứng dụng sử dụng

mã gốc chẳng hạn như C và C++. Android NDK cung cấp một chuỗi các công cụ và

các file xây dựng để tạo các thư viện mã gốc từ các nguồn C và C++; Android NDK

8

Page 22: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

là một cách để gói các thư viện vào trong file APK (file APK là file sẽ được phát

hành trên Android cho việc thực thi ứng dụng); Android NDK bao gồm một chuỗi các

header của hệ thống được hỗ trợ trong các phiên bản của nền tảng Android (ví dụ:

libc, JNI headers, C++ headers, OpenGL, …); Android NDK bao gồm một số tài liệu,

mã đơn giản và một số các ví dụ.

Android NDK hỗ trợ JNI giúp các nhà phát triển ứng dụng xây dựng các ứng

dụng có sử dụng các đoạn mã gốc của tầng bên dưới. Điều này là quan trọng vì trong

một hệ thống nhúng bao gồm các tầng tạo nên một ngăn xếp phần mềm. Khi ta cần

xây dựng một ứng dụng thuộc tầng trên cần kế thừa một số hàm viết bằng mã gốc

thuộc tầng bên dưới (có thể là tầng lõi liên quan đến phần cứng) thì JNI đóng vai trò

quan trọng.

JNI là một tính năng mạnh của nền tảng Java cho phép các nhà lập trình tận

dụng được sức mạnh của nền tảng Java (một chương trình viết bằng ngôn ngữ Java có

thể chạy được trên nhiều hệ điều hành “viết một lần chạy mọi nơi”). JNI là một giao

diện hai chiều cho phép các ứng dụng Java gọi mã gốc và ngược lại. Hình dưới đây

mô tả vai trò của JNI:

Hình 6.Vai trò của JNI [7]

Ta có thể sử dụng JNI để viết các phương thức gốc (native methods) cho phép

các ứng dụng Java gọi các hàm được thực thi trong các thư viện gốc. Các ứng dụng

Java gọi các phương thức gốc trong cùng một cách. Dưới đây là mô hình xây dựng và

chạy code JNI:

9

Page 23: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 7.Mô hình xây dựng và chạy code JNI [7]

Hoạt động của mô hình trên như sau: Đầu tiên ta viết mã nguồn Java (Java

Source) sau đó sử dụng trình biên dịch javac để biên dịch các file mã nguồn này thành

file ở định dạng (.class). Trong file mã nguồn Java ta sẽ thực hiện các công việc là

viết lệnh gọi thư viện động mà ta sẽ tạo ở phần sau (Dynamic Library) và định nghĩa

hay khai báo các phương thức thực hiện các hàm native code mà ta sẽ viết ở sau, và

mã nguồn Java này cũng là nơi để khởi tạo các phương thức.

Tiếp theo ta sẽ tạo ra các header file bằng cách dùng lệnh với javah –jni. Sau khi

tạo ra các header file thì ta sẽ viết mã C thực thi các hàm và các phương thức mà được

khai báo trong mã nguồn Java. Tiếp theo để tạo ra thư viện động ta cần phải biên dịch

mã C vừa viết ở trên. Để link được thư viện này tới mã nguồn Java thì trong mã

nguồn Java ta viết lệnh gọi thư viện này. Sau tất cả các bước trên thì chương trình

được thực thi trên máy ảo Java.

1.7. Porting OpenCV vào Android

Để phát triển ứng dụng Android với OpenCV thì đầu tiên ta cần porting được

thư viện này vào trong kiến trúc của Android. OpenCV (Open Computer Vision

library) do Intel phát triển. Thư viện OpenCV gồm khoảng 500 hàm được viết bằng

ngôn ngữ lập trình C và C++. OpenCV là công cụ mã nguồn mở thích hợp cho nghiên

cứu và phát triển. Để porting OpenCV vào Android ta sử dụng Android NDK. Dưới

đây là mô hình porting OpenCV:

10

Page 24: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 8.Mô hình porting OpenCV vào Android

Tổ chức thư viện OpenCV bao gồm 4 module chính và 2 module mở rộng. Các

module CV và CVAUX hỗ trợ các chức năng cấp cao (nhận dạng khuôn mặt, hiệu

chỉnh camera), xử lý ảnh, phân tích chuyển động. Module CxCore tổ chức dữ liệu cơ

sở, thực hiện các thuật toán (phép tính ma trận, tính toán). Module HighGuid giúp tạo

nhanh giao diện và hỗ trợ truy xuất ảnh/phim từ file hoặc thiết bị ngoại vi.

Để porting thì đầu tiên ta tải thư viện OpenCV về và giải nén. Sau đó dùng

Android NDK để porting. Trong eclipse ta sẽ tạo một project cho việc thực thi

porting. Sau đó tạo một file tên là jni trong project. File jni này sẽ chứa hai file là

Application.mk và Android.mk. File Android.mk bao gồm các module là các thư viện

của OpenCV cần porting vào trong Android với đường dẫn đúng. Sau đó dùng lệnh

ndk-build trên Ubuntu để biên dịch thư viện OpenCV cho kiến trúc Arm của Android.

Chú ý để sử dụng được lệnh ndk-build ta cần phải tải android NDK về và link đến

đúng thư mục chứa android NDK đã được giải nén. Sau khi porting thì ta sẽ được

một thư viện chia sẻ tên là libOpenCV.so và nằm trong thư mục libs/armeabi. Thư

viện chia sẻ này sẽ nằm trong tầng Libraries trong kiến trúc Android. Hình dưới đây

mô tả quá trình porting OpenCV cho kiến trúc Arm của Android.

11

Page 25: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 9.Qúa trình porting OpenCV vào Android

1.8. Các thành phần tạo nên một ứng dụng Android

Các ứng dụng Android sẽ được xây dựng từ các thành phần cơ bản đó là:

Activity, Service, Broadcast receiver, Content Provider và Intent.

Activity

Activity là một thành phần ứng dụng cung cấp một màn hình mà người dùng có

thể tương tác để làm một cái gì đó. Chẳng hạn như: quay số điện thoại, chụp ảnh, gửi

email hoặc xem một bản đồ. Một Activity có thể bắt đầu từ các Activity khác. Bên

trong hệ thống các Activity được quản lý như một ngăn xếp. Khi một Activity mới

được bắt đầu thì nó được đặt ở đỉnh của ngăn xếp và trở trành Activity đang chạy.

Activity trước sẽ ở bên dưới Activity mới và sẽ không thấy trong suốt quá trình

Activity mới tồn tại. Nếu người dùng nhấn nút Back thì Activity kế tiếp của ngăn xếp

sẽ di chuyển lên và trở thành active. Hình dưới đây mô tả một ngăn xếp các Activity:

12

Page 26: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 10.Ngăn xếp Activity

Mỗi tiến trình chạy ứng dụng trên nền tảng Android được đặt trên một ngăn xếp.

Khi sử dụng một Activity trên foreground thì tiến trình hệ thống sẽ đưa Activity đó

lên trên cùng của ngăn xếp và tiến trình trước đó sẽ được chuyển xuống mức dưới.

Tất cả các Activity đều có khả năng bị dừng lại hoặc bị phá hủy bất cứ lúc nào bởi vì

người sử dụng có thể thay đổi các Activity tùy theo ý thích của họ. Chẳng hạn như:

họ đang dùng Activity là một cuộc gọi và sau đó họ dừng cuộc gọi và chuyển sang

Activity khác là chụp ảnh, gửi email hay nhắn tin SMS. Nếu tiến trình Activity bị

thoát ra khỏi foreground thì nó sẽ bị hủy. Hình dưới đây mô tả chu kỳ sống của

Activity:

13

Page 27: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 11.Chu kỳ sống của Activity [4]

• Trạng thái Starting:

Khi một Activity không tồn tại trong bộ nhớ thì nó ở trạng thái starting. Trong

khi Activity đang khởi động thì Activity sẽ đi qua một chuỗi các phương thức

callback. Và cuối cùng Activity sẽ ở trạng thái running. Lưu ý rằng quá trình chuyển

đổi từ trạng thái starting sang trạng thái running là một trong những các hoạt động tốn

kém nhất về thời gian tính toán, và nó cũng ảnh hưởng trực tiếp đến tuổi thọ của pin.

Đó là lý do tại sao ta không thể tự động hủy các Activity mà chúng không còn được

hiển thị.

• Trạng thái Running:

Activity ở trong trạng thái running (đang hoạt động) nghĩa là Activity đó được

hiển thị trên màn hình và tương tác với người dùng. Người dùng có thể tương tác như

gõ phím, chạm vào màn hình và nhấn các nút. Tất cả các thao tác này được xử lý bởi

Activity này. Như vậy tại một thời điểm nào đó thì chỉ có một Activity.

• Trạng thái Paused:

Khi một Activity không được focus( chẳng hạn như nó không được tương tác

với người sử dụng ) nhưng nó vẫn có thể được nhìn thấy ở trên màn hình. Trong

trường hợp này ta nói Activity đang ở trạng thái tạm dừng (paused).

14

Page 28: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

• Trạng thái Stopped:

Khi một Activity không hiển thị nhưng vẫn còn ở trong bộ nhớ thì ta nói rằng nó

đang ở trạng thái dừng (Stopped). Các Activity ở trạng thái dừng này có thể được đưa

trở lại để trở thành một Activity đang chạy (running) hoặc nó cũng có thể bị phá hủy

và loại bỏ khỏi bộ nhớ. Hệ thống vẫn giữ lại các Activity xung quanh trạng thái

stopped bởi vì có thể người dùng vẫn sẽ muốn quay trở lại các Activity trước đó và

muốn khởi động lại các Activity ở trạng thái dừng, do đó sẽ tiết kiệm được thời gian

khởi động vì ta sẽ không phải khởi động một Activity lại từ đầu. Các Activity ở trạng

thái stopped có thể bị loại khỏi bộ nhớ bất cứ lúc nào.

• Trạng thái Destroyed:

Một Activity bị phá hủy thì nó không còn ở trong bộ nhớ. Trình quản lý

Activity quyết định Activity này không còn cần thiết và do đó sẽ loại bỏ Activity đó.

Trước khi Activity bị phá hủy thì nó có thể thực hiện các hành động nhất định, ví dụ

như bất kỳ một thông tin nào chưa được lưu thì nó sẽ lưu lại các thông tin đó. Tuy

nhiên trước khi bị phá hủy thì Activity sẽ được ngừng lại (stopped).

Trong suốt chu kỳ sống của Activity thì mỗi Activity của một chương trình

Android sẽ tồn tại ở vài trạng thái khác nhau. Lập trình viên không phải điều khiển

các trạng thái trong chương trình. Tất cả hoạt động đó đều được xử lý bằng cách gọi

phương thức theo cấu trúc on_ten_trang_thai(), ví dụ như onStart(), onPause(). Lập

trình viên sẽ phải ghi đè các phương thức này trong lớp Activity, và Android sẽ gọi

chúng ở thời điểm thích hợp:

onCreate(Bundle): phương thức này được gọi khi Activity khởi chạy lần đầu

tiên. Ta có thể sử dụng nó để thực thi việc khởi tạo các thành phần khác như tạo giao

diện người dùng, kết nối dữ liệu đến danh sách. Phương thức này có một tham số, nó

có thể là null hoặc là thông tin trạng thái trước đó được lưu bởi phương thức

onSaveInstanceState().

onStart: Phương thức này được gọi trước khi một Activity ẩn với người dùng.

onResume(): Được gọi khi Activity bắt đầu tương tác với người dùng. Tại thời

điểm này thì Activity ở trên đỉnh của ngăn xếp Activity.

15

Page 29: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

onPause(): Nó được gọi khi chuyển sang chế độ chạy nền, thường là khi có một

Activity khác được chạy trên nó. Tại đây ta có thể lưu lại trạng thái cố định của

chương trình cũng như ghi lại thay đổi trong cơ sở dữ liệu.

onStop(): Gọi khi Activity không còn xuất hiện với người dùng và nó sẽ không

cần tới nữa. Nếu bộ nhớ không đủ, phương thức này sẽ không bao giờ được gọi.

onRestart(): Nếu phương thức này được gọi, thì Activity sẽ được hiển thị lại từ

trạng thái stop.

onDestroy(): Phương thức này phải được gọi trước khi hủy một Activity. Nếu

bộ nhớ không đủ, phương thức này sẽ không bao giờ được gọi.

onSaveIntanceState(Bundle): Android sẽ gọi phương thức này để cho phép

Activity lưu lại trạng thái của nó. Thường ta sẽ không cần ghi đè nó bởi vì quá trình

thực hiện để lưu lại trạng thái cho tất cả các giao diện người dùng được điều khiển

một cách tự động.

onRestoreInstanceStat(Bundle): Sẽ được gọi khi Activity được khởi tạo lại từ

trạng thái được lưu trước đó, được thực hiện bởi phương thức:onSaveInstanceState():

Các Activity không chạy ở trên cùng có thể bị dừng lại hoặc hệ thống sẽ hủy tiến

trình Linux chứa Activity đó để tạo không gian cho các Activity mới.

Service

Một Service là một thành phần ứng dụng có thể thực hiện các hoạt động lâu dài

trong nền (background) mà không có bất kỳ các thành phần giao diện người dùng nào.

Chú ý là không được nhầm lẫn các dịch vụ của Android (một thành phần của ứng

dụng) với các thành phần cấp dưới của hệ điều hành như các dịch vụ Linux nguồn

(native Linux), các server. Chu kỳ sống của Service đơn giản hơn rất nhiều so với chu

kỳ sống của Activity. Hình 11 mô tả chu kỳ sống của một Service:

16

Page 30: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 12.Chu kỳ sống của Service [4]

Khi một Service sử dụng IPC, AIDL (Android Interface Definnition Language)

được sử dụng để tạo ra mã cho phép truyền thông giữa hai tiến trình qua IPC. Hình

dưới mô tả quá trình truyền thông giữa hai tiến trình:

Hình 13.Truyền thông giữa hai tiến trình

Broadcast receiver

Broadcast receiver là một thành phần thu nhận các Intent bên ngoài gửi tới. Ví

dụ: ta cần viết một chương trình thay thế cho phần gọi điện mặc định của Android khi

đó ta cần một broadcast receiver để nhận biết các Intent là các cuộc gọi tới.

Hình 14.Broadcast receiver

17

Page 31: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Content Provider

Content Provider lưu trữ và lấy dữ liệu và nó có thể truy cập vào tất cả các ứng

dụng. Đây là cách duy nhất để chia sẻ dữ liệu giữa các ứng dụng. Android với một số

Content Provider cho các loại dữ liệu( như video, âm thanh, hình ảnh, thông tin liên

lạc cá nhân, …). Các loại dữ liệu này được liệt kê trong gói android.provider. Hình

dưới mô tả chức năng của một Content Provider. Ứng dụng có thể truy xuất và chia sẻ

dữ liệu với Database qua Content Provider với các phương thức insert(), update(),

delete() và query().

Hình 15.Content Provider [4]

Hệ thống Android luôn luôn sử dụng cơ chế này. Ví dụ, trình liên hệ (Contacts

Provider) là một trình cung cấp nội dung (Conten Provider). Contacts Provider cho

thấy tất cả các dữ liệu liên hệ (contact data) người dùng đến nhiều ứng dụng. Lưu trữ

truyền thông (Media Store) sẽ chịu trách nhiệm lưu trữ và chia sẻ các phương tiện

truyền thông khác nhau, ví dụ như hình ảnh và âm nhạc trên các ứng dụng khác nhau.

Hình 14 minh họa cách sử dụng các ứng dụng liên hệ (Contacts app) sử dụng

Contacts Provider. Một ứng dụng là hoàn toàn riêng biệt để lấy dữ liệu về các liên hệ

của người dùng .

Hình 16.Ứng dụng Contacts sử dụng Contacts Provider để lấy dữ liệu

18

Page 32: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Intent

Intent là thông điệp của hệ thống chạy xung quanh ở bên trong thiết bị, thông

báo cho các ứng dụng của các sự kiện khác nhau từ việc thay đổi trạng thái phần cứng

đến việc dữ liệu đến (như một tin nhắn SMS đến) hay các sự kiện ứng dụng (như hoạt

động được đưa ra từ menu chính của thiết bị). Hay nói cách khác Inten là một miêu

tả về hoạt động cần được thực hiện, là một cơ cấu cho phép truyền thông điệp giữa

các thành phần của một ứng dụng và giữa các ứng dụng với nhau.

Một ứng dụng Android thường bao gồm nhiều Activity, mỗi Activity hoạt động

độc lập với nhau và thực hiện những công việc khác nhau. Intent chính là cầu nối giữa

các Activity, là người đưa thư giúp ta triệu gọi và truyền các dữ liệu cần thiết để thực

hiện một Activity từ một Activity khác. Hình 15 cho thấy Intent có thể được sử dụng

để “nhảy” giữa các Activity khác nhau ở trong cùng một ứng dụng hoặc trong các ứng

dụng khác nhau.

Hình 17.Intent [4]

1.9. Phát triển ứng dụng Android và DVM

Như tôi đã đề cập ở trên thì file APK là file sẽ được phát hành trên Android cho

việc thực thi các ứng dụng Android. DVM hay Dalvik Virtual Machine là máy ảo để

thực thi các ứng dụng. Hình dưới đây mô tả quá trình tạo ra một file APK:

19

Page 33: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 18.Qúa trình tạo file APK

Hình trên mô tả quá trình tạo file APK. Đầu tiên các file mã nguồn Java sẽ được

biên dịch bởi trình biên dịch Java thành các file class sau đó các file class này được

biên dịch thành một file dex bởi công cụ dx. Tiếp đó công cụ đóng gói Android (aapt)

sẽ nén tất cả các file dex, file AndroidManifest.xml và các file resource thành một file

APK. File APK này sẽ được phát hành trên Android cho việc thực thi ứng dụng. File

AndroidManifest.xml là file tự động sinh ra khi ta xây dựng bất kỳ một ứng dụng

Android nào. File này định nghĩa các thông tin về hệ thống.

Qúa trình này cũng giải thích được tại sao người ta sử dụng máy ảo Dalvik thay

vì sử dụng máy ảo Java để chạy các ứng dụng. Một ứng dụng định nghĩa nhiều lớp,

sau khi biên dịch thì rất nhiều file class được tạo ra trong đó có chứa rất nhiều những

thông tin dư thừa. Các file ở định dạng .dex có thể tích hợp tất cả các file class vào

một file duy nhất để giảm bớt kích thước của file và các hoạt động I/O. Từ đó đẩy

nhanh tốc độ tìm kiếm.

1.10. Tạo và demo ứng dụng “Hello World” sử dụng Android NDK

Android NDK (Native Development Kit) đơn giản hóa làm việc với mã nguồn

gốc. Nó bao gồm toàn bộ chuỗi công cụ cần thiết để xây dựng trên kiến trúc ARM.

Nó được thiết kế để tạo ra một thư viện chia sẻ (shared library). Lưu ý rằng mã nguồn

(native code) có thể truy cập thông qua JNI vẫn chạy bên trong máy ảo Dalvik. Hình

dưới đây mô tả tất cả các bước khi phát triển một ứng dụng Android cần phải sử dụng

đoạn mã viết bằng C/C++:

20

Page 34: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 19.Quá trình truy cập mã gốc qua JNI [4]

Tạo lớp Java biểu thị cho mã nguồn

Mã nguồn Java nằm bên trong thư mục src trong Eclipse project. Nó như là một

loại keo liên kết đến mã nguồn của ứng dụng Android ta sẽ viết ở sau. Trong file mã

nguồn Java nà ta sẽ khai báo các phương thức gốc mà sẽ được thực hiện ở trong file

mã C viết ở sau và đồng thời trong file này ta cũng viết lệnh để load thư viện chia sẻ

được dùng trong ứng dụng.

// Code chương trình:

/src/com.hop/NativeLib.java

Package com.hop;

publicclass NativeLib

{

static

{ System.loadLibrary("ndk_demo"); }

/** * Trả về chuỗi Hello World*/

public native String hello();

}

21

Page 35: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Tạo các file header mã nguồn

Trong thư mục bin của project. Ta chạy lệnh javah để tạo ra file header JNI.

Tiếp theo ta tạo một thư mục tên là jni trong thư mục project. Sau đó sao chép header

JNI từ thư mục bin vừa tạo ra ở trên đến thư mục jni.

**/ Code chuong trinh*/

NDKDemo/bin$ javah -jni com.hop.NativeLibNDKDemo/bin$ mv

com_hop_NativeLib.h ../jni/

Sau đó viết code C. Trong folder jni tạo file ndk_demo.c. Trong hàm C này ta sẽ

viết code thực hiện mã nguồn (native code). Để bắt đầu, ta sao chép các signatures

của các hàm từ file header và viết code thực hiện cho các hàm này. Trong ví dụ này

file header mà ta tạo ra dùng lệnh javah ở trên có dạng như sau:

**/code của file header JNI tao ra voi lenh javah*/

<EclipseWorkspace>/NDKDemo/jni/com_hop_NativeLib.h

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>/* Header for class com_hop_NativeLib */

#ifndef _Included_com_hop_NativeLib

#define_Included_com_hop_NativeLib

#ifdef__cplusplusextern "C"

{

#endif

/*

*Class:com_hop_NativeLib

*Method: hello

*Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL

Java_com_hop_NativeLib_hello (JNIEnv *, jobject);

#ifdef __cplusplus

22

Page 36: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

}

#endif

#endif

Thực thi mã nguồn bằng cách viết code C

Ta sẽ viết code thực hiện trong hàm C như sau:

<EclipseWorkspace>/NDKDemo/jni/ndk_demo.c

#include "com_hop_NativeLib.h"JNIEXPORTjstring JNICALL

Java_com_hop_NativeLib_hello (JNIEnv * env, jobjectobj)

{ return (*env)->NewStringUTF(env, "Hello World!");}

Biên dịch tất cả và xây dựng thư viện chia sẻ

Để xây dựng thư viện, đầu tiên ta cần tạo một makefile cho việc biên dịch code

c:

<EclipseWorkspace>/NDKDemo/jni/Android.mk

// code:

LOCAL_PATH := $(call my-dir)include

$(CLEAR_VARS)LOCAL_MODULE := ndk_demo

LOCAL_SRC_FILES := ndk_demo.cinclude

$(BUILD_SHARED_LIBRARY)

Tập tin Android.mk là một bản xây dựng nhỏ để mô tả nguồn cho NDK xây

dựng hệ thống. Cú pháp của nó được mô tả chi tiết trong file docs/Android-MK.html.

NDK nhóm các nguồn thành các module, mỗi module có thể là một thư viện tĩnh hoặc

một thư viện chia sẻ. Ta cũng có thể định nghĩa một số module trong một file

Android.mk hoặc có thể viết một số file Android.mk, mỗi file sẽ định nghĩa một

module. Chú ý rằng: một file Android.mk có thể được phân tích nhiều lần bởi hệ

thống xây dựng. Theo mặc định thì NDK sẽ xem xét cho bản xây dựng với dạng sau:

$PROJECT/jni/Android.mk

23

Page 37: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Nếu ta muốn định nghĩa các file Android.mk trong các thư mục con thì ta nên sử

dụng cấu trúc: include $(call all-subdir-makefiles). Cấu trúc này sẽ bao gồm tất cả các

file Android.mk trong các thư mục con của đường dẫn file xây dựng hiện tại.

Bước tiếp theo là cần phải nói cho NDK biết cách để xây dựng thư viện chia sẻ

và đưa nó vào nơi đúng ở bên trong Eclipse project. Để làm điều này cần tạo một

folder <NDKHOME>/apps/ndk_demo/ và ở bên trong folder này tạo file

Application.mk. Dưới đây là mã:

<NDKHOME>/apps/ndk_demo/Application.mk

APP_PROJECT_PATH := $(call my-dir)/project

APP_MODULES := ndk_demo

Trong khi file Android.mk miêu tả các module cho hệ thống xây dựng, thì file

Application.mk mô tả bản thân ứng dụng. Tập tin Application.mk bao gồm chính xác

các modul theo yêu cầu của ứng dụng và các kiến trúc CPU để tạo ra mã máy, chi tiết

xem trong file docs/APPLICATION-MK.html. Chú ý là để xem được các file này cần

tải Android NDK tại http://developer.android.com/sdk/ndk/index.html , sau đó giải

nén trong một thư mục nào đó. Bước tiếp theo ta tạo một liên kết mềm

<NDKHOME>/apps/ndk_demo/ project đến Eclipseproject. Dùng lệnh trên

command line của Ubuntu.

[username]

$lns~/Workspace/Android/NDKDemo<NDKHOME>/apps/ndk_demo/project

Sau khi làm xong các bước trên, vào trong thư mục NDK và chạy lệnh :

make APP=ndk_demo

Kết quả khi chạy lệnh trên như sau :

android-ndk-1.5_r1$ make APP=ndk_demoAndroid NDK: Building for

application 'ndk_demo'

Compilethumb :

ndk_demo<= sources/ndk_demo/ndk_demo.cSharedLibrary :

libndk_demo.soInstall : libndk_demo.so =>

apps/ndk_demo/project/libs/armeabi

24

Page 38: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Thư viện chia sẻ được tạo ra sẽ ở dạng có tiền tố lib đằng trước và đuôi là .so.

Như ví dụ trên thì thư viện chia sẻ được tạo ra là libndk_demo.so. Để chương trình

ứng dụng Android có thể sử dụng và link được đến thư viện này thì thư viện này phải

nằm trong thư mục libs/armeabi của project. Điều đó cho thấy ta đã porting được thư

viện này vào trong Android trên kiến trúc Arm.

Sử dụng mã nguồn bên trong các Activity của Android

Ta đã có thư viện native c được thực thi, biên dịch và được đặt trong một nơi

đúng. Bây giờ ta có thể gọi nó từ Activity bằng cách khởi tạo các lớp NativeLib và nó

chỉ là một đối tượng Java bình thường.

Package com.hop;

importandroid.app.Activity;

importandroid.os.Bundle;

public class NDKDemo extends Activity

{ NativeLibnativeLib;

/** Called when the activity is first created. */

@Override public void onCreate(Bundle savedInstanceState)

{ super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Cuối cùng chạy chương trình ta sẽ nhìn thấy dòng chữ Hello World.

25

Page 39: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 20.Demo ứng dụng Hello World dùng Android NDK

26

Page 40: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

CHƯƠNG 2 .CÁC PHƯƠNG PHÁP PHÁT HIỆN KHUÔN

MẶT TRÊN ANDROID

2.1. Thuật toán của Viola – Jones trong OpenCV

Ý tưởng của thuật toán phát hiện khuôn mặt của Vola – Jones là biểu diễn ảnh

theo Integral Image và sử dụng thuật toán Adaboost kết hợp với các đặc trưng Haar-

like.

2.1.1. Đặc trưng Haar-like

Có 4 đặc trưng cơ bản để xác định khuôn mặt người. Mỗi đặc trưng Haar-like là

sự kết hợp của hai hoặc ba hình chữ nhật đen trắng. Hình dưới đây mô tả 4 đặc trưng

Haar-like cơ bản:

Hình 21.Các đặc trưng Haar-like cơ bản [7]

Để phát hiện khuôn mặt thì các đặc trưng Haar-like cơ bản trên được mở rộng

thành các đặc trưng cạnh, đặc trưng đường và đặc trưng trung tâm.

Hình 22.Các đặc trưng Haar-like mở rộng [6]

Giá trị của các đặc trưng Haar-like là sự chênh lệch giữa tổng các điểm ảnh của

các vùng đen và các vùng trắng. Để có thể tính nhanh các giá trị đặc trưng này Viola

– Jones đưa ra khái niệm Integral Image. Integral Image là một mảng hai chiều với

kích thước bằng kích thước của ảnh cần tính giá trị đặc trưng Haar-like. Hình dưới

đây mô tả cách tính Integral Image:

27

Page 41: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 23.Cách tính Integral Image [8]

Sau khi đã tính được Integral Image thì việc tính tổng các giá trị mức xám của

một vùng bất kỳ nào đó trên ảnh thực hiện rất đơn giản theo cách sau:

Giả sử ta cần tính tổng các giá trị mức xám của vùng D như trong hình dưới

đây. Ta có thể tính như sau:

D = A + B + C + D – (A+B) – (A+C) + A Với A + B + C + D

Với A+B+C+D là giá trị tại điểm P4 trên Integral Image. Tương tự như vậy

A+B là giá trị tại điểm P2, A+C là giá trị tại điểm P3, A là giá trị tại điểm P1. Vậy D

được tính như sau:

Hình 24.Ví dụ cách tính nhanh các giá trị mức xám [7]

Tiếp theo để chọn các đặc trưng Haar-like dùng cho việc thiết lập ngưỡng, Viola

và Jones sử dụng một phương pháp máy học được gọi là AdaBoost. AdaBoost được

kết hợp với các bộ phân loại yếu để tạo thành một bộ phân loại mạnh. Với bộ phân

loại mạnh có thể đưa ra câu trả lời chính xác trên 60%.

2.1.2. AdaBoost

AdaBoost là một bộ phân loại mạnh phi tuyến phức dựa trên hướng tiếp cận

boosting được Freund và Schapire đưa ra vào năm 1995. AdaBoost cũng hoạt động

trên nguyên tắc kết hợp tuyến tính các bộ phân loại yếu để tạo nên một bộ phân loại

28

Page 42: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

mạnh. AdaBoost là một cải tiến của tiếp cận boosting. AdaBoost sử dụng thêm khái

niệm trọng số để đánh dấu các mẫu khó nhận dạng. Trong quá trình tập huấn cứ mỗi

bộ phân loại yếu được xây dựng thì thuật toán sẽ tiến hành cập nhật lại trọng số để

chuẩn bị cho việc xây dựng bộ phân loại yếu tiếp theo. Cập nhật bằng cách tăng trọng

số của các mẫu bị nhận dạng sai và giảm trọng số của các mẫu được nhận dạng đúng

bởi bộ phân loại yếu vừa xây dựng. Bằng cách này thì bộ phân loại yếu sau có thể tập

trung vào các mẫu mà bộ phân loại yếu trước nó làm chưa tốt. Cuối cùng là các bộ

phân loại yếu sẽ được kết hợp lại tùy theo mức độ tốt của chúng để tạo nên một bộ

phân loại mạnh AdaBoost. Viola – Jones dùng AdaBoost kết hợp với các bộ phân loại

yếu sử dụng các đặc trưng Haar-like theo mô hình cascade sau:

Hình 25.Mô hình cascade kết hợp với các bộ phân loại yếu [7]

Trong đó hk là các bộ phân loại yếu được biểu diễn như sau:

x là cửa sổ con cần xét, θk là ngưỡng, fk là giá trị đặc trưng Haar-like và pk là hệ

số quyết định chiều của phương trình. Hình dưới đây mô tả quá trình kết hợp các bộ

phân loại yếu thành bộ phân loại mạnh.

29

Page 43: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Hình 26.Kết hợp các bộ phân loại yếu thành bộ phân loại mạnh

2.1.3. Mô hình phát hiện khuôn mặt

Hình dưới đây là mô hình phát hiện khuôn mặt của thuật toán do Viola và Jones

đưa ra.

Hình 27. Hệ thống phát hiện khuôn mặt

Từ ảnh gốc ban đầu ta sẽ tính được Integral Image là mảng hai chiều với phần

tử (x, y) sẽ được tính bằng tổng của các phần tử (x’, y’) với x’<x và y’<y. Mục đích

là để tính nhanh tổng của các giá trị mức xám của một vùng hình chữ nhật bất kỳ trên

ảnh gốc. Các vùng ảnh con này sẽ được đưa qua các hàm Haar cơ bản để ước lượng

đặc trưng. Kết quả ước lượng sẽ được đưa qua bộ điều chỉnh AdaBoost để loại bỏ

nhanh các đặc trưng không có khả năng là đặc trưng của khuôn mặt người. Chỉ có

một tập nhỏ các đặc trưng mà bộ điều chỉnh AdaBoost cho là có khả năng là đặc

30

Page 44: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

trưng của khuôn mặt. Tập các đặc trưng này sẽ được chuyển sang cho bộ quyết định

kết quả. Bộ quyết định kết quả là tập các bộ phân loại yếu . Bộ này sẽ tổng hợp kết

quả là khuôn mặt người nếu kết quả của các bộ phân loại yếu trả về là khuôn mặt.

Mỗi bộ phân loại yếu sẽ quyết định kết quả cho một đặc trưng Haar-like, được

xác định ngưỡng đủ nhỏ sao cho có thể vượt được tất cả các bộ dữ liệu mẫu trong tập

dữ liệu tập huấn. Trong quá trình xác định khuôn mặt người, mỗi vùng ảnh con sẽ

được kiểm tra với các đặc trưng trong chuỗi các đặc trưng Haar-like. Nếu có một đặc

trưng Haar-like nào cho ra kết quả là khuôn mặt người thì các đặc trưng khác không

cần xét nữa.

2.2. Phát hiện khuôn mặt sử dụng framework API của Android

2.2.1.Gói android.graphics

Gói này cung cấp các công cụ đồ họa cấp thấp như canvas, các bộ lọc màu sắc,

điểm, và hình chữ nhật, cho phép ta xử lý và vẽ ra màn hình trực tiếp.

Trong gói này có các lớp con như:

• Bitmap.

• BitmapFactory– tạo các đối tượng Bitmap từ nhiều nguồn khác nhau, bao gồm

các tập tin, các dòng (stream), và các mảng byte. Trong lớp này có lớp con

BitmapFactory.Options.

• BitmapRegionDecoder– được sử dụng để giải mã vùng hình chữ nhật từ một

hình ảnh.

• BitmapShader– được sử dụng để vẽ ảnh bitmap như một kiến trúc (texture).

• Camera – một camera có thể được sử dụng để tính toán biến đổi 3D và tạo ra

một ma trận có thể được áp dụng, ví dụ như trên Canvas.

• Canvas- lớp Canvas giữ yêu cầu vẽ.

• Color- lớp color xác định các phương thức cho việc tạo và chuyển đổi số

nguyên về màu sắc.

• ImageFormat- cung cấp các định dạng màu như JPEG (định dạng được mã

hóa), NV16 (định dạng YCbCr được sử dụng cho video), NV21 (định dạng YCrCb

được sử dụng cho ảnh, sử dụng định dạng mã hóa NV21), RGB-565(định dạng RGB

được sử dụng cho ảnh mã hóa như RGB-565), UNKNOWN( giá trị không đổi là 0),

31

Page 45: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

YUY2 (định dạng YCbCr được sử dụng cho ảnh, sử dụng định dạng mã hóa YUY2),

và cuối cùng là định dạng YV12(định dạng YUV android: định dạng này được tiếp

xúc với bộ giải mã phần mềm và ứng dụng).

• Matrix- lớp Matrix giữ một ma trận cỡ 3x3 cho việc chuyển đổi tọa độ.

• Paint-lớp Paint nắm giữ thông tin về màu sắc về việc làm thế nào để vẽ hình,

văn bản và các ảnh bitmap.

• PixelFormat-bao gồm các định dạng A_8, JPEG, LA_88, L_8, RGB-322,

RGB-565,….

• Rect-có chức năng nắm giữ tọa độ 4 số nguyên cho hình chữ nhật.

và còn nhiều các lớp và các hàm con khác.

Trong ứng dụng phát hiện khuôn mặt ta sẽ sử dụng một số lớp trong gói

android.graphics bằng cách viết lệnh trong mã nguồn Java:

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PoinF;

2.2.2.Gói android.app

Gói này chứa các lớp cấp cao đóng gói mô hình ứng dụng android.Một ứng

dụng Android được xác định bằng cách sử dụng một hoặc nhiều hơn 4 thành phần

ứng dụng lõi của Android. Trong gói này có hai thành phần ứng dụng được định

nghĩa là: hoạt động (Activity) và dịch vụ (Service). Trong gói android.content có hai

thành phần khác là BroadcastReceiver và Contentprovider. Gói android.app cung cấp

một số lớp với các chức năng nhất định. Dưới đây là một số lớp:

• ActionBar- đây là giao diện công cộng cho các ActionBar. Các hoạt động của

ActionBar như là một thay thế cho các thanh tiêu đề trong các Activity. Nó cung cấp

cơ sở cho việc tạo ra các hành động cũng như các phương thức điều hướng trên một

ứng dụng.

32

Page 46: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

• Activity- một hoạt động là đơn lẻ, những gì người dùng có thể làm được tập

trung. Hầu như tất cả các hoạt động đều tương tác với người sử dụng, vì vậy lớp

Activity sẽ tạo ra một cửa sổ mà có thể đặt giao diện người dùng với setContenView

(View). Trong khi các hoạt động thường được trình bày cho người sử dụng như là cửa

sổ toàn màn hình, chúng cũng có thể được trình bày theo những cách khác như : cửa

sổ nổi hoặc nhúng bên trong một hoạt động (sử dụng ActivityGroup).

• AcivityGroup- là một màn hình có chứa và chạy nhiều các hoạt động nhúng.

• ActivityManager- Tương tác với các hoạt động chạy trong hệ thống.

• ActivityManager.MemoryInfo- Ta có thể có được thông tin về bộ nhớ sẵn có.

• ActivityManager.ProcessErrorSateInfo- thông tin có thể lấy được về bất kỳ

quá trình nào có lỗi xảy ra.

• ActivityManager.RecentTaskInfo- thông có thể lấy được về nhiệm vụ mà

người dùng gần đây nhất bắt đầu hoặc truy cập.

• ActivityManager.RunningAppProcessInfo- thông tin có thể lấy được về quá

trình chạy chương trình.

• ActivityManager.RunningServiceInfo- thông tin có thể lấy được về một dịch

vụ cụ thể mà hiện đang chạy trong hệ thống.

• ActivityManager.RunningTaskInfo-thông tin có thể lấy được về một nhiệm

vụ cụ thể mà hiện tại đang chạy trong hệ thống.

• AlarmManager- Lớp này cung cấp truy cập đến các dịch vụ báo động hệ

thống.

• AlertDialog- đây là một lớp con của hộp thoại (Dialog) có thể hiển thị một, hai

hoặc ba nút (button).

• Application-đây là lớp cơ sở cho những ai cần phải duy trì trạng thái ứng dụng

toàn cầu.

• FragmentTransaction- giao diện để tương tác với các đối tượng Fragment bên

trong một Activity.

• Instrumentation-đây là lớp cơ sở cho việc thực thi mã ứng dụng.

• Instrumentation.ActivityResult- mô tả kết quả thực thi của một Activity để trả

về cho activity ban đầu.

33

Page 47: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

• LauncherActivity-hiển thị một danh sách tất cả các hoạt động có thể được thực

hiện cho một mục đích nhất định.

• LauncherActivity.IconResizer- tiện ích để thay đổi kích thước các biểu tượng

(icon) để phù hợp với kích thước biểu tượng mặc định.

• ListActivity- một Activity có thể hiển thị một danh sách các mục bằng cách

liên kết với một nguồn dữ liệu như một một mảng và đưa ra xử lý sự kiện khi người

dùng chọn một mục.

Và còn có một số lớp khác như NativeActivity, Notification,…Trong ứng dụng

phát hiện khuôn mặt ta sử dụng lớp Activity bằng cách viết trong mã nguồn Java :

import android.app.Activity;

2.2.3.Gói android.content

Chứa các lớp cho việc truy cập và xuất bản dữ liệu trên thiết bị. Nó bao gồm ba

loại chính của APIs: Thứ nhất là chia sẻ nội dung: đối với nội dung chia sẻ (sharing

content) giữa các thành phần ứng dụng thì các lớp quan trọng nhất là:

• ContentProvider và ContentResolver cho việc quản lý và xuất bản dữ liệu kết

hợp với ứng dụng.

• Intent và IntentFilter, để cung cấp các tin nhắn cấu trúc giữa các thành phần

ứng dụng khác nhau cho phép các thành phần khởi tạo các thành phần khác và trả về

kết quả.

Thứ hai là quản lý gói (android.content.pm) : Để truy cập thông tin về một gói

Android (.apk), bao gồm thông tin về các hoạt động, quyền (permission), dịch vụ,

giao diện, bộ cung cấp (provider). Các lớp quan trọng nhất để truy cập thông tin này

là PackageManager.

Thứ ba là quản lý tài nguyên (android.content.res): Để lấy dữ liệu tài nguyên

kết hợp với một ứng dụng, chẳng hạn như chuỗi, drawables, truyền thông và chi tiết

về cấu hình thiết bị. Các lớp quan trọng nhất để truy cập dữ liệu này là Resources- lớp

này để truy cập tài nguyên của ứng dụng.

Hệ thống tài nguyên Android theo dõi tất cả assets phi mã (non-code) kết hợp

với một ứng dụng. Assets là một thư mục trong Android project. Ta có thể có được

thể hiện của Resources liên quan đến ứng dụng với getResources().

34

Page 48: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Các công cụ Android SDK biên dịch các tài nguyên ứng dụng vào các ứng dụng

nhị phân ở thời gian xây dựng. Để sử dụng một resource thì cần phải cài đặt một cách

chính xác trong cây mã nguồn (nằm bên trong thư mục res của project) và xây dựng

các ứng dụng. Như một phần của quá trình xây dựng, các công cụ SDK tạo ra các

biểu tượng cho mỗi tài nguyên mà có thể được sử dụng trong mã ứng dụng để truy

cập vào tài nguyên.

Sử dụng tài nguyên ứng dụng giúp cho việc cập nhật các đặc điểm khác nhau

của các ứng dụng mà không cần thay đổi mã, và bằng cách cung cấp bộ tài nguyên

thay thế, cho phép tối ưu hóa ứng dụng đối với một loạt các cấu hình thiết bị (chẳng

hạn như cho các ngôn ngữ khác nhau và kích cỡ màn hình). Đây là một khía cạnh

quan trọng để phát triển ứng dụng Android được tương thích trên các loại thiết bị

khác nhau.

Trong gói android.content có chứa một số lớp con trong đó có lớp context – đây

là một lớp trừu tượng trong đó sự thực thi được cung cấp bởi hệ thống Android. Nó

cho phép truy cập vào tài nguyên ứng dụng cụ thể và các lớp, …

Trong ứng dụng phát hiện khuôn mặt ta sử dụng lớp Context bằng cách viết

trong mã nguồn Java: import android.content.Context;

2.2.4.Gói android.media

Gói này cung cấp các lớp quản lý các giao diện truyền thông khác nhau trong

audio và video.Các giao diện lập trình ứng dụng viết tắt là API (Appication

Programming Interface) Media trong một số trường hợp để chơi (play) và ghi lại

(record) các tập tin media – bao gồm âm thanh (ví dụ như chơi nhạc MP3 hoặc các

file nhạc khác, nhạc chuông, hiệu ứng âm thanh trò chơi) và video (ví dụ như bật một

đoạn video xem trực tiếp qua web).

Các lớp đặc biệt khác trong gói cung cấp khả năng phát hiện khuôn mặt người

trong ảnh Bitmap (FaceDetector), điều khiển âm thanh định tuyến (với điện thoại

hoặc tai nghe) và điều khiển cảnh báo như nhạc chuông và tiếng rung của điện thoại

( lớp AudioManager). Trong ứng dụng ta sử dụng các lớp trong gói này bằng cách

viết trong mã nguồn Java:

import android.media.FaceDetector;

import android.media.FaceDetector.Face;

Các lớp FaceDetector và FaceDetector.Face sẽ trình bày ở phần sau

35

Page 49: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

2.3. Xây dựng chương trình phát hiện khuôn mặt trên Android

Android cung cấp một lớp android.media.FaceDetector để xác định khuôn mặt

người trong ảnh Bitmap. Các lớp FaceDetector và FaceDetector.Face do android

SDK cung cấp [11]. Các lớp này có mặt trong android.media. Ta có thể vào trang

phát triển của Google để tìm hiểu về các gói và các lớp Android hỗ trợ. Hình dưới đây

mô tả các gói Android hỗ trợ trong trang phát triển của Google:

Hình 28.Các gói Android cung cấp trong framework API

2.3.1.Mô hình phát hiện khuôn mặt trên Android sử dụng framework API

Hình 29.Mô hình phát hiện khuôn mặt trên Androi

Khối Image input:

Ảnh đầu vào là ảnh bitmap với định dạng RGB-565 và kích thước ảnh là

320x480 .

36

Page 50: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Khối FaceDetector:

Khối này thực hiện chức năng phát hiện khuôn mặt trong đối tượng ảnh bitmap.

Lớp FaceDetector trong khối này nhận các thông số của ảnh đầu vào là chiều rộng ,

chiều cao của ảnh để phân tích và số lượng tối đa khuôn mặt có thể phát hiện được.

Khi một đối tượng được xây dựng thì những thông số này không thể thay đổi được.

Lớp FaceDetector nằm trong gói android.media.

Khối findFaces:

Khối này có chức năng tìm tất cả các khuôn mặt trong một bức ảnh. Hàm thực

hiện chức năng này là:

Public int findFaces (Bitmap bitmap, Face[]faces)

Hàm này trả về số lượng khuôn mặt. Ở hàm trên với thông số faces là một mảng

chứa tất cả các thông tin để xác định vị trí của một khuôn mặt trong ảnh bitmap. Các

thông tin này được lưu trong lớp FaceDetector.Face. Một khuôn mặt với các tư thế

chụp ảnh khác nhau. Phát hiện khuôn mặt dựa trên các góc Euler của khuôn mặt ,

khoảng cách giữa hai mắt và vị trí của điểm giữa hai mắt.

Góc Euler đại diện cho sự định hướng không gian của bất kỳ hệ quy chiếu nào

như một thành phần của phép quay từ một hệ quy chiếu. Trong hệ tọa độ cố định

được kí hiệu là (x, y, z) và trong hệ quay được kí hiệu bằng chữ in hoa (X, Y, Z). Với

một hệ quy chiếu có các hướng cần mô tả, đầu tiên xác định đường thẳng đi qua nút

N như hình vẽ dưới đây:

Hình 30.Các góc Euler- hệ tọa độ xyz (cố định), hệ tọa độ XYZ (quay)

Với N là giao điểm của các mặt phẳng tọa độ xy và XY. Đường thẳng đi qua nút

N được thể hiện bằng màu xanh lá cây với:

α là góc giữa trục x và đường thẳng qua nút.

β là góc giữa trục z và trục Z.

37

Page 51: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

γ là góc giữa đường thẳng của các nút và trục X.

Trong lớp FaceDetector.Face ta sử dụng một hàm Pose (int euler). Hàm này sẽ

trả về tư thế của khuôn mặt hay góc Euler của khuôn mặt đối với trục tọa độ cho

trước. Đó là phép quay quanh hoặc là theo trục X, hoặc là theo trục Y, hoặc là theo

trục Z (Các vị trí trong không gian Euclide 3- chiều). Với thông số euler là tọa độ

Euler để lấy một góc từ (EULER_X hoặc EULER_Y hoặc EULER_Z). Trong đó

EULER_X là trục X góc Euler của khuôn mặt với giá trị không đổi : 0(0x00000000);

EULER_Y là trục Y góc Euler của khuôn mặt với giá trị không đổi: 1(0x00000001);

EULER_Z là trục Z góc Euler của khuôn mặt với giá trị không đổi là: 2(0x00000002).

// mã thực thi hàm pose (int euler)

Để cho kết quả phát hiện khuôn mặt được tốt nhất thì thông số hệ số tin

cậy trên 0.3 thường là đủ tốt. Ta sử dụng hàm confidence() , trả về hệ số an toàn giữa

0 và 1. Dưới đây là mã nguồn thực thi các hàm:

38

Page 52: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Khối drawRect

Sau khi qua khối findFaces phát hiện ra tất cả các khuôn mặt thì khối drawRect

sẽ thực hiện chức năng vẽ khung hình chữ nhật lên khuôn mặt phát hiện được sử dụng

đồ họa canvas trong gói android.graphics.

39

Page 53: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

2.3.2.Viết chương trình ứng dụng phát hiện khuôn mặt trên Android

Phần này tôi trình bày về các thành phần trong một ứng dụng Android

cụ thể với ứng dụng phát hiện khuôn mặt trên Android sử dụng APIs của Android

trong tầng Applications framework.

Hình 31.Các thành phần trong một Android Project

Thư mục src

Thư mục này chứa tất cả các lớp do người dùng xác định, bao gồm lớp hoạt

động mặc định. Trong thư mục này là code cho mã nguồn Java. Dưới đây là mã

nguồn Java cho ứng dụng phát hiện khuôn mặt. Ta sử dụng các phương thức gọi các

hàm trên trong chương trình Java:

40

Page 54: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

41

package hop.android;

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;// sử dụng canvas để vẽ.

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PointF;

import android.media.FaceDetector;

import android.media.FaceDetector.Face;

import android.os.Bundle;

import android.view.View;

public class AndroidFaceDetector extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//setContentView(R.layout.main);

setContentView(new myView(this));

}

private class myView extends View{

private int imageWidth, imageHeight;

private int numberOfFace = 5;// số khuôn mặt cần detect.

private FaceDetector myFaceDetect;

private FaceDetector.Face[] myFace;

Page 55: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

42

float myEyesDistance;

int numberOfFaceDetected;

Bitmap myBitmap;

public myView(Context context) {

super(context);

BitmapFactory.Options BitmapFactoryOptionsbfo = new

BitmapFactory.Options();

BitmapFactoryOptionsbfo.inPreferredConfig =

Bitmap.Config.RGB_565;

myBitmap =

BitmapFactory.decodeResource(getResources(),

R.drawable.face5,

BitmapFactoryOptionsbfo);

imageWidth = myBitmap.getWidth();

imageHeight = myBitmap.getHeight();

myFace = new FaceDetector.Face[numberOfFace];

myFaceDetect = new FaceDetector(imageWidth,

imageHeight, numberOfFace);

numberOfFaceDetected =

myFaceDetect.findFaces(myBitmap, myFace);

}

@Override

protected void onDraw(Canvas canvas) {

canvas.drawBitmap(myBitmap, 0, 0, null);

Paint myPaint = new Paint();

Page 56: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

43

myPaint.setColor(Color.GREEN);

myPaint.setStyle(Paint.Style.STROKE);

myPaint.setStrokeWidth(3);

/** thuật toán lấy điểm giữa và khoảng cách hai mắt

** với biến i chạy từ 0 đến số lượng khuôn mặt cần phát hiện*/

for(int i=0; i < numberOfFaceDetected; i++)

{

Face face = myFace[i];

PointF myMidPoint = new PointF();

face.getMidPoint(myMidPoint);

myEyesDistance = face.eyesDistance();

/** vẽ hình chữ nhật với canvas*/

canvas.drawRect(

(int)(myMidPoint.x - myEyesDistance),

(int)(myMidPoint.y - myEyesDistance),

(int)(myMidPoint.x + myEyesDistance),

(int)(myMidPoint.y + myEyesDistance),

myPaint);

}

}

}

}

Page 57: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Thư mục gen

Chứa các tệp do ADT tạo tự động. Tệp R.java bên trong thư mục này chứa các

tham chiếu tĩnh tới tất cả các tài nguyên hiện có trong thư mục res để cho chúng có

thể tham khảo dễ dàng và động từ mã Java. Tệp này được tự động sinh ra khi xây

dựng ứng dụng.

44

package hop.android;

public final class R {

public static final class attr {

}

public static final class drawable {

public static final int face3=0x7f020000;

public static final int face4=0x7f020001;

public static final int face5=0x7f020002;

public static final int icon=0x7f020003;

}

public static final class layout {

public static final int main=0x7f030000;

}

public static final class string {

public static final int app_name=0x7f040001;

public static final int hello=0x7f040000;

}

}

Page 58: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Thư mục res

Chứa tất cả các tài nguyên cho project: Các biểu tượng, các hình ảnh, các chuỗi

ký tự và các bố trí. Thư mục res bao gồm:

Các thư mục drawable : Dành cho tất cả các tệp hình ảnh.

Thư mục layout:

Dành cho các bố trí quy định các màn hình giao diện người dùng cho các hoạt

động dưới dạng mã XML. Tệp Main.xml được tự động tạo ra. Thư mục này gắn liền

với cách bố trí thẳng đứng mặc định. Tệp Main.xml có một biểu diễn giao diện người

dùng, có thể kéo thả các bố trí khác nhau và các khung nhìn trên một màn hình trống

để xây dựng các thành phần giao diện người dùng cho hoạt động này. Dưới đây là nội

dung của tệp Main.xml:

45

<?xml version="1.0" encoding="utf-8"?><LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /></LinearLayout>

Page 59: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Thư mục bin

Chứa các tệp class được biên dịch và một số tệp sau:

Hình 32. Các tệp trong thư mục bin của Android Project.

Tệp class.dex: Tệp có thể thực thi được tạo ra từ các lớp biên dịch.

Tệp Tran_Thi_Hop_FaceDetect.apk: Tệp lưu trữ nén sẽ được chuyển đến

thiết bị Android. Ứng dụng này có thể được cài đặt trên thiết bị Android bất kỳ thông

qua tệp lưu trữ này.

Tệp resources.ap_: Tệp các tài nguyên ứng dụng nén.

AndroidManifest.xml

Mỗi ứng dụng phải có một file AndroidManifest.xml nằm trong thư mục gốc

của nó. File này định nghĩa các thông tin cần thiết về ứng dụng cho hệ thống Android,

thông tin hệ thống phải có trước khi nó có thể chạy bất kỳ code của ứng dụng. Đây là

một phần rất quan trọng của ứng dụng Android.

Khi ta tạo một ứng dụng Android sử dụng Eclipse thì sẽ sinh ra file

AndroidManifest.xml. File này được tự động sinh ra bởi Eclipse. Vì vậy, ta không

bận tâm đến việc tạo ra nó mà hãy quan tâm đến nội dung bên trong file này. Dưới

đây là nội dung của một file AndroidManifest.xml tự động được sinh ra khi tạo ứng

dụng phát hiện khuôn mặt:

46

Page 60: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

Thẻ <application>, bên trong thẻ này chứa các thuộc tính được định

nghĩa cho ứng dụng Android như :

• android:icon = “drawable resource” ở đây đặt đường dẫn đến file icon của

ứng dụng khi cài đặt. Ví dụ: android:icon = “@drawable/icon”.

Thẻ <activity>, bên trong thẻ này có các thuộc tính:

• android:name = “string” tên của lớp thực hiện Activity hay nó là một lớp

con của Activity. Trong ứng dụng này là : AndroidFaceDetector.

• android:label – nhãn cho Activity, được hiển thị trên màn hình khi Activity

được chạy. Nó thường được hiển thị cùng với biểu tượng của hoạt động. Trong file

manifest trên thì nhãn tên là Tran_Thi_Hop_FaceDetection.

Ngoài ra còn có nhiều thuộc tính khác, chi tiết xem tại :

http://developer.android.com/guide/topics/manifest/manifest-

intro.html#filestruct

47

<?xml version="1.0" encoding="utf-8"?><manifest

xmlns:android="http://schemas.android.com/apk/res/android" package="hop.android" android:versionCode="1" android:versionName="1.0"><uses-sdk android:minSdkVersion="8" />

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".AndroidFaceDetector" android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category

android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

</application></manifest>

Page 61: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

CHƯƠNG 3. KẾT QUẢ ĐẠT ĐƯỢC

3.1. Kết quả phát hiện khuôn mặt sử dụng framework API của Android

Hình 33.Hình ảnh gốc ban đầu

Hình 34.Kết quả phát hiện khuôn mặt trên Android

48

Page 62: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

3.2. Khó khăn và hướng giải quyết

Như tôi đã đề cập trong phần kiến trúc Android. Khi viết chương trình ứng dụng

cho Android ta phải sử dụng ngôn ngữ Java. Trong bài toán phát hiện khuôn mặt sử

dụng thuật toán của Viola – Jones trong OpenCV thì vấn đề khó khăn là để Java có

thể gọi được các thư viện của OpenCV viết bằng ngôn ngữ C và C++ thì cần phải

thành thạo ngôn ngữ lập trình JNI. Do thời gian hạn chế nên khóa luận này tôi chỉ đưa

ra hướng giải quyết sử dụng JNI để viết chương trình phát hiện khuôn mặt sử dụng

OpenCV trên Android. Quy trình xây dựng và thực thi ứng dụng sẽ giống với quy

trình tạo và demo ứng dụng “Hello World” dùng Android NDK mà tôi đã trình bày ở

phần trên. Chúng ta đã porting được OpenCV vào Android rồi, vấn đề chỉ là tìm hiểu

về lập trình JNI để tiếp tục phát triển ứng dụng. Đây cũng là hướng phát triển đề tài

trong tương lai.

49

Page 63: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

KẾT LUẬN

Khóa luận này đưa ra được tổng quan về hệ điều hành Android. Đây là nền tảng

để cho những ai mới bắt đầu lập trình với Android. Khóa luận đã đạt được những

mục tiêu cần tìm hiểu để xây dựng chương trình ứng dụng Android.

Trong khóa luận tôi đã trình bày về kiến trúc Android trong đó có demo một

chương trình ứng dụng phát hiện khuôn mặt sử dụng framework API của Android

trong tầng Applications framework. Từ đó giúp phát triển thêm các ứng dụng khác sử

dụng framework API để xây dựng. Trước khi xây dựng chương trình ứng dụng thì tôi

trình bày về các thành phần tạo nên một ứng dụng cho Android ;quá trình một ứng

dụng được thực thi như thế nào; các thành phần trong một dự án Android ; sự khác

biệt giữa máy ảo Java và máy ảo Dalvik và trình bày về cách porting thư viện

OpenCV và thuật toán phát hiện khuôn mặt của Viola – Jones được sử dụng trong

OpenCV.

Môi trường cần để xây dựng và thực thi các ứng dụng cho Android đó là các

ngôn ngữ lập trình Java, JNI, C/C++. Ngoài ra Android dựa trên nền tảng Linux nên

môi trường tốt để viết các ứng dụng là Linux hoặc Ubuntu. Tuy nhiên cũng có thể

viết trên Windows nhưng phải dùng đến swing để dùng các lệnh của Linux. Dùng

Ubuntu sẽ ít gặp rắc rối về lỗi và virus.

Khóa luận cũng đã trình bày về Android SDK, Android NDK là các công cụ hỗ

trợ mạnh cho phát triển các ứng dụng Android. Tôi cũng đưa ra được các quy trình

làm một dự án phần mềm với các công cụ này. Một ví dụ đơn giản để từ đó hiểu được

quy trình làm một dự án và chương trình được thực thi như thế nào trên Android. Từ

đó sau này có thể phát triển thêm nhiều ứng dụng hấp dẫn khác cho Android.

Tóm lại để có thể xây dựng và phát triển các ứng dụng Android thì cần phải có

kiến thức về Android được trình bày trong khóa luận và biết lập trình Java, JNI, C/C+

+ và nắm chắc kiến thức về Linux với lập trình shell và các tập lệnh của Linux.

TÀI LIỆU THAM KHẢO

50

Page 64: 90452216-Hệ-điều-hanh-ANDROID-va-thực-thi-ứng-dụng-phat-hiện-khuon-mặt-tren-ANDROID

TÀI LIỆU TIẾNG ANH:

[1] AndroidTM A Programmer’s Guide, J.F. DiMarzio, Pulisher: McGraw-Hill

Proesional, 2008.

[2] Harvey M. Deitel, Paul J.Deitel, Java How to Program (4th Edition), Publisher:

Prentice Hall PRT Upper Saddle River, NJ, USA, 2001.

[3] James Steele Nelson To, The Android Developer’s Cookbook Building

Applications with the Android SDK, Publisher: Add ison-Wes ley, 2010.

[4] Marko Gargenta, Learning Android, Publisher: O’Reilly Media, 1 edition, 2010.

[5] Robin Hewitt, Seeing with OpenCV, Servo magazine, January 2007, Inc.

[6] Rainer Lienhart and Jochen Maydt, “An extended set of Haar- like features for

Rapid Object Detection”, Intel Labs, Intel Corporation, Santa Clara, CA 95052, USA.

[7] Sheng Liang, The JavaTM Native Interface, Programmer’s Guide and

Specification, Publisher: Prentice Hall PRT, 1st edition, 1999.

[8] Viola–Jones, “Rapid Object Detection using a Boosted Cascade of Simple

Features”, Accepted conference on Computer Vision and pattern recognition 2001.

[9] Viola–Jones, “Robust Real-time Object Detection”, Second international

workshop on statistical and computational theories of vision – modeling, learning,

computing, and sampling, Vancouver, Canada, July 13, 2001.

[10] W. Frank Ableson, Charilie Collins, Robi Sen, Unlocking Android, Publisher:

Manning Publications, 2009.

[11] http://developer.android.com

51