diff options
| author | Ivan Evlogiev <ivanevlogiev@codeaurora.org> | 2013-08-28 14:24:28 +0300 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-10-18 13:54:24 -0700 |
| commit | 1e2f0e7e5b194b24ee6eca4ffad3aef4bf5e3c66 (patch) | |
| tree | 0f0819d2b30ddaf5959c67a5c75d3baefb9e5cb2 /src | |
| parent | cb20328f0054322f168c98c8a1f932b0f7258197 (diff) | |
| download | android_packages_apps_Gallery2-1e2f0e7e5b194b24ee6eca4ffad3aef4bf5e3c66.tar.gz android_packages_apps_Gallery2-1e2f0e7e5b194b24ee6eca4ffad3aef4bf5e3c66.tar.bz2 android_packages_apps_Gallery2-1e2f0e7e5b194b24ee6eca4ffad3aef4bf5e3c66.zip | |
Camera: Add facial processing features
Add smile, gaze and blink detection features
CRs-fixed: 531927
Change-Id: I7e710e6d9038b14d00d77ea87f9b4c65baa74fc0
Diffstat (limited to 'src')
| -rw-r--r-- | src/com/android/camera/ui/FaceView.java | 126 |
1 files changed, 114 insertions, 12 deletions
diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java index f4dd823d1..d67b835e4 100644 --- a/src/com/android/camera/ui/FaceView.java +++ b/src/com/android/camera/ui/FaceView.java @@ -22,6 +22,7 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Color; import android.graphics.Paint.Style; import android.graphics.RectF; import android.hardware.Camera.Face; @@ -36,6 +37,7 @@ import com.android.camera.CameraScreenNail; import com.android.camera.Util; import com.android.gallery3d.R; import com.android.gallery3d.common.ApiHelper; +import org.codeaurora.camera.QCFace; @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) public class FaceView extends View @@ -66,6 +68,11 @@ public class FaceView extends View private int mUncroppedWidth; private int mUncroppedHeight; + + private final int smile_threashold_no_smile = 30; + private final int smile_threashold_small_smile = 60; + private final int blink_threashold = 60; + private static final int MSG_SWITCH_FACES = 1; private static final int SWITCH_DELAY = 70; private boolean mStateSwitchPending = false; @@ -93,6 +100,9 @@ public class FaceView extends View mPaint.setAntiAlias(true); mPaint.setStyle(Style.STROKE); mPaint.setStrokeWidth(res.getDimension(R.dimen.face_circle_stroke)); + mPaint.setDither(true); + mPaint.setColor(Color.WHITE);//setColor(0xFFFFFF00); + mPaint.setStrokeCap(Paint.Cap.ROUND); } public void setFaces(Face[] faces) { @@ -209,19 +219,111 @@ public class FaceView extends View mMatrix.postRotate(mOrientation); // postRotate is clockwise canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas) for (int i = 0; i < mFaces.length; i++) { - // Filter out false positives. - if (mFaces[i].score < 50) continue; - - // Transform the coordinates. - mRect.set(mFaces[i].rect); - if (LOGV) Util.dumpRect(mRect, "Original rect"); - mMatrix.mapRect(mRect); - if (LOGV) Util.dumpRect(mRect, "Transformed rect"); - mPaint.setColor(mColor); - mRect.offset(dx, dy); - canvas.drawOval(mRect, mPaint); + // Filter out false positives. + if (mFaces[i].score < 50) continue; + + // Transform the coordinates. + mRect.set(mFaces[i].rect); + if (LOGV) Util.dumpRect(mRect, "Original rect"); + mMatrix.mapRect(mRect); + if (LOGV) Util.dumpRect(mRect, "Transformed rect"); + mPaint.setColor(mColor); + mRect.offset(dx, dy); + canvas.drawOval(mRect, mPaint); + if (mFaces[i] instanceof QCFace) { + QCFace face = (QCFace)mFaces[i]; + float[] point = new float[4]; + int delta_x = mFaces[i].rect.width() / 12; + int delta_y = mFaces[i].rect.height() / 12; + Log.e(TAG, "blink: (" + face.getLeftEyeBlinkDegree()+ ", " + + face.getRightEyeBlinkDegree() + ")"); + if (face.leftEye != null) { + point[0] = face.leftEye.x + dx; + point[1] = face.leftEye.y-delta_y/2; + point[2] = face.leftEye.x; + point[3] = face.leftEye.y+delta_y/2; + mMatrix.mapPoints (point); + if (face.getLeftEyeBlinkDegree() >= blink_threashold) { + canvas.drawLine(point[0]+ dx, point[1]+ dy, point[2]+ dx, + point[3]+ dy, mPaint); + } + } + if (face.rightEye != null) { + point[0] = face.rightEye.x; + point[1] = face.rightEye.y-delta_y/2; + point[2] = face.rightEye.x; + point[3] = face.rightEye.y+delta_y/2; + mMatrix.mapPoints (point); + if (face.getRightEyeBlinkDegree() >= blink_threashold) { + //Add offset to the points if the rect has an offset + canvas.drawLine(point[0] + dx, point[1] + dy, point[2] +dx, + point[3] +dy, mPaint); + } + } + if (face.getLeftRightGazeDegree() != 0 || face.getTopBottomGazeDegree() != 0 ) { + double length = Math.sqrt((face.leftEye.x - face.rightEye.x) * + (face.leftEye.x - face.rightEye.x) + + (face.leftEye.y - face.rightEye.y) * + (face.leftEye.y - face.rightEye.y)) / 2.0; + double nGazeYaw = -face.getLeftRightGazeDegree(); + double nGazePitch = -face.getTopBottomGazeDegree(); + float gazeRollX = (float)((-Math.sin(nGazeYaw/180.0*Math.PI) * + Math.cos(-face.getRollDirection()/ 180.0*Math.PI)+ + Math.sin(nGazePitch/180.0*Math.PI)* Math.cos(nGazeYaw/180.0*Math.PI) + * Math.sin(-face.getRollDirection()/180.0*Math.PI)) + * (-length) + 0.5); + float gazeRollY = (float)((Math.sin(-nGazeYaw/180.0*Math.PI) * + Math.sin(-face.getRollDirection()/180.0*Math.PI)- + Math.sin(nGazePitch/180.0*Math.PI)* Math.cos(nGazeYaw/180.0*Math.PI)* + Math.cos(-face.getRollDirection()/180.0*Math.PI))* (-length) + 0.5); + + if (face.getLeftEyeBlinkDegree() < blink_threashold) { + point[0] = face.leftEye.x; + point[1] = face.leftEye.y; + point[2] = face.leftEye.x + gazeRollX; + point[3] = face.leftEye.y + gazeRollY; + mMatrix.mapPoints (point); + canvas.drawLine(point[0] +dx, point[1] + dy, point[2] + + dx, point[3] +dy, mPaint); + } + + if (face.getRightEyeBlinkDegree() < blink_threashold) { + point[0] = face.rightEye.x; + point[1] = face.rightEye.y; + point[2] = face.rightEye.x + gazeRollX; + point[3] = face.rightEye.y + gazeRollY; + mMatrix.mapPoints (point); + canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + + dx, point[3] + dy, mPaint); + } + } + if (face.mouth != null) { + Log.e(TAG, "smile: " + face.getSmileDegree() + "," + face.getSmileScore()); + if (face.getSmileDegree() < smile_threashold_no_smile) { + point[0] = face.mouth.x + dx; + point[1] = face.mouth.y-delta_y +dy; + point[2] = face.mouth.x + dx; + point[3] = face.mouth.y+delta_y + dy; + mMatrix.mapPoints (point); + canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + + dx, point[3] + dy, mPaint); + } else if (face.getSmileDegree() < smile_threashold_small_smile) { + mRect.set(face.mouth.x-delta_x, face.mouth.y-delta_y, + face.mouth.x+delta_x, face.mouth.y+delta_y); + mMatrix.mapRect(mRect); + mRect.offset(dx, dy); + canvas.drawArc(mRect, 0, 180, true, mPaint); + } else { + mRect.set(face.mouth.x-delta_x, face.mouth.y-delta_y, + face.mouth.x+delta_x, face.mouth.y+delta_y); + mMatrix.mapRect(mRect); + mRect.offset(dx, dy); + canvas.drawOval(mRect, mPaint); + } + } + } } - canvas.restore(); + canvas.restore(); } super.onDraw(canvas); } |
