├── .gitignore
├── .idea
├── checkstyle-idea.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ ├── androidutils.jar
│ ├── libutils.jar
│ ├── libvlc-3.0.0.aar
│ ├── libvlc-3.0.0_32.aar
│ └── xutils.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── cayden
│ │ └── face
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── mtcnn_freezed_model.pb
│ ├── java
│ │ └── com
│ │ │ └── cayden
│ │ │ └── face
│ │ │ ├── FaceApplication.java
│ │ │ ├── FaceDB.java
│ │ │ ├── FaceManagerActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── facenet
│ │ │ ├── Box.java
│ │ │ ├── FaceFeature.java
│ │ │ ├── Facenet.java
│ │ │ ├── MTCNN.java
│ │ │ └── Utils.java
│ │ │ ├── stream
│ │ │ ├── ExtByteTools.java
│ │ │ ├── ExtInputStream.java
│ │ │ └── ExtOutputStream.java
│ │ │ ├── utils
│ │ │ ├── ImageUtils.java
│ │ │ └── NV21ToBitmap.java
│ │ │ └── vlc
│ │ │ ├── AppBeanService.java
│ │ │ ├── ConstData.java
│ │ │ ├── Rtsp.java
│ │ │ ├── RtspCallbackInterface.java
│ │ │ ├── UdpPlayerApplication.java
│ │ │ ├── UrlInfo.java
│ │ │ └── UrlInfoService.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_register.xml
│ │ ├── activity_vlc_player.xml
│ │ └── camera_view.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── btn_main.png
│ │ ├── face_reco_bg.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── cayden
│ └── face
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | *.iml
11 | .gradle
12 | /local.properties
13 | /.idea/workspace.xml
14 | /.idea/libraries
15 | .DS_Store
16 | /build
17 | /captures
18 | .gradle
19 | /local.properties
20 | /.idea/workspace.xml
21 | /.idea/libraries
22 | .DS_Store
23 | /build
24 | /captures
25 | # Local per-repo rules can be added to the .git/info/exclude file in your
26 | # repo. These rules are not committed with the repo so they are not shared
27 | # with others. This method can be used for locally-generated files that you
28 | # don’t expect other users to generate, like files created by your editor.
29 | .settings
30 | .classpath
31 | bin
32 | Debug
33 | obj
34 | coverage
35 | coverage.ec
36 | coverage.em
37 | gen
38 | javadoc
39 | junit-report.xml
40 | lint-results.*ml
41 | lint-results_files
42 | local.properties
43 | monkey.txt
44 | *~
45 | *.iws
46 | atlassian-ide-plugin.xml
47 | target
48 | build
49 | .gradle
50 | out
51 | build.xml
52 | proguard-project.txt
53 | .idea/
54 | *.iml
55 | # Built application files
56 | *.apk
57 | *.ap_
58 |
59 | # Files for the Dalvik VM
60 | *.dex
61 |
62 | # Java class files
63 | *.class
64 |
65 | # Generated files
66 | bin/
67 | gen/
68 |
69 | # Gradle files
70 | .gradle/
71 | build/
72 |
73 | # Local configuration file (sdk path, etc)
74 | local.properties
75 |
76 | # Proguard folder generated by Eclipse
77 | proguard/
78 |
79 | # Log Files
80 | *.log
81 | # Built application files
82 | *.apk
83 | *.ap_
84 |
85 | # Files for the ART/Dalvik VM
86 | *.dex
87 |
88 | # Java class files
89 | *.class
90 |
91 | # Generated files
92 | bin/
93 | gen/
94 | out/
95 |
96 | # Gradle files
97 | .gradle/
98 | build/
99 |
100 | # Local configuration file (sdk path, etc)
101 | local.properties
102 |
103 | # Proguard folder generated by Eclipse
104 | proguard/
105 |
106 | # Log Files
107 | *.log
108 |
109 | # Android Studio Navigation editor temp files
110 | .navigation/
111 |
112 | # Android Studio captures folder
113 | captures/
114 |
115 | # Intellij
116 | *.iml
117 | .idea/workspace.xml
118 | .idea/tasks.xml
119 | .idea/gradle.xml
120 | .idea/dictionaries
121 | .idea/libraries
122 |
123 | # Keystore files
124 | *.jks
125 |
126 | # External native build folder generated in Android Studio 2.2 and later
127 | .externalNativeBuild
128 |
129 | # Google Services (e.g. APIs or Firebase)
130 | google-services.json
131 |
132 | # Freeline
133 | freeline.py
134 | freeline/
135 | freeline_project_description.json
--------------------------------------------------------------------------------
/.idea/checkstyle-idea.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # facesample
2 |
3 | 本项目主要基于vlc来播放流媒体视频
4 | 可以入QQ群参与讨论:735436509
5 |
6 | 主要包含以下内容
7 |
8 | - 1、使用已经编译的libvlc来播放流媒体视频
9 | - 2、使用MTCNN进行人脸识别并标记人脸
10 | - 3、保存标记的人脸图片
11 | - 4、使用FACENET进行人脸比对
12 | - 未完待续...
13 |
14 |
15 | ### v1.0.3
16 | - 1, 通过FACENET获取脸部特征数据
17 | - 2, 人脸比对,找出相似度最高的人
18 |
19 |
20 | ### v1.0.2
21 | - 1, 通过MTCNN检测人脸
22 | - 2, 对人脸进行标记
23 |
24 |
25 | ### v1.0.1
26 | - 1, 获取返回的视频流数据
27 | - 2, 将数据nv12转换为nv21,并保存图片
28 |
29 | ### v1.0.0
30 | - 1, added libvlc
31 | - 2, support for playing rtsp video stream
32 |
33 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion '27.0.3'
6 | defaultConfig {
7 | applicationId "com.cayden.face"
8 | minSdkVersion 19
9 | targetSdkVersion 27
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | android {
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 | }
28 |
29 | repositories {
30 | flatDir {
31 | dirs 'libs'
32 | }
33 | maven {
34 | url "http://dl.bintray.com/jlmd/maven"
35 | }
36 | }
37 |
38 | dependencies {
39 | implementation fileTree(include: ['*.jar'], dir: 'libs')
40 | implementation 'com.android.support:appcompat-v7:27.1.1'
41 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
42 | testImplementation 'junit:junit:4.12'
43 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
44 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
45 | compile(name: 'libvlc-3.0.0', ext: 'aar')
46 | implementation files('libs/androidutils.jar')
47 | compile 'org.tensorflow:tensorflow-android:+'
48 | implementation files('libs/libutils.jar')
49 | }
50 |
--------------------------------------------------------------------------------
/app/libs/androidutils.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/libs/androidutils.jar
--------------------------------------------------------------------------------
/app/libs/libutils.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/libs/libutils.jar
--------------------------------------------------------------------------------
/app/libs/libvlc-3.0.0.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/libs/libvlc-3.0.0.aar
--------------------------------------------------------------------------------
/app/libs/libvlc-3.0.0_32.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/libs/libvlc-3.0.0_32.aar
--------------------------------------------------------------------------------
/app/libs/xutils.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/libs/xutils.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/cayden/face/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.cayden.face", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/assets/mtcnn_freezed_model.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/assets/mtcnn_freezed_model.pb
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/FaceApplication.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.Matrix;
8 | import android.media.ExifInterface;
9 | import android.net.Uri;
10 | import android.os.Environment;
11 | import android.util.Log;
12 |
13 |
14 | /**
15 | * Created by caydencui on 2018/9/6.
16 | */
17 |
18 | public class FaceApplication extends Application {
19 | private static final String TAG = "FaceApplication";
20 | public FaceDB mFaceDB;
21 | Uri mImage;
22 | private static FaceApplication instance;
23 |
24 | //绘制左右翻转
25 | public static final boolean yu = true;
26 |
27 | public FaceApplication(){
28 |
29 | }
30 |
31 | @Override
32 | public void onCreate() {
33 | super.onCreate();
34 | instance=this;
35 | mFaceDB= FaceDB.getInstance();
36 | mFaceDB.init(Environment.getExternalStorageDirectory().getPath() + "/FaceDetect");
37 | mImage = null;
38 | }
39 |
40 | // 获取Application
41 | public static Context getMyApplication() {
42 | return instance;
43 | }
44 |
45 | public void setCaptureImage(Uri uri) {
46 | mImage = uri;
47 | }
48 |
49 | public Uri getCaptureImage() {
50 | return mImage;
51 | }
52 |
53 | /**
54 | * @param path
55 | * @return
56 | */
57 | public static Bitmap decodeImage(String path) {
58 | Bitmap res;
59 | try {
60 | ExifInterface exif = new ExifInterface(path);
61 | int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
62 |
63 | BitmapFactory.Options op = new BitmapFactory.Options();
64 | op.inSampleSize = 1;
65 | op.inJustDecodeBounds = false;
66 | //op.inMutable = true;
67 | res = BitmapFactory.decodeFile(path, op);
68 | //rotate and scale.
69 | Matrix matrix = new Matrix();
70 |
71 | if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
72 | matrix.postRotate(90);
73 | } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
74 | matrix.postRotate(180);
75 | } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
76 | matrix.postRotate(270);
77 | }
78 |
79 | Bitmap temp = Bitmap.createBitmap(res, 0, 0, res.getWidth(), res.getHeight(), matrix, true);
80 | Log.d(TAG, "check target Image:" + temp.getWidth() + "X" + temp.getHeight());
81 |
82 | if (!temp.equals(res)) {
83 | res.recycle();
84 | }
85 | return temp;
86 | } catch (Exception e) {
87 | e.printStackTrace();
88 | }
89 | return null;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/FaceDB.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face;
2 |
3 | import android.util.Log;
4 |
5 |
6 | import com.cayden.face.facenet.FaceFeature;
7 | import com.cayden.face.stream.ExtInputStream;
8 | import com.cayden.face.stream.ExtOutputStream;
9 |
10 | import java.io.File;
11 | import java.io.FileInputStream;
12 | import java.io.FileNotFoundException;
13 | import java.io.FileOutputStream;
14 | import java.io.IOException;
15 | import java.io.RandomAccessFile;
16 | import java.nio.ByteBuffer;
17 | import java.nio.channels.FileChannel;
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | /**
22 | * Created by caydencui on 2018/9/6.
23 | */
24 |
25 | public class FaceDB {
26 | private final String TAG = this.getClass().toString();
27 |
28 | String mDBPath;
29 | public List mRegister;
30 | private FaceDB() {
31 |
32 | }
33 |
34 | private static class SingletonInstance {
35 | private static final FaceDB INSTANCE = new FaceDB();
36 | }
37 |
38 | public static FaceDB getInstance() {
39 | return SingletonInstance.INSTANCE;
40 | }
41 |
42 | public void init(String path){
43 | mDBPath = path;
44 | mRegister = new ArrayList<>();
45 | }
46 |
47 | public class FaceRegist {
48 | public String mName;
49 | public FaceFeature faceFeature;
50 |
51 | public FaceRegist(String name) {
52 | mName = name;
53 | faceFeature = new FaceFeature();
54 | }
55 | }
56 |
57 | private boolean saveInfo() {
58 | try {
59 | Log.d(TAG, "mDBPath=" +mDBPath + "/face.txt");
60 | FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt");
61 | ExtOutputStream bos = new ExtOutputStream(fs);
62 | bos.writeString( "tusi-face-v1.0.0," + 1);
63 | bos.close();
64 | fs.close();
65 | return true;
66 | } catch (FileNotFoundException e) {
67 | e.printStackTrace();
68 | } catch (IOException e) {
69 | e.printStackTrace();
70 | }
71 | return false;
72 | }
73 |
74 | /**
75 | * 加载数据
76 | * @return
77 | */
78 | private boolean loadInfo() {
79 | if (!mRegister.isEmpty()) {
80 | return false;
81 | }
82 | try {
83 | File file=new File(mDBPath );
84 | if(!file.exists()){
85 | file.mkdir();
86 |
87 | }
88 | FileInputStream fs = new FileInputStream(mDBPath + "/face.txt");
89 | ExtInputStream bos = new ExtInputStream(fs);
90 | //load version
91 | String version_saved = bos.readString();
92 |
93 | //load all regist name.
94 | if (version_saved != null) {
95 | for (String name = bos.readString(); name != null; name = bos.readString()){
96 | if (new File(mDBPath + "/" + name + ".data").exists()) {
97 | mRegister.add(new FaceRegist(new String(name)));
98 | }
99 | }
100 | }
101 | bos.close();
102 | fs.close();
103 | return true;
104 | } catch (FileNotFoundException e) {
105 | e.printStackTrace();
106 | } catch (IOException e) {
107 | e.printStackTrace();
108 | }
109 | return false;
110 | }
111 |
112 | /**
113 | * 加载人脸数据
114 | * @return
115 | */
116 | public boolean loadFaces(){
117 | if (loadInfo()) {
118 | try {
119 | for (FaceRegist face : mRegister) {
120 | Log.d(TAG, "load name:" + face.mName + "'s face feature data.");
121 | FileInputStream fs = new FileInputStream(mDBPath + "/" + face.mName + ".data");
122 |
123 | float [] fea= readFloatFromData(mDBPath + "/" + face.mName + ".data",512);
124 | face.faceFeature.setFea(fea);
125 |
126 | }
127 | Log.d(TAG, "load mRegister: size = " + mRegister.size());
128 | return true;
129 | }
130 | catch (Exception e) {
131 | e.printStackTrace();
132 | }
133 | }
134 | return false;
135 | }
136 |
137 | /**
138 | * 添加人脸数据信息
139 | * @param name
140 | * @param face
141 | */
142 | public void addFace(String name, FaceFeature face) {
143 | try {
144 | //check if already registered.
145 | boolean add = true;
146 | for (FaceRegist frface : mRegister) {
147 | if (frface.mName.equals(name)) {
148 | frface.faceFeature=face;
149 | add = false;
150 | break;
151 | }
152 | }
153 | if (add) { // not registered.
154 | FaceRegist frface = new FaceRegist(name);
155 | frface.faceFeature=face;
156 | mRegister.add(frface);
157 | }
158 |
159 | if (saveInfo()) {
160 | //update all names
161 | FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt", true);
162 | ExtOutputStream bos = new ExtOutputStream(fs);
163 | for (FaceRegist frface : mRegister) {
164 | bos.writeString(frface.mName);
165 | }
166 | bos.close();
167 | fs.close();
168 |
169 | //save new feature
170 | writeFloatToData(face.getFeature(),mDBPath + "/" + name + ".data",512);
171 |
172 | }
173 | } catch (FileNotFoundException e) {
174 | e.printStackTrace();
175 | } catch (IOException e) {
176 | e.printStackTrace();
177 | }
178 | }
179 |
180 | /**
181 | * 删除对应人脸信息
182 | * @param name
183 | * @return
184 | */
185 | public boolean delete(String name) {
186 | try {
187 | //check if already registered.
188 | boolean find = false;
189 | for (FaceRegist frface : mRegister) {
190 | if (frface.mName.equals(name)) {
191 | File delfile = new File(mDBPath + "/" + name + ".data");
192 | if (delfile.exists()) {
193 | delfile.delete();
194 | }
195 | mRegister.remove(frface);
196 | find = true;
197 | break;
198 | }
199 | }
200 |
201 | if (find) {
202 | if (saveInfo()) {
203 | //update all names
204 | FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt", true);
205 | ExtOutputStream bos = new ExtOutputStream(fs);
206 | for (FaceRegist frface : mRegister) {
207 | bos.writeString(frface.mName);
208 | }
209 | bos.close();
210 | fs.close();
211 | }
212 | }
213 | return find;
214 | } catch (FileNotFoundException e) {
215 | e.printStackTrace();
216 | } catch (IOException e) {
217 | e.printStackTrace();
218 | }
219 | return false;
220 | }
221 |
222 |
223 | /**
224 | * 将float[]写入文件
225 | * @param verts
226 | * @param gcodeFile
227 | * @param count
228 | */
229 | private void writeFloatToData(float[] verts, String gcodeFile, int count) {
230 | try {
231 | RandomAccessFile aFile = new RandomAccessFile(gcodeFile, "rw");
232 | FileChannel outChannel = aFile.getChannel();
233 | //one float 4 bytes
234 | ByteBuffer buf = ByteBuffer.allocate(4 * count * 3 * 3);
235 | buf.clear();
236 | buf.asFloatBuffer().put(verts);
237 | //while(buf.hasRemaining())
238 | {
239 | outChannel.write(buf);
240 | }
241 | //outChannel.close();
242 | buf.rewind();
243 | outChannel.close();
244 | } catch (IOException ex) {
245 | System.err.println(ex.getMessage());
246 | }
247 | }
248 |
249 | /**
250 | * 读取文件返回float[]
251 | * @param gcodeFile
252 | * @param Count
253 | * @return
254 | */
255 | private float[] readFloatFromData(String gcodeFile, int Count) {
256 | float[] verts = new float[Count * 3 * 3];
257 | try {
258 | RandomAccessFile rFile = new RandomAccessFile(gcodeFile, "rw");
259 | FileChannel inChannel = rFile.getChannel();
260 | ByteBuffer buf_in = ByteBuffer.allocate(3 * 3 * Count * 4);
261 | buf_in.clear();
262 | inChannel.read(buf_in);
263 | buf_in.rewind();
264 | buf_in.asFloatBuffer().get(verts);
265 | inChannel.close();
266 | } catch (IOException ex) {
267 | System.err.println(ex.getMessage());
268 | }
269 | return verts;
270 | }
271 |
272 |
273 | }
274 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/FaceManagerActivity.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.ContentUris;
5 | import android.content.Intent;
6 | import android.database.Cursor;
7 | import android.graphics.Bitmap;
8 | import android.graphics.BitmapFactory;
9 | import android.graphics.Rect;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.os.Bundle;
13 | import android.os.Environment;
14 | import android.provider.DocumentsContract;
15 | import android.provider.MediaStore;
16 | import android.support.annotation.Nullable;
17 | import android.support.v7.app.AppCompatActivity;
18 | import android.text.TextUtils;
19 | import android.util.Log;
20 | import android.view.View;
21 | import android.widget.Button;
22 | import android.widget.EditText;
23 | import android.widget.ImageView;
24 | import android.widget.Toast;
25 |
26 | import com.cayden.face.facenet.Box;
27 | import com.cayden.face.facenet.FaceFeature;
28 | import com.cayden.face.facenet.Facenet;
29 | import com.cayden.face.facenet.MTCNN;
30 | import com.cayden.face.facenet.Utils;
31 |
32 | import java.io.File;
33 | import java.io.IOException;
34 | import java.util.Vector;
35 |
36 | /**
37 | * Created by caydencui on 2018/12/29.
38 | */
39 |
40 | public class FaceManagerActivity extends AppCompatActivity implements View.OnClickListener {
41 |
42 | public static final int CHOOSE_PHOTO=0;
43 | private Button btn_select,btn_register;
44 | private EditText edit_name;
45 | private ImageView iv_head;
46 | private Uri imageUri;
47 | private Facenet facenet;
48 | private MTCNN mtcnn;
49 | private Bitmap bitmap=null;//选择的图片
50 | @Override
51 | protected void onCreate(@Nullable Bundle savedInstanceState) {
52 | super.onCreate(savedInstanceState);
53 | setContentView(R.layout.activity_register);
54 | facenet=Facenet.getInstance();
55 | mtcnn = MTCNN.getInstance();
56 | btn_select=(Button)findViewById(R.id.pic_select);
57 | btn_register=(Button)findViewById(R.id.pic_register);
58 | btn_select.setOnClickListener(this);
59 | btn_register.setOnClickListener(this);
60 | iv_head=(ImageView)findViewById(R.id.iv_head);
61 | edit_name=(EditText)findViewById(R.id.edit_name);
62 |
63 | }
64 |
65 | @Override
66 | public void onClick(View v) {
67 | switch (v.getId()){
68 | case R.id.pic_select:
69 | choosePhoto();
70 | break;
71 | case R.id.pic_register:
72 | registerFace();
73 | break;
74 | }
75 | }
76 |
77 |
78 | public Bitmap detectFaces(){
79 | if(null==bitmap)return null;
80 |
81 | Vector boxes=mtcnn.detectFaces(bitmap,40);
82 | if (boxes.size()==0) return null;
83 | for (int i=0;i boxes = mtcnn.detectFaces(bitmap, 20);
171 |
172 | drawAnim(boxes, draw_view, scale_bit, 1, "");
173 |
174 | if (boxes.size()==0) return ;
175 | for (int i=0;i mResgist =FaceDB.getInstance().mRegister;
191 | double tempScore=-1;
192 | for(int i=0;itemp){
203 | foundName=faceRegist.mName;
204 | tempScore=temp;
205 | }
206 | }
207 | Log.d(TAG,">>>>>>>>>>temp="+temp+",tempScore="+tempScore+",foundName:"+foundName);
208 | }
209 | cmp=tempScore;
210 | runOnUiThread(new Runnable() {
211 | @Override
212 | public void run() {
213 |
214 | tv_result.setText(String.format("名字:%s 相似度 : %.4f", foundName,cmp) );
215 | }
216 | });
217 | }
218 |
219 | }
220 | });
221 |
222 | }
223 |
224 |
225 | protected void drawAnim(Vector faces, SurfaceView outputView, float scale_bit, int cameraId, String fps) {
226 | Paint paint = new Paint();
227 | Canvas canvas = ((SurfaceView) outputView).getHolder().lockCanvas();
228 | if (canvas != null) {
229 | try {
230 | int viewH = outputView.getHeight();
231 | int viewW = outputView.getWidth();
232 | // DLog.d("viewW:"+viewW+",viewH:"+viewH);
233 | canvas.drawColor(0, PorterDuff.Mode.CLEAR);
234 | if (faces == null || faces.size() == 0) return;
235 | for (int i = 0; i < faces.size(); i++) {
236 | paint.setColor(Color.BLUE);
237 | int size = DisplayUtil.dip2px(this, 3);
238 | paint.setStrokeWidth(size);
239 | paint.setStyle(Paint.Style.STROKE);
240 | Box box = faces.get(i);
241 | float[] rect = box.transform2float();
242 | float x1 = rect[0] * scale_bit;
243 | float y1 = rect[1] * scale_bit;
244 | float rect_width = rect[2] * 0.5F;
245 | RectF rectf = new RectF(x1, y1, x1 + rect_width, y1 + rect_width);
246 | canvas.drawRect(rectf, paint);
247 | }
248 |
249 | } catch (Exception e) {
250 | e.printStackTrace();
251 | } finally {
252 | ((SurfaceView) outputView).getHolder().unlockCanvasAndPost(canvas);
253 | }
254 | }
255 | }
256 |
257 |
258 | public static String tempTarget = Environment.getExternalStorageDirectory() + File.separator + "CWModels" + File.separator + "Register.jpg";
259 |
260 | /**
261 | * 保存图片
262 | *
263 | * @param data
264 | */
265 | public void mPictureSave(byte[] data) {
266 | byte[] NV21 = new byte[data.length];
267 | NV12ToNV21(data, NV21, ConstData.DEFAULT_PREVIEW_WIDTH, ConstData.DEFAULT_PREVIEW_HEIGHT);
268 | YuvImage yuvImage = new YuvImage(NV21, ImageFormat.NV21, ConstData.DEFAULT_PREVIEW_WIDTH, ConstData.DEFAULT_PREVIEW_HEIGHT, null);
269 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
270 | yuvImage.compressToJpeg(new Rect(0, 0, ConstData.DEFAULT_PREVIEW_WIDTH, ConstData.DEFAULT_PREVIEW_HEIGHT), 80, baos);
271 | byte[] jdata = baos.toByteArray();
272 | Bitmap bitmap = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);
273 | File file = null;
274 | file = new File(tempTarget);
275 | FileOutputStream fileOutputStream = null;
276 | try {
277 | fileOutputStream = new FileOutputStream(file);
278 | fileOutputStream.write(jdata);
279 | fileOutputStream.close();
280 |
281 | } catch (IOException e) {
282 | e.printStackTrace();
283 | }
284 |
285 | }
286 |
287 | private void NV12ToNV21(byte[] nv12, byte[] nv21, int width, int height) {
288 | if (nv21 == null || nv12 == null) return;
289 | int framesize = width * height;
290 | int i = 0, j = 0;
291 | //System.arraycopy(nv21, test, nv12, test, framesize);
292 | for (i = 0; i < framesize; i++) {
293 | nv21[i] = nv12[i];
294 | }
295 | for (j = 0; j < framesize / 2; j += 2) {
296 | nv21[framesize + j] = nv12[j + framesize + 1];
297 | }
298 | for (j = 0; j < framesize / 2; j += 2) {
299 | nv21[framesize + j + 1] = nv12[j + framesize];
300 | }
301 | }
302 |
303 | private View.OnClickListener onClickListener_run = new View.OnClickListener() {
304 | @Override
305 | public void onClick(View v) {
306 |
307 |
308 | // mRegisterStatus.setText("");
309 | // mEditText.setText("");
310 | mRun_verify.setClickable(false);
311 | //mBackgroundHandler1.post(new ImageProcess());
312 |
313 | }
314 | };
315 | private View.OnClickListener onClickListener_PicSave = new View.OnClickListener() {
316 | @Override
317 | public void onClick(View v) {
318 | isSave = true;
319 | }
320 | };
321 |
322 | private View.OnClickListener onClickListener_StartPlay = new View.OnClickListener() {
323 | @Override
324 | public void onClick(View v) {
325 | String netAddress = mEditNetAddress.getText().toString().trim();
326 | if (!TextUtils.isEmpty(netAddress)) {
327 | UrlInfo urlInfo = new UrlInfo();
328 | urlInfo.setUrl(netAddress);
329 | mUrlInfoService.save(urlInfo);
330 | Rtsp.mRun = true;
331 | isStart=true;
332 | mNxpRtsp.SetUrl(netAddress);
333 | mNxpRtsp.init(null, mVideoTexture);
334 | mNxpRtsp.play();
335 | }
336 |
337 | }
338 | };
339 |
340 | private View.OnClickListener onClickListener_Stop = new View.OnClickListener() {
341 | @Override
342 | public void onClick(View v) {
343 | mNxpRtsp.stop();
344 |
345 | }
346 | };
347 |
348 |
349 | @Override
350 | protected void onDestroy() {
351 | super.onDestroy();
352 | if(null!=mNxpRtsp&&isStart){
353 | Rtsp.mRun = false;
354 | mNxpRtsp.stop();
355 | }
356 |
357 | }
358 | }
359 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/facenet/Box.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.facenet;
2 |
3 | import android.graphics.Point;
4 | import android.graphics.Rect;
5 |
6 | import static java.lang.Math.max;
7 |
8 | /**
9 | * Created by caydencui on 2018/9/6.
10 | */
11 | public class Box {
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 | Box(){
18 | box=new int[4];
19 | bbr=new float[4];
20 | deleted=false;
21 | landmark=new Point[5];
22 | }
23 | public int left(){return box[0];}
24 | public int right(){return box[2];}
25 | public int top(){return box[1];}
26 | public int bottom(){return box[2];}
27 | public int width(){return box[2]-box[0]+1;}
28 | public int height(){return box[3]-box[1]+1;}
29 | //转为rect
30 | public Rect transform2Rect(){
31 | Rect rect=new Rect();
32 | rect.left= Math.round(box[0]);
33 | rect.top= Math.round(box[1]);
34 | rect.right= Math.round(box[2]);
35 | rect.bottom= Math.round(box[3]);
36 | return rect;
37 | }
38 |
39 | public float[] transform2float(){
40 | float [] floats=new float[4];
41 |
42 | floats[0]= Math.round(box[0]);
43 | floats[1]= Math.round(box[1]);
44 | floats[2]= Math.round(box[2]);
45 | floats[3]= Math.round(box[3]);
46 |
47 | return floats;
48 | }
49 | //面积
50 | public int area(){
51 | return width()*height();
52 | }
53 | //Bounding Box Regression
54 | public void calibrate(){
55 | int w=box[2]-box[0]+1;
56 | int h=box[3]-box[1]+1;
57 | box[0]=(int)(box[0]+w*bbr[0]);
58 | box[1]=(int)(box[1]+h*bbr[1]);
59 | box[2]=(int)(box[2]+w*bbr[2]);
60 | box[3]=(int)(box[3]+h*bbr[3]);
61 | for (int i=0;i<4;i++) bbr[i]=0.0f;
62 | }
63 | //当前box转为正方形
64 | public void toSquareShape(){
65 | int w=width();
66 | int h=height();
67 | if (w>h){
68 | box[1]-=(w-h)/2;
69 | box[3]+=(w-h+1)/2;
70 | }else{
71 | box[0]-=(h-w)/2;
72 | box[2]+=(h-w+1)/2;
73 | }
74 | }
75 | //防止边界溢出,并维持square大小
76 | public void limit_square(int w,int h){
77 | if (box[0]<0 || box[1]<0){
78 | int len=max(-box[0],-box[1]);
79 | box[0]+=len;
80 | box[1]+=len;
81 | }
82 | if (box[2]>=w || box[3]>=h){
83 | int len=max(box[2]-w+1,box[3]-h+1);
84 | box[2]-=len;
85 | box[3]-=len;
86 | }
87 | }
88 | public void limit_square2(int w,int h){
89 | if (width() > w) box[2]-=width()-w;
90 | if (height()> h) box[3]-=height()-h;
91 | if (box[0]<0){
92 | int sz=-box[0];
93 | box[0]+=sz;
94 | box[2]+=sz;
95 | }
96 | if (box[1]<0){
97 | int sz=-box[1];
98 | box[1]+=sz;
99 | box[3]+=sz;
100 | }
101 | if (box[2]>=w){
102 | int sz=box[2]-w+1;
103 | box[2]-=sz;
104 | box[0]-=sz;
105 | }
106 | if (box[3]>=h){
107 | int sz=box[3]-h+1;
108 | box[3]-=sz;
109 | box[1]-=sz;
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/facenet/FaceFeature.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.facenet;
2 |
3 | /**
4 | * Created by caydencui on 2018/9/6.
5 | * 人脸特征(512维特征值)
6 | * 相似度取特征向量之间的欧式距离.
7 | */
8 | public class FaceFeature {
9 | public static final int DIMS=512;
10 | private float fea[];
11 | public FaceFeature(){
12 | fea=new float[DIMS];
13 | }
14 | public float[] getFeature(){
15 | return fea;
16 | }
17 |
18 | public void setFea(float[] fea) {
19 | this.fea = fea;
20 | }
21 |
22 | //比较当前特征和另一个特征之间的相似度
23 | public double compare(FaceFeature ff){
24 | double dist=0;
25 | for (int i=0;i> 16) & 0xFF) - imageMean) / imageStd;
91 | floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
92 | floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
93 | }
94 | //Log.d("Facenet","[*]normalizeImage");
95 | //Log.d("Facenet","[*]normalizeImage"+intValues.length);
96 | return 0;
97 | }
98 | public FaceFeature recognizeImage(final Bitmap bitmap){
99 | //Log.d("Facenet","[*]recognizeImage");
100 | //(0)图片预处理,normailize
101 | normalizeImage(bitmap);
102 | //(1)Feed
103 | try {
104 | inferenceInterface.feed(INPUT_NAME, floatValues, 1, INPUT_SIZE, INPUT_SIZE, 3);
105 | boolean [] phase=new boolean[1];
106 | // phase[0]=false;
107 | inferenceInterface.feed(PHASE_NAME,phase);
108 |
109 | }catch (Exception e){
110 | Log.e("Facenet","[*] feed Error\n"+e);
111 | return null;
112 | }
113 | //(2)run
114 | // Log.d("Facenet","[*]Feed:"+INPUT_NAME);
115 | try {
116 | inferenceInterface.run(outputNames, false);
117 | }catch (Exception e){
118 | Log.e("Facenet","[*] run error\n"+e);
119 | return null;
120 | }
121 | //(3)fetch
122 | FaceFeature faceFeature=new FaceFeature();
123 | float[] outputs=faceFeature.getFeature();
124 | try {
125 | inferenceInterface.fetch(OUTPUT_NAME, outputs);
126 | }catch (Exception e){
127 | Log.e("Facenet","[*] fetch error\n"+e);
128 | return null;
129 | }
130 | return faceFeature;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/facenet/MTCNN.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.facenet;
2 |
3 | import android.content.res.AssetManager;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Matrix;
6 | import android.graphics.Point;
7 | import android.util.Log;
8 |
9 |
10 | import com.cayden.face.FaceApplication;
11 |
12 | import org.tensorflow.contrib.android.TensorFlowInferenceInterface;
13 |
14 | import java.util.Vector;
15 |
16 | import static java.lang.Math.max;
17 | import static java.lang.Math.min;
18 |
19 | /**
20 | * Created by caydencui on 2018/9/6.
21 | */
22 | public class MTCNN {
23 | //参数
24 | private float factor=0.709f;
25 | private float PNetThreshold=0.6f;
26 | private float RNetThreshold=0.7f;
27 | private float ONetThreshold=0.7f;
28 | //MODEL PATH
29 | private static final String MODEL_FILE = "file:///android_asset/mtcnn_freezed_model.pb";
30 | //tensor name
31 | private static final String PNetInName ="pnet/input:0";
32 | private static final String[] PNetOutName =new String[]{"pnet/prob1:0","pnet/conv4-2/BiasAdd:0"};
33 | private static final String RNetInName ="rnet/input:0";
34 | private static final String[] RNetOutName =new String[]{ "rnet/prob1:0","rnet/conv5-2/conv5-2:0",};
35 | private static final String ONetInName ="onet/input:0";
36 | private static final String[] ONetOutName =new String[]{ "onet/prob1:0","onet/conv6-2/conv6-2:0","onet/conv6-3/conv6-3:0"};
37 |
38 |
39 | private static class SingletonInstance {
40 | private static final MTCNN INSTANCE = new MTCNN();
41 | }
42 |
43 | public static MTCNN getInstance() {
44 | return SingletonInstance.INSTANCE;
45 | }
46 |
47 | //安卓相关
48 | public long lastProcessTime; //最后一张图片处理的时间ms
49 | private static final String TAG="MTCNN";
50 | private AssetManager assetManager;
51 | private TensorFlowInferenceInterface inferenceInterface;
52 |
53 | private MTCNN() {
54 | assetManager= FaceApplication.getMyApplication().getAssets();
55 | loadModel();
56 | }
57 |
58 |
59 |
60 | private boolean loadModel() {
61 | //AssetManager
62 | try {
63 | inferenceInterface = new TensorFlowInferenceInterface(assetManager, MODEL_FILE);
64 | Log.d("MTCNN","[*]load model success");
65 | }catch(Exception e){
66 | Log.e("MTCNN","[*]load model failed"+e);
67 | return false;
68 | }
69 | return true;
70 | }
71 | //读取Bitmap像素值,预处理(-127.5 /128),转化为一维数组返回
72 | private float[] normalizeImage(Bitmap bitmap){
73 | int w=bitmap.getWidth();
74 | int h=bitmap.getHeight();
75 | float[] floatValues=new float[w*h*3];
76 | int[] intValues=new int[w*h];
77 | bitmap.getPixels(intValues,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
78 | float imageMean=127.5f;
79 | float imageStd=128;
80 |
81 | for (int i=0;i> 16) & 0xFF) - imageMean) / imageStd;
84 | floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
85 | floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
86 | }
87 | return floatValues;
88 | }
89 | /*
90 | 检测人脸,minSize是最小的人脸像素值
91 | */
92 | private Bitmap bitmapResize(Bitmap bm, float scale) {
93 | int width = bm.getWidth();
94 | int height = bm.getHeight();
95 | // CREATE A MATRIX FOR THE MANIPULATION。matrix指定图片仿射变换参数
96 | Matrix matrix = new Matrix();
97 | // RESIZE THE BIT MAP
98 | matrix.postScale(scale, scale);
99 | Bitmap resizedBitmap = Bitmap.createBitmap(
100 | bm, 0, 0, width, height, matrix, true);
101 | return resizedBitmap;
102 | }
103 | //输入前要翻转,输出也要翻转
104 | private int PNetForward(Bitmap bitmap, float [][]PNetOutProb, float[][][]PNetOutBias){
105 | int w=bitmap.getWidth();
106 | int h=bitmap.getHeight();
107 |
108 | float[] PNetIn=normalizeImage(bitmap);
109 | Utils.flip_diag(PNetIn,h,w,3); //沿着对角线翻转
110 | inferenceInterface.feed(PNetInName,PNetIn,1,w,h,3);
111 | inferenceInterface.run(PNetOutName,false);
112 | int PNetOutSizeW=(int) Math.ceil(w*0.5-5);
113 | int PNetOutSizeH=(int) Math.ceil(h*0.5-5);
114 | float[] PNetOutP=new float[PNetOutSizeW*PNetOutSizeH*2];
115 | float[] PNetOutB=new float[PNetOutSizeW*PNetOutSizeH*4];
116 | inferenceInterface.fetch(PNetOutName[0],PNetOutP);
117 | inferenceInterface.fetch(PNetOutName[1],PNetOutB);
118 | //【写法一】先翻转,后转为2/3维数组
119 | Utils.flip_diag(PNetOutP,PNetOutSizeW,PNetOutSizeH,2);
120 | Utils.flip_diag(PNetOutB,PNetOutSizeW,PNetOutSizeH,4);
121 | Utils.expand(PNetOutB,PNetOutBias);
122 | Utils.expandProb(PNetOutP,PNetOutProb);
123 | /*
124 | *【写法二】这个比较快,快了3ms。意义不大,用上面的方法比较直观
125 | for (int y=0;y boxes, float threshold, String method){
138 | //NMS.两两比对
139 | //int delete_cnt=0;
140 | for(int i=0;i= threshold) { //删除prob小的那个框
159 | if (box.score>box2.score)
160 | box2.deleted=true;
161 | else
162 | box.deleted=true;
163 | //delete_cnt++;
164 | }
165 | }
166 | }
167 | }
168 | }
169 | //Log.i(TAG,"[*]sum:"+boxes.size()+" delete:"+delete_cnt);
170 | }
171 | private int generateBoxes(float[][] prob,float[][][]bias,float scale,float threshold,Vector boxes){
172 | int h=prob.length;
173 | int w=prob[0].length;
174 | //Log.i(TAG,"[*]height:"+prob.length+" width:"+prob[0].length);
175 | for (int y=0;ythreadshold(0.6 here)
179 | if (score>PNetThreshold){
180 | Box box=new Box();
181 | //score
182 | box.score=score;
183 | //box
184 | box.box[0]= Math.round(x*2/scale);
185 | box.box[1]= Math.round(y*2/scale);
186 | box.box[2]= Math.round((x*2+11)/scale);
187 | box.box[3]= Math.round((y*2+11)/scale);
188 | //bbr
189 | for(int i=0;i<4;i++)
190 | box.bbr[i]=bias[y][x][i];
191 | //add
192 | boxes.addElement(box);
193 | }
194 | }
195 | return 0;
196 | }
197 | private void BoundingBoxReggression(Vector boxes){
198 | for (int i=0;i PNet(Bitmap bitmap, int minSize){
209 | int whMin=min(bitmap.getWidth(),bitmap.getHeight());
210 | float currentFaceSize=minSize; //currentFaceSize=minSize/(factor^k) k=0,1,2... until excced whMin
211 | Vector totalBoxes=new Vector();
212 | //【1】Image Paramid and Feed to Pnet
213 | while (currentFaceSize<=whMin){
214 | float scale=12.0f/currentFaceSize;
215 | //(1)Image Resize
216 | Bitmap bm=bitmapResize(bitmap,scale);
217 | int w=bm.getWidth();
218 | int h=bm.getHeight();
219 | //(2)RUN CNN
220 | int PNetOutSizeW=(int)(Math.ceil(w*0.5-5)+0.5);
221 | int PNetOutSizeH=(int)(Math.ceil(h*0.5-5)+0.5);
222 | float[][] PNetOutProb=new float[PNetOutSizeH][PNetOutSizeW];;
223 | float[][][] PNetOutBias=new float[PNetOutSizeH][PNetOutSizeW][4];
224 | PNetForward(bm,PNetOutProb,PNetOutBias);
225 | //(3)数据解析
226 | Vector curBoxes=new Vector();
227 | generateBoxes(PNetOutProb,PNetOutBias,scale,PNetThreshold,curBoxes);
228 | //Log.i(TAG,"[*]CNN Output Box number:"+curBoxes.size()+" Scale:"+scale);
229 | //(4)nms 0.5
230 | nms(curBoxes,0.5f,"Union");
231 | //(5)add to totalBoxes
232 | for (int i=0;i> 16) & 0xFF) - imageMean) / imageStd;
260 | data[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
261 | data[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
262 | }
263 | }
264 | /*
265 | * RNET跑神经网络,将score和bias写入boxes
266 | */
267 | private void RNetForward(float[] RNetIn,Vector boxes){
268 | int num=RNetIn.length/24/24/3;
269 | //feed & run
270 | inferenceInterface.feed(RNetInName,RNetIn,num,24,24,3);
271 | inferenceInterface.run(RNetOutName,false);
272 | //fetch
273 | float[] RNetP=new float[num*2];
274 | float[] RNetB=new float[num*4];
275 | inferenceInterface.fetch(RNetOutName[0],RNetP);
276 | inferenceInterface.fetch(RNetOutName[1],RNetB);
277 | //转换
278 | for (int i=0;i RNet(Bitmap bitmap, Vector boxes){
286 | //RNet Input Init
287 | int num=boxes.size();
288 | float[] RNetIn=new float[num*24*24*3];
289 | float[] curCrop=new float[24*24*3];
290 | int RNetInIdx=0;
291 | for (int i=0;i boxes){
312 | int num=ONetIn.length/48/48/3;
313 | //feed & run
314 | inferenceInterface.feed(ONetInName,ONetIn,num,48,48,3);
315 | inferenceInterface.run(ONetOutName,false);
316 | //fetch
317 | float[] ONetP=new float[num*2]; //prob
318 | float[] ONetB=new float[num*4]; //bias
319 | float[] ONetL=new float[num*10]; //landmark
320 | inferenceInterface.fetch(ONetOutName[0],ONetP);
321 | inferenceInterface.fetch(ONetOutName[1],ONetB);
322 | inferenceInterface.fetch(ONetOutName[2],ONetL);
323 | //转换
324 | for (int i=0;i ONet(Bitmap bitmap, Vector boxes){
342 | //ONet Input Init
343 | int num=boxes.size();
344 | float[] ONetIn=new float[num*48*48*3];
345 | float[] curCrop=new float[48*48*3];
346 | int ONetInIdx=0;
347 | for (int i=0;i boxes, int w, int h){
364 | //square
365 | for (int i=0;i detectFaces(Bitmap bitmap, int minFaceSize) {
378 | long t_start = System.currentTimeMillis();
379 | //【1】PNet generate candidate boxes
380 | Vector boxes=PNet(bitmap,minFaceSize);
381 | square_limit(boxes,bitmap.getWidth(),bitmap.getHeight());
382 | //【2】RNet
383 | boxes=RNet(bitmap,boxes);
384 | square_limit(boxes,bitmap.getWidth(),bitmap.getHeight());
385 | //【3】ONet
386 | boxes=ONet(bitmap,boxes);
387 | //return
388 | Log.i(TAG,"[*]Mtcnn Detection Time:"+(System.currentTimeMillis()-t_start));
389 | lastProcessTime=(System.currentTimeMillis()-t_start);
390 | return boxes;
391 | }
392 | }
393 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/facenet/Utils.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.facenet;
2 | import android.graphics.Bitmap;
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Matrix;
6 | import android.graphics.Paint;
7 | import android.graphics.Point;
8 | import android.graphics.Rect;
9 | import android.util.Log;
10 |
11 | import java.util.Vector;
12 |
13 | import static java.lang.Math.max;
14 | import static java.lang.Math.min;
15 |
16 | /**
17 | * Created by caydencui on 2018/9/6.
18 | */
19 | public class Utils {
20 | //复制图片,并设置isMutable=true
21 | public static Bitmap copyBitmap(Bitmap bitmap){
22 | return bitmap.copy(bitmap.getConfig(),true);
23 | }
24 | //在bitmap中画矩形
25 | public static void drawRect(Bitmap bitmap, Rect rect, int thick){
26 | try {
27 | Canvas canvas = new Canvas(bitmap);
28 | Paint paint = new Paint();
29 | int r=255;//(int)(Math.random()*255);
30 | int g=0;//(int)(Math.random()*255);
31 | int b=0;//(int)(Math.random()*255);
32 | paint.setColor(Color.rgb(r, g, b));
33 | paint.setStrokeWidth(thick);
34 | paint.setStyle(Paint.Style.STROKE);
35 | canvas.drawRect(rect, paint);
36 | //Log.i("Util","[*]draw rect");
37 | }catch (Exception e){
38 | Log.i("Utils","[*] error"+e);
39 | // e.printStackTrace();
40 | }
41 | }
42 | //在图中画点
43 | public static void drawPoints(Bitmap bitmap, Point[] landmark, int thick){
44 | for (int i=0;i boxes){
91 | int cnt=0;
92 | for (int i=0;i updateBoxes(Vector boxes){
102 | Vector b=new Vector();
103 | for (int i=0;i>16)&0xff)+"G:"+((v>>8)&0xff)+ " B:"+(v&0xff));
123 | }
124 | static public Bitmap resize(Bitmap _bitmap, int new_width){
125 | float scale=((float)new_width)/_bitmap.getWidth();
126 | Matrix matrix=new Matrix();
127 | matrix.postScale(scale,scale);
128 | Bitmap bitmap= Bitmap.createBitmap(_bitmap,0,0,_bitmap.getWidth(),_bitmap.getHeight(),matrix,true);
129 | return bitmap;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/stream/ExtByteTools.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.stream;
2 |
3 | /**
4 | * Created by caydencui on 2018/9/6.
5 | */
6 |
7 | public class ExtByteTools {
8 |
9 | public static byte[] convert_from_int(int val) {
10 | byte[] size = new byte[4];
11 | size[0] = (byte)(val >> 24);
12 | size[1] = (byte)(val >> 16);
13 | size[2] = (byte)(val >> 8);
14 | size[3] = (byte)(val >> 0);
15 | return size;
16 | }
17 | public static int convert_to_int(byte[] val) {
18 | int size = 0;
19 | if (val.length >= 4) {
20 | size |= ((val[0] & 0xFF) << 24);
21 | size |= ((val[1] & 0xFF) << 16);
22 | size |= ((val[2] & 0xFF) << 8);
23 | size |= ((val[3] & 0xFF) << 0);
24 | }
25 | return size;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/stream/ExtInputStream.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.stream;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | /**
8 | * Created by caydencui on 2018/9/6.
9 | */
10 |
11 | public class ExtInputStream extends BufferedInputStream {
12 | public ExtInputStream(InputStream in) {
13 | super(in);
14 | }
15 |
16 | public ExtInputStream(InputStream in, int size) {
17 | super(in, size);
18 | }
19 |
20 | public String readString() throws IOException {
21 | byte[] size = new byte[4];
22 | if (read(size) > 0) {
23 | byte[] name = new byte[ExtByteTools.convert_to_int(size)];
24 | if (name.length == read(name)) {
25 | return new String(name);
26 | }
27 | }
28 | return null;
29 | }
30 |
31 | public byte[] readBytes() throws IOException {
32 | byte[] size = new byte[4];
33 | if (read(size) > 0) {
34 | byte[] data = new byte[ExtByteTools.convert_to_int(size)];
35 | if (data.length == read(data)) {
36 | return data;
37 | }
38 | }
39 | return null;
40 | }
41 |
42 | public boolean readBytes(byte[] data) throws IOException {
43 | byte[] size = new byte[4];
44 | if (read(size) > 0) {
45 | if (ExtByteTools.convert_to_int(size) == data.length) {
46 | if (data.length == read(data)) {
47 | return true;
48 | }
49 | }
50 | }
51 | return false;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/stream/ExtOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.stream;
2 |
3 | import java.io.BufferedOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStream;
6 |
7 | /**
8 | * Created by caydencui on 2018/9/6.
9 | */
10 |
11 | public class ExtOutputStream extends BufferedOutputStream {
12 | public ExtOutputStream(OutputStream out) {
13 | super(out);
14 | }
15 |
16 | public ExtOutputStream(OutputStream out, int size) {
17 | super(out, size);
18 | }
19 |
20 | public boolean writeString(String name) throws IOException {
21 | write(ExtByteTools.convert_from_int(name.getBytes().length));
22 | write(name.getBytes());
23 | return true;
24 | }
25 |
26 | public boolean writeBytes(byte[] data) throws IOException {
27 | write(ExtByteTools.convert_from_int(data.length));
28 | write(data);
29 | return false;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/utils/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.utils;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.net.Uri;
7 | import android.os.Environment;
8 | import android.util.Log;
9 | import android.widget.Toast;
10 |
11 | import java.io.File;
12 | import java.io.FileNotFoundException;
13 | import java.io.FileOutputStream;
14 | import java.io.IOException;
15 | import java.text.SimpleDateFormat;
16 | import java.util.Date;
17 |
18 | /**
19 | * Created by caydencui on 2018/9/10.
20 | */
21 |
22 | public class ImageUtils {
23 |
24 | public static final int MEDIA_TYPE_IMAGE = 1;
25 | public static final int MEDIA_TYPE_VIDEO = 2;
26 |
27 | // save image to sdcard path: Pictures/MyTestImage/
28 | public static void saveImageData(byte[] imageData) {
29 | File imageFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
30 | if (imageFile == null) return;
31 | try {
32 | FileOutputStream fos = new FileOutputStream(imageFile);
33 | fos.write(imageData);
34 | fos.close();
35 | Log.d("save","saved in "+imageFile.getAbsolutePath());
36 | } catch (FileNotFoundException e) {
37 | e.printStackTrace();
38 | } catch (IOException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 |
43 | public static File getOutputMediaFile(int type) {
44 | File imageFileDir =
45 | new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyTestImage");
46 | if (!imageFileDir.exists()) if (!imageFileDir.mkdirs()) {
47 | return null;
48 | }
49 | // Create a media file name
50 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
51 | File imageFile;
52 | if (type == MEDIA_TYPE_IMAGE) {
53 | imageFile = new File(imageFileDir.getPath() + File.separator +
54 | "IMG_" + timeStamp + ".jpg");
55 | } else if (type == MEDIA_TYPE_VIDEO) {
56 | imageFile = new File(imageFileDir.getPath() + File.separator +
57 | "VID_" + timeStamp + ".mp4");
58 | } else return null;
59 | return imageFile;
60 | }
61 |
62 | /**
63 | * save bitmap to image
64 | * @param bitmap
65 | * @return
66 | */
67 | public static boolean saveImg(Bitmap bitmap) {
68 | try {
69 | String sdcardPath = System.getenv("EXTERNAL_STORAGE"); //获得sd卡路径
70 | String dir = sdcardPath + "/facesample/"; //图片保存的文件夹名
71 | File file = new File(dir); //已File来构建
72 | if (!file.exists()) { //如果不存在 就mkdirs()创建此文件夹
73 | file.mkdirs();
74 | }
75 | Log.i("SaveImg", "file uri==>" + dir);
76 | // Create a media file name
77 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
78 | File mFile = new File(dir + timeStamp+".jpg"); //将要保存的图片文件
79 |
80 | FileOutputStream outputStream = new FileOutputStream(mFile); //构建输出流
81 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); //compress到输出outputStream
82 |
83 | return true;
84 |
85 | } catch (FileNotFoundException e) {
86 | e.printStackTrace();
87 | }
88 | return false;
89 | }
90 |
91 |
92 | }
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/utils/NV21ToBitmap.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.renderscript.Allocation;
6 | import android.renderscript.Element;
7 | import android.renderscript.RenderScript;
8 | import android.renderscript.ScriptIntrinsicYuvToRGB;
9 | import android.renderscript.Type;
10 |
11 | /**
12 | * Created by caydencui on 2018/12/7.
13 | */
14 |
15 | public class NV21ToBitmap {
16 |
17 | private RenderScript rs;
18 | private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
19 | private Type.Builder yuvType, rgbaType;
20 | private Allocation in, out;
21 |
22 | public NV21ToBitmap(Context context) {
23 | rs = RenderScript.create(context);
24 | yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
25 | }
26 |
27 | public Bitmap nv21ToBitmap(byte[] nv21, int width, int height){
28 | if (yuvType == null){
29 | yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length);
30 | in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
31 |
32 | rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
33 | out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
34 | }
35 |
36 | in.copyFrom(nv21);
37 |
38 | yuvToRgbIntrinsic.setInput(in);
39 | yuvToRgbIntrinsic.forEach(out);
40 |
41 | Bitmap bmpout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
42 | out.copyTo(bmpout);
43 |
44 | return bmpout;
45 |
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/AppBeanService.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.vlc;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import momo.cn.edu.fjnu.androidutils.base.BaseBeanService;
9 |
10 | public abstract class AppBeanService implements BaseBeanService {
11 | private final String TAG = AppBeanService.class.getSimpleName();
12 | @Override
13 | public void save(T object) {
14 | try {
15 | UdpPlayerApplication.mDBManager.save(object);
16 | } catch (Exception e) {
17 | e.printStackTrace();
18 | }
19 | }
20 |
21 | @Override
22 | public void delete(T object) {
23 | try {
24 | UdpPlayerApplication.mDBManager.delete(object);
25 | } catch (Exception e) {
26 | e.printStackTrace();
27 | }
28 | }
29 |
30 | @Override
31 | public void update(T object) {
32 | try {
33 | UdpPlayerApplication.mDBManager.update(object);
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | }
37 | }
38 |
39 | @Override
40 | public List getAll(Class tClass) {
41 | List lists = new ArrayList();
42 | try {
43 | lists = UdpPlayerApplication.mDBManager.findAll(tClass);
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | }
47 | return lists;
48 | }
49 |
50 | @Override
51 | public T getObjectById(Class tClass, Object id) {
52 | T object = null;
53 | try {
54 | object = UdpPlayerApplication.mDBManager.findById(tClass, id);
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | return object;
59 | }
60 |
61 | @Override
62 | public abstract boolean isExist(T object) ;
63 |
64 | @Override
65 | public void saveAll(List objects) {
66 | try {
67 | UdpPlayerApplication.mDBManager.save(objects);
68 |
69 | } catch (Exception e) {
70 | Log.e(TAG, "saveAll->exception:" + e);
71 | e.printStackTrace();
72 | }
73 |
74 | }
75 |
76 | @Override
77 | public void updateAll(List objects) {
78 | try {
79 | UdpPlayerApplication.mDBManager.update(objects);
80 | } catch (Exception e) {
81 | e.printStackTrace();
82 | }
83 | }
84 |
85 | @Override
86 | public void saveOrUpdateAll(List objects) {
87 | try {
88 | UdpPlayerApplication.mDBManager.saveOrUpdate(objects);
89 | } catch (Exception e) {
90 | Log.e(TAG, "saveOrUpdateAll->exception:" + e);
91 | e.printStackTrace();
92 | }
93 | }
94 |
95 | public void saveOrUpdate(T object){
96 | try {
97 | UdpPlayerApplication.mDBManager.saveOrUpdate(object);
98 | } catch (Exception e) {
99 | e.printStackTrace();
100 | }
101 | }
102 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/ConstData.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.vlc;
2 |
3 |
4 | import momo.cn.edu.fjnu.androidutils.data.CommonValues;
5 |
6 | public class ConstData {
7 | public static final int DB_VERSION = 1;
8 | public static final String DB_DIRECTORY = CommonValues.application.getFilesDir().getPath();
9 | public static final String DB_NAME = "udp_player.db";
10 |
11 | public static final int DEFAULT_PREVIEW_WIDTH = 800;
12 | public static final int DEFAULT_PREVIEW_HEIGHT = 654;
13 | public static final int PIXEL_SIZE = 4;
14 | public static final int DEFAULT_PREVIEW_MODE = 0;
15 | public static final int DEFAULT_PREVIEW_MIN_FPS = 1;
16 | public static final int DEFAULT_PREVIEW_MAX_FPS = 30;
17 | public static final float DEFAULT_BANDWIDTH = 1.0f;
18 |
19 | public static final int FRAME_FORMAT_YUYV = 0;
20 | public static final int FRAME_FORMAT_MJPEG = 1;
21 |
22 | public static final int PIXEL_FORMAT_RAW = 0;
23 | public static final int PIXEL_FORMAT_YUV = 1;
24 | public static final int PIXEL_FORMAT_RGB565 = 2;
25 | public static final int PIXEL_FORMAT_RGBX = 3;
26 | public static final int PIXEL_FORMAT_YUV420SP = 4;
27 | public static final int PIXEL_FORMAT_NV21 = 5; // = YVU420SemiPlanar
28 |
29 | public interface IntentKey{
30 | String VIDEO_URL = "video_url";
31 | String INSTALL_TIME = "install_time";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/Rtsp.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.vlc;
2 |
3 | import android.content.Context;
4 | import android.media.MediaCodec;
5 | import android.media.MediaFormat;
6 | import android.net.Uri;
7 | import android.os.Process;
8 | import android.util.Log;
9 | import android.view.SurfaceView;
10 | import android.view.TextureView;
11 |
12 | import org.videolan.libvlc.IVLCVout;
13 | import org.videolan.libvlc.LibVLC;
14 | import org.videolan.libvlc.Media;
15 | import org.videolan.libvlc.MediaPlayCallback;
16 | import org.videolan.libvlc.MediaPlayer;
17 |
18 | import java.io.File;
19 | import java.io.FileOutputStream;
20 | import java.io.IOException;
21 | import java.nio.ByteBuffer;
22 | import java.util.ArrayList;
23 |
24 |
25 | public class Rtsp {
26 |
27 | private String mUrl;
28 | private MediaPlayer mMediaPlayer = null;
29 | private LibVLC mLibVLC = null;
30 | private Context mContext;
31 | private SurfaceView msView = null;
32 | private TextureView mtView = null;
33 | private Thread mGetFrameBufferThread;
34 | private RtspCallbackInterface mNxpRtspCallbackInterface=null;
35 | private String TAG ="Rtsp";
36 | private MediaCodec mMediaCodec = null;
37 | private MediaFormat mOutFormat;
38 | private SurfaceView mSurfaceView = null;
39 | private int mRotationDegrees = 0;
40 | private int mLostFrameCount = 0;
41 | private int mRenderMode = 1;
42 | private int mcxVideo = 0;
43 | private int mcyVideo = 0;
44 | private int mNxpRtspState=-1;
45 | public int len=10;
46 | public byte[] frameData = new byte[4000000];
47 | public int[] frameInfo = new int[2];
48 |
49 |
50 | public Rtsp(Context context, RtspCallbackInterface callback){
51 | mContext=context;
52 | mNxpRtspCallbackInterface=callback;
53 | }
54 | public boolean SetUrl(String url){
55 | this.mUrl=url;
56 | return true;
57 | }
58 |
59 | public boolean init(SurfaceView sView, SurfaceView tView){
60 |
61 | final ArrayList args = new ArrayList<>();
62 | args.add("-vvv");
63 | mLibVLC = new LibVLC(mContext, args);
64 | mMediaPlayer = new MediaPlayer(mLibVLC);
65 |
66 | //init mMediaPlayer
67 | final IVLCVout vlcVout = mMediaPlayer.getVLCVout();
68 | if(sView!=null) {
69 | msView = sView;
70 | vlcVout.setVideoView(mtView);
71 | }
72 | else if(tView!=null){
73 | mSurfaceView=tView;
74 | vlcVout.setVideoView(mSurfaceView);
75 |
76 | }
77 |
78 | vlcVout.attachViews();
79 |
80 | Media media = new Media(mLibVLC, Uri.parse(mUrl));
81 | media.setHWDecoderEnabled(true,true);
82 | media.addOption(":no-audio");
83 | media.addOption(":network-caching=150");
84 | media.addOption(":file-caching=150");
85 | media.addOption(":sout-mux-caching=150");
86 | media.addOption(":live-caching=150");
87 | mMediaPlayer.setMedia(media);
88 | //
89 | mMediaPlayer.getVLCVout().setWindowSize(ConstData.DEFAULT_PREVIEW_WIDTH,ConstData.DEFAULT_PREVIEW_HEIGHT);
90 | mMediaPlayer.setAspectRatio(ConstData.DEFAULT_PREVIEW_WIDTH+":"+ConstData.DEFAULT_PREVIEW_HEIGHT);
91 | mMediaPlayer.setScale(0);
92 |
93 | media.release();
94 | float scale=704/576;
95 | // vlcVout.setWindowSize(1280,(int)(1280/scale));
96 | // vlcVout.setWindowSize(1280,720);
97 | //creat a thread to get the frame data
98 | this.mGetFrameBufferThread=new Thread(this.mGetFrameBufferRun);
99 |
100 |
101 | return true;
102 | }
103 |
104 | public boolean init(SurfaceView sView, TextureView tView){
105 |
106 | final ArrayList args = new ArrayList<>();
107 | args.add("-vvv");
108 | mLibVLC = new LibVLC(mContext, args);
109 | mMediaPlayer = new MediaPlayer(mLibVLC);
110 |
111 | //init mMediaPlayer
112 | final IVLCVout vlcVout = mMediaPlayer.getVLCVout();
113 | if(sView!=null) {
114 | msView = sView;
115 | vlcVout.setVideoView(mtView);
116 | }
117 | else if(tView!=null){
118 | mtView=tView;
119 | vlcVout.setVideoView(mtView);
120 | }
121 |
122 | vlcVout.attachViews();
123 |
124 | Media media = new Media(mLibVLC, Uri.parse(mUrl));
125 | media.setHWDecoderEnabled(true,true);
126 | media.addOption(":no-audio");
127 | media.addOption(":network-caching=150");
128 | media.addOption(":file-caching=150");
129 | media.addOption(":sout-mux-caching=150");
130 | media.addOption(":live-caching=150");
131 | mMediaPlayer.setMedia(media);
132 |
133 | mMediaPlayer.getVLCVout().setWindowSize(ConstData.DEFAULT_PREVIEW_WIDTH,ConstData.DEFAULT_PREVIEW_HEIGHT);
134 | mMediaPlayer.setAspectRatio(ConstData.DEFAULT_PREVIEW_WIDTH+":"+ConstData.DEFAULT_PREVIEW_HEIGHT);
135 | mMediaPlayer.setScale(0);
136 |
137 | media.release();
138 |
139 | //creat a thread to get the frame data
140 | this.mGetFrameBufferThread=new Thread(this.mGetFrameBufferRun);
141 |
142 |
143 | return true;
144 | }
145 |
146 | public void setVideoCallback(MediaPlayCallback mediaPlayCallback){
147 | if(mMediaPlayer!=null){
148 | ByteBuffer frameBuffer = ByteBuffer.allocateDirect(ConstData.DEFAULT_PREVIEW_WIDTH*ConstData.DEFAULT_PREVIEW_HEIGHT*ConstData.PIXEL_SIZE);
149 | mMediaPlayer.setVideoFormat("RGBA",ConstData.DEFAULT_PREVIEW_WIDTH,ConstData.DEFAULT_PREVIEW_HEIGHT,ConstData.PIXEL_SIZE);
150 | mMediaPlayer.setVideoCallback(frameBuffer,mediaPlayCallback);
151 | }
152 | }
153 |
154 | public boolean play(){
155 | Process.setThreadPriority(-20);
156 | mMediaPlayer.play();
157 | //test();
158 | this.mGetFrameBufferThread.start();
159 |
160 |
161 | return true;
162 | }
163 | void sleep(int millisecond)
164 | {
165 | try
166 | {
167 | Thread.sleep(millisecond);
168 | }
169 | catch (InterruptedException e)
170 | {
171 | e.printStackTrace();
172 | }
173 | }
174 |
175 | private void test() throws IOException {
176 | // byte[] array = {9,100,10,37,5,10};
177 |
178 | len=mMediaPlayer.getBuffer(frameData,frameInfo);
179 | /// for(int temp=0;temp<10;temp++){
180 | /// Log.d(TAG, "the Array len is "+frameData[temp]);
181 | /// }
182 | //确定写出文件的位置
183 | File file = new File("/sdcard/DumpData.yuv");
184 | FileOutputStream fos = new FileOutputStream(file);
185 | fos.write(frameData);
186 | fos.close();
187 | Log.d(TAG, "the Array len is "+len);
188 | }
189 |
190 | public boolean stop(){
191 | mMediaPlayer.stop();
192 | this.mGetFrameBufferThread.interrupt();
193 | mMediaPlayer.getVLCVout().detachViews();
194 | return true;
195 | }
196 | public boolean pause(){
197 | mMediaPlayer.pause();
198 | mMediaPlayer.getVLCVout().detachViews();
199 | return true;
200 | }
201 |
202 | public static boolean mRun=true;
203 |
204 |
205 | private Runnable mGetFrameBufferRun=new Runnable() {
206 | @Override
207 | public void run()
208 | {
209 | // Process.setThreadPriority(-8);
210 |
211 | while(true) {
212 |
213 | try {
214 | if(mRun) {
215 | // sleep(100);
216 | len = mMediaPlayer.getBuffer(frameData, frameInfo);
217 | if(len>0){
218 | mNxpRtspCallbackInterface.decodeOutputBuffer(len,frameData,frameInfo[0],frameInfo[1]);
219 | }
220 | // LocalFaceSDK.getInstance(null).cwPushBinaryFrame(frameData, frameInfo[0], frameInfo[1],
221 | // FaceInterface.cw_img_form_t.CW_IMAGE_NV12, CaremaType.BACK_LANDSCAPE);
222 | }
223 | // test();
224 | } catch (Exception e) {
225 | e.printStackTrace();
226 | }
227 | }
228 | }
229 | };
230 | }
231 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/RtspCallbackInterface.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face.vlc;
2 |
3 | public abstract interface RtspCallbackInterface {
4 | public abstract void decodeOutputBuffer(int frameLen, byte[] frameBuffer, long width, long height);
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/UdpPlayerApplication.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.cayden.face.vlc;
5 |
6 | import org.xutils.DbManager;
7 | import org.xutils.x;
8 |
9 | import java.io.File;
10 |
11 | import momo.cn.edu.fjnu.androidutils.base.BaseApplication;
12 |
13 | public class UdpPlayerApplication extends BaseApplication {
14 | public static DbManager mDBManager;
15 |
16 | @Override
17 | public void onCreate() {
18 | super.onCreate();
19 | DbManager.DaoConfig dbConfig = new DbManager.DaoConfig().setDbDir(new File(ConstData.DB_DIRECTORY))
20 | .setDbName(ConstData.DB_NAME).setDbVersion(ConstData.DB_VERSION).setAllowTransaction(true)
21 | .setDbOpenListener(new DbManager.DbOpenListener() {
22 | @Override
23 | public void onDbOpened(DbManager db) {
24 | db.getDatabase().enableWriteAheadLogging();
25 | }
26 | }).setDbUpgradeListener(null);
27 | if (null == mDBManager)
28 | mDBManager = x.getDb(dbConfig);
29 | mDBManager = x.getDb(dbConfig);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/UrlInfo.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.cayden.face.vlc;
5 |
6 | import org.xutils.db.annotation.Column;
7 | import org.xutils.db.annotation.Table;
8 |
9 | @Table(name="UrlInfo")
10 | public class UrlInfo {
11 | @Column(name="id", isId=true, autoGen=true)
12 | private int id;
13 | @Column(name="url", property="UNIQUE")
14 | private String url;
15 | public int getId() {
16 | return id;
17 | }
18 | public void setId(int id) {
19 | this.id = id;
20 | }
21 | public String getUrl() {
22 | return url;
23 | }
24 | public void setUrl(String url) {
25 | this.url = url;
26 | }
27 | @Override
28 | public String toString() {
29 | return url;
30 | }
31 |
32 | @Override
33 | protected void finalize() throws Throwable {
34 | super.finalize();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cayden/face/vlc/UrlInfoService.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.cayden.face.vlc;
5 |
6 | import org.xutils.ex.DbException;
7 |
8 | import java.util.List;
9 |
10 |
11 | public class UrlInfoService extends AppBeanService{
12 |
13 | @Override
14 | public boolean isExist(UrlInfo object) {
15 | return false;
16 | }
17 |
18 | public List getAll(){
19 | return getAll(UrlInfo.class);
20 | }
21 |
22 | public void deleteAll(){
23 | try {
24 | UdpPlayerApplication.mDBManager.delete(UrlInfo.class);
25 | } catch (DbException e) {
26 | e.printStackTrace();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
21 |
22 |
28 |
29 |
38 |
44 |
45 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_vlc_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
20 |
26 |
27 |
35 |
36 |
44 |
45 |
54 |
63 |
64 |
73 |
74 |
75 |
83 |
84 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/camera_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/btn_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-hdpi/btn_main.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/face_reco_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-hdpi/face_reco_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #FFFFFF
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 人脸识别
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/cayden/face/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.cayden.face;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Tue Dec 25 16:52:52 CST 2018
16 | systemProp.https.proxyPort=8080
17 | systemProp.http.proxyHost=web-proxy.oa.com
18 | org.gradle.jvmargs=-Xmx1536m
19 | systemProp.https.proxyHost=web-proxy.oa.com
20 | systemProp.http.proxyPort=8080
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cayden/facesample/70b5eebc4fb7349eb46992daa2d30501c510c48d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Dec 25 16:52:47 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------