diff --git a/.travis.yml b/.travis.yml index b09674a..0254a89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,19 +32,23 @@ android: - platform-tools # The BuildTools version used by your project - - build-tools-27.0.3 + - build-tools-28.0.3 # The SDK version used to compile your project - - android-27 + - android-28 # Additional components - extra-android-m2repository +before_install: + # Accept the licenses needed for OpenCV and this project + - yes | sdkmanager "platforms;android-27" "platforms;android-28" + before_script: # Download Android NDK, OpenCV Android SDK and Eigen 3 - - if test ! -e $HOME/zip-cache/android-ndk.zip ; then wget https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -O $HOME/zip-cache/android-ndk.zip ; fi + - if test ! -e $HOME/zip-cache/android-ndk.zip ; then wget https://dl.google.com/android/repository/android-ndk-r18-linux-x86_64.zip -O $HOME/zip-cache/android-ndk.zip ; fi - if test ! -e $HOME/zip-cache/opencv-sdk.zip ; then wget https://github.com/opencv/opencv/releases/download/3.4.1/opencv-3.4.1-android-sdk.zip -O $HOME/zip-cache/opencv-sdk.zip ; fi - - if test ! -e $HOME/zip-cache/eigen3.zip ; then wget https://bitbucket.org/eigen/eigen/get/3.3.4.zip -O $HOME/zip-cache/eigen3.zip ; fi + - if test ! -e $HOME/zip-cache/eigen3.zip ; then wget https://bitbucket.org/eigen/eigen/get/3.3.5.zip -O $HOME/zip-cache/eigen3.zip ; fi # Unzip the zip files into their directories - unzip -qq -n $HOME/zip-cache/android-ndk.zip -d $HOME/android-ndk @@ -52,12 +56,12 @@ before_script: - unzip -qq -n $HOME/zip-cache/eigen3.zip -d $HOME/eigen3 # Set environmental variables - - export ANDROID_NDK_HOME=$HOME/android-ndk/android-ndk-r16b + - export ANDROID_NDK_HOME=$(dirname $HOME/android-ndk/android-ndk-*/ndk-build) - export OPENCV_ANDROID_SDK=$HOME/opencv-sdk/OpenCV-android-sdk - export EIGEN3_DIR=$(dirname $(find $HOME/eigen3 -type f -name 'signature_of_eigen3_matrix_library' -print -quit)) - # Patch OpenCV, so it does not abort on lint errors - - patch $OPENCV_ANDROID_SDK/sdk/build.gradle < opencv.patch + # Apply patch to OpenCV + - patch -d$OPENCV_ANDROID_SDK/../ -p0 < opencv.patch script: - ./gradlew --no-daemon build diff --git a/README.md b/README.md index cdc886b..5ec70f9 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,12 @@ git submodule update --init --recursive The project is relying on the environmental variables ```OPENCV_ANDROID_SDK``` and ```EIGEN3_DIR``` for [settings.gradle](settings.gradle) and [Android.mk](app/src/main/cpp/Android.mk) to be set to the path of the [OpenCV Android SDK](http://opencv.org/platforms/android) and [Eigen3](https://eigen.tuxfamily.org) libraries. -Please use [OpenCV 3.4.1](https://github.com/opencv/opencv/releases/download/3.4.1/opencv-3.4.1-android-sdk.zip) and [Eigen3 3.3.4](https://bitbucket.org/eigen/eigen/get/3.3.4.zip). Both can be installed from the command line like so: +Please use [OpenCV 3.4.1](https://github.com/opencv/opencv/releases/download/3.4.1/opencv-3.4.1-android-sdk.zip) and [Eigen3 3.3.5](https://bitbucket.org/eigen/eigen/get/3.3.5.zip). Both can be installed from the command line like so: ```bash wget https://github.com/opencv/opencv/releases/download/3.4.1/opencv-3.4.1-android-sdk.zip unzip opencv-3.4.1-android-sdk.zip -wget https://bitbucket.org/eigen/eigen/get/3.3.4.zip -O Eigen3.zip +wget https://bitbucket.org/eigen/eigen/get/3.3.5.zip -O Eigen3.zip unzip Eigen3.zip ``` @@ -84,5 +84,3 @@ echo %OPENCV_ANDROID_SDK% %EIGEN3_DIR% __Please note that ```/path/to/``` should be replaced with the actual path to the Eigen and OpenCV Android SDK directories.__ If you have troubles setting the environmental variables, then you can just hardcode the paths in [settings.gradle](settings.gradle) and [Android.mk](app/src/main/cpp/Android.mk). - -For more information send me an email at . diff --git a/app/build.gradle b/app/build.gradle index e89d190..a7631bb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,17 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 27 + compileSdkVersion 28 defaultConfig { applicationId 'com.lauszus.facerecognitionapp' - minSdkVersion 15 - targetSdkVersion 27 + minSdkVersion 16 + targetSdkVersion 28 versionCode 5 versionName '1.2.2' vectorDrawables.useSupportLibrary = true ndk { - stl 'gnustl_static' - cFlags '-std=gnu++11 -fexceptions -frtti' + stl 'c++_static' + cFlags '-std=gnu++11 -fexceptions -frtti -DANDROID_STL=c++_static' } setProperty('archivesBaseName', rootProject.name + '-' + defaultConfig.versionName) } @@ -70,8 +70,8 @@ android { } dependencies { - implementation 'com.android.support:appcompat-v7:27.1.1' - implementation 'com.android.support:design:27.1.1' + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support:design:28.0.0' implementation project(':opencv') } diff --git a/app/src/main/cpp/Application.mk b/app/src/main/cpp/Application.mk index 6858498..cfce828 100644 --- a/app/src/main/cpp/Application.mk +++ b/app/src/main/cpp/Application.mk @@ -1,7 +1,7 @@ -APP_PLATFORM := android-27 +APP_PLATFORM := android-28 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 -APP_STL := gnustl_static -APP_CPPFLAGS := -std=gnu++11 -frtti -fexceptions +APP_STL := c++_static +APP_CPPFLAGS := -std=gnu++11 -frtti -fexceptions -DANDROID_STL=c++_static ifeq ($(NDK_DEBUG),0) APP_CPPFLAGS += -DNDEBUG diff --git a/app/src/main/java/com/lauszus/facerecognitionapp/CameraBridgeViewBase.java b/app/src/main/java/com/lauszus/facerecognitionapp/CameraBridgeViewBase.java index db2e4ef..1c2aa82 100644 --- a/app/src/main/java/com/lauszus/facerecognitionapp/CameraBridgeViewBase.java +++ b/app/src/main/java/com/lauszus/facerecognitionapp/CameraBridgeViewBase.java @@ -71,10 +71,8 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac public CameraBridgeViewBase(Context context, int cameraId) { super(context); - mCameraIndex = cameraId; - getHolder().addCallback(this); - mMaxWidth = MAX_UNSPECIFIED; - mMaxHeight = MAX_UNSPECIFIED; + construct(context, cameraId); + } public CameraBridgeViewBase(Context context, AttributeSet attrs) { @@ -87,13 +85,16 @@ public CameraBridgeViewBase(Context context, AttributeSet attrs) { if (styledAttrs.getBoolean(R.styleable.CameraBridgeViewBase_show_fps, false)) enableFpsMeter(); - mCameraIndex = styledAttrs.getInt(R.styleable.CameraBridgeViewBase_camera_id, CAMERA_ID_ANY); + int cameraId = styledAttrs.getInt(R.styleable.CameraBridgeViewBase_camera_id, CAMERA_ID_ANY); + styledAttrs.recycle(); + construct(context, cameraId); + } + private void construct(Context context, int cameraId) { + mCameraIndex = cameraId; getHolder().addCallback(this); mMaxWidth = MAX_UNSPECIFIED; mMaxHeight = MAX_UNSPECIFIED; - styledAttrs.recycle(); - mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); } diff --git a/app/src/main/java/com/lauszus/facerecognitionapp/FaceRecognitionAppActivity.java b/app/src/main/java/com/lauszus/facerecognitionapp/FaceRecognitionAppActivity.java index a96ea20..c922aa8 100644 --- a/app/src/main/java/com/lauszus/facerecognitionapp/FaceRecognitionAppActivity.java +++ b/app/src/main/java/com/lauszus/facerecognitionapp/FaceRecognitionAppActivity.java @@ -42,8 +42,10 @@ import android.support.v7.widget.Toolbar; import android.text.InputType; import android.util.Log; +import android.view.GestureDetector; import android.view.Menu; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; @@ -394,7 +396,11 @@ public void onClick(View v) { Log.i(TAG, "Gray height: " + mGray.height() + " Width: " + mGray.width() + " total: " + mGray.total()); if (mGray.total() == 0) return; - Size imageSize = new Size(200, 200.0f / ((float) mGray.width() / (float) mGray.height())); // Scale image in order to decrease computation time + + // Scale image in order to decrease computation time and make the image square, + // so it does not crash on phones with different aspect ratios for the front + // and back camera + Size imageSize = new Size(200, 200); Imgproc.resize(mGray, mGray, imageSize); Log.i(TAG, "Small gray height: " + mGray.height() + " Width: " + mGray.width() + " total: " + mGray.total()); //SaveImage(mGray); @@ -417,10 +423,29 @@ public void onClick(View v) { } }); + final GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDown(MotionEvent e) { + return true; + } + @Override + public boolean onDoubleTap(MotionEvent e) { + // Show flip animation when the camera is flipped due to a double tap + flipCameraAnimation(); + return true; + } + }); + mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_java_surface_view); mOpenCvCameraView.setCameraIndex(prefs.getInt("mCameraIndex", CameraBridgeViewBase.CAMERA_ID_FRONT)); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); + mOpenCvCameraView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return mGestureDetector.onTouchEvent(event); + } + }); } private NativeMethods.MeasureDistTask.Callback measureDistTaskCallback = new NativeMethods.MeasureDistTask.Callback() { @@ -670,44 +695,49 @@ public boolean onCreateOptionsMenu(Menu menu) { // Show rear camera icon if front camera is currently used and front camera icon if back camera is used MenuItem menuItem = menu.findItem(R.id.flip_camera); if (mOpenCvCameraView.mCameraIndex == CameraBridgeViewBase.CAMERA_ID_FRONT) - menuItem.setIcon(R.drawable.ic_camera_rear_white_24dp); - else menuItem.setIcon(R.drawable.ic_camera_front_white_24dp); + else + menuItem.setIcon(R.drawable.ic_camera_rear_white_24dp); return true; } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.flip_camera: - mOpenCvCameraView.flipCamera(); + private void flipCameraAnimation() { + // Flip the camera + mOpenCvCameraView.flipCamera(); - // Do flip camera animation - View v = mToolbar.findViewById(R.id.flip_camera); - ObjectAnimator animator = ObjectAnimator.ofFloat(v, "rotationY", v.getRotationY() + 180.0f); - animator.setDuration(500); - animator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { + // Do flip camera animation + View v = mToolbar.findViewById(R.id.flip_camera); + ObjectAnimator animator = ObjectAnimator.ofFloat(v, "rotationY", v.getRotationY() + 180.0f); + animator.setDuration(500); + animator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { - } + } - @Override - public void onAnimationEnd(Animator animation) { - supportInvalidateOptionsMenu(); // This will call onCreateOptionsMenu() - } + @Override + public void onAnimationEnd(Animator animation) { + supportInvalidateOptionsMenu(); // This will call onCreateOptionsMenu() + } - @Override - public void onAnimationCancel(Animator animation) { + @Override + public void onAnimationCancel(Animator animation) { - } + } - @Override - public void onAnimationRepeat(Animator animation) { + @Override + public void onAnimationRepeat(Animator animation) { - } - }); - animator.start(); + } + }); + animator.start(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.flip_camera: + flipCameraAnimation(); return true; } return super.onOptionsItemSelected(item); diff --git a/build.gradle b/build.gradle index 44bac8f..ae9fbaf 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.android.tools.build:gradle:3.2.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1ff26c2..89adcbe 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Apr 16 03:03:10 CEST 2018 +#Sun Dec 16 21:52:50 CET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/opencv.patch b/opencv.patch index 048fc4b..a21fde9 100644 --- a/opencv.patch +++ b/opencv.patch @@ -1,13 +1,27 @@ ---- build-orig.gradle 2018-04-16 09:10:01.000000000 +0200 -+++ build.gradle 2018-04-16 09:11:53.000000000 +0200 -@@ -121,6 +121,10 @@ - manifest.srcFile 'java/AndroidManifest.xml' - } - } -+ -+ lintOptions { -+ abortOnError false -+ } - } - - dependencies { +diff -crb OpenCV-android-sdk/sdk/build.gradle OpenCV-android-sdk-patch/sdk/build.gradle +*** OpenCV-android-sdk/sdk/build.gradle Sun Dec 16 22:44:27 2018 +--- OpenCV-android-sdk-patch/sdk/build.gradle Sun Dec 16 22:34:33 2018 +*************** +*** 121,126 **** +--- 121,130 ---- + manifest.srcFile 'java/AndroidManifest.xml' + } + } ++ ++ lintOptions { ++ abortOnError false ++ } + } + + dependencies { +diff -crb OpenCV-android-sdk/sdk/java/AndroidManifest.xml OpenCV-android-sdk-patch/sdk/java/AndroidManifest.xml +*** OpenCV-android-sdk/sdk/java/AndroidManifest.xml Fri Feb 23 12:24:24 2018 +--- OpenCV-android-sdk-patch/sdk/java/AndroidManifest.xml Sun Dec 16 22:28:32 2018 +*************** +*** 4,8 **** + android:versionCode="3410" + android:versionName="3.4.1"> + +- + +--- 4,7 ----