12/08/2018, 17:44

Face Detection with Mobile Vision API

Gần đây chúng ta đã quá quen với các kỹ thuật xử lý hình ảnh đặc biệt vấn đề nhận dạng hình ảnh. Các hãng sản xuất điện thoại đua nhau trình diễn các công nghệ về nhận dạng khuôn mặt và ứng dụng của nó vào bảo mật, vào các tính năng đầy hấp dẫn. Và để không bị lạc hậu quá với thời đại, sau đây mình ...

Gần đây chúng ta đã quá quen với các kỹ thuật xử lý hình ảnh đặc biệt vấn đề nhận dạng hình ảnh. Các hãng sản xuất điện thoại đua nhau trình diễn các công nghệ về nhận dạng khuôn mặt và ứng dụng của nó vào bảo mật, vào các tính năng đầy hấp dẫn. Và để không bị lạc hậu quá với thời đại, sau đây mình sẽ giới thiệu một cách đơn giản và dễ dàng để Nhận Diện Mặt Người - Face Detection trên Android.

Bắt đầu từ phiên bản 7.8 của Google Play services, bạn đã có thể sử dụng một tính năng mới của Mobile Vision APIs đó là Face Detection APIs. Đây là API hỗ trợ phát hiện mặt người trên ảnh và video khá nhanh và tốt, đồng thời nó cũng cung cấp một số dịch vụ khác như: understanding faces at different orientations, detecting facial features và understanding facial expressions.

Face Detection là một bước phát triển mới từ Android FaceDetector.Face API. Nó được thiết kế tốt hơn để phát hiện mặt người ở trong ảnh và video, nó có thể nhận diện được khuôn mặt ngay cả ở các hướng khác nhau, vì vậy dù chủ thể có thể ngồi lệch sang một bên, nó vẫn có thể phát hiện ra được. Ngay cả các thành phần trên khuôn mặt cũng có thể xác định được như mắt, mũi, môi.

Chú ý: Face Detection API không phải là Face Recognition API - Nhận Dạng Khuôn Mặt. Nó chỉ là API dùng để phát hiện mặt người trong ảnh hoặc video.

Sau đây mình sẽ hướng dẫn các bạn build một app android đơn giản để có thể sử dụng Face Detection API này.

Configure Build.gradle

Đầu tiên ta cần import lib cái đã:

compile 'com.google.android.gms:play-services-vision:9.4.0+'

Chú ý: Khi bạn import play-services-vision version 9.4.0+ tức là target của Google play services trên máy điện thoại cũng là 9.4.0+, nếu version của Google play services trên máy thấp hơn thì api sẽ không hoạt động được, bạn cần phải hạ version của play-services-vision xuống hoặc update services trên điện thoại lên, nhưng dù có hạ hay nâng gì thì cũng phải bắt buộc phải là 7.8+ nha.

Configure AndroidManifest.xml

<meta-data android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version"/>

<meta-data
    android:name="com.google.android.gms.vision.DEPENDENCIES"
    android:value="face" />

Face Detector with Image

Nếu bạn chỉ muốn sử dụng Face Detection API để phát hiện mặt người trên một bức ảnh xác định, đã có nào đó thì rất là đơn giản.

Đầu tiên ta cần get ảnh đó lên dưới dạng bitmap:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable=true;
Bitmap myBitmap = BitmapFactory.decodeResource(
        getApplicationContext().getResources(), 
        R.drawable.image_test, 
        options);

Tiếp theo tạo một Face Detector:

FaceDetector faceDetector = new FaceDetector.Builder(getApplicationContext())
			.setTrackingEnabled(false)
			.build();

Và detect face thôi:

Frame frame = new Frame.Builder().setBitmap(myBitmap).build();
SparseArray<Face> faces = faceDetector.detect(frame);

Đối tượng trả về là Face sẽ chứa các tọa độ của vùng chứa khuôn mặt trên bitmap, và bạn có thể thực hiện vẽ 1 khung vuông màu trên đó để xác định vùng được phát hiện:

Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);

Paint myRectPaint = new Paint();
myRectPaint.setStrokeWidth(5);
myRectPaint.setColor(Color.RED);
myRectPaint.setStyle(Paint.Style.STROKE);

for(int i=0; i<faces.size(); i++) {
  Face thisFace = faces.valueAt(i);
  float x1 = thisFace.getPosition().x;
  float y1 = thisFace.getPosition().y;
  float x2 = x1 + thisFace.getWidth();
  float y2 = y1 + thisFace.getHeight();
  tempCanvas.drawRoundRect(new RectF(x1, y1, x2, y2), 2, 2, myRectPaint);
}

Như vậy là ta đã có thể xác định khuôn mặt trên một bức ảnh cụ thể rồi.

Face Detector with Camera

Để sử dụng FaceDetector với Camera thì sẽ phức tạp hơn, nhưng sẽ thú vị và hay hơn, bạn có thể giơ giơ cam ra và soi soi xem đâu là mặt người, nếu thằng nào mà không xác định được thì ... =))

Đầu tiên bạn cần xây dựng 1 CameraSource: phần này khá dài và phức tạp nên bạn có thể tham khảo code trực tiếp tại đây.

Tiếp theo chúng ta cần 1 class để thực hiện vẽ các khung vuông màu lên vùng xác định được khuôn mặt FaceGraphic: để rõ hơn thì bạn có thể đọc tại đây.

@Override
public void draw(Canvas canvas) {
        Face face = mFace;
        if (face == null) {
            return;
        }

        // Draws a circle at the position of the detected face, with the face's track id below.
        float x = translateX(face.getPosition().x + face.getWidth() / 2);
        float y = translateY(face.getPosition().y + face.getHeight() / 2);
        canvas.drawCircle(x, y, FACE_POSITION_RADIUS, mFacePositionPaint);
        canvas.drawText("id: " + mFaceId, x + ID_X_OFFSET, y + ID_Y_OFFSET, mIdPaint);
        canvas.drawText("happiness: " + String.format("%.2f", face.getIsSmilingProbability()), x - ID_X_OFFSET, y - ID_Y_OFFSET, mIdPaint);
        canvas.drawText("right eye: " + String.format("%.2f", face.getIsRightEyeOpenProbability()), x + ID_X_OFFSET * 2, y + ID_Y_OFFSET * 2, mIdPaint);
        canvas.drawText("left eye: " + String.format("%.2f", face.getIsLeftEyeOpenProbability()), x - ID_X_OFFSET*2, y - ID_Y_OFFSET*2, mIdPaint);

        // Draws a bounding box around the face.
        float xOffset = scaleX(face.getWidth() / 2.0f);
        float yOffset = scaleY(face.getHeight() / 2.0f);
        float left = x - xOffset;
        float top = y - yOffset;
        float right = x + xOffset;
        float bottom = y + yOffset;
        canvas.drawRect(left, top, right, bottom, mBoxPaint);
}

Và cuối cùng là add Detector:

Context context = getApplicationContext();
FaceDetector detector = new FaceDetector.Builder(context)
		.setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
		.build();
detector.setProcessor(new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory())
		.build());
										
 mCameraSource = new CameraSource.Builder(context, detector)
				.setRequestedPreviewSize(640, 480)
				.setFacing(CameraSource.CAMERA_FACING_BACK)
				.setRequestedFps(30.0f)
				.build();

Build app và sử dụng thôi.

Trên đây là bài giới thiệu ngắn ngọn của mình về việc sử dụng Face Detection API để xây dựng 1 ứng dụng phát hiện khuôn mặt người. Bạn có thể tham khảo sample đầy đủ tại đây.

0