diff --git a/.gitignore b/.gitignore
index fe0ebdcb..d5effa2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,12 @@
build/*.*
-openCVLibrary310/*.*
\ No newline at end of file
+openCVLibrary310/*.*
+
+# Gradle files
+.gradle/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Intellij
+*.iml
+.idea
diff --git a/Android-Face-Recognition-with-Deep-Learning-Library.iml b/Android-Face-Recognition-with-Deep-Learning-Library.iml
deleted file mode 100644
index 9908c3ea..00000000
--- a/Android-Face-Recognition-with-Deep-Learning-Library.iml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 09767308..b5c775d9 100755
--- a/build.gradle
+++ b/build.gradle
@@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
+ classpath 'com.android.tools.build:gradle:3.2.1'
}
}
@@ -15,6 +16,7 @@ allprojects {
maven {
url "http://dl.bintray.com/qualeams/Android-Face-Recognition-Deep-Learning-Library"
}
+ google()
}
}
diff --git a/facerecognitionlibrary.iml b/facerecognitionlibrary.iml
deleted file mode 100644
index ee138a63..00000000
--- a/facerecognitionlibrary.iml
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/facerecognitionlibrary/facerecognitionlibrary.iml b/facerecognitionlibrary/facerecognitionlibrary.iml
deleted file mode 100644
index 2428fb50..00000000
--- a/facerecognitionlibrary/facerecognitionlibrary.iml
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Helpers/FaceDetection.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Helpers/FaceDetection.java
index 07fa510a..b9ffa675 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Helpers/FaceDetection.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Helpers/FaceDetection.java
@@ -146,6 +146,8 @@ public Eyes getEyes(Mat img){
Mat leftHalfImg = img.submat(leftHalf);
leftEyeDetector.detectMultiScale(leftHalfImg, leftEyes);
+ rightHalfImg.release();
+ leftHalfImg.release();
if (rightEyes.empty() || leftEyes.empty() || rightEyes.toArray().length > 1 || leftEyes.toArray().length > 1){
return null;
}
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessor.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessor.java
index 78f875f3..bf19f869 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessor.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessor.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.media.FaceDetector;
+import android.util.Log;
import org.opencv.android.Utils;
import org.opencv.core.Core;
@@ -84,9 +85,11 @@ public void setFaces(PreProcessorFactory.PreprocessingMode preprocessingMode) {
if (preprocessingMode == PreProcessorFactory.PreprocessingMode.RECOGNITION && preferencesHelper.getDetectionMethod()){
// Change the image rotation to the angle where the face was detected
- images.remove(0);
+ Mat img = images.remove(0);
images.add(faceDetection.getImg());
- setImages(images);
+ if(img != faceDetection.getImg()) {
+ img.release();
+ }
}
}
@@ -141,4 +144,26 @@ public void setImg(Mat img) {
public void normalize0255(Mat norm){
Core.normalize(norm, norm, 0, 255, Core.NORM_MINMAX, CvType.CV_8UC1);
}
+
+ //Release images
+ public void releaseImages() {
+ if (images == null || images.size() == 0)
+ return;
+ try {
+ for (int i = 0; i < images.size(); i++) {
+ if (images.get(i) != null) {
+ images.get(i).release();
+ } else {
+ Log.e("PreProcessor","releaseImages null image(" + i + "/" + images.size() +")");
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ images.clear();
+ images = null;
+ }
+ }
+
}
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessorFactory.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessorFactory.java
index ee16b64e..58c6cc4a 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessorFactory.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/PreProcessor/PreProcessorFactory.java
@@ -46,7 +46,6 @@ public class PreProcessorFactory {
public enum PreprocessingMode {DETECTION, RECOGNITION};
private PreProcessor preProcessorRecognition;
private PreProcessor preProcessorDetection;
- private List images;
public CommandFactory commandFactory;
private FaceDetection faceDetection;
private boolean eyeDetectionEnabled;
@@ -72,17 +71,23 @@ public PreProcessorFactory(Context context) {
public List getCroppedImage(Mat img){
preProcessorDetection = new PreProcessor(faceDetection, getCopiedImageList(img), context);
List preprocessingsDetection = getPreprocessings(PreferencesHelper.Usage.DETECTION);
- images = new ArrayList();
+ ArrayList images = new ArrayList();
images.add(img);
preProcessorRecognition = new PreProcessor(faceDetection, images, context);
try {
preprocess(preProcessorDetection, preprocessingsDetection);
preProcessorRecognition.setFaces(PreprocessingMode.RECOGNITION);
+ if(preProcessorRecognition.getFaces() == null || preProcessorRecognition.getFaces().length == 0) {
+ Log.d("getCroppedImage", "No face detected");
+ return null;
+ }
+
preProcessorRecognition = commandFactory.executeCommand(resources.getString(R.string.crop), preProcessorRecognition);
if (eyeDetectionEnabled) {
Eyes[] eyes = preProcessorRecognition.setEyes();
if (eyes == null || eyes[0] == null){
+ preProcessorRecognition.releaseImages();
return null;
}
}
@@ -90,6 +95,8 @@ public List getCroppedImage(Mat img){
} catch (NullPointerException e){
Log.d("getCroppedImage", "No face detected");
return null;
+ } finally {
+ preProcessorDetection.releaseImages();
}
return preProcessorRecognition.getImages();
}
@@ -98,7 +105,7 @@ public List getProcessedImage(Mat img, PreprocessingMode preprocessingMode)
preProcessorDetection = new PreProcessor(faceDetection, getCopiedImageList(img), context);
- images = new ArrayList();
+ ArrayList images = new ArrayList();
images.add(img);
preProcessorRecognition = new PreProcessor(faceDetection, images, context);
@@ -106,6 +113,11 @@ public List getProcessedImage(Mat img, PreprocessingMode preprocessingMode)
preprocess(preProcessorDetection, getPreprocessings(PreferencesHelper.Usage.DETECTION));
preProcessorDetection.setFaces(preprocessingMode);
+
+ if(preProcessorDetection.getFaces()==null || preProcessorDetection.getFaces().length == 0) {
+ preProcessorDetection.releaseImages();
+ return null;
+ }
preProcessorRecognition.setFaces(preProcessorDetection.getFaces());
preProcessorRecognition.setAngle(preProcessorDetection.getAngle());
preProcessorRecognition = commandFactory.executeCommand(resources.getString(R.string.crop), preProcessorRecognition);
@@ -113,6 +125,8 @@ public List getProcessedImage(Mat img, PreprocessingMode preprocessingMode)
if (eyeDetectionEnabled) {
Eyes[] eyes = preProcessorRecognition.setEyes();
if (eyes == null || eyes[0] == null){
+ preProcessorDetection.releaseImages();
+ preProcessorRecognition.releaseImages();
return null;
}
}
@@ -122,12 +136,14 @@ public List getProcessedImage(Mat img, PreprocessingMode preprocessingMode)
}
} catch (NullPointerException e){
+ preProcessorDetection.releaseImages();
Log.d("getProcessedImage", "No face detected");
return null;
}
if (preprocessingMode == PreprocessingMode.DETECTION){
return preProcessorDetection.getImages();
} else {
+ preProcessorDetection.releaseImages();
return preProcessorRecognition.getImages();
}
}
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/Caffe.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/Caffe.java
index fdb725f0..83aaa8e5 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/Caffe.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/Caffe.java
@@ -82,7 +82,10 @@ public boolean train() {
@Override
public String recognize(Mat img, String expectedLabel) {
- return rec.recognize(getFeatureVector(img), expectedLabel);
+ Mat feature = getFeatureVector(img);
+ String str = rec.recognize(feature, expectedLabel);
+ feature.release();
+ return str;
}
@Override
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/KNearestNeighbor.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/KNearestNeighbor.java
index d3ee453f..9245565e 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/KNearestNeighbor.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/KNearestNeighbor.java
@@ -83,7 +83,7 @@ public String recognize(Mat img, String expectedLabel) {
img = getFeatureVector(img);
addImage(img, expectedLabel, true);
nearest = knn.findNearest(img,k,result);
-
+ img.release();
return labelMap.getKey((int) nearest);
}
diff --git a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/TensorFlow.java b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/TensorFlow.java
index 00838e13..088ae499 100644
--- a/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/TensorFlow.java
+++ b/facerecognitionlibrary/src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/TensorFlow.java
@@ -103,7 +103,10 @@ public boolean train() {
@Override
public String recognize(Mat img, String expectedLabel) {
- return rec.recognize(getFeatureVector(img), expectedLabel);
+ Mat feature = getFeatureVector(img);
+ String str = rec.recognize(feature, expectedLabel);
+ feature.release();
+ return str;
}
@Override
diff --git a/gradlew b/gradlew
index 9d82f789..cccdd3d5 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,20 +6,38 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,26 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index aec99730..e95643d6 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line