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

Một phần của tài liệu hệ điều hành android và thực thi ứng dụng phát hiện khuôn mặt trên android (Trang 49 - 61)

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 FaceDetectorFaceDetector.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

 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 .

 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:

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.

 γ 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:

 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.

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:

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; (adsbygoogle = window.adsbygoogle || []).push({});

private int numberOfFace = 5;// số khuôn mặt cần detect. private FaceDetector myFaceDetect;

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();

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); } } } }

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.

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; }

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: (adsbygoogle = window.adsbygoogle || []).push({});

<?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>

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:

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 <?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>

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

Một phần của tài liệu hệ điều hành android và thực thi ứng dụng phát hiện khuôn mặt trên android (Trang 49 - 61)