Skip to content

Commit b02e9d0

Browse files
committed
Fixed errors in mobile application
1 parent 19d16ba commit b02e9d0

File tree

15 files changed

+669
-405
lines changed

15 files changed

+669
-405
lines changed

mobile_app/app/build.gradle

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33

44
android {
5-
compileSdkVersion 31
6-
buildToolsVersion "31.0.0"
5+
compileSdkVersion 33
6+
buildToolsVersion "33.0.0"
77

88
defaultConfig {
99
applicationId "com.asav.facialprocessing"
1010
minSdkVersion 24
11-
targetSdkVersion 31
11+
targetSdkVersion 33
1212
versionCode 1
1313
versionName "1.0"
1414
}
@@ -17,6 +17,9 @@ android {
1717
release {
1818
minifyEnabled false
1919
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
20+
ndk {
21+
abiFilters "arm64-v8a"
22+
}
2023
}
2124
}
2225
aaptOptions {
@@ -37,10 +40,9 @@ dependencies {
3740
implementation fileTree(dir: "libs", include: ["*.jar"])
3841
implementation 'androidx.appcompat:appcompat:1.2.0'
3942
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
40-
implementation 'org.pytorch:pytorch_android_lite:1.9.0'
41-
implementation 'org.pytorch:pytorch_android_torchvision:1.9.0'
42-
implementation 'org.tensorflow:tensorflow-android:+'
43-
implementation 'org.tensorflow:tensorflow-lite-gpu:+'
43+
implementation 'org.pytorch:pytorch_android_lite:+'
44+
implementation 'org.pytorch:pytorch_android_torchvision_lite:+'
45+
implementation 'org.tensorflow:tensorflow-lite:+'
4446
implementation 'org.tensorflow:tensorflow-lite-support:+'
4547
testImplementation 'junit:junit:4.12'
4648
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
-1.91 MB
Binary file not shown.
1.49 MB
Binary file not shown.
31.6 KB
Binary file not shown.
398 KB
Binary file not shown.

mobile_app/app/src/main/java/com/asav/facialprocessing/EmotionPyTorchClassifier.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class EmotionPyTorchClassifier{
3232
/** Tag for the {@link Log}. */
3333
private static final String TAG = "EmotionPyTorch";
3434

35-
private static final String MODEL_FILE = "enet_b0_8_best_vgaf.ptl";//"enet_b0_8_va_mtl.ptl";//"enet_b2_8.ptl";
35+
private static final String MODEL_FILE = "enet_b0_8_va_mtl.ptl";//"enet_b0_8_best_vgaf.ptl";//"enet_b2_8.ptl";
3636
private List<String> labels;
3737
private Module module=null;
3838
//private int width=260, height=260;

mobile_app/app/src/main/java/com/asav/facialprocessing/MainActivity.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import android.widget.*;
2323

2424
import com.asav.facialprocessing.mtcnn.Box;
25-
import com.asav.facialprocessing.mtcnn.MTCNNModel;
25+
import com.asav.facialprocessing.mtcnn.MTCNN;
2626

2727
import java.io.*;
2828
import java.nio.ByteBuffer;
@@ -42,7 +42,7 @@ public class MainActivity extends AppCompatActivity {
4242
private Handler mBackgroundHandler=null;
4343

4444
private static int minFaceSize=32;
45-
private MTCNNModel mtcnnFaceDetector=null;
45+
private MTCNN mtcnnFaceDetector=null;
4646
private AgeGenderEthnicityTfLiteClassifier facialAttributeClassifier=null;
4747
private EmotionTfLiteClassifier emotionClassifierTfLite =null;
4848
private EmotionPyTorchClassifier emotionClassifierPyTorch = null;
@@ -76,7 +76,7 @@ private void init(){
7676
Log.e(TAG, "Exception initializing EmotionPyTorchClassifier!", e);
7777
}
7878
try {
79-
mtcnnFaceDetector =MTCNNModel.Companion.create(getAssets());
79+
mtcnnFaceDetector =new MTCNN(getApplicationContext());
8080
} catch (final Exception e) {
8181
Log.e(TAG, "Exception initializing MTCNNModel!"+e);
8282
}

mobile_app/app/src/main/java/com/asav/facialprocessing/TfLiteClassifier.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,12 @@
99
import android.util.Log;
1010

1111
import org.tensorflow.lite.Interpreter;
12-
import org.tensorflow.lite.gpu.CompatibilityList;
1312
import org.tensorflow.lite.support.common.*;
14-
import org.tensorflow.lite.support.image.*;
15-
import org.tensorflow.lite.support.image.ops.*;
1613

17-
import java.io.FileInputStream;
1814
import java.io.IOException;
1915
import java.nio.ByteBuffer;
2016
import java.nio.ByteOrder;
2117
import java.nio.MappedByteBuffer;
22-
import java.nio.channels.FileChannel;
2318
import java.util.HashMap;
2419
import java.util.Map;
2520

@@ -43,16 +38,7 @@ public abstract class TfLiteClassifier {
4338
Map<Integer, Object> outputMap = new HashMap<>();
4439

4540
public TfLiteClassifier(final Context context, String model_path) throws IOException {
46-
//GpuDelegate delegate = new GpuDelegate();
47-
Interpreter.Options options = (new Interpreter.Options()).setNumThreads(4);//.addDelegate(delegate);
48-
CompatibilityList compatList = new CompatibilityList();
49-
boolean hasGPU=compatList.isDelegateSupportedOnThisDevice();
50-
if (hasGPU) {
51-
org.tensorflow.lite.gpu.GpuDelegate delegate = new org.tensorflow.lite.gpu.GpuDelegate();
52-
options.addDelegate(delegate);
53-
}
54-
55-
41+
Interpreter.Options options = (new Interpreter.Options()).setNumThreads(4);
5642
MappedByteBuffer tfliteModel= FileUtil.loadMappedFile(context,model_path);
5743
tflite = new Interpreter(tfliteModel,options);
5844
tflite.allocateTensors();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.asav.facialprocessing.mtcnn;
2+
3+
import android.graphics.Bitmap;
4+
import android.graphics.Matrix;
5+
import android.graphics.Point;
6+
7+
/**
8+
* 人脸对齐矫正
9+
*/
10+
public class Align {
11+
12+
/**
13+
* 仿射变换
14+
* @param bitmap 原图片
15+
* @param landmarks landmarks
16+
* @return 变换后的图片
17+
*/
18+
public static Bitmap face_align(Bitmap bitmap, Point[] landmarks) {
19+
float diffEyeX = landmarks[1].x - landmarks[0].x;
20+
float diffEyeY = landmarks[1].y - landmarks[0].y;
21+
22+
float fAngle;
23+
if (Math.abs(diffEyeY) < 1e-7) {
24+
fAngle = 0.f;
25+
} else {
26+
fAngle = (float) (Math.atan(diffEyeY / diffEyeX) * 180.0f / Math.PI);
27+
}
28+
Matrix matrix = new Matrix();
29+
matrix.setRotate(-fAngle);
30+
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
31+
}
32+
}

mobile_app/app/src/main/java/com/asav/facialprocessing/mtcnn/Box.java

Lines changed: 89 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,72 +4,108 @@
44
import android.graphics.Rect;
55

66
import static java.lang.Math.max;
7-
import static java.lang.Math.min;
87

8+
/**
9+
* 人脸框
10+
*/
911
public class Box {
10-
public int[] box; //left:box[0],top:box[1],right:box[2],bottom:box[3]
11-
public float score; //probability
12-
public float[] bbr; //bounding box regression
13-
public boolean deleted;
14-
public Point[] landmark; //facial landmark.只有ONet输出Landmark
15-
Box(){
16-
box=new int[4];
17-
bbr=new float[4];
18-
deleted=false;
19-
landmark=new Point[5];
12+
public int[] box; // left:box[0],top:box[1],right:box[2],bottom:box[3]
13+
public float score; // probability
14+
public float[] bbr; // bounding box regression
15+
public boolean deleted;
16+
public Point[] landmark; // facial landmark.只有ONet输出Landmark
17+
18+
public Box() {
19+
box = new int[4];
20+
bbr = new float[4];
21+
deleted = false;
22+
landmark = new Point[5];
2023
}
21-
public int left(){return box[0];}
22-
public int right(){return box[2];}
23-
public int top(){return box[1];}
24-
public int bottom(){return box[3];}
25-
public int width(){return box[2]-box[0]+1;}
26-
public int height(){return box[3]-box[1]+1;}
27-
28-
public Rect transform2Rect(){
29-
Rect rect=new Rect();
30-
rect.left=Math.round(box[0]);
31-
rect.top=Math.round(box[1]);
32-
rect.right=Math.round(box[2]);
33-
rect.bottom=Math.round(box[3]);
34-
return rect;
24+
25+
public int left() {
26+
return box[0];
3527
}
3628

37-
public int area(){
38-
return width()*height();
29+
public int right() {
30+
return box[2];
3931
}
4032

41-
public void calibrate(){
42-
int w=box[2]-box[0]+1;
43-
int h=box[3]-box[1]+1;
44-
box[0]=(int)(box[0]+w*bbr[0]);
45-
box[1]=(int)(box[1]+h*bbr[1]);
46-
box[2]=(int)(box[2]+w*bbr[2]);
47-
box[3]=(int)(box[3]+h*bbr[3]);
48-
for (int i=0;i<4;i++) bbr[i]=0.0f;
33+
public int top() {
34+
return box[1];
4935
}
5036

51-
public void toSquareShape(){
52-
int w=width();
53-
int h=height();
54-
if (w>h){
55-
box[1]-=(w-h)/2;
56-
box[3]+=(w-h+1)/2;
57-
}else{
58-
box[0]-=(h-w)/2;
59-
box[2]+=(h-w+1)/2;
37+
public int bottom() {
38+
return box[2];
39+
}
40+
41+
public int width() {
42+
return box[2] - box[0] + 1;
43+
}
44+
45+
public int height() {
46+
return box[3] - box[1] + 1;
47+
}
48+
49+
// 转为rect
50+
public Rect transform2Rect() {
51+
Rect rect = new Rect();
52+
rect.left = box[0];
53+
rect.top = box[1];
54+
rect.right = box[2];
55+
rect.bottom = box[3];
56+
return rect;
57+
}
58+
59+
// 面积
60+
public int area() {
61+
return width() * height();
62+
}
63+
64+
// Bounding Box Regression
65+
public void calibrate() {
66+
int w = box[2] - box[0] + 1;
67+
int h = box[3] - box[1] + 1;
68+
box[0] = (int) (box[0] + w * bbr[0]);
69+
box[1] = (int) (box[1] + h * bbr[1]);
70+
box[2] = (int) (box[2] + w * bbr[2]);
71+
box[3] = (int) (box[3] + h * bbr[3]);
72+
for (int i = 0; i < 4; i++) bbr[i] = 0.0f;
73+
}
74+
75+
// 当前box转为正方形
76+
public void toSquareShape() {
77+
int w = width();
78+
int h = height();
79+
if (w > h) {
80+
box[1] -= (w - h) / 2;
81+
box[3] += (w - h + 1) / 2;
82+
} else {
83+
box[0] -= (h - w) / 2;
84+
box[2] += (h - w + 1) / 2;
6085
}
6186
}
6287

63-
public void limit_square(int w,int h){
64-
if (box[0]<0 || box[1]<0){
65-
int len=max(-box[0],-box[1]);
66-
box[0]+=len;
67-
box[1]+=len;
88+
// 防止边界溢出,并维持square大小
89+
public void limitSquare(int w, int h) {
90+
if (box[0] < 0 || box[1] < 0) {
91+
int len = max(-box[0], -box[1]);
92+
box[0] += len;
93+
box[1] += len;
94+
}
95+
if (box[2] >= w || box[3] >= h) {
96+
int len = max(box[2] - w + 1, box[3] - h + 1);
97+
box[2] -= len;
98+
box[3] -= len;
6899
}
69-
if (box[2]>=w || box[3]>=h){
70-
int len=max(box[2]-w+1,box[3]-h+1);
71-
box[2]-=len;
72-
box[3]-=len;
100+
}
101+
102+
// 坐标是否越界
103+
public boolean transbound(int w, int h) {
104+
if (box[0] < 0 || box[1] < 0) {
105+
return true;
106+
} else if (box[2] >= w || box[3] >= h) {
107+
return true;
73108
}
109+
return false;
74110
}
75111
}

0 commit comments

Comments
 (0)