From e1e1617614e5a5223bced2fd0d770d13ea3cd017 Mon Sep 17 00:00:00 2001 From: xueweining Date: Fri, 14 Jul 2017 16:48:38 +0800 Subject: [PATCH] add face detect --- build.gradle | 2 +- .../wysaid/cgeDemo/CameraDemoActivity.java | 125 ++++++- .../main/res/layout/activity_camera_demo.xml | 7 + gradle/wrapper/gradle-wrapper.properties | 4 +- library/build.gradle | 1 + .../org/wysaid/camera/CameraInstance.java | 7 + .../wysaid/nativePort/CGEFrameRenderer.java | 15 +- .../org/wysaid/stmobile/Accelerometer.java | 138 +++++++ .../org/wysaid/view/CameraGLSurfaceView.java | 26 ++ library/src/main/jni/Android.mk | 1 + .../main/jni/cge/common/cgeImageHandler.cpp | 7 + .../jni/cge/filters/cgeDataParsingEngine.cpp | 30 +- .../jni/cge/filters/cgeFaceDetectFilter.cpp | 63 ++++ .../jni/cge/filters/cgeMultipleEffects.cpp | 5 +- .../src/main/jni/include/cgeImageHandler.h | 8 +- .../include/filters/cgeDataParsingEngine.h | 2 +- .../jni/include/filters/cgeFaceDetectFilter.h | 25 ++ .../jni/interface/cgeFrameRendererWrapper.cpp | 15 +- .../jni/interface/cgeFrameRendererWrapper.h | 2 +- library/src/main/libs/armeabi-v7a/libCGE.so | Bin 509732 -> 509732 bytes .../src/main/libs/armeabi-v7a/libCGEExt.so | Bin 190180 -> 194276 bytes .../main/libs/armeabi-v7a/libFaceTracker.so | Bin 3829272 -> 3829272 bytes settings.gradle | 2 +- stmobile/.gitignore | 1 + stmobile/build.gradle | 36 ++ stmobile/libs/jna-min.jar | Bin 0 -> 159753 bytes stmobile/proguard-rules.pro | 25 ++ stmobile/src/main/AndroidManifest.xml | 14 + .../main/assets/track_face_action1.0.0.model | Bin 0 -> 2385936 bytes .../sensetime/stmobileapi/STImageFormat.java | 9 + .../sensetime/stmobileapi/STMobile106.java | 66 ++++ .../stmobileapi/STMobileApiBridge.java | 346 ++++++++++++++++++ .../stmobileapi/STMobileFaceAction.java | 50 +++ .../stmobileapi/STMobileFaceDetection.java | 226 ++++++++++++ .../stmobileapi/STMobileMultiTrack106.java | 321 ++++++++++++++++ .../com/sensetime/stmobileapi/STUtils.java | 286 +++++++++++++++ .../jniLibs/armeabi-v7a/libjnidispatch.so | Bin 0 -> 97883 bytes .../main/jniLibs/armeabi-v7a/libst_mobile.so | Bin 0 -> 2501416 bytes stmobile/src/main/res/values/strings.xml | 3 + 39 files changed, 1844 insertions(+), 24 deletions(-) create mode 100644 library/src/main/java/org/wysaid/stmobile/Accelerometer.java create mode 100644 library/src/main/jni/cge/filters/cgeFaceDetectFilter.cpp create mode 100644 library/src/main/jni/include/filters/cgeFaceDetectFilter.h create mode 100644 stmobile/.gitignore create mode 100644 stmobile/build.gradle create mode 100644 stmobile/libs/jna-min.jar create mode 100644 stmobile/proguard-rules.pro create mode 100644 stmobile/src/main/AndroidManifest.xml create mode 100644 stmobile/src/main/assets/track_face_action1.0.0.model create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STImageFormat.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STMobile106.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STMobileApiBridge.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STMobileFaceAction.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STMobileFaceDetection.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STMobileMultiTrack106.java create mode 100644 stmobile/src/main/java/com/sensetime/stmobileapi/STUtils.java create mode 100644 stmobile/src/main/jniLibs/armeabi-v7a/libjnidispatch.so create mode 100644 stmobile/src/main/jniLibs/armeabi-v7a/libst_mobile.so create mode 100644 stmobile/src/main/res/values/strings.xml diff --git a/build.gradle b/build.gradle index 59660130..5890fd0c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.0.0-alpha6' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/cgeDemo/src/main/java/org/wysaid/cgeDemo/CameraDemoActivity.java b/cgeDemo/src/main/java/org/wysaid/cgeDemo/CameraDemoActivity.java index 3acd7287..eb90485c 100755 --- a/cgeDemo/src/main/java/org/wysaid/cgeDemo/CameraDemoActivity.java +++ b/cgeDemo/src/main/java/org/wysaid/cgeDemo/CameraDemoActivity.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.PointF; import android.hardware.Camera; import android.net.Uri; import android.os.Bundle; @@ -18,12 +19,17 @@ import android.widget.LinearLayout; import android.widget.SeekBar; +import com.sensetime.stmobileapi.STMobileFaceAction; +import com.sensetime.stmobileapi.STMobileMultiTrack106; +import com.sensetime.stmobileapi.STUtils; + import org.wysaid.camera.CameraInstance; import org.wysaid.myUtils.FileUtil; import org.wysaid.myUtils.ImageUtil; import org.wysaid.myUtils.MsgUtil; import org.wysaid.nativePort.CGEFrameRecorder; import org.wysaid.nativePort.CGENativeLibrary; +import org.wysaid.stmobile.Accelerometer; import org.wysaid.view.CameraRecordGLSurfaceView; public class CameraDemoActivity extends AppCompatActivity { @@ -338,12 +344,110 @@ public void onAutoFocus(boolean success, Camera camera) { }); mCameraView.setPictureSize(600, 800, true); + + Button faceDetectBtn = (Button) findViewById(R.id.face_detect_btn); + faceDetectBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CameraInstance.getInstance().getCameraDevice().setPreviewCallback(new Camera.PreviewCallback() { + @Override + public void onPreviewFrame(byte[] data, Camera camera) { + if (mNV21Data == null) { + mNV21Data = new byte[CameraInstance.getInstance().previewHeight() * CameraInstance.getInstance().previewWidth() * 2]; + } + synchronized (mNV21Data) { + System.arraycopy(data, 0, mNV21Data, 0, data.length); + mIsNV21ready = true; + } + } + }); + mCameraView.setFilterWithConfig("@facedetect"); + } + }); + mAcc = new Accelerometer(this); + mAcc.start(); + } + + private byte[] mNV21Data; + private boolean mIsFaceDetectThreadKilled = false; + private Thread mFaceDetectThread; + private boolean mIsNV21ready = false; + private Accelerometer mAcc; + private STMobileMultiTrack106 mTracker = null; + private static final int ST_MOBILE_TRACKING_ENABLE_FACE_ACTION = 0x00000020; + private byte[] tmp = null; + + private void stopFaceDetectThread() { + mIsFaceDetectThreadKilled = true; + if (mFaceDetectThread != null) { + try { + mFaceDetectThread.join(1000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + } + + private void startFaceDetectThread() { + mIsFaceDetectThreadKilled = false; + + mFaceDetectThread = new Thread() { + @Override + public void run() { + while (!mIsFaceDetectThreadKilled) { + if (!mIsNV21ready) { + continue; + } + if (tmp == null) { + tmp = new byte[CameraInstance.getInstance().previewHeight() * CameraInstance.getInstance().previewWidth() * 2]; + } + synchronized (mNV21Data) { + System.arraycopy(mNV21Data, 0, tmp, 0, mNV21Data.length); + mIsNV21ready = false; + } + boolean frontCamera = (CameraInstance.getInstance().getFacing() == Camera.CameraInfo.CAMERA_FACING_FRONT); + int dir = Accelerometer.getDirection(); + /** + * 请注意前置摄像头与后置摄像头旋转定义不同 + * 请注意不同手机摄像头旋转定义不同 + */ + if (frontCamera && + ((CameraInstance.getInstance().getCameraInfo().orientation == 270 && (dir & 1) == 1) || + (CameraInstance.getInstance().getCameraInfo().orientation == 90 && (dir & 1) == 0))) { + dir = (dir ^ 2); + } + STMobileFaceAction[] faceActions = mTracker.trackFaceAction(tmp, dir, CameraInstance.getInstance().previewWidth(), CameraInstance.getInstance().previewHeight()); + boolean rotate270 = CameraInstance.getInstance().getCameraInfo().orientation == 270; + Log.e("xuezi", "rotate270" + rotate270); + if (faceActions != null && faceActions.length > 0) { + STMobileFaceAction r = faceActions[0]; + PointF[] points = r.getFace().getPointsArray(); + float[] pointArray = new float[212]; + for (int i = 0; i < points.length; i++) { + if (rotate270) { + points[i] = STUtils.RotateDeg270(points[i], CameraInstance.getInstance().previewWidth(), CameraInstance.getInstance().previewHeight(), frontCamera); + } else { + points[i] = STUtils.RotateDeg90(points[i], CameraInstance.getInstance().previewWidth(), CameraInstance.getInstance().previewHeight(), frontCamera); + } + pointArray[2*i] = points[i].x / CameraInstance.getInstance().previewHeight(); + pointArray[2*i+1] = points[i].y / CameraInstance.getInstance().previewWidth(); + } + mCameraView.setFaceDetectPoints(pointArray); + } + else { + mCameraView.clearFaceDetectPoints(); + } + } + } + }; + mFaceDetectThread.start(); } private View.OnClickListener mFilterSwitchListener = new View.OnClickListener() { @Override public void onClick(View v) { - MyButtons btn = (MyButtons) v; + CameraInstance.getInstance().getCameraDevice().setPreviewCallback(null); + MyButtons btn = (MyButtons)v; mCameraView.setFilterWithConfig(btn.filterConfig); mCurrentConfig = btn.filterConfig; } @@ -388,6 +492,13 @@ public void onPause() { Log.i(LOG_TAG, "activity onPause..."); mCameraView.release(null); mCameraView.onPause(); + mAcc.stop(); + stopFaceDetectThread(); + if (mTracker != null) { + System.out.println("destroy tracker"); + mTracker.destory(); + mTracker = null; + } } @Override @@ -395,6 +506,18 @@ public void onResume() { super.onResume(); mCameraView.onResume(); + mAcc.start(); + if (mTracker == null) { +// long start_init = System.currentTimeMillis(); +// int config = 0; //default config + int config = ST_MOBILE_TRACKING_ENABLE_FACE_ACTION; + mTracker = new STMobileMultiTrack106(this, config); + int max = 1; + mTracker.setMaxDetectableFaces(max); +// long end_init = System.currentTimeMillis(); +// Log.i("track106", "init cost "+(end_init - start_init) +" ms"); + } + startFaceDetectThread(); } @Override diff --git a/cgeDemo/src/main/res/layout/activity_camera_demo.xml b/cgeDemo/src/main/res/layout/activity_camera_demo.xml index 6122be06..44cd87f7 100755 --- a/cgeDemo/src/main/res/layout/activity_camera_demo.xml +++ b/cgeDemo/src/main/res/layout/activity_camera_demo.xml @@ -29,6 +29,7 @@ @@ -123,4 +124,10 @@ +