/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.catroid.facedetection; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PointF; import android.media.FaceDetector; import android.media.FaceDetector.Face; import org.catrobat.catroid.camera.CameraManager; import org.catrobat.catroid.camera.JpgPreviewCallback; public class SlowFaceDetector extends org.catrobat.catroid.facedetection.FaceDetector implements JpgPreviewCallback { private static final int NUMBER_OF_FACES = 1; @Override public boolean startFaceDetection() { CameraManager.getInstance().addOnJpgPreviewFrameCallback(this); return CameraManager.getInstance().startCamera(); } @Override public void stopFaceDetection() { CameraManager.getInstance().removeOnJpgPreviewFrameCallback(this); CameraManager.getInstance().releaseCamera(); } @Override public void onFrame(byte[] data) { Bitmap preview = BitmapFactory.decodeByteArray(data, 0, data.length); detectFaces(preview); preview.recycle(); } private void detectFaces(Bitmap bitmap) { if (bitmap == null) { return; } int height = bitmap.getWidth(); int width = bitmap.getHeight(); Matrix rotateAndInvertX = new Matrix(); int rotationAngle = 0; boolean invertX = CameraManager.getInstance().isCurrentCameraFacingBack(); rotateAndInvertX.postRotate(rotationAngle); rotateAndInvertX.postScale(invertX ? -1 : 1, 1); Bitmap portraitBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), rotateAndInvertX, true); Bitmap rgb565Bitmap = Bitmap.createBitmap(width, height, Config.RGB_565); Paint paint = new Paint(); paint.setDither(true); Canvas canvas = new Canvas(); canvas.setBitmap(rgb565Bitmap); canvas.drawBitmap(portraitBitmap, 0, 0, paint); FaceDetector detector = new FaceDetector(width, height, NUMBER_OF_FACES); Face[] faces = new Face[NUMBER_OF_FACES]; int numberOfFaces = detector.findFaces(rgb565Bitmap, faces); boolean detected = numberOfFaces > 0; onFaceDetected(detected); if (detected) { PointF centerPoint = new PointF(); faces[0].getMidPoint(centerPoint); float eyeDistance = faces[0].eyesDistance(); onFaceFound(centerPoint, eyeDistance, width, height); } } private void onFaceFound(PointF centerPoint, float eyeDistance, int detectionWidth, int detectionHeight) { Point intPoint = new Point((int) centerPoint.x, (int) centerPoint.y); Point relationSize = getRelationForFacePosition(); Point relativePoint = new Point((intPoint.x - detectionWidth / 2) * relationSize.x / detectionWidth, (intPoint.y - detectionHeight / 2) * relationSize.y / detectionHeight); int estimatedFaceWidth = (int) (eyeDistance * 2); int relativeFaceSize = 200 * estimatedFaceWidth / detectionWidth; relativeFaceSize = relativeFaceSize > 100 ? 100 : relativeFaceSize; onFaceDetected(relativePoint, relativeFaceSize); } }