├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── chenty
│ │ └── testncnn
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ │ ├── CMakeLists.txt
│ │ ├── arcface
│ │ │ ├── arcface.cpp
│ │ │ ├── arcface.h
│ │ │ ├── base.cpp
│ │ │ ├── base.h
│ │ │ ├── det1.h
│ │ │ ├── det1.id.h
│ │ │ ├── det2.h
│ │ │ ├── det2.id.h
│ │ │ ├── det3.h
│ │ │ ├── det3.id.h
│ │ │ ├── det4.h
│ │ │ ├── det4.id.h
│ │ │ ├── interface.cpp
│ │ │ ├── interface.h
│ │ │ ├── mobilefacenet.h
│ │ │ ├── mobilefacenet.id.h
│ │ │ ├── mtcnn.cpp
│ │ │ └── mtcnn.h
│ │ ├── jni.cpp
│ │ └── ncnn-android-lib
│ │ │ ├── arm64-v8a
│ │ │ └── libncnn.a
│ │ │ ├── armeabi-v7a
│ │ │ └── libncnn.a
│ │ │ └── include
│ │ │ └── ncnn
│ │ │ ├── allocator.h
│ │ │ ├── benchmark.h
│ │ │ ├── blob.h
│ │ │ ├── command.h
│ │ │ ├── cpu.h
│ │ │ ├── datareader.h
│ │ │ ├── gpu.h
│ │ │ ├── layer.h
│ │ │ ├── layer_type.h
│ │ │ ├── layer_type_enum.h
│ │ │ ├── mat.h
│ │ │ ├── modelbin.h
│ │ │ ├── net.h
│ │ │ ├── opencv.h
│ │ │ ├── option.h
│ │ │ ├── paramdict.h
│ │ │ ├── pipeline.h
│ │ │ └── platform.h
│ ├── java
│ │ └── com
│ │ │ └── chenty
│ │ │ └── testncnn
│ │ │ ├── AutoFitSurfaceView.java
│ │ │ ├── CameraNcnnFragment.java
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_action_info.png
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── fragment_camera2_basic.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── 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
│ │ ├── raw
│ │ ├── fragment.glsl
│ │ └── vertex.glsl
│ │ ├── values-zh
│ │ └── strings.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── chenty
│ └── testncnn
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── imgs
├── Screenshot_2019-08-16-12-07-00-002_com.chenty.tes.png
├── Screenshot_2019-08-16-13-54-38-377_com.chenty.tes.png
└── sample.gif
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2019, Christopher
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## APP实现的功能
3 |
4 | 1. 框选出人脸和5个landmark(LandMark太惊悚 没绘制出来)
5 | 2. 裁剪出人脸对场景中的第一个人脸解析特征向量
6 | 3. 与存储在手机中的人脸的特征向量比较,确认是否为同一人
7 |
8 |
9 | ## APK和效果
10 |
11 | 
12 |
13 | app地址 :https://pan.baidu.com/s/14v-uFwRprGvnsj2NANNjVg
14 |
15 | # 以下内容引用 MobileSSD的工程说明 大体流程是一样的
16 |
17 | https://github.com/chentyjpm/MobileNetSSD_Demo_AndroidNCNN
18 |
19 | ## 安卓程序编写过程
20 |
21 | 程序本身并不复杂 但是搞安卓的过程中发下摄像头获取下视频真的是累的要去死
22 |
23 |
24 | ### 程序框架
25 |
26 | #### 启动过程
27 |
28 | ```
29 | ---------- ----------------- -------------
30 | |Main窗口| -->|Camera Fragment| 获取图像 ----> |Surface显示| <--
31 | ---------- | ----------------- | ------------- |
32 | | | |
33 | | -------------- | -------------- |
34 | -->|JNI 加载模型| --->|ncnn推理计算|---
35 | -------------- --------------
36 | ```
37 | ### 数据流程
38 |
39 | JAVA
40 | ----------- ------------------ -------------
41 | |CAMERAYUV| -->|YUV 转RGB Bitmap| --> |Surface显示|
42 | ----------- | ------------------ -------------
43 | | |
44 | JNI | -------------- ----------- |
45 | ->|YUV Y 转 RGB| -->|Mobilenet| -->|
46 | -------------- -----------
47 |
48 |
49 | ### 编写过程
50 |
51 |
52 | #### 摄像头权限问题
53 |
54 | android 7以后的程序需要获取摄像头的需要主动申请权限 一开始没弄各种不行
55 |
56 | 后参考使用camera2 官方demo解决
57 |
58 | ```
59 |
60 | private void requestCameraPermission() {
61 | if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
62 | new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
63 | } else {
64 | requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
65 | }
66 | }
67 |
68 | @Override
69 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
70 | @NonNull int[] grantResults) {
71 | if (requestCode == REQUEST_CAMERA_PERMISSION) {
72 | if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
73 | ErrorDialog.newInstance(getString(R.string.request_permission))
74 | .show(getChildFragmentManager(), FRAGMENT_DIALOG);
75 | }
76 | } else {
77 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
78 | }
79 | }
80 | ```
81 |
82 | #### 引入ncnn库的问题
83 |
84 | 其实官方说明已经很详细了(~ ~! 并没有找到啊~~)
85 |
86 | 实际引入需要对cmakefile进行一些调整
87 |
88 | 首先参照AS的向导建立ndk工程
89 |
90 | 然后将github上release中的 ncnn库文件 和lib拷贝到 cpp目录下
91 |
92 | 这里我使用的是 ncnn-android-lib 目录 如图
93 | 
94 |
95 | 导入后需要对路径进行配置 并链接 openmp 否则会出现错误
96 |
97 | 修改CMakeLists.txt
98 |
99 | ```
100 | # For more information about using CMake with Android Studio, read the
101 | # documentation: https://d.android.com/studio/projects/add-native-code.html
102 |
103 | # Sets the minimum version of CMake required to build the native library.
104 |
105 | cmake_minimum_required(VERSION 3.4.1)
106 |
107 | FIND_PACKAGE( OpenMP REQUIRED)
108 | if(OPENMP_FOUND)
109 | message("OPENMP FOUND")
110 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
111 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
112 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
113 | endif()
114 |
115 | # Creates and names a library, sets it as either STATIC
116 | # or SHARED, and provides the relative paths to its source code.
117 | # You can define multiple libraries, and CMake builds them for you.
118 | # Gradle automatically packages shared libraries with your APK.
119 |
120 | include_directories(./ncnn-android-lib/include)
121 |
122 | add_library( # Sets the name of the library.
123 | native-lib
124 |
125 |
126 | # Sets the library as a shared library.
127 | SHARED
128 |
129 | # Provides a relative path to your source file(s).
130 | mobilenetssd.cpp)
131 |
132 | # Searches for a specified prebuilt library and stores the path as a
133 | # variable. Because CMake includes system libraries in the search path by
134 | # default, you only need to specify the name of the public NDK library
135 | # you want to add. CMake verifies that the library exists before
136 | # completing its build.
137 |
138 | find_library( # Sets the name of the path variable.
139 | log-lib
140 |
141 | # Specifies the name of the NDK library that
142 | # you want CMake to locate.
143 | log)
144 |
145 |
146 | # Specifies libraries CMake should link to your target library. You
147 | # can link multiple libraries, such as libraries you define in this
148 | # build script, prebuilt third-party libraries, or system libraries.
149 |
150 | target_link_libraries( # Specifies the target library.
151 | native-lib
152 |
153 | ${CMAKE_SOURCE_DIR}/ncnn-android-lib/${ANDROID_ABI}/libncnn.a
154 |
155 | # Links the target library to the log library
156 | # included in the NDK.
157 | ${log-lib})
158 | ```
159 |
160 | 然后就可以正常使用 NCNN了
161 |
162 |
163 | ### jni调用的参数传递
164 |
165 | 为了提高效率 我并没有对图像数组进行拷贝
166 |
167 | 而是使用了 临界区映射的方法 GetPrimitiveArrayCritical 这样避免了拷贝但是出现了一个巨坑 各种百度不到
168 |
169 | ```
170 | extern "C" JNIEXPORT jdoubleArray JNICALL
171 | Java_com_chenty_testncnn_CameraNcnnFragment_detectyonly(JNIEnv *env, jobject thiz, jbyteArray frame, jint src_width,
172 | jint src_height, jdoubleArray detect) {
173 | char *argb_frame = (char*)env->GetPrimitiveArrayCritical(frame, NULL);
174 |
175 | int size = env->GetArrayLength(frame);
176 | int objectcnt = 0;
177 | int i;
178 |
179 | //shift argb to rgba
180 | char *rgba = (char *)malloc(size);
181 | memcpy(rgba, argb_frame + 1, size - 1);
182 |
183 | env->ReleasePrimitiveArrayCritical(frame, argb_frame, JNI_ABORT);
184 |
185 | struct ai_object_t *obj = cpp_mobilenet_aidetect((const unsigned char *)rgba, src_width, src_height, &objectcnt);
186 |
187 | free(rgba);
188 |
189 | double *detect_out = (double *)env->GetPrimitiveArrayCritical(detect, NULL);
190 | if(objectcnt <= 0)
191 | objectcnt = 1;
192 |
193 | for(i = 0 ; i < objectcnt ; i++)
194 | {
195 | detect_out[i*6 + 0] = obj->label;
196 | detect_out[i*6 + 1] = obj->prob;
197 | detect_out[i*6 + 2] = obj->x;
198 | detect_out[i*6 + 3] = obj->y;
199 | detect_out[i*6 + 4] = obj->xe;
200 | detect_out[i*6 + 5] = obj->ye;
201 | obj++;
202 | }
203 |
204 |
205 | env->ReleasePrimitiveArrayCritical(detect, detect_out, JNI_ABORT);
206 |
207 | return detect;
208 | }
209 | ```
210 |
211 | 问题是 本身函数设计是 输入图像数组 长 宽 输出 判定结果
212 | 然后在里面死活new 不了double数组
213 |
214 | 后来想想应该就是这个临界区不能new对象的原因
215 |
216 | 最后丧心病狂 直接java new一个数组传进来算了。这就是目前的实现了
217 |
218 | ### YUV数据的获取
219 |
220 | 安卓默认获取摄像头数据 是直接写入到SURFACE的 效率很高 无法直接获取
221 |
222 | 目前有2个方法获取这个数据
223 |
224 | 1. 先绘制到SURFACE,然后从SURFACEDUMP RGB数据(OpenCV的做法)
225 | 2. 建立一个拍照Session 手动获取图片
226 |
227 | 这里使用第二种方法 这个魔改demo的地方实在是太多了 大家自己看吧
228 | 基本上就是建立session 获取YUV 其中的坑很多 但是都可以百度解决还行吧。
229 |
230 | ## 数据进入计算都完成了
231 | 现在已经可以在Log中看到SSD出来的目标了,很好,然后是数据绘制
232 |
233 | ### 数据绘制
234 |
235 | 我们截断了数据的获取过程,当需要显示的时候又很纠结了。
236 | 首先发现安卓 后摄像头默认是横着的 WTF。。。 绘制图像需要旋转90度。。。
237 | 直接锁定应用只能横屏显示(机智~~)
238 |
239 | 绘制需要使用Surface 并且缩放,so Ctrl+C Ctrl+V了一堆代码 实现了。。
240 |
241 | ### 显示和计算分离
242 |
243 | 经过上面的过程,已经可以显示出大体的效果了,但是每次计算耗时需要1秒,图像像幻灯片一样 这这么行。
244 | 于是做了一个简单的自锁和计算显示分离
245 |
246 | ```
247 | //split process function to prevent img reflash stop
248 | if(!mDetect_isbusy)
249 | {
250 | mDetect_isbusy = true;
251 | new Thread(new Runnable() {
252 | public void run() {
253 | mDetect_result = ncnnprocess_imgyuv(yuv, width, height);
254 | mDetect_isbusy = false;
255 | }
256 | }).start();
257 | }
258 | if(mDetect_result != null) {
259 | mSurfaceView.Draw(yuv, width, height, mDetect_result, 90);
260 | }
261 |
262 | ```
263 |
264 | 至此 功能部分已经完整OK了
265 |
266 | Code:https://github.com/chentyjpm/MobileNetSSD_Demo_AndoridNCNN
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | generateDebugSources
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 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "com.chenty.ncnninsightface"
7 | minSdkVersion 21
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | externalNativeBuild {
13 | cmake {
14 | cppFlags "-std=c++11"
15 | }
16 | }
17 | ndk {
18 | abiFilters "armeabi-v7a"
19 | // abiFilters "armeabi-v7a", "arm64-v8a"
20 | }
21 | }
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | externalNativeBuild {
29 | cmake {
30 | path "src/main/cpp/CMakeLists.txt"
31 | version "3.10.2"
32 | }
33 | }
34 | compileOptions {
35 | sourceCompatibility = '1.8'
36 | targetCompatibility = '1.8'
37 | }
38 | buildToolsVersion = '28.0.3'
39 | }
40 |
41 | dependencies {
42 | implementation fileTree(dir: 'libs', include: ['*.jar'])
43 | implementation 'com.android.support:appcompat-v7:26.0.0'
44 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
45 | testImplementation 'junit:junit:4.12'
46 | }
47 |
--------------------------------------------------------------------------------
/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/chenty/testncnn/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.chenty.testncnn;
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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.chenty.testncnn", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | FIND_PACKAGE( OpenMP REQUIRED)
9 | if(OPENMP_FOUND)
10 | message("OPENMP FOUND")
11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
13 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
14 | endif()
15 |
16 | # Creates and names a library, sets it as either STATIC
17 | # or SHARED, and provides the relative paths to its source code.
18 | # You can define multiple libraries, and CMake builds them for you.
19 | # Gradle automatically packages shared libraries with your APK.
20 |
21 | include_directories(./ncnn-android-lib/include/ncnn)
22 |
23 |
24 | file(GLOB arcface_files "./arcface/*.cpp")
25 |
26 | set(NCNN_SRC_LISTS
27 | ${arcface_files}
28 | jni.cpp
29 | )
30 |
31 | add_library( # Sets the name of the library.
32 | native-lib
33 |
34 |
35 | # Sets the library as a shared library.
36 | SHARED
37 |
38 | # Provides a relative path to your source file(s).
39 | ${NCNN_SRC_LISTS})
40 |
41 | # Searches for a specified prebuilt library and stores the path as a
42 | # variable. Because CMake includes system libraries in the search path by
43 | # default, you only need to specify the name of the public NDK library
44 | # you want to add. CMake verifies that the library exists before
45 | # completing its build.
46 |
47 | find_library( # Sets the name of the path variable.
48 | log-lib
49 |
50 | # Specifies the name of the NDK library that
51 | # you want CMake to locate.
52 | log
53 | android # fix assert
54 | )
55 |
56 |
57 | # Specifies libraries CMake should link to your target library. You
58 | # can link multiple libraries, such as libraries you define in this
59 | # build script, prebuilt third-party libraries, or system libraries.
60 |
61 | target_link_libraries( # Specifies the target library.
62 | native-lib
63 | android
64 | ${CMAKE_SOURCE_DIR}/ncnn-android-lib/${ANDROID_ABI}/libncnn.a
65 |
66 | # Links the target library to the log library
67 | # included in the NDK.
68 | ${log-lib})
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/arcface.cpp:
--------------------------------------------------------------------------------
1 | #include "arcface.h"
2 | #include "mobilefacenet.id.h"
3 | #include "mobilefacenet.h"
4 |
5 | Arcface::Arcface()
6 | {
7 | this->net.load_param(mobilefacenet_param_bin);
8 | this->net.load_model(mobilefacenet_bin);
9 | }
10 |
11 | Arcface::~Arcface()
12 | {
13 | this->net.clear();
14 | }
15 |
16 | vector Arcface::getFeature(ncnn::Mat img)
17 | {
18 | vector feature;
19 | ncnn::Mat in = resize(img, 112, 112);
20 | in = bgr2rgb(in);
21 | ncnn::Extractor ex = net.create_extractor();
22 | ex.set_light_mode(true);
23 | ex.input(mobilefacenet_param_id::BLOB_data, in);
24 | ncnn::Mat out;
25 | ex.extract(mobilefacenet_param_id::BLOB_fc1, out);
26 | feature.resize(this->feature_dim);
27 | for (int i = 0; i < this->feature_dim; i++)
28 | feature[i] = out[i];
29 | normalize(feature);
30 | return feature;
31 | }
32 |
33 | void Arcface::normalize(vector &feature)
34 | {
35 | float sum = 0;
36 | for (auto it = feature.begin(); it != feature.end(); it++)
37 | sum += (float)*it * (float)*it;
38 | sum = sqrt(sum);
39 | for (auto it = feature.begin(); it != feature.end(); it++)
40 | *it /= sum;
41 | }
42 |
43 | ncnn::Mat preprocess(ncnn::Mat img, FaceInfo info)
44 | {
45 | int image_w = 112; //96 or 112
46 | int image_h = 112;
47 |
48 | float dst[10] = {30.2946, 65.5318, 48.0252, 33.5493, 62.7299,
49 | 51.6963, 51.5014, 71.7366, 92.3655, 92.2041};
50 |
51 | if (image_w == 112)
52 | for (int i = 0; i < 5; i++)
53 | dst[i] += 8.0;
54 |
55 | float src[10];
56 | for (int i = 0; i < 5; i++)
57 | {
58 | src[i] = info.landmark[2 * i];
59 | src[i + 5] = info.landmark[2 * i + 1];
60 | }
61 |
62 | float M[6];
63 | getAffineMatrix(src, dst, M);
64 | ncnn::Mat out;
65 | warpAffineMatrix(img, out, M, image_w, image_h);
66 | return out;
67 | }
68 |
69 | double calcSimilar(std::vector feature1, std::vector feature2)
70 | {
71 | //assert(feature1.size() == feature2.size());
72 | double sim = 0.0;
73 | for (int i = 0; i < feature1.size(); i++)
74 | sim += feature1[i] * feature2[i];
75 | return sim;
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/arcface.h:
--------------------------------------------------------------------------------
1 | #ifndef ARCFACE_H
2 | #define ARCFACE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include "net.h"
8 | #include "base.h"
9 |
10 | using namespace std;
11 |
12 | ncnn::Mat preprocess(ncnn::Mat img, FaceInfo info);
13 |
14 | double calcSimilar(std::vector feature1, std::vector feature2);
15 |
16 |
17 | class Arcface {
18 |
19 | public:
20 | Arcface();
21 | ~Arcface();
22 | vector getFeature(ncnn::Mat img);
23 |
24 | private:
25 | ncnn::Net net;
26 |
27 | const int feature_dim = 128;
28 |
29 | void normalize(vector &feature);
30 | };
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/base.cpp:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | ncnn::Mat resize(ncnn::Mat src, int w, int h)
4 | {
5 | int src_w = src.w;
6 | int src_h = src.h;
7 | unsigned char* u_src = new unsigned char[src_w * src_h * 3];
8 | src.to_pixels(u_src, ncnn::Mat::PIXEL_RGB);
9 | unsigned char* u_dst = new unsigned char[w * h * 3];
10 | ncnn::resize_bilinear_c3(u_src, src_w, src_h, u_dst, w, h);
11 | ncnn::Mat dst = ncnn::Mat::from_pixels(u_dst, ncnn::Mat::PIXEL_RGB, w, h);
12 | delete[] u_src;
13 | delete[] u_dst;
14 | return dst;
15 | }
16 |
17 | ncnn::Mat bgr2rgb(ncnn::Mat src)
18 | {
19 | int src_w = src.w;
20 | int src_h = src.h;
21 | unsigned char* u_rgb = new unsigned char[src_w * src_h * 3];
22 | src.to_pixels(u_rgb, ncnn::Mat::PIXEL_BGR2RGB);
23 | ncnn::Mat dst = ncnn::Mat::from_pixels(u_rgb, ncnn::Mat::PIXEL_RGB, src_w, src_h);
24 | delete[] u_rgb;
25 | return dst;
26 | }
27 |
28 | ncnn::Mat rgb2bgr(ncnn::Mat src)
29 | {
30 | return bgr2rgb(src);
31 | }
32 |
33 | void getAffineMatrix(float* src_5pts, const float* dst_5pts, float* M)
34 | {
35 | float src[10], dst[10];
36 | memcpy(src, src_5pts, sizeof(float)*10);
37 | memcpy(dst, dst_5pts, sizeof(float)*10);
38 |
39 | float ptmp[2];
40 | ptmp[0] = ptmp[1] = 0;
41 | for (int i = 0; i < 5; ++i) {
42 | ptmp[0] += src[i];
43 | ptmp[1] += src[5+i];
44 | }
45 | ptmp[0] /= 5;
46 | ptmp[1] /= 5;
47 | for (int i = 0; i < 5; ++i) {
48 | src[i] -= ptmp[0];
49 | src[5+i] -= ptmp[1];
50 | dst[i] -= ptmp[0];
51 | dst[5+i] -= ptmp[1];
52 | }
53 |
54 | float dst_x = (dst[3]+dst[4]-dst[0]-dst[1])/2, dst_y = (dst[8]+dst[9]-dst[5]-dst[6])/2;
55 | float src_x = (src[3]+src[4]-src[0]-src[1])/2, src_y = (src[8]+src[9]-src[5]-src[6])/2;
56 | float theta = atan2(dst_x, dst_y) - atan2(src_x, src_y);
57 |
58 | float scale = sqrt(pow(dst_x, 2) + pow(dst_y, 2)) / sqrt(pow(src_x, 2) + pow(src_y, 2));
59 | float pts1[10];
60 | float pts0[2];
61 | float _a = sin(theta), _b = cos(theta);
62 | pts0[0] = pts0[1] = 0;
63 | for (int i = 0; i < 5; ++i) {
64 | pts1[i] = scale*(src[i]*_b + src[i+5]*_a);
65 | pts1[i+5] = scale*(-src[i]*_a + src[i+5]*_b);
66 | pts0[0] += (dst[i] - pts1[i]);
67 | pts0[1] += (dst[i+5] - pts1[i+5]);
68 | }
69 | pts0[0] /= 5;
70 | pts0[1] /= 5;
71 |
72 | float sqloss = 0;
73 | for (int i = 0; i < 5; ++i) {
74 | sqloss += ((pts0[0]+pts1[i]-dst[i])*(pts0[0]+pts1[i]-dst[i])
75 | + (pts0[1]+pts1[i+5]-dst[i+5])*(pts0[1]+pts1[i+5]-dst[i+5]));
76 | }
77 |
78 | float square_sum = 0;
79 | for (int i = 0; i < 10; ++i) {
80 | square_sum += src[i]*src[i];
81 | }
82 | for (int t = 0; t < 200; ++t) {
83 | _a = 0;
84 | _b = 0;
85 | for (int i = 0; i < 5; ++i) {
86 | _a += ((pts0[0]-dst[i])*src[i+5] - (pts0[1]-dst[i+5])*src[i]);
87 | _b += ((pts0[0]-dst[i])*src[i] + (pts0[1]-dst[i+5])*src[i+5]);
88 | }
89 | if (_b < 0) {
90 | _b = -_b;
91 | _a = -_a;
92 | }
93 | float _s = sqrt(_a*_a + _b*_b);
94 | _b /= _s;
95 | _a /= _s;
96 |
97 | for (int i = 0; i < 5; ++i) {
98 | pts1[i] = scale*(src[i]*_b + src[i+5]*_a);
99 | pts1[i+5] = scale*(-src[i]*_a + src[i+5]*_b);
100 | }
101 |
102 | float _scale = 0;
103 | for (int i = 0; i < 5; ++i) {
104 | _scale += ((dst[i]-pts0[0])*pts1[i] + (dst[i+5]-pts0[1])*pts1[i+5]);
105 | }
106 | _scale /= (square_sum*scale);
107 | for (int i = 0; i < 10; ++i) {
108 | pts1[i] *= (_scale / scale);
109 | }
110 | scale = _scale;
111 |
112 | pts0[0] = pts0[1] = 0;
113 | for (int i = 0; i < 5; ++i) {
114 | pts0[0] += (dst[i] - pts1[i]);
115 | pts0[1] += (dst[i+5] - pts1[i+5]);
116 | }
117 | pts0[0] /= 5;
118 | pts0[1] /= 5;
119 |
120 | float _sqloss = 0;
121 | for (int i = 0; i < 5; ++i) {
122 | _sqloss += ((pts0[0]+pts1[i]-dst[i])*(pts0[0]+pts1[i]-dst[i])
123 | + (pts0[1]+pts1[i+5]-dst[i+5])*(pts0[1]+pts1[i+5]-dst[i+5]));
124 | }
125 | if (abs(_sqloss - sqloss) < 1e-2) {
126 | break;
127 | }
128 | sqloss = _sqloss;
129 | }
130 |
131 | for (int i = 0; i < 5; ++i) {
132 | pts1[i] += (pts0[0] + ptmp[0]);
133 | pts1[i+5] += (pts0[1] + ptmp[1]);
134 | }
135 |
136 | M[0] = _b*scale;
137 | M[1] = _a*scale;
138 | M[3] = -_a*scale;
139 | M[4] = _b*scale;
140 | M[2] = pts0[0] + ptmp[0] - scale*(ptmp[0]*_b + ptmp[1]*_a);
141 | M[5] = pts0[1] + ptmp[1] - scale*(-ptmp[0]*_a + ptmp[1]*_b);
142 | }
143 |
144 | void warpAffineMatrix(ncnn::Mat src, ncnn::Mat &dst, float *M, int dst_w, int dst_h)
145 | {
146 | int src_w = src.w;
147 | int src_h = src.h;
148 |
149 | unsigned char * src_u = new unsigned char[src_w * src_h * 3]{0};
150 | unsigned char * dst_u = new unsigned char[dst_w * dst_h * 3]{0};
151 |
152 | src.to_pixels(src_u, ncnn::Mat::PIXEL_RGB);
153 |
154 | float m[6];
155 | for (int i = 0; i < 6; i++)
156 | m[i] = M[i];
157 | float D = m[0] * m[4] - m[1] * m[3];
158 | D = D != 0 ? 1./D : 0;
159 | float A11 = m[4] * D, A22 = m[0] * D;
160 | m[0] = A11; m[1] *= -D;
161 | m[3] *= -D; m[4] = A22;
162 | float b1 = -m[0] * m[2] - m[1] * m[5];
163 | float b2 = -m[3] * m[2] - m[4] * m[5];
164 | m[2] = b1; m[5] = b2;
165 |
166 | for (int y= 0; y < dst_h; y++)
167 | {
168 | for (int x = 0; x < dst_w; x++)
169 | {
170 | float fx = m[0] * x + m[1] * y + m[2];
171 | float fy = m[3] * x + m[4] * y + m[5];
172 |
173 | int sy = (int)floor(fy);
174 | fy -= sy;
175 | if (sy < 0 || sy >= src_h) continue;
176 |
177 | short cbufy[2];
178 | cbufy[0] = (short)((1.f - fy) * 2048);
179 | cbufy[1] = 2048 - cbufy[0];
180 |
181 | int sx = (int)floor(fx);
182 | fx -= sx;
183 | if (sx < 0 || sx >= src_w) continue;
184 |
185 | short cbufx[2];
186 | cbufx[0] = (short)((1.f - fx) * 2048);
187 | cbufx[1] = 2048 - cbufx[0];
188 |
189 | if (sy == src_h - 1 || sx == src_w - 1)
190 | continue;
191 | for (int c = 0; c < 3; c++)
192 | {
193 | dst_u[3 * (y * dst_w + x) + c] =
194 | (
195 | src_u[3 * (sy * src_w + sx) + c] * cbufx[0] * cbufy[0] +
196 | src_u[3 * ((sy + 1) * src_w + sx) + c] * cbufx[0] * cbufy[1] +
197 | src_u[3 * (sy * src_w + sx + 1) + c] * cbufx[1] * cbufy[0] +
198 | src_u[3 * ((sy + 1) * src_w + sx + 1) + c] * cbufx[1] * cbufy[1]
199 | ) >> 22;
200 | }
201 | }
202 | }
203 |
204 | dst = ncnn::Mat::from_pixels(dst_u, ncnn::Mat::PIXEL_BGR, dst_w, dst_h);
205 | delete[] src_u;
206 | delete[] dst_u;
207 | }
208 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/base.h:
--------------------------------------------------------------------------------
1 | #ifndef BASE_H
2 | #define BASE_H
3 | #include
4 | #include
5 | #include "net.h"
6 |
7 | typedef struct FaceInfo {
8 | float score;
9 | int x[2];
10 | int y[2];
11 | float area;
12 | float regreCoord[4];
13 | int landmark[10];
14 | } FaceInfo;
15 |
16 | ncnn::Mat resize(ncnn::Mat src, int w, int h);
17 |
18 | ncnn::Mat bgr2rgb(ncnn::Mat src);
19 |
20 | ncnn::Mat rgb2bgr(ncnn::Mat src);
21 |
22 | void getAffineMatrix(float* src_5pts, const float* dst_5pts, float* M);
23 |
24 | void warpAffineMatrix(ncnn::Mat src, ncnn::Mat &dst, float *M, int dst_w, int dst_h);
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/det1.id.h:
--------------------------------------------------------------------------------
1 | #ifndef NCNN_INCLUDE_GUARD_det1_id_h
2 | #define NCNN_INCLUDE_GUARD_det1_id_h
3 | namespace det1_param_id {
4 | const int LAYER_data = 0;
5 | const int BLOB_data = 0;
6 | const int LAYER_conv1 = 1;
7 | const int BLOB_conv1 = 1;
8 | const int LAYER_prelu1 = 2;
9 | const int BLOB_prelu1 = 2;
10 | const int LAYER_pool1 = 3;
11 | const int BLOB_pool1 = 3;
12 | const int LAYER_conv2 = 4;
13 | const int BLOB_conv2 = 4;
14 | const int LAYER_prelu2 = 5;
15 | const int BLOB_prelu2 = 5;
16 | const int LAYER_conv3 = 6;
17 | const int BLOB_conv3 = 6;
18 | const int LAYER_prelu3 = 7;
19 | const int BLOB_prelu3 = 7;
20 | const int LAYER_splitncnn_0 = 8;
21 | const int BLOB_prelu3_splitncnn_0 = 8;
22 | const int BLOB_prelu3_splitncnn_1 = 9;
23 | const int LAYER_conv4_2 = 9;
24 | const int BLOB_conv4_2 = 10;
25 | const int LAYER_conv4_1 = 10;
26 | const int BLOB_conv4_1 = 11;
27 | const int LAYER_prob1 = 11;
28 | const int BLOB_prob1 = 12;
29 | } // namespace det1_param_id
30 | #endif // NCNN_INCLUDE_GUARD_det1_id_h
31 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/det2.id.h:
--------------------------------------------------------------------------------
1 | #ifndef NCNN_INCLUDE_GUARD_det2_id_h
2 | #define NCNN_INCLUDE_GUARD_det2_id_h
3 | namespace det2_param_id {
4 | const int LAYER_data = 0;
5 | const int BLOB_data = 0;
6 | const int LAYER_conv1 = 1;
7 | const int BLOB_conv1 = 1;
8 | const int LAYER_prelu1 = 2;
9 | const int BLOB_prelu1 = 2;
10 | const int LAYER_pool1 = 3;
11 | const int BLOB_pool1 = 3;
12 | const int LAYER_conv2 = 4;
13 | const int BLOB_conv2 = 4;
14 | const int LAYER_prelu2 = 5;
15 | const int BLOB_prelu2 = 5;
16 | const int LAYER_pool2 = 6;
17 | const int BLOB_pool2 = 6;
18 | const int LAYER_conv3 = 7;
19 | const int BLOB_conv3 = 7;
20 | const int LAYER_prelu3 = 8;
21 | const int BLOB_prelu3 = 8;
22 | const int LAYER_conv4 = 9;
23 | const int BLOB_conv4 = 9;
24 | const int LAYER_prelu4 = 10;
25 | const int BLOB_prelu4 = 10;
26 | const int LAYER_splitncnn_0 = 11;
27 | const int BLOB_prelu4_splitncnn_0 = 11;
28 | const int BLOB_prelu4_splitncnn_1 = 12;
29 | const int LAYER_conv5_2 = 12;
30 | const int BLOB_conv5_2 = 13;
31 | const int LAYER_conv5_1 = 13;
32 | const int BLOB_conv5_1 = 14;
33 | const int LAYER_prob1_label = 14;
34 | const int BLOB_prob1_label = 15;
35 | const int LAYER_prob1 = 15;
36 | const int BLOB_prob1 = 16;
37 | } // namespace det2_param_id
38 | #endif // NCNN_INCLUDE_GUARD_det2_id_h
39 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/det3.id.h:
--------------------------------------------------------------------------------
1 | #ifndef NCNN_INCLUDE_GUARD_det3_id_h
2 | #define NCNN_INCLUDE_GUARD_det3_id_h
3 | namespace det3_param_id {
4 | const int LAYER_data = 0;
5 | const int BLOB_data = 0;
6 | const int LAYER_conv1 = 1;
7 | const int BLOB_conv1 = 1;
8 | const int LAYER_prelu1 = 2;
9 | const int BLOB_prelu1 = 2;
10 | const int LAYER_pool1 = 3;
11 | const int BLOB_pool1 = 3;
12 | const int LAYER_conv2 = 4;
13 | const int BLOB_conv2 = 4;
14 | const int LAYER_prelu2 = 5;
15 | const int BLOB_prelu2 = 5;
16 | const int LAYER_pool2 = 6;
17 | const int BLOB_pool2 = 6;
18 | const int LAYER_conv3 = 7;
19 | const int BLOB_conv3 = 7;
20 | const int LAYER_prelu3 = 8;
21 | const int BLOB_prelu3 = 8;
22 | const int LAYER_pool3 = 9;
23 | const int BLOB_pool3 = 9;
24 | const int LAYER_conv4 = 10;
25 | const int BLOB_conv4 = 10;
26 | const int LAYER_prelu4 = 11;
27 | const int BLOB_prelu4 = 11;
28 | const int LAYER_conv5 = 12;
29 | const int BLOB_conv5 = 12;
30 | const int LAYER_prelu5 = 13;
31 | const int BLOB_prelu5 = 13;
32 | const int LAYER_splitncnn_0 = 14;
33 | const int BLOB_prelu5_splitncnn_0 = 14;
34 | const int BLOB_prelu5_splitncnn_1 = 15;
35 | const int BLOB_prelu5_splitncnn_2 = 16;
36 | const int LAYER_conv6_3 = 15;
37 | const int BLOB_conv6_3 = 17;
38 | const int LAYER_conv6_2 = 16;
39 | const int BLOB_conv6_2 = 18;
40 | const int LAYER_conv6_1 = 17;
41 | const int BLOB_conv6_1 = 19;
42 | const int LAYER_prob1_label = 18;
43 | const int BLOB_prob1_label = 20;
44 | const int LAYER_prob1 = 19;
45 | const int BLOB_prob1 = 21;
46 | } // namespace det3_param_id
47 | #endif // NCNN_INCLUDE_GUARD_det3_id_h
48 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/det4.id.h:
--------------------------------------------------------------------------------
1 | #ifndef NCNN_INCLUDE_GUARD_det4_id_h
2 | #define NCNN_INCLUDE_GUARD_det4_id_h
3 | namespace det4_param_id {
4 | const int LAYER_data = 0;
5 | const int BLOB_data = 0;
6 | const int LAYER_slice = 1;
7 | const int BLOB_slice = 1;
8 | const int BLOB_slice_subncnn_1 = 2;
9 | const int BLOB_slice_subncnn_2 = 3;
10 | const int BLOB_slice_subncnn_3 = 4;
11 | const int BLOB_slice_subncnn_4 = 5;
12 | const int LAYER_conv1_1 = 2;
13 | const int BLOB_conv1_1 = 6;
14 | const int LAYER_prelu1_1 = 3;
15 | const int BLOB_prelu1_1 = 7;
16 | const int LAYER_pool1_1 = 4;
17 | const int BLOB_pool1_1 = 8;
18 | const int LAYER_conv2_1 = 5;
19 | const int BLOB_conv2_1 = 9;
20 | const int LAYER_prelu2_1 = 6;
21 | const int BLOB_prelu2_1 = 10;
22 | const int LAYER_pool2_1 = 7;
23 | const int BLOB_pool2_1 = 11;
24 | const int LAYER_conv3_1 = 8;
25 | const int BLOB_conv3_1 = 12;
26 | const int LAYER_prelu3_1 = 9;
27 | const int BLOB_prelu3_1 = 13;
28 | const int LAYER_conv1_2 = 10;
29 | const int BLOB_conv1_2 = 14;
30 | const int LAYER_prelu1_2 = 11;
31 | const int BLOB_prelu1_2 = 15;
32 | const int LAYER_pool1_2 = 12;
33 | const int BLOB_pool1_2 = 16;
34 | const int LAYER_conv2_2 = 13;
35 | const int BLOB_conv2_2 = 17;
36 | const int LAYER_prelu2_2 = 14;
37 | const int BLOB_prelu2_2 = 18;
38 | const int LAYER_pool2_2 = 15;
39 | const int BLOB_pool2_2 = 19;
40 | const int LAYER_conv3_2 = 16;
41 | const int BLOB_conv3_2 = 20;
42 | const int LAYER_prelu3_2 = 17;
43 | const int BLOB_prelu3_2 = 21;
44 | const int LAYER_conv1_3 = 18;
45 | const int BLOB_conv1_3 = 22;
46 | const int LAYER_prelu1_3 = 19;
47 | const int BLOB_prelu1_3 = 23;
48 | const int LAYER_pool1_3 = 20;
49 | const int BLOB_pool1_3 = 24;
50 | const int LAYER_conv2_3 = 21;
51 | const int BLOB_conv2_3 = 25;
52 | const int LAYER_prelu2_3 = 22;
53 | const int BLOB_prelu2_3 = 26;
54 | const int LAYER_pool2_3 = 23;
55 | const int BLOB_pool2_3 = 27;
56 | const int LAYER_conv3_3 = 24;
57 | const int BLOB_conv3_3 = 28;
58 | const int LAYER_prelu3_3 = 25;
59 | const int BLOB_prelu3_3 = 29;
60 | const int LAYER_conv1_4 = 26;
61 | const int BLOB_conv1_4 = 30;
62 | const int LAYER_prelu1_4 = 27;
63 | const int BLOB_prelu1_4 = 31;
64 | const int LAYER_pool1_4 = 28;
65 | const int BLOB_pool1_4 = 32;
66 | const int LAYER_conv2_4 = 29;
67 | const int BLOB_conv2_4 = 33;
68 | const int LAYER_prelu2_4 = 30;
69 | const int BLOB_prelu2_4 = 34;
70 | const int LAYER_pool2_4 = 31;
71 | const int BLOB_pool2_4 = 35;
72 | const int LAYER_conv3_4 = 32;
73 | const int BLOB_conv3_4 = 36;
74 | const int LAYER_prelu3_4 = 33;
75 | const int BLOB_prelu3_4 = 37;
76 | const int LAYER_conv1_5 = 34;
77 | const int BLOB_conv1_5 = 38;
78 | const int LAYER_prelu1_5 = 35;
79 | const int BLOB_prelu1_5 = 39;
80 | const int LAYER_pool1_5 = 36;
81 | const int BLOB_pool1_5 = 40;
82 | const int LAYER_conv2_5 = 37;
83 | const int BLOB_conv2_5 = 41;
84 | const int LAYER_prelu2_5 = 38;
85 | const int BLOB_prelu2_5 = 42;
86 | const int LAYER_pool2_5 = 39;
87 | const int BLOB_pool2_5 = 43;
88 | const int LAYER_conv3_5 = 40;
89 | const int BLOB_conv3_5 = 44;
90 | const int LAYER_prelu3_5 = 41;
91 | const int BLOB_prelu3_5 = 45;
92 | const int LAYER_concat = 42;
93 | const int BLOB_concat = 46;
94 | const int LAYER_fc4 = 43;
95 | const int BLOB_fc4 = 47;
96 | const int LAYER_prelu4 = 44;
97 | const int BLOB_prelu4 = 48;
98 | const int LAYER_splitncnn_0 = 45;
99 | const int BLOB_prelu4_splitncnn_0 = 49;
100 | const int BLOB_prelu4_splitncnn_1 = 50;
101 | const int BLOB_prelu4_splitncnn_2 = 51;
102 | const int BLOB_prelu4_splitncnn_3 = 52;
103 | const int BLOB_prelu4_splitncnn_4 = 53;
104 | const int LAYER_fc4_1 = 46;
105 | const int BLOB_fc4_1 = 54;
106 | const int LAYER_prelu4_1 = 47;
107 | const int BLOB_prelu4_1 = 55;
108 | const int LAYER_fc5_1 = 48;
109 | const int BLOB_fc5_1 = 56;
110 | const int LAYER_fc4_2 = 49;
111 | const int BLOB_fc4_2 = 57;
112 | const int LAYER_prelu4_2 = 50;
113 | const int BLOB_prelu4_2 = 58;
114 | const int LAYER_fc5_2 = 51;
115 | const int BLOB_fc5_2 = 59;
116 | const int LAYER_fc4_3 = 52;
117 | const int BLOB_fc4_3 = 60;
118 | const int LAYER_prelu4_3 = 53;
119 | const int BLOB_prelu4_3 = 61;
120 | const int LAYER_fc5_3 = 54;
121 | const int BLOB_fc5_3 = 62;
122 | const int LAYER_fc4_4 = 55;
123 | const int BLOB_fc4_4 = 63;
124 | const int LAYER_prelu4_4 = 56;
125 | const int BLOB_prelu4_4 = 64;
126 | const int LAYER_fc5_4 = 57;
127 | const int BLOB_fc5_4 = 65;
128 | const int LAYER_fc4_5 = 58;
129 | const int BLOB_fc4_5 = 66;
130 | const int LAYER_prelu4_5 = 59;
131 | const int BLOB_prelu4_5 = 67;
132 | const int LAYER_fc5_5 = 60;
133 | const int BLOB_fc5_5 = 68;
134 | } // namespace det4_param_id
135 | #endif // NCNN_INCLUDE_GUARD_det4_id_h
136 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/interface.cpp:
--------------------------------------------------------------------------------
1 | #include "interface.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 |
8 | #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "libface", __VA_ARGS__))
9 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO , "libface", __VA_ARGS__))
10 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN , "libface", __VA_ARGS__))
11 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "libface", __VA_ARGS__))
12 |
13 | MtcnnDetector g_mtcnnDetector;
14 | Arcface g_arcFace;
15 |
16 |
17 | //outputdat is x y x y
18 | vector face_detect(ncnn::Mat ncnn_img)
19 | {
20 | int st, et, cnt;
21 | double costtime;
22 | st = clock();
23 | vector results = g_mtcnnDetector.Detect(ncnn_img);
24 | et = clock();
25 | costtime = et - st;
26 | LOGD("detect face cost %fs\n", costtime / CLOCKS_PER_SEC);
27 |
28 | return results;
29 | }
30 |
31 | vector face_exactfeature(ncnn::Mat img, FaceInfo info)
32 | {
33 | int st, et, cnt;
34 | double costtime;
35 | st = clock();
36 | ncnn::Mat det = preprocess(img, info);
37 | et = clock();
38 | costtime = et - st;
39 | LOGD("face_exactfeature preprocess cost %fs\n", costtime / CLOCKS_PER_SEC);
40 | st = clock();
41 | vectorfeature = g_arcFace.getFeature(det);
42 | et = clock();
43 | costtime = et - st;
44 | LOGD("face_exactfeature getFeature cost %fs\n", costtime / CLOCKS_PER_SEC);
45 |
46 | return feature;
47 | }
48 |
49 | float face_calcSimilar(std::vector feature1, std::vector feature2)
50 | {
51 | double similar = 0;
52 | int st, et;
53 | double costtime;
54 |
55 | st = clock();
56 | similar = calcSimilar(feature1, feature2);
57 | et = clock();
58 | costtime = et - st;
59 | LOGD("calcSimilar cost %fs result %f\n", costtime / CLOCKS_PER_SEC, similar);
60 | return (float)similar;
61 | }
62 |
63 | float face_calcSimilar_ext(ncnn::Mat img1, ncnn::Mat img2, FaceInfo face1, FaceInfo face2)
64 | {
65 | std::vector feature1 = face_exactfeature(img1, face1);
66 | std::vector feature2 = face_exactfeature(img2, face2);
67 |
68 | return calcSimilar(feature1, feature2);
69 | }
70 |
71 | //#include
72 |
73 | //using namespace cv;
74 | //using namespace std;
75 |
76 | /*
77 | cv::Mat ncnn2cv(ncnn::Mat img)
78 | {
79 | unsigned char pix[img.h * img.w * 3];
80 | img.to_pixels(pix, ncnn::Mat::PIXEL_BGR);
81 | cv::Mat cv_img(img.h, img.w, CV_8UC3);
82 | for (int i = 0; i < cv_img.rows; i++)
83 | {
84 | for (int j = 0; j < cv_img.cols; j++)
85 | {
86 | cv_img.at(i,j)[0] = pix[3 * (i * cv_img.cols + j)];
87 | cv_img.at(i,j)[1] = pix[3 * (i * cv_img.cols + j) + 1];
88 | cv_img.at(i,j)[2] = pix[3 * (i * cv_img.cols + j) + 2];
89 | }
90 | }
91 | return cv_img;
92 | }
93 |
94 | int main(int argc, char* argv[])
95 | {
96 | Mat img1;
97 | Mat img2;
98 | if (argc == 3)
99 | {
100 | img1 = imread(argv[1]);
101 | img2 = imread(argv[2]);
102 | }
103 | else{
104 | img1 = imread("../image/gyy1.jpeg");
105 | img2 = imread("../image/gyy2.jpeg");
106 | }
107 | ncnn::Mat ncnn_img1 = ncnn::Mat::from_pixels(img1.data, ncnn::Mat::PIXEL_BGR, img1.cols, img1.rows);
108 | ncnn::Mat ncnn_img2 = ncnn::Mat::from_pixels(img2.data, ncnn::Mat::PIXEL_BGR, img2.cols, img2.rows);
109 |
110 | MtcnnDetector detector("../models");
111 |
112 | double start = (double)getTickCount();
113 | vector results1 = detector.Detect(ncnn_img1);
114 | cout << "Detection Time: " << (getTickCount() - start) / getTickFrequency() << "s" << std::endl;
115 |
116 | start = (double)getTickCount();
117 | vector results2 = detector.Detect(ncnn_img2);
118 | cout << "Detection Time: " << (getTickCount() - start) / getTickFrequency() << "s" << std::endl;
119 |
120 | ncnn::Mat det1 = preprocess(ncnn_img1, results1[0]);
121 | ncnn::Mat det2 = preprocess(ncnn_img2, results2[0]);
122 |
123 | //for (auto it = results1.begin(); it != results1.end(); it++)
124 | //{
125 | // rectangle(img1, cv::Point(it->x[0], it->y[0]), cv::Point(it->x[1], it->y[1]), cv::Scalar(0, 255, 0), 2);
126 | // circle(img1, cv::Point(it->landmark[0], it->landmark[1]), 2, cv::Scalar(0, 255, 0), 2);
127 | // circle(img1, cv::Point(it->landmark[2], it->landmark[3]), 2, cv::Scalar(0, 255, 0), 2);
128 | // circle(img1, cv::Point(it->landmark[4], it->landmark[5]), 2, cv::Scalar(0, 255, 0), 2);
129 | // circle(img1, cv::Point(it->landmark[6], it->landmark[7]), 2, cv::Scalar(0, 255, 0), 2);
130 | // circle(img1, cv::Point(it->landmark[8], it->landmark[9]), 2, cv::Scalar(0, 255, 0), 2);
131 | //}
132 |
133 | //for (auto it = results2.begin(); it != results2.end(); it++)
134 | //{
135 | // rectangle(img2, cv::Point(it->x[0], it->y[0]), cv::Point(it->x[1], it->y[1]), cv::Scalar(0, 255, 0), 2);
136 | // circle(img2, cv::Point(it->landmark[0], it->landmark[1]), 2, cv::Scalar(0, 255, 0), 2);
137 | // circle(img2, cv::Point(it->landmark[2], it->landmark[3]), 2, cv::Scalar(0, 255, 0), 2);
138 | // circle(img2, cv::Point(it->landmark[4], it->landmark[5]), 2, cv::Scalar(0, 255, 0), 2);
139 | // circle(img2, cv::Point(it->landmark[6], it->landmark[7]), 2, cv::Scalar(0, 255, 0), 2);
140 | // circle(img2, cv::Point(it->landmark[8], it->landmark[9]), 2, cv::Scalar(0, 255, 0), 2);
141 | //}
142 |
143 | Arcface arc("../models");
144 |
145 | start = (double)getTickCount();
146 | vector feature1 = arc.getFeature(det1);
147 | cout << "Extraction Time: " << (getTickCount() - start) / getTickFrequency() << "s" << std::endl;
148 |
149 | start = (double)getTickCount();
150 | vector feature2 = arc.getFeature(det2);
151 | cout << "Extraction Time: " << (getTickCount() - start) / getTickFrequency() << "s" << std::endl;
152 |
153 | std::cout << "Similarity: " << calcSimilar(feature1, feature2) << std::endl;;
154 |
155 | //imshow("img1", img1);
156 | //imshow("img2", img2);
157 |
158 | imshow("det1", ncnn2cv(det1));
159 | imshow("det2", ncnn2cv(det2));
160 |
161 | waitKey(0);
162 | return 0;
163 | }
164 | */
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/interface.h:
--------------------------------------------------------------------------------
1 | #ifndef ARCFACE_INTERFACE_H
2 | #define ARCFACE_INTERFACE_H
3 | #include "net.h"
4 | #include "base.h"
5 | #include "arcface.h"
6 | #include "mtcnn.h"
7 | #include
8 |
9 | vector face_detect(ncnn::Mat ncnn_img);
10 | vector face_exactfeature(ncnn::Mat img, FaceInfo info);
11 |
12 | float face_calcSimilar(std::vector feature1, std::vector feature2);
13 |
14 | #endif
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/mobilefacenet.id.h:
--------------------------------------------------------------------------------
1 | #ifndef NCNN_INCLUDE_GUARD_mobilefacenet_id_h
2 | #define NCNN_INCLUDE_GUARD_mobilefacenet_id_h
3 | namespace mobilefacenet_param_id {
4 | const int LAYER_data = 0;
5 | const int BLOB_data = 0;
6 | const int LAYER__minusscalar0 = 1;
7 | const int BLOB__minusscalar0 = 1;
8 | const int LAYER__mulscalar0 = 2;
9 | const int BLOB__mulscalar0 = 2;
10 | const int LAYER_conv_1_conv2d = 3;
11 | const int BLOB_conv_1_conv2d = 3;
12 | const int LAYER_conv_1_batchnorm = 4;
13 | const int BLOB_conv_1_batchnorm = 4;
14 | const int LAYER_conv_1_relu = 5;
15 | const int BLOB_conv_1_relu = 5;
16 | const int LAYER_conv_2_dw_conv2d = 6;
17 | const int BLOB_conv_2_dw_conv2d = 6;
18 | const int LAYER_conv_2_dw_batchnorm = 7;
19 | const int BLOB_conv_2_dw_batchnorm = 7;
20 | const int LAYER_conv_2_dw_relu = 8;
21 | const int BLOB_conv_2_dw_relu = 8;
22 | const int LAYER_dconv_23_conv_sep_conv2d = 9;
23 | const int BLOB_dconv_23_conv_sep_conv2d = 9;
24 | const int LAYER_dconv_23_conv_sep_batchnorm = 10;
25 | const int BLOB_dconv_23_conv_sep_batchnorm = 10;
26 | const int LAYER_dconv_23_conv_sep_relu = 11;
27 | const int BLOB_dconv_23_conv_sep_relu = 11;
28 | const int LAYER_dconv_23_conv_dw_conv2d = 12;
29 | const int BLOB_dconv_23_conv_dw_conv2d = 12;
30 | const int LAYER_dconv_23_conv_dw_batchnorm = 13;
31 | const int BLOB_dconv_23_conv_dw_batchnorm = 13;
32 | const int LAYER_dconv_23_conv_dw_relu = 14;
33 | const int BLOB_dconv_23_conv_dw_relu = 14;
34 | const int LAYER_dconv_23_conv_proj_conv2d = 15;
35 | const int BLOB_dconv_23_conv_proj_conv2d = 15;
36 | const int LAYER_dconv_23_conv_proj_batchnorm = 16;
37 | const int BLOB_dconv_23_conv_proj_batchnorm = 16;
38 | const int LAYER_splitncnn_0 = 17;
39 | const int BLOB_dconv_23_conv_proj_batchnorm_splitncnn_0 = 17;
40 | const int BLOB_dconv_23_conv_proj_batchnorm_splitncnn_1 = 18;
41 | const int LAYER_res_3_block0_conv_sep_conv2d = 18;
42 | const int BLOB_res_3_block0_conv_sep_conv2d = 19;
43 | const int LAYER_res_3_block0_conv_sep_batchnorm = 19;
44 | const int BLOB_res_3_block0_conv_sep_batchnorm = 20;
45 | const int LAYER_res_3_block0_conv_sep_relu = 20;
46 | const int BLOB_res_3_block0_conv_sep_relu = 21;
47 | const int LAYER_res_3_block0_conv_dw_conv2d = 21;
48 | const int BLOB_res_3_block0_conv_dw_conv2d = 22;
49 | const int LAYER_res_3_block0_conv_dw_batchnorm = 22;
50 | const int BLOB_res_3_block0_conv_dw_batchnorm = 23;
51 | const int LAYER_res_3_block0_conv_dw_relu = 23;
52 | const int BLOB_res_3_block0_conv_dw_relu = 24;
53 | const int LAYER_res_3_block0_conv_proj_conv2d = 24;
54 | const int BLOB_res_3_block0_conv_proj_conv2d = 25;
55 | const int LAYER_res_3_block0_conv_proj_batchnorm = 25;
56 | const int BLOB_res_3_block0_conv_proj_batchnorm = 26;
57 | const int LAYER__plus0 = 26;
58 | const int BLOB__plus0 = 27;
59 | const int LAYER_splitncnn_1 = 27;
60 | const int BLOB__plus0_splitncnn_0 = 28;
61 | const int BLOB__plus0_splitncnn_1 = 29;
62 | const int LAYER_res_3_block1_conv_sep_conv2d = 28;
63 | const int BLOB_res_3_block1_conv_sep_conv2d = 30;
64 | const int LAYER_res_3_block1_conv_sep_batchnorm = 29;
65 | const int BLOB_res_3_block1_conv_sep_batchnorm = 31;
66 | const int LAYER_res_3_block1_conv_sep_relu = 30;
67 | const int BLOB_res_3_block1_conv_sep_relu = 32;
68 | const int LAYER_res_3_block1_conv_dw_conv2d = 31;
69 | const int BLOB_res_3_block1_conv_dw_conv2d = 33;
70 | const int LAYER_res_3_block1_conv_dw_batchnorm = 32;
71 | const int BLOB_res_3_block1_conv_dw_batchnorm = 34;
72 | const int LAYER_res_3_block1_conv_dw_relu = 33;
73 | const int BLOB_res_3_block1_conv_dw_relu = 35;
74 | const int LAYER_res_3_block1_conv_proj_conv2d = 34;
75 | const int BLOB_res_3_block1_conv_proj_conv2d = 36;
76 | const int LAYER_res_3_block1_conv_proj_batchnorm = 35;
77 | const int BLOB_res_3_block1_conv_proj_batchnorm = 37;
78 | const int LAYER__plus1 = 36;
79 | const int BLOB__plus1 = 38;
80 | const int LAYER_splitncnn_2 = 37;
81 | const int BLOB__plus1_splitncnn_0 = 39;
82 | const int BLOB__plus1_splitncnn_1 = 40;
83 | const int LAYER_res_3_block2_conv_sep_conv2d = 38;
84 | const int BLOB_res_3_block2_conv_sep_conv2d = 41;
85 | const int LAYER_res_3_block2_conv_sep_batchnorm = 39;
86 | const int BLOB_res_3_block2_conv_sep_batchnorm = 42;
87 | const int LAYER_res_3_block2_conv_sep_relu = 40;
88 | const int BLOB_res_3_block2_conv_sep_relu = 43;
89 | const int LAYER_res_3_block2_conv_dw_conv2d = 41;
90 | const int BLOB_res_3_block2_conv_dw_conv2d = 44;
91 | const int LAYER_res_3_block2_conv_dw_batchnorm = 42;
92 | const int BLOB_res_3_block2_conv_dw_batchnorm = 45;
93 | const int LAYER_res_3_block2_conv_dw_relu = 43;
94 | const int BLOB_res_3_block2_conv_dw_relu = 46;
95 | const int LAYER_res_3_block2_conv_proj_conv2d = 44;
96 | const int BLOB_res_3_block2_conv_proj_conv2d = 47;
97 | const int LAYER_res_3_block2_conv_proj_batchnorm = 45;
98 | const int BLOB_res_3_block2_conv_proj_batchnorm = 48;
99 | const int LAYER__plus2 = 46;
100 | const int BLOB__plus2 = 49;
101 | const int LAYER_splitncnn_3 = 47;
102 | const int BLOB__plus2_splitncnn_0 = 50;
103 | const int BLOB__plus2_splitncnn_1 = 51;
104 | const int LAYER_res_3_block3_conv_sep_conv2d = 48;
105 | const int BLOB_res_3_block3_conv_sep_conv2d = 52;
106 | const int LAYER_res_3_block3_conv_sep_batchnorm = 49;
107 | const int BLOB_res_3_block3_conv_sep_batchnorm = 53;
108 | const int LAYER_res_3_block3_conv_sep_relu = 50;
109 | const int BLOB_res_3_block3_conv_sep_relu = 54;
110 | const int LAYER_res_3_block3_conv_dw_conv2d = 51;
111 | const int BLOB_res_3_block3_conv_dw_conv2d = 55;
112 | const int LAYER_res_3_block3_conv_dw_batchnorm = 52;
113 | const int BLOB_res_3_block3_conv_dw_batchnorm = 56;
114 | const int LAYER_res_3_block3_conv_dw_relu = 53;
115 | const int BLOB_res_3_block3_conv_dw_relu = 57;
116 | const int LAYER_res_3_block3_conv_proj_conv2d = 54;
117 | const int BLOB_res_3_block3_conv_proj_conv2d = 58;
118 | const int LAYER_res_3_block3_conv_proj_batchnorm = 55;
119 | const int BLOB_res_3_block3_conv_proj_batchnorm = 59;
120 | const int LAYER__plus3 = 56;
121 | const int BLOB__plus3 = 60;
122 | const int LAYER_dconv_34_conv_sep_conv2d = 57;
123 | const int BLOB_dconv_34_conv_sep_conv2d = 61;
124 | const int LAYER_dconv_34_conv_sep_batchnorm = 58;
125 | const int BLOB_dconv_34_conv_sep_batchnorm = 62;
126 | const int LAYER_dconv_34_conv_sep_relu = 59;
127 | const int BLOB_dconv_34_conv_sep_relu = 63;
128 | const int LAYER_dconv_34_conv_dw_conv2d = 60;
129 | const int BLOB_dconv_34_conv_dw_conv2d = 64;
130 | const int LAYER_dconv_34_conv_dw_batchnorm = 61;
131 | const int BLOB_dconv_34_conv_dw_batchnorm = 65;
132 | const int LAYER_dconv_34_conv_dw_relu = 62;
133 | const int BLOB_dconv_34_conv_dw_relu = 66;
134 | const int LAYER_dconv_34_conv_proj_conv2d = 63;
135 | const int BLOB_dconv_34_conv_proj_conv2d = 67;
136 | const int LAYER_dconv_34_conv_proj_batchnorm = 64;
137 | const int BLOB_dconv_34_conv_proj_batchnorm = 68;
138 | const int LAYER_splitncnn_4 = 65;
139 | const int BLOB_dconv_34_conv_proj_batchnorm_splitncnn_0 = 69;
140 | const int BLOB_dconv_34_conv_proj_batchnorm_splitncnn_1 = 70;
141 | const int LAYER_res_4_block0_conv_sep_conv2d = 66;
142 | const int BLOB_res_4_block0_conv_sep_conv2d = 71;
143 | const int LAYER_res_4_block0_conv_sep_batchnorm = 67;
144 | const int BLOB_res_4_block0_conv_sep_batchnorm = 72;
145 | const int LAYER_res_4_block0_conv_sep_relu = 68;
146 | const int BLOB_res_4_block0_conv_sep_relu = 73;
147 | const int LAYER_res_4_block0_conv_dw_conv2d = 69;
148 | const int BLOB_res_4_block0_conv_dw_conv2d = 74;
149 | const int LAYER_res_4_block0_conv_dw_batchnorm = 70;
150 | const int BLOB_res_4_block0_conv_dw_batchnorm = 75;
151 | const int LAYER_res_4_block0_conv_dw_relu = 71;
152 | const int BLOB_res_4_block0_conv_dw_relu = 76;
153 | const int LAYER_res_4_block0_conv_proj_conv2d = 72;
154 | const int BLOB_res_4_block0_conv_proj_conv2d = 77;
155 | const int LAYER_res_4_block0_conv_proj_batchnorm = 73;
156 | const int BLOB_res_4_block0_conv_proj_batchnorm = 78;
157 | const int LAYER__plus4 = 74;
158 | const int BLOB__plus4 = 79;
159 | const int LAYER_splitncnn_5 = 75;
160 | const int BLOB__plus4_splitncnn_0 = 80;
161 | const int BLOB__plus4_splitncnn_1 = 81;
162 | const int LAYER_res_4_block1_conv_sep_conv2d = 76;
163 | const int BLOB_res_4_block1_conv_sep_conv2d = 82;
164 | const int LAYER_res_4_block1_conv_sep_batchnorm = 77;
165 | const int BLOB_res_4_block1_conv_sep_batchnorm = 83;
166 | const int LAYER_res_4_block1_conv_sep_relu = 78;
167 | const int BLOB_res_4_block1_conv_sep_relu = 84;
168 | const int LAYER_res_4_block1_conv_dw_conv2d = 79;
169 | const int BLOB_res_4_block1_conv_dw_conv2d = 85;
170 | const int LAYER_res_4_block1_conv_dw_batchnorm = 80;
171 | const int BLOB_res_4_block1_conv_dw_batchnorm = 86;
172 | const int LAYER_res_4_block1_conv_dw_relu = 81;
173 | const int BLOB_res_4_block1_conv_dw_relu = 87;
174 | const int LAYER_res_4_block1_conv_proj_conv2d = 82;
175 | const int BLOB_res_4_block1_conv_proj_conv2d = 88;
176 | const int LAYER_res_4_block1_conv_proj_batchnorm = 83;
177 | const int BLOB_res_4_block1_conv_proj_batchnorm = 89;
178 | const int LAYER__plus5 = 84;
179 | const int BLOB__plus5 = 90;
180 | const int LAYER_splitncnn_6 = 85;
181 | const int BLOB__plus5_splitncnn_0 = 91;
182 | const int BLOB__plus5_splitncnn_1 = 92;
183 | const int LAYER_res_4_block2_conv_sep_conv2d = 86;
184 | const int BLOB_res_4_block2_conv_sep_conv2d = 93;
185 | const int LAYER_res_4_block2_conv_sep_batchnorm = 87;
186 | const int BLOB_res_4_block2_conv_sep_batchnorm = 94;
187 | const int LAYER_res_4_block2_conv_sep_relu = 88;
188 | const int BLOB_res_4_block2_conv_sep_relu = 95;
189 | const int LAYER_res_4_block2_conv_dw_conv2d = 89;
190 | const int BLOB_res_4_block2_conv_dw_conv2d = 96;
191 | const int LAYER_res_4_block2_conv_dw_batchnorm = 90;
192 | const int BLOB_res_4_block2_conv_dw_batchnorm = 97;
193 | const int LAYER_res_4_block2_conv_dw_relu = 91;
194 | const int BLOB_res_4_block2_conv_dw_relu = 98;
195 | const int LAYER_res_4_block2_conv_proj_conv2d = 92;
196 | const int BLOB_res_4_block2_conv_proj_conv2d = 99;
197 | const int LAYER_res_4_block2_conv_proj_batchnorm = 93;
198 | const int BLOB_res_4_block2_conv_proj_batchnorm = 100;
199 | const int LAYER__plus6 = 94;
200 | const int BLOB__plus6 = 101;
201 | const int LAYER_splitncnn_7 = 95;
202 | const int BLOB__plus6_splitncnn_0 = 102;
203 | const int BLOB__plus6_splitncnn_1 = 103;
204 | const int LAYER_res_4_block3_conv_sep_conv2d = 96;
205 | const int BLOB_res_4_block3_conv_sep_conv2d = 104;
206 | const int LAYER_res_4_block3_conv_sep_batchnorm = 97;
207 | const int BLOB_res_4_block3_conv_sep_batchnorm = 105;
208 | const int LAYER_res_4_block3_conv_sep_relu = 98;
209 | const int BLOB_res_4_block3_conv_sep_relu = 106;
210 | const int LAYER_res_4_block3_conv_dw_conv2d = 99;
211 | const int BLOB_res_4_block3_conv_dw_conv2d = 107;
212 | const int LAYER_res_4_block3_conv_dw_batchnorm = 100;
213 | const int BLOB_res_4_block3_conv_dw_batchnorm = 108;
214 | const int LAYER_res_4_block3_conv_dw_relu = 101;
215 | const int BLOB_res_4_block3_conv_dw_relu = 109;
216 | const int LAYER_res_4_block3_conv_proj_conv2d = 102;
217 | const int BLOB_res_4_block3_conv_proj_conv2d = 110;
218 | const int LAYER_res_4_block3_conv_proj_batchnorm = 103;
219 | const int BLOB_res_4_block3_conv_proj_batchnorm = 111;
220 | const int LAYER__plus7 = 104;
221 | const int BLOB__plus7 = 112;
222 | const int LAYER_splitncnn_8 = 105;
223 | const int BLOB__plus7_splitncnn_0 = 113;
224 | const int BLOB__plus7_splitncnn_1 = 114;
225 | const int LAYER_res_4_block4_conv_sep_conv2d = 106;
226 | const int BLOB_res_4_block4_conv_sep_conv2d = 115;
227 | const int LAYER_res_4_block4_conv_sep_batchnorm = 107;
228 | const int BLOB_res_4_block4_conv_sep_batchnorm = 116;
229 | const int LAYER_res_4_block4_conv_sep_relu = 108;
230 | const int BLOB_res_4_block4_conv_sep_relu = 117;
231 | const int LAYER_res_4_block4_conv_dw_conv2d = 109;
232 | const int BLOB_res_4_block4_conv_dw_conv2d = 118;
233 | const int LAYER_res_4_block4_conv_dw_batchnorm = 110;
234 | const int BLOB_res_4_block4_conv_dw_batchnorm = 119;
235 | const int LAYER_res_4_block4_conv_dw_relu = 111;
236 | const int BLOB_res_4_block4_conv_dw_relu = 120;
237 | const int LAYER_res_4_block4_conv_proj_conv2d = 112;
238 | const int BLOB_res_4_block4_conv_proj_conv2d = 121;
239 | const int LAYER_res_4_block4_conv_proj_batchnorm = 113;
240 | const int BLOB_res_4_block4_conv_proj_batchnorm = 122;
241 | const int LAYER__plus8 = 114;
242 | const int BLOB__plus8 = 123;
243 | const int LAYER_splitncnn_9 = 115;
244 | const int BLOB__plus8_splitncnn_0 = 124;
245 | const int BLOB__plus8_splitncnn_1 = 125;
246 | const int LAYER_res_4_block5_conv_sep_conv2d = 116;
247 | const int BLOB_res_4_block5_conv_sep_conv2d = 126;
248 | const int LAYER_res_4_block5_conv_sep_batchnorm = 117;
249 | const int BLOB_res_4_block5_conv_sep_batchnorm = 127;
250 | const int LAYER_res_4_block5_conv_sep_relu = 118;
251 | const int BLOB_res_4_block5_conv_sep_relu = 128;
252 | const int LAYER_res_4_block5_conv_dw_conv2d = 119;
253 | const int BLOB_res_4_block5_conv_dw_conv2d = 129;
254 | const int LAYER_res_4_block5_conv_dw_batchnorm = 120;
255 | const int BLOB_res_4_block5_conv_dw_batchnorm = 130;
256 | const int LAYER_res_4_block5_conv_dw_relu = 121;
257 | const int BLOB_res_4_block5_conv_dw_relu = 131;
258 | const int LAYER_res_4_block5_conv_proj_conv2d = 122;
259 | const int BLOB_res_4_block5_conv_proj_conv2d = 132;
260 | const int LAYER_res_4_block5_conv_proj_batchnorm = 123;
261 | const int BLOB_res_4_block5_conv_proj_batchnorm = 133;
262 | const int LAYER__plus9 = 124;
263 | const int BLOB__plus9 = 134;
264 | const int LAYER_dconv_45_conv_sep_conv2d = 125;
265 | const int BLOB_dconv_45_conv_sep_conv2d = 135;
266 | const int LAYER_dconv_45_conv_sep_batchnorm = 126;
267 | const int BLOB_dconv_45_conv_sep_batchnorm = 136;
268 | const int LAYER_dconv_45_conv_sep_relu = 127;
269 | const int BLOB_dconv_45_conv_sep_relu = 137;
270 | const int LAYER_dconv_45_conv_dw_conv2d = 128;
271 | const int BLOB_dconv_45_conv_dw_conv2d = 138;
272 | const int LAYER_dconv_45_conv_dw_batchnorm = 129;
273 | const int BLOB_dconv_45_conv_dw_batchnorm = 139;
274 | const int LAYER_dconv_45_conv_dw_relu = 130;
275 | const int BLOB_dconv_45_conv_dw_relu = 140;
276 | const int LAYER_dconv_45_conv_proj_conv2d = 131;
277 | const int BLOB_dconv_45_conv_proj_conv2d = 141;
278 | const int LAYER_dconv_45_conv_proj_batchnorm = 132;
279 | const int BLOB_dconv_45_conv_proj_batchnorm = 142;
280 | const int LAYER_splitncnn_10 = 133;
281 | const int BLOB_dconv_45_conv_proj_batchnorm_splitncnn_0 = 143;
282 | const int BLOB_dconv_45_conv_proj_batchnorm_splitncnn_1 = 144;
283 | const int LAYER_res_5_block0_conv_sep_conv2d = 134;
284 | const int BLOB_res_5_block0_conv_sep_conv2d = 145;
285 | const int LAYER_res_5_block0_conv_sep_batchnorm = 135;
286 | const int BLOB_res_5_block0_conv_sep_batchnorm = 146;
287 | const int LAYER_res_5_block0_conv_sep_relu = 136;
288 | const int BLOB_res_5_block0_conv_sep_relu = 147;
289 | const int LAYER_res_5_block0_conv_dw_conv2d = 137;
290 | const int BLOB_res_5_block0_conv_dw_conv2d = 148;
291 | const int LAYER_res_5_block0_conv_dw_batchnorm = 138;
292 | const int BLOB_res_5_block0_conv_dw_batchnorm = 149;
293 | const int LAYER_res_5_block0_conv_dw_relu = 139;
294 | const int BLOB_res_5_block0_conv_dw_relu = 150;
295 | const int LAYER_res_5_block0_conv_proj_conv2d = 140;
296 | const int BLOB_res_5_block0_conv_proj_conv2d = 151;
297 | const int LAYER_res_5_block0_conv_proj_batchnorm = 141;
298 | const int BLOB_res_5_block0_conv_proj_batchnorm = 152;
299 | const int LAYER__plus10 = 142;
300 | const int BLOB__plus10 = 153;
301 | const int LAYER_splitncnn_11 = 143;
302 | const int BLOB__plus10_splitncnn_0 = 154;
303 | const int BLOB__plus10_splitncnn_1 = 155;
304 | const int LAYER_res_5_block1_conv_sep_conv2d = 144;
305 | const int BLOB_res_5_block1_conv_sep_conv2d = 156;
306 | const int LAYER_res_5_block1_conv_sep_batchnorm = 145;
307 | const int BLOB_res_5_block1_conv_sep_batchnorm = 157;
308 | const int LAYER_res_5_block1_conv_sep_relu = 146;
309 | const int BLOB_res_5_block1_conv_sep_relu = 158;
310 | const int LAYER_res_5_block1_conv_dw_conv2d = 147;
311 | const int BLOB_res_5_block1_conv_dw_conv2d = 159;
312 | const int LAYER_res_5_block1_conv_dw_batchnorm = 148;
313 | const int BLOB_res_5_block1_conv_dw_batchnorm = 160;
314 | const int LAYER_res_5_block1_conv_dw_relu = 149;
315 | const int BLOB_res_5_block1_conv_dw_relu = 161;
316 | const int LAYER_res_5_block1_conv_proj_conv2d = 150;
317 | const int BLOB_res_5_block1_conv_proj_conv2d = 162;
318 | const int LAYER_res_5_block1_conv_proj_batchnorm = 151;
319 | const int BLOB_res_5_block1_conv_proj_batchnorm = 163;
320 | const int LAYER__plus11 = 152;
321 | const int BLOB__plus11 = 164;
322 | const int LAYER_conv_6sep_conv2d = 153;
323 | const int BLOB_conv_6sep_conv2d = 165;
324 | const int LAYER_conv_6sep_batchnorm = 154;
325 | const int BLOB_conv_6sep_batchnorm = 166;
326 | const int LAYER_conv_6sep_relu = 155;
327 | const int BLOB_conv_6sep_relu = 167;
328 | const int LAYER_conv_6dw7_7_conv2d = 156;
329 | const int BLOB_conv_6dw7_7_conv2d = 168;
330 | const int LAYER_conv_6dw7_7_batchnorm = 157;
331 | const int BLOB_conv_6dw7_7_batchnorm = 169;
332 | const int LAYER_pre_fc1 = 158;
333 | const int BLOB_pre_fc1 = 170;
334 | const int LAYER_fc1 = 159;
335 | const int BLOB_fc1 = 171;
336 | } // namespace mobilefacenet_param_id
337 | #endif // NCNN_INCLUDE_GUARD_mobilefacenet_id_h
338 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/mtcnn.cpp:
--------------------------------------------------------------------------------
1 | #include "mtcnn.h"
2 | #include "det1.h"
3 | #include "det1.id.h"
4 | #include "det2.h"
5 | #include "det2.id.h"
6 | #include "det3.h"
7 | #include "det3.id.h"
8 | #include "det4.h"
9 | #include "det4.id.h"
10 |
11 |
12 | MtcnnDetector::MtcnnDetector()
13 | {
14 | this->Pnet.load_param(det1_param_bin);
15 | this->Pnet.load_model(det1_bin);
16 | this->Rnet.load_param(det2_param_bin);
17 | this->Rnet.load_model(det2_bin);
18 | this->Onet.load_param(det3_param_bin);
19 | this->Onet.load_model(det3_bin);
20 | this->Lnet.load_param(det4_param_bin);
21 | this->Lnet.load_model(det4_bin);
22 | }
23 |
24 | MtcnnDetector::~MtcnnDetector()
25 | {
26 | this->Pnet.clear();
27 | this->Rnet.clear();
28 | this->Onet.clear();
29 | this->Lnet.clear();
30 | }
31 |
32 | vector MtcnnDetector::Detect(ncnn::Mat img)
33 | {
34 | int img_w = img.w;
35 | int img_h = img.h;
36 |
37 | vector pnet_results = Pnet_Detect(img);
38 | doNms(pnet_results, 0.7, "union");
39 | refine(pnet_results, img_h, img_w, true);
40 |
41 | vector rnet_results = Rnet_Detect(img, pnet_results);
42 | doNms(rnet_results, 0.7, "union");
43 | refine(rnet_results, img_h, img_w, true);
44 |
45 | vector onet_results = Onet_Detect(img, rnet_results);
46 | refine(onet_results, img_h, img_w, false);
47 | doNms(onet_results, 0.7, "min");
48 |
49 | Lnet_Detect(img, onet_results);
50 |
51 | return onet_results;
52 | }
53 |
54 | vector MtcnnDetector::Pnet_Detect(ncnn::Mat img)
55 | {
56 | vector results;
57 | int img_w = img.w;
58 | int img_h = img.h;
59 | float minl = img_w < img_h ? img_w : img_h;
60 | double scale = 12.0 / this->minsize;
61 | minl *= scale;
62 | vector scales;
63 | while (minl > 12)
64 | {
65 | scales.push_back(scale);
66 | minl *= this->factor;
67 | scale *= this->factor;
68 | }
69 | for (auto it = scales.begin(); it != scales.end(); it++)
70 | {
71 | scale = (double)(*it);
72 | int hs = (int) ceil(img_h * scale);
73 | int ws = (int) ceil(img_w * scale);
74 | ncnn::Mat in = resize(img, ws, hs);
75 | in.substract_mean_normalize(this->mean_vals, this->norm_vals);
76 | ncnn::Extractor ex = Pnet.create_extractor();
77 | ex.set_light_mode(true);
78 | ex.input(det1_param_id::BLOB_data, in);
79 | ncnn::Mat score;
80 | ncnn::Mat location;
81 | ex.extract(det1_param_id::BLOB_prob1, score);
82 | ex.extract(det1_param_id::BLOB_conv4_2, location);
83 | vector bboxs = generateBbox(score, location, *it, this->threshold[0]);
84 | doNms(bboxs, 0.5, "union");
85 | results.insert(results.end(), bboxs.begin(), bboxs.end());
86 | }
87 | return results;
88 | }
89 |
90 | vector MtcnnDetector::Rnet_Detect(ncnn::Mat img, vector bboxs)
91 | {
92 | vector results;
93 |
94 | int img_w = img.w;
95 | int img_h = img.h;
96 |
97 | for (auto it = bboxs.begin(); it != bboxs.end(); it++)
98 | {
99 | ncnn::Mat img_t;
100 | copy_cut_border(img, img_t, it->y[0], img_h - it->y[1], it->x[0], img_w - it->x[1]);
101 | ncnn::Mat in = resize(img_t, 24, 24);
102 | in.substract_mean_normalize(this->mean_vals, this->norm_vals);
103 | ncnn::Extractor ex = Rnet.create_extractor();
104 | ex.set_light_mode(true);
105 | ex.input(det2_param_id::BLOB_data, in);
106 | ncnn::Mat score, bbox;
107 | ex.extract(det2_param_id::BLOB_prob1, score);
108 | ex.extract(det2_param_id::BLOB_conv5_2, bbox);
109 | if ((float)score[1] > threshold[1])
110 | {
111 | for (int c = 0; c < 4; c++)
112 | {
113 | it->regreCoord[c] = (float)bbox[c];
114 | }
115 | it->score = (float)score[1];
116 | results.push_back(*it);
117 | }
118 | }
119 | return results;
120 | }
121 |
122 | vector MtcnnDetector::Onet_Detect(ncnn::Mat img, vector bboxs)
123 | {
124 | vector results;
125 |
126 | int img_w = img.w;
127 | int img_h = img.h;
128 |
129 | for (auto it = bboxs.begin(); it != bboxs.end(); it++)
130 | {
131 | ncnn::Mat img_t;
132 | copy_cut_border(img, img_t, it->y[0], img_h - it->y[1], it->x[0], img_w - it->x[1]);
133 | ncnn::Mat in = resize(img_t, 48, 48);
134 | in.substract_mean_normalize(this->mean_vals, this->norm_vals);
135 | ncnn::Extractor ex = Onet.create_extractor();
136 | ex.set_light_mode(true);
137 | ex.input(det3_param_id::BLOB_data, in);
138 | ncnn::Mat score, bbox, point;
139 | ex.extract(det3_param_id::BLOB_prob1, score);
140 | ex.extract(det3_param_id::BLOB_conv6_2, bbox);
141 | ex.extract(det3_param_id::BLOB_conv6_3, point);
142 | if ((float)score[1] > threshold[2])
143 | {
144 | for (int c = 0; c < 4; c++)
145 | {
146 | it->regreCoord[c] = (float)bbox[c];
147 | }
148 | for (int p = 0; p < 5; p++)
149 | {
150 | it->landmark[2 * p] = it->x[0] + (it->x[1] - it->x[0]) * point[p];
151 | it->landmark[2 * p + 1] = it->y[0] + (it->y[1] - it->y[0]) * point[p + 5];
152 | }
153 | it->score = (float)score[1];
154 | results.push_back(*it);
155 | }
156 | }
157 | return results;
158 | }
159 |
160 | void MtcnnDetector::Lnet_Detect(ncnn::Mat img, vector &bboxes)
161 | {
162 | int img_w = img.w;
163 | int img_h = img.h;
164 |
165 | for (auto it = bboxes.begin(); it != bboxes.end(); it++)
166 | {
167 | int w = it->x[1] - it->x[0] + 1;
168 | int h = it->y[1] - it->y[0] + 1;
169 | int m = w > h ? w : h;
170 | m = (int)round(m * 0.25);
171 | if (m % 2 == 1) m++;
172 | m /= 2;
173 |
174 | ncnn::Mat in(24, 24, 15);
175 |
176 | for (int i = 0; i < 5; i++)
177 | {
178 | int px = it->landmark[2 * i];
179 | int py = it->landmark[2 * i + 1];
180 | ncnn::Mat cut;
181 | copy_cut_border(img, cut, py - m, img_h - py - m, px - m, img_w - px - m);
182 | ncnn::Mat resized = resize(cut, 24, 24);
183 | resized.substract_mean_normalize(this->mean_vals, this->norm_vals);
184 | for (int j = 0; j < 3; j++)
185 | memcpy(in.channel(3 * i + j), resized.channel(j), 24 * 24 * sizeof(float));
186 | }
187 |
188 | ncnn::Extractor ex = Lnet.create_extractor();
189 | ex.set_light_mode(true);
190 | ex.input(det4_param_id::BLOB_data, in);
191 | ncnn::Mat out1, out2, out3, out4, out5;
192 |
193 | ex.extract(det4_param_id::BLOB_fc5_1, out1);
194 | ex.extract(det4_param_id::BLOB_fc5_2, out2);
195 | ex.extract(det4_param_id::BLOB_fc5_3, out3);
196 | ex.extract(det4_param_id::BLOB_fc5_4, out4);
197 | ex.extract(det4_param_id::BLOB_fc5_5, out5);
198 |
199 | if (abs(out1[0] - 0.5) > 0.35) out1[0] = 0.5f;
200 | if (abs(out1[1] - 0.5) > 0.35) out1[1] = 0.5f;
201 | if (abs(out2[0] - 0.5) > 0.35) out2[0] = 0.5f;
202 | if (abs(out2[1] - 0.5) > 0.35) out2[1] = 0.5f;
203 | if (abs(out3[0] - 0.5) > 0.35) out3[0] = 0.5f;
204 | if (abs(out3[1] - 0.5) > 0.35) out3[1] = 0.5f;
205 | if (abs(out4[0] - 0.5) > 0.35) out4[0] = 0.5f;
206 | if (abs(out4[1] - 0.5) > 0.35) out4[1] = 0.5f;
207 | if (abs(out5[0] - 0.5) > 0.35) out5[0] = 0.5f;
208 | if (abs(out5[1] - 0.5) > 0.35) out5[1] = 0.5f;
209 |
210 | it->landmark[0] += (int)round((out1[0] - 0.5) * m * 2);
211 | it->landmark[1] += (int)round((out1[1] - 0.5) * m * 2);
212 | it->landmark[2] += (int)round((out2[0] - 0.5) * m * 2);
213 | it->landmark[3] += (int)round((out2[1] - 0.5) * m * 2);
214 | it->landmark[4] += (int)round((out3[0] - 0.5) * m * 2);
215 | it->landmark[5] += (int)round((out3[1] - 0.5) * m * 2);
216 | it->landmark[6] += (int)round((out4[0] - 0.5) * m * 2);
217 | it->landmark[7] += (int)round((out4[1] - 0.5) * m * 2);
218 | it->landmark[8] += (int)round((out5[0] - 0.5) * m * 2);
219 | it->landmark[9] += (int)round((out5[1] - 0.5) * m * 2);
220 | }
221 | }
222 |
223 | vector MtcnnDetector::generateBbox(ncnn::Mat score, ncnn::Mat loc, float scale, float thresh)
224 | {
225 | int stride = 2;
226 | int cellsize = 12;
227 | float *p = score.channel(1);
228 | float inv_scale = 1.0f / scale;
229 | vector results;
230 | for (int row = 0; row < score.h; row++)
231 | {
232 | for (int col = 0; col < score.w; col++)
233 | {
234 | if (*p > thresh)
235 | {
236 | FaceInfo box;
237 | box.score = *p;
238 | box.x[0] = round((stride * col + 1) * inv_scale);
239 | box.y[0] = round((stride * row + 1) * inv_scale);
240 | box.x[1] = round((stride * col + 1 + cellsize) * inv_scale);
241 | box.y[1] = round((stride * row + 1 + cellsize) * inv_scale);
242 | box.area = (box.x[1] - box.x[0]) * (box.y[1] - box.y[0]);
243 | int index = row * score.w + col;
244 | for (int c = 0; c < 4; c++)
245 | box.regreCoord[c] = loc.channel(c)[index];
246 | results.push_back(box);
247 | }
248 | p++;
249 | }
250 | }
251 | return results;
252 | }
253 |
254 | bool cmpScore(FaceInfo x, FaceInfo y)
255 | {
256 | if (x.score > y.score)
257 | return true;
258 | else
259 | return false;
260 | }
261 |
262 | float calcIOU(FaceInfo box1, FaceInfo box2, string mode)
263 | {
264 | int maxX = max(box1.x[0], box2.x[0]);
265 | int maxY = max(box1.y[0], box2.y[0]);
266 | int minX = min(box1.x[1], box2.x[1]);
267 | int minY = min(box1.y[1], box2.y[1]);
268 | int width = ((minX - maxX + 1) > 0) ? (minX - maxX + 1) : 0;
269 | int height = ((minY - maxY + 1) > 0) ? (minY - maxY + 1) : 0;
270 | int inter = width * height;
271 | if (!mode.compare("union"))
272 | return float(inter) / (box1.area + box2.area - float(inter));
273 | else if (!mode.compare("min"))
274 | return float(inter) / (box1.area < box2.area ? box1.area : box2.area);
275 | else
276 | return 0;
277 | }
278 |
279 | void MtcnnDetector::doNms(vector &bboxs, float nms_thresh, string mode)
280 | {
281 | if (bboxs.empty())
282 | return;
283 | sort(bboxs.begin(), bboxs.end(), cmpScore);
284 | for (int i = 0; i < bboxs.size(); i++)
285 | if (bboxs[i].score > 0)
286 | for (int j = i + 1; j < bboxs.size(); j++)
287 | if (bboxs[j].score > 0)
288 | {
289 | float iou = calcIOU(bboxs[i], bboxs[j], mode);
290 | if (iou > nms_thresh)
291 | bboxs[j].score = 0;
292 | }
293 | for (auto it = bboxs.begin(); it != bboxs.end();)
294 | if ((*it).score == 0)
295 | bboxs.erase(it);
296 | else
297 | it++;
298 | }
299 |
300 | void MtcnnDetector::refine(vector &bboxs, int height, int width, bool flag)
301 | {
302 | if (bboxs.empty())
303 | return;
304 | for (auto it = bboxs.begin(); it != bboxs.end(); it++)
305 | {
306 | float bw = it->x[1] - it->x[0] + 1;
307 | float bh = it->y[1] - it->y[0] + 1;
308 | float x0 = it->x[0] + it->regreCoord[0] * bw;
309 | float y0 = it->y[0] + it->regreCoord[1] * bh;
310 | float x1 = it->x[1] + it->regreCoord[2] * bw;
311 | float y1 = it->y[1] + it->regreCoord[3] * bh;
312 |
313 | if (flag)
314 | {
315 | float w = x1 - x0 + 1;
316 | float h = y1 - y0 + 1;
317 | float m = (h > w) ? h : w;
318 | x0 = x0 + w * 0.5 - m * 0.5;
319 | y0 = y0 + h * 0.5 - m * 0.5;
320 | x1 = x0 + m - 1;
321 | y1 = y0 + m - 1;
322 | }
323 | it->x[0] = round(x0);
324 | it->y[0] = round(y0);
325 | it->x[1] = round(x1);
326 | it->y[1] = round(y1);
327 |
328 | if (it->x[0] < 0) it->x[0] = 0;
329 | if (it->y[0] < 0) it->y[0] = 0;
330 | if (it->x[1] > width) it->x[1] = width - 1;
331 | if (it->y[1] > height) it->y[1] = height - 1;
332 |
333 | it->area = (it->x[1] - it->x[0]) * (it->y[1] - it->y[0]);
334 | }
335 | }
336 |
--------------------------------------------------------------------------------
/app/src/main/cpp/arcface/mtcnn.h:
--------------------------------------------------------------------------------
1 | #ifndef MTCNN_H
2 | #define MTCNN_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "net.h"
10 | #include "base.h"
11 |
12 | using namespace std;
13 |
14 | class MtcnnDetector {
15 | public:
16 | MtcnnDetector();
17 | ~MtcnnDetector();
18 | vector Detect(ncnn::Mat img);
19 | private:
20 | float minsize = 20;
21 | float threshold[3] = {0.6f, 0.7f, 0.8f};
22 | float factor = 0.709f;
23 | const float mean_vals[3] = {127.5f, 127.5f, 127.5f};
24 | const float norm_vals[3] = {0.0078125f, 0.0078125f, 0.0078125f};
25 | ncnn::Net Pnet;
26 | ncnn::Net Rnet;
27 | ncnn::Net Onet;
28 | ncnn::Net Lnet;
29 | vector Pnet_Detect(ncnn::Mat img);
30 | vector Rnet_Detect(ncnn::Mat img, vector bboxs);
31 | vector Onet_Detect(ncnn::Mat img, vector bboxs);
32 | void Lnet_Detect(ncnn::Mat img, vector &bboxs);
33 | vector generateBbox(ncnn::Mat score, ncnn::Mat loc, float scale, float thresh);
34 | void doNms(vector &bboxs, float nms_thresh, string mode);
35 | void refine(vector &bboxs, int height, int width, bool flag = false);
36 | };
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/app/src/main/cpp/jni.cpp:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 |
22 | #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "jni", __VA_ARGS__))
23 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO , "jni", __VA_ARGS__))
24 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN , "libssd", __VA_ARGS__))
25 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "libssd", __VA_ARGS__))
26 |
27 | #include "arcface/interface.h"
28 |
29 |
30 | #ifdef __cplusplus
31 | extern "C" {
32 | #endif
33 |
34 | #define FACE_DETECT_SIZEH 448
35 | int sizeh, sizev;
36 |
37 |
38 | int faceinfo2float(float *out, FaceInfo *in)
39 | {
40 | if(sizeh == 0 || sizev == 0)
41 | return 20;
42 | *out = (float)in->x[0]/sizeh;out++;
43 | *out = (float)in->y[0]/sizev;out++;
44 | *out = (float)in->x[1]/sizeh;out++;
45 | *out = (float)in->y[1]/sizev;out++;
46 | *out = in->landmark[0];out++;
47 | *out = in->landmark[1];out++;
48 | *out = in->landmark[2];out++;
49 | *out = in->landmark[3];out++;
50 | *out = in->landmark[4];out++;
51 | *out = in->landmark[5];out++;
52 | *out = in->landmark[6];out++;
53 | *out = in->landmark[7];out++;
54 | *out = in->landmark[8];out++;
55 | *out = in->landmark[9];out++;
56 | *out = in->score;out++;
57 | *out = in->area;out++;
58 | *out = in->regreCoord[0];out++;
59 | *out = in->regreCoord[1];out++;
60 | *out = in->regreCoord[2];out++;
61 | *out = in->regreCoord[3];out++;
62 | return 20;
63 | }
64 |
65 | int float2faceinfo(FaceInfo *out, float *in)
66 | {
67 | if(sizeh == 0 || sizev == 0)
68 | return 20;
69 | out->x[0]=(*in)*sizeh;in++;
70 | out->y[0]=(*in)*sizev;in++;
71 | out->x[1]=(*in)*sizeh;in++;
72 | out->y[1]=(*in)*sizev;in++;
73 | out->landmark[0]=*in;in++;
74 | out->landmark[1]=*in;in++;
75 | out->landmark[2]=*in;in++;
76 | out->landmark[3]=*in;in++;
77 | out->landmark[4]=*in;in++;
78 | out->landmark[5]=*in;in++;
79 | out->landmark[6]=*in;in++;
80 | out->landmark[7]=*in;in++;
81 | out->landmark[8]=*in;in++;
82 | out->landmark[9]=*in;in++;
83 | out->score=*in;in++;
84 | out->area=*in;in++;
85 | out->regreCoord[0]=*in;in++;
86 | out->regreCoord[1]=*in;in++;
87 | out->regreCoord[2]=*in;in++;
88 | out->regreCoord[3]=*in;in++;
89 | return 20;
90 | }
91 |
92 | extern "C" JNIEXPORT jfloatArray JNICALL
93 | Java_com_chenty_testncnn_CameraNcnnFragment_detectface(JNIEnv *env, jobject thiz, jbyteArray frame, jint src_width,
94 | jint src_height) {
95 | char *yuv_frame = (char*)env->GetPrimitiveArrayCritical(frame, NULL);
96 |
97 | int size = env->GetArrayLength(frame);
98 | int objectcnt = 0;
99 | int i;
100 |
101 |
102 | sizeh = FACE_DETECT_SIZEH;
103 | sizev = FACE_DETECT_SIZEH*src_height/src_width;
104 |
105 | //shift argb to rgba
106 | char *yuv = (char *)malloc(size);
107 | memcpy(yuv, yuv_frame, size);
108 |
109 | env->ReleasePrimitiveArrayCritical(frame, yuv_frame, JNI_ABORT);
110 |
111 | ncnn::Mat in = ncnn::Mat::from_pixels_resize((const unsigned char *)yuv, ncnn::Mat::PIXEL_GRAY2BGR, src_width, src_height, sizeh, sizev);
112 | LOGD("detect face in %dX%d", src_width, src_height);
113 | vector faceinfo = face_detect(in);
114 |
115 | free(yuv);
116 | int gap = 20;
117 | int cnt = faceinfo.size();
118 | if(cnt)
119 | {
120 | float detect_out[240];
121 | float *out = detect_out;
122 |
123 | if(cnt > 240/gap)
124 | cnt = 240/gap;
125 |
126 | for (int i = 0 ; i < cnt ; i ++)
127 | {
128 | FaceInfo face = faceinfo[i];
129 | LOGD("get face %d %d %d %d", face.x[0], face.y[0], face.x[1], face.y[1]);
130 | int res = faceinfo2float(out, &face);
131 | out=out+res;
132 | }
133 |
134 | FaceInfo face = faceinfo[0];
135 | vector feature = face_exactfeature(in, face);
136 |
137 | LOGD("get feature %d ", feature.size());
138 | float feature_f[256];
139 | jfloatArray detect = env->NewFloatArray(cnt*gap + 128);
140 | LOGD("vect2float %d", feature.size());
141 | out = feature_f;
142 | for(int i = 0 ; i < feature.size(); i++)
143 | {
144 | *out = feature[i];
145 | out++;
146 | }
147 | //vect2float(feature_f, feature);
148 | //memcpy(feature_f, &feature[0], feature.size()*sizeof(float));
149 | LOGD("set feature %d ", feature.size());
150 | env->SetFloatArrayRegion(detect,0,128, feature_f);
151 | LOGD("set face %d ", cnt*gap);
152 | env->SetFloatArrayRegion(detect, 128, cnt*gap, detect_out);
153 |
154 | return detect;
155 | } else{
156 |
157 | return nullptr;
158 | }
159 | }
160 |
161 |
162 |
163 | extern "C" JNIEXPORT jfloat JNICALL
164 | Java_com_chenty_testncnn_CameraNcnnFragment_compareface(JNIEnv *env, jobject thiz, jfloatArray face0, jfloatArray face1) {
165 |
166 | float face0cache[128], face1cache[128];
167 |
168 | env->GetFloatArrayRegion(face0,0,128,face0cache);
169 | env->GetFloatArrayRegion(face1,0,128,face1cache);
170 |
171 | vector face0feature(face0cache, face0cache+sizeof(face0cache)/sizeof(float));
172 | vector face1feature(face1cache, face1cache+sizeof(face1cache)/sizeof(float));
173 |
174 | jfloat result = face_calcSimilar(face0feature, face1feature);
175 | LOGD("calcSimilar result %f\n", result);
176 |
177 | return result;
178 |
179 |
180 | }
181 |
182 |
183 | #ifdef __cplusplus
184 | }
185 | #endif
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/arm64-v8a/libncnn.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/cpp/ncnn-android-lib/arm64-v8a/libncnn.a
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/armeabi-v7a/libncnn.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/cpp/ncnn-android-lib/armeabi-v7a/libncnn.a
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/allocator.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_ALLOCATOR_H
16 | #define NCNN_ALLOCATOR_H
17 |
18 | #ifdef _WIN32
19 | #define WIN32_LEAN_AND_MEAN
20 | #include
21 | #else
22 | #include
23 | #endif
24 |
25 | #include
26 | #include
27 | #include
28 | #include "platform.h"
29 |
30 | #if NCNN_VULKAN
31 | #include
32 | #include "gpu.h"
33 | #endif // NCNN_VULKAN
34 |
35 | struct AHardwareBuffer;
36 |
37 | namespace ncnn {
38 |
39 | // the alignment of all the allocated buffers
40 | #define MALLOC_ALIGN 16
41 |
42 | // Aligns a pointer to the specified number of bytes
43 | // ptr Aligned pointer
44 | // n Alignment size that must be a power of two
45 | template static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
46 | {
47 | return (_Tp*)(((size_t)ptr + n-1) & -n);
48 | }
49 |
50 | // Aligns a buffer size to the specified number of bytes
51 | // The function returns the minimum number that is greater or equal to sz and is divisible by n
52 | // sz Buffer size to align
53 | // n Alignment size that must be a power of two
54 | static inline size_t alignSize(size_t sz, int n)
55 | {
56 | return (sz + n-1) & -n;
57 | }
58 |
59 | static inline void* fastMalloc(size_t size)
60 | {
61 | #if _MSC_VER
62 | return _aligned_malloc(size, MALLOC_ALIGN);
63 | #elif _POSIX_C_SOURCE >= 200112L || (__ANDROID__ && __ANDROID_API__ >= 17)
64 | void* ptr = 0;
65 | if (posix_memalign(&ptr, MALLOC_ALIGN, size))
66 | ptr = 0;
67 | return ptr;
68 | #elif __ANDROID__ && __ANDROID_API__ < 17
69 | return memalign(MALLOC_ALIGN, size);
70 | #else
71 | unsigned char* udata = (unsigned char*)malloc(size + sizeof(void*) + MALLOC_ALIGN);
72 | if (!udata)
73 | return 0;
74 | unsigned char** adata = alignPtr((unsigned char**)udata + 1, MALLOC_ALIGN);
75 | adata[-1] = udata;
76 | return adata;
77 | #endif
78 | }
79 |
80 | static inline void fastFree(void* ptr)
81 | {
82 | if (ptr)
83 | {
84 | #if _MSC_VER
85 | _aligned_free(ptr);
86 | #elif _POSIX_C_SOURCE >= 200112L || (__ANDROID__ && __ANDROID_API__ >= 17)
87 | free(ptr);
88 | #elif __ANDROID__ && __ANDROID_API__ < 17
89 | free(ptr);
90 | #else
91 | unsigned char* udata = ((unsigned char**)ptr)[-1];
92 | free(udata);
93 | #endif
94 | }
95 | }
96 |
97 | // exchange-add operation for atomic operations on reference counters
98 | #if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
99 | // atomic increment on the linux version of the Intel(tm) compiler
100 | # define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast(reinterpret_cast(addr)), delta)
101 | #elif defined __GNUC__
102 | # if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
103 | # ifdef __ATOMIC_ACQ_REL
104 | # define NCNN_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
105 | # else
106 | # define NCNN_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
107 | # endif
108 | # else
109 | # if defined __ATOMIC_ACQ_REL && !defined __clang__
110 | // version for gcc >= 4.7
111 | # define NCNN_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL)
112 | # else
113 | # define NCNN_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta))
114 | # endif
115 | # endif
116 | #elif defined _MSC_VER && !defined RC_INVOKED
117 | # include
118 | # define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
119 | #else
120 | // thread-unsafe branch
121 | static inline int NCNN_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
122 | #endif
123 |
124 | class Allocator
125 | {
126 | public:
127 | virtual ~Allocator();
128 | virtual void* fastMalloc(size_t size) = 0;
129 | virtual void fastFree(void* ptr) = 0;
130 | };
131 |
132 | class PoolAllocator : public Allocator
133 | {
134 | public:
135 | PoolAllocator();
136 | ~PoolAllocator();
137 |
138 | // ratio range 0 ~ 1
139 | // default cr = 0.75
140 | void set_size_compare_ratio(float scr);
141 |
142 | // release all budgets immediately
143 | void clear();
144 |
145 | virtual void* fastMalloc(size_t size);
146 | virtual void fastFree(void* ptr);
147 |
148 | private:
149 | Mutex budgets_lock;
150 | Mutex payouts_lock;
151 | unsigned int size_compare_ratio;// 0~256
152 | std::list< std::pair > budgets;
153 | std::list< std::pair > payouts;
154 | };
155 |
156 | class UnlockedPoolAllocator : public Allocator
157 | {
158 | public:
159 | UnlockedPoolAllocator();
160 | ~UnlockedPoolAllocator();
161 |
162 | // ratio range 0 ~ 1
163 | // default cr = 0.75
164 | void set_size_compare_ratio(float scr);
165 |
166 | // release all budgets immediately
167 | void clear();
168 |
169 | virtual void* fastMalloc(size_t size);
170 | virtual void fastFree(void* ptr);
171 |
172 | private:
173 | unsigned int size_compare_ratio;// 0~256
174 | std::list< std::pair > budgets;
175 | std::list< std::pair > payouts;
176 | };
177 |
178 | #if NCNN_VULKAN
179 |
180 | class VkBufferMemory
181 | {
182 | public:
183 | VkBuffer buffer;
184 |
185 | // the base offset assigned by allocator
186 | size_t offset;
187 | size_t capacity;
188 |
189 | VkDeviceMemory memory;
190 | void* mapped_ptr;
191 |
192 | // buffer state, modified by command functions internally
193 | // 0=null
194 | // 1=created
195 | // 2=transfer
196 | // 3=compute
197 | // 4=readonly
198 | mutable int state;
199 |
200 | // initialize and modified by mat
201 | int refcount;
202 | };
203 |
204 | class VkAllocator
205 | {
206 | public:
207 | VkAllocator(const VulkanDevice* _vkdev);
208 | virtual ~VkAllocator() { clear(); }
209 | virtual void clear() {}
210 | virtual VkBufferMemory* fastMalloc(size_t size) = 0;
211 | virtual void fastFree(VkBufferMemory* ptr) = 0;
212 | virtual int flush(VkBufferMemory* ptr);
213 | virtual int invalidate(VkBufferMemory* ptr);
214 |
215 | public:
216 | const VulkanDevice* vkdev;
217 | uint32_t memory_type_index;
218 | bool mappable;
219 | bool coherent;
220 |
221 | protected:
222 | VkBuffer create_buffer(size_t size, VkBufferUsageFlags usage);
223 | VkDeviceMemory allocate_memory(size_t size);
224 | VkDeviceMemory allocate_dedicated_memory(size_t size, VkBuffer buffer);
225 | };
226 |
227 | class VkBlobBufferAllocator : public VkAllocator
228 | {
229 | public:
230 | VkBlobBufferAllocator(const VulkanDevice* vkdev);
231 | virtual ~VkBlobBufferAllocator();
232 |
233 | public:
234 | // release all budgets immediately
235 | virtual void clear();
236 |
237 | virtual VkBufferMemory* fastMalloc(size_t size);
238 | virtual void fastFree(VkBufferMemory* ptr);
239 |
240 | private:
241 | size_t block_size;
242 | size_t buffer_offset_alignment;
243 | std::vector< std::list< std::pair > > budgets;
244 | std::vector buffer_blocks;
245 | };
246 |
247 | class VkWeightBufferAllocator : public VkAllocator
248 | {
249 | public:
250 | VkWeightBufferAllocator(const VulkanDevice* vkdev);
251 | virtual ~VkWeightBufferAllocator();
252 |
253 | public:
254 | // release all blocks immediately
255 | virtual void clear();
256 |
257 | public:
258 | virtual VkBufferMemory* fastMalloc(size_t size);
259 | virtual void fastFree(VkBufferMemory* ptr);
260 |
261 | private:
262 | size_t block_size;
263 | size_t buffer_offset_alignment;
264 | std::vector buffer_block_free_spaces;
265 | std::vector buffer_blocks;
266 | std::vector dedicated_buffer_blocks;
267 | };
268 |
269 | class VkStagingBufferAllocator : public VkAllocator
270 | {
271 | public:
272 | VkStagingBufferAllocator(const VulkanDevice* vkdev);
273 | virtual ~VkStagingBufferAllocator();
274 |
275 | public:
276 | // ratio range 0 ~ 1
277 | // default cr = 0.75
278 | void set_size_compare_ratio(float scr);
279 |
280 | // release all budgets immediately
281 | virtual void clear();
282 |
283 | virtual VkBufferMemory* fastMalloc(size_t size);
284 | virtual void fastFree(VkBufferMemory* ptr);
285 |
286 | private:
287 | unsigned int size_compare_ratio;// 0~256
288 | std::list budgets;
289 | };
290 |
291 | class VkWeightStagingBufferAllocator : public VkAllocator
292 | {
293 | public:
294 | VkWeightStagingBufferAllocator(const VulkanDevice* vkdev);
295 | virtual ~VkWeightStagingBufferAllocator();
296 |
297 | public:
298 | virtual VkBufferMemory* fastMalloc(size_t size);
299 | virtual void fastFree(VkBufferMemory* ptr);
300 |
301 | private:
302 | };
303 |
304 | class VkImageMemory
305 | {
306 | public:
307 | VkImage image;
308 | VkImageView imageview;
309 |
310 | VkDeviceMemory memory;
311 |
312 | // buffer state, modified by command functions internally
313 | // 0=null
314 | // 1=created
315 | // 2=transfer
316 | // 3=compute
317 | // 4=readonly
318 | mutable int state;
319 |
320 | // initialize and modified by mat
321 | int refcount;
322 | };
323 |
324 | class VkImageAllocator : public VkAllocator
325 | {
326 | public:
327 | VkImageAllocator(const VulkanDevice* _vkdev);
328 | virtual ~VkImageAllocator() { clear(); }
329 | virtual void clear() {}
330 | virtual VkImageMemory* fastMalloc(int width, int height, VkFormat format) = 0;
331 | virtual void fastFree(VkImageMemory* ptr) = 0;
332 |
333 | protected:
334 | virtual VkBufferMemory* fastMalloc(size_t /*size*/) { return 0; }
335 | virtual void fastFree(VkBufferMemory* /*ptr*/) {}
336 |
337 | protected:
338 | VkImage create_image(int width, int height, VkFormat format, VkImageUsageFlags usage);
339 | VkImageView create_imageview(VkImage image, VkFormat format);
340 | VkDeviceMemory allocate_dedicated_memory(size_t size, VkImage image);
341 | };
342 |
343 | class VkSimpleImageAllocator : public VkImageAllocator
344 | {
345 | public:
346 | VkSimpleImageAllocator(const VulkanDevice* vkdev);
347 | virtual ~VkSimpleImageAllocator();
348 |
349 | public:
350 | virtual VkImageMemory* fastMalloc(int width, int height, VkFormat format);
351 | virtual void fastFree(VkImageMemory* ptr);
352 | };
353 |
354 | #if __ANDROID_API__ >= 26
355 | class ImportAndroidHardwareBufferPipeline;
356 | class VkAndroidHardwareBufferImageAllocator : public VkImageAllocator
357 | {
358 | public:
359 | VkAndroidHardwareBufferImageAllocator(const VulkanDevice* vkdev, const ImportAndroidHardwareBufferPipeline* p);
360 | virtual ~VkAndroidHardwareBufferImageAllocator();
361 |
362 | public:
363 | virtual VkImageMemory* fastMalloc(AHardwareBuffer* hb);
364 | virtual void fastFree(VkImageMemory* ptr);
365 |
366 | protected:
367 | virtual VkImageMemory* fastMalloc(int /*width*/, int /*height*/, VkFormat /*format*/) { return 0; }
368 | virtual VkBufferMemory* fastMalloc(size_t /*size*/) { return 0; }
369 |
370 | private:
371 | const ImportAndroidHardwareBufferPipeline* const q;
372 | };
373 | #endif // __ANDROID_API__ >= 26
374 |
375 | #endif // NCNN_VULKAN
376 |
377 | } // namespace ncnn
378 |
379 | #endif // NCNN_ALLOCATOR_H
380 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/benchmark.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_BENCHMARK_H
16 | #define NCNN_BENCHMARK_H
17 |
18 | #include "platform.h"
19 | #include "mat.h"
20 | #include "layer.h"
21 |
22 | namespace ncnn {
23 |
24 | // get now timestamp in ms
25 | double get_current_time();
26 |
27 | #if NCNN_BENCHMARK
28 |
29 | void benchmark(const Layer* layer, double start, double end);
30 | void benchmark(const Layer* layer, const Mat& bottom_blob, Mat& top_blob, double start, double end);
31 |
32 | #endif // NCNN_BENCHMARK
33 |
34 | } // namespace ncnn
35 |
36 | #endif // NCNN_BENCHMARK_H
37 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/blob.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_BLOB_H
16 | #define NCNN_BLOB_H
17 |
18 | #include
19 | #include
20 | #include "platform.h"
21 | #include "mat.h"
22 |
23 | namespace ncnn {
24 |
25 | class Blob
26 | {
27 | public:
28 | // empty
29 | Blob();
30 |
31 | public:
32 | #if NCNN_STRING
33 | // blob name
34 | std::string name;
35 | #endif // NCNN_STRING
36 | // layer index which produce this blob as output
37 | int producer;
38 | // layer index which need this blob as input
39 | std::vector consumers;
40 | // shape hint
41 | Mat shape;
42 | };
43 |
44 | } // namespace ncnn
45 |
46 | #endif // NCNN_BLOB_H
47 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/command.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_COMMAND_H
16 | #define NCNN_COMMAND_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_VULKAN
21 |
22 | #include
23 | #include
24 | #include "mat.h"
25 | #include "pipeline.h"
26 |
27 | namespace ncnn {
28 |
29 | class Command
30 | {
31 | public:
32 | Command(const VulkanDevice* vkdev, uint32_t queue_family_index);
33 | virtual ~Command();
34 |
35 | protected:
36 | int create_command_pool();
37 | int create_command_buffer();
38 |
39 | // record issue
40 | int begin_command_buffer();
41 | int end_command_buffer();
42 | int queue_submit_and_wait_fence();
43 |
44 | protected:
45 | const VulkanDevice* vkdev;
46 | uint32_t queue_family_index;
47 |
48 | VkCommandPool command_pool;
49 | VkCommandBuffer command_buffer;
50 |
51 | VkFence fence;
52 | };
53 |
54 | class VkCompute : public Command
55 | {
56 | public:
57 | VkCompute(const VulkanDevice* vkdev);
58 | ~VkCompute();
59 |
60 | void record_upload(const VkMat& m);
61 |
62 | void record_download(const VkMat& m);
63 |
64 | void record_clone(const VkMat& src, const VkMat& dst);
65 |
66 | void record_copy_region(const VkMat& src, const VkMat& dst, const VkBufferCopy& region);
67 |
68 | void record_copy_regions(const VkMat& src, const VkMat& dst, const std::vector& regions);
69 |
70 | void record_pipeline(const Pipeline* pipeline, const std::vector& bindings, const std::vector& constants, const VkMat& m);
71 |
72 | #if NCNN_BENCHMARK
73 | void record_write_timestamp(uint32_t query);
74 | #endif // NCNN_BENCHMARK
75 |
76 | void record_queue_transfer_acquire(const VkMat& m, uint32_t src_queue_family_index);
77 |
78 | #if __ANDROID_API__ >= 26
79 | void record_import_android_hardware_buffer(const ImportAndroidHardwareBufferPipeline* pipeline, const VkImageMat& im, const VkMat& m);
80 | #endif // __ANDROID_API__ >= 26
81 |
82 | int submit_and_wait();
83 |
84 | int reset();
85 |
86 | #if NCNN_BENCHMARK
87 | int create_query_pool(uint32_t query_count);
88 |
89 | int get_query_pool_results(uint32_t first_query, uint32_t query_count, std::vector& results);
90 | #endif // NCNN_BENCHMARK
91 |
92 | protected:
93 | // record pipeline things
94 | void record_bind_pipeline(VkPipeline pipeline);
95 | void record_update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorSetLayout descriptorset_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& bindings);
96 | void record_push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants);
97 | void record_dispatch(const uint32_t* group_count_xyz);
98 |
99 | // record barrier things
100 | void record_transfer_compute_barrier(const VkMat& m);
101 | void record_compute_transfer_barrier(const VkMat& m);
102 | void record_compute_compute_barrier(const VkMat& m);
103 | void record_transfer_transfer_barrier(const VkMat& m);
104 | void record_host_transfer_barrier(const VkMat& m);
105 | void record_transfer_host_barrier(const VkMat& m);
106 | void record_host_compute_barrier(const VkMat& m);
107 | void record_compute_host_barrier(const VkMat& m);
108 |
109 | // record prepare things
110 | void record_prepare_transfer_barrier(const VkMat& m);
111 | void record_prepare_compute_barrier(const VkMat& m);
112 | void record_prepare_host_barrier(const VkMat& m);
113 |
114 | void record_initial_image_compute_barrier(const VkImageMat& im);
115 |
116 | #if __ANDROID_API__ >= 26
117 | void record_update_import_android_hardware_buffer_bindings(VkPipelineLayout pipeline_layout, VkDescriptorSetLayout descriptorset_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, VkSampler sampler, const VkImageMat& im, const VkMat& m);
118 | #endif // __ANDROID_API__ >= 26
119 |
120 | #if NCNN_BENCHMARK
121 | void reset_query_pool();
122 | #endif // NCNN_BENCHMARK
123 |
124 | protected:
125 | // recording issue
126 | void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size);
127 | void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions);
128 | void bind_pipeline(VkPipeline pipeline);
129 | void bind_descriptorset(VkPipelineLayout pipeline_layout, VkDescriptorSet descriptorset);
130 | void update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& descriptorBufferInfos);
131 | void push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants);
132 | void dispatch(const uint32_t* group_count_xyz);
133 | void transfer_compute_barrier(VkBuffer buffer, size_t offset, size_t size);
134 | void compute_transfer_barrier(VkBuffer buffer, size_t offset, size_t size);
135 | void compute_compute_barrier(VkBuffer buffer, size_t offset, size_t size);
136 | void transfer_transfer_barrier(VkBuffer buffer, size_t offset, size_t size);
137 | void host_transfer_barrier(VkBuffer buffer, size_t offset, size_t size);
138 | void transfer_host_barrier(VkBuffer buffer, size_t offset, size_t size);
139 | void host_compute_barrier(VkBuffer buffer, size_t offset, size_t size);
140 | void compute_host_barrier(VkBuffer buffer, size_t offset, size_t size);
141 | void queue_transfer_acquire_barrier(VkBuffer buffer, size_t offset, size_t size, uint32_t src_queue_family_index);
142 | void initial_image_compute_barrier(VkImage image);
143 | #if __ANDROID_API__ >= 26
144 | void update_import_android_hardware_buffer_bindings(VkPipelineLayout pipeline_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const VkDescriptorImageInfo& descriptorImageInfo, const VkDescriptorBufferInfo& descriptorBufferInfo);
145 | #endif // __ANDROID_API__ >= 26
146 | #if NCNN_BENCHMARK
147 | void write_timestamp(uint32_t query);
148 | #endif // NCNN_BENCHMARK
149 |
150 | protected:
151 | // delayed record
152 | // the good-old path for device without VK_KHR_push_descriptor
153 | std::vector descriptor_pools;
154 | std::vector descriptorsets;
155 | struct record_type
156 | {
157 | // 0=copy
158 | // 1=copy regions
159 | // 2=bind pipeline
160 | // 3=bind descriptorset
161 | // 4=push constants
162 | // 5=dispatch
163 | // 6=transfer-compute barrier
164 | // 7=compute-transfer barrier
165 | // 8=compute-compute barrier
166 | // 9=transfer-transfer barrier
167 | // 10=write timestamp
168 | // 11=initial image compute barrier
169 | // 12=host-transfer barrier
170 | // 13=transfer-host barrier
171 | // 14=host-compute barrier
172 | // 15=compute-host barrier
173 | // 16=queue-transfer-acquire barrier
174 | int type;
175 |
176 | union
177 | {
178 | struct { VkBuffer src; size_t src_offset; VkBuffer dst; size_t dst_offset; size_t size; } copy;
179 | struct { VkBuffer src; VkBuffer dst; } copy_regions;
180 | struct { VkPipeline pipeline; } bind_pipeline;
181 | struct { VkPipelineLayout pipeline_layout; VkDescriptorSet descriptorset; } bind_descriptorset;
182 | struct { VkPipelineLayout pipeline_layout; } push_constants;
183 | struct { uint32_t group_count_xyz[3]; } dispatch;
184 | struct { VkBuffer buffer; size_t offset; size_t size; } transfer_compute_barrier;
185 | struct { VkBuffer buffer; size_t offset; size_t size; } compute_transfer_barrier;
186 | struct { VkBuffer buffer; size_t offset; size_t size; } compute_compute_barrier;
187 | struct { VkBuffer buffer; size_t offset; size_t size; } transfer_transfer_barrier;
188 | #if NCNN_BENCHMARK
189 | struct { uint32_t query; } write_timestamp;
190 | #endif // NCNN_BENCHMARK
191 | struct { VkImage image; } initial_image_compute_barrier;
192 | struct { VkBuffer buffer; size_t offset; size_t size; } host_transfer_barrier;
193 | struct { VkBuffer buffer; size_t offset; size_t size; } transfer_host_barrier;
194 | struct { VkBuffer buffer; size_t offset; size_t size; } host_compute_barrier;
195 | struct { VkBuffer buffer; size_t offset; size_t size; } compute_host_barrier;
196 | struct { VkBuffer buffer; size_t offset; size_t size; size_t src_queue_family_index; } queue_transfer_acquire_barrier;
197 | };
198 |
199 | std::vector regions;
200 | std::vector constants;
201 | };
202 | std::vector delayed_records;
203 |
204 | #if NCNN_BENCHMARK
205 | uint32_t query_count;
206 | VkQueryPool query_pool;
207 | #endif // NCNN_BENCHMARK
208 | };
209 |
210 | class VkTransfer : public Command
211 | {
212 | public:
213 | VkTransfer(const VulkanDevice* vkdev);
214 | ~VkTransfer();
215 |
216 | void record_upload(const Mat& src, VkMat& dst, const Option& opt);
217 |
218 | int submit_and_wait();
219 |
220 | public:
221 | VkAllocator* weight_vkallocator;
222 | VkAllocator* staging_vkallocator;
223 |
224 | protected:
225 | // recording issue
226 | void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size);
227 | void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions);
228 | void queue_transfer_release_barrier(VkBuffer buffer, size_t offset, size_t size, uint32_t target_queue_family_index);
229 |
230 | protected:
231 | size_t buffer_offset_alignment;
232 | VkBufferMemory* staging_data;
233 |
234 | // delayed record
235 | struct record_type
236 | {
237 | size_t size;
238 | Mat mat;
239 | VkMat vkmat;
240 | };
241 | std::vector delayed_records;
242 | };
243 |
244 | } // namespace ncnn
245 |
246 | #endif // NCNN_VULKAN
247 |
248 | #endif // NCNN_COMMAND_H
249 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/cpu.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_CPU_H
16 | #define NCNN_CPU_H
17 |
18 | namespace ncnn {
19 |
20 | // test optional cpu features
21 | // neon = armv7 neon or aarch64 asimd
22 | int cpu_support_arm_neon();
23 | // vfpv4 = armv7 fp16 + fma
24 | int cpu_support_arm_vfpv4();
25 | // asimdhp = aarch64 asimd half precision
26 | int cpu_support_arm_asimdhp();
27 |
28 | // cpu info
29 | int get_cpu_count();
30 |
31 | // bind all threads on little clusters if powersave enabled
32 | // affacts HMP arch cpu like ARM big.LITTLE
33 | // only implemented on android at the moment
34 | // switching powersave is expensive and not thread-safe
35 | // 0 = all cores enabled(default)
36 | // 1 = only little clusters enabled
37 | // 2 = only big clusters enabled
38 | // return 0 if success for setter function
39 | int get_cpu_powersave();
40 | int set_cpu_powersave(int powersave);
41 |
42 | // misc function wrapper for openmp routines
43 | int get_omp_num_threads();
44 | void set_omp_num_threads(int num_threads);
45 |
46 | int get_omp_dynamic();
47 | void set_omp_dynamic(int dynamic);
48 |
49 | } // namespace ncnn
50 |
51 | #endif // NCNN_CPU_H
52 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/datareader.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_DATAREADER_H
16 | #define NCNN_DATAREADER_H
17 |
18 | #include
19 | #include "platform.h"
20 |
21 | #if __ANDROID_API__ >= 9
22 | #include
23 | #endif
24 |
25 | namespace ncnn {
26 |
27 | // data read wrapper
28 | class DataReader
29 | {
30 | public:
31 | virtual ~DataReader();
32 |
33 | #if NCNN_STRING
34 | // parse plain param text
35 | // return 1 if scan success
36 | virtual int scan(const char* format, void* p) const;
37 | #endif // NCNN_STRING
38 |
39 | // read binary param and model data
40 | // return bytes read
41 | virtual size_t read(void* buf, size_t size) const;
42 | };
43 |
44 | #if NCNN_STDIO
45 | class DataReaderFromStdio : public DataReader
46 | {
47 | public:
48 | DataReaderFromStdio(FILE* fp);
49 |
50 | #if NCNN_STRING
51 | virtual int scan(const char* format, void* p) const;
52 | #endif // NCNN_STRING
53 | virtual size_t read(void* buf, size_t size) const;
54 |
55 | protected:
56 | FILE* fp;
57 | };
58 | #endif // NCNN_STDIO
59 |
60 | class DataReaderFromMemory : public DataReader
61 | {
62 | public:
63 | DataReaderFromMemory(const unsigned char*& mem);
64 |
65 | #if NCNN_STRING
66 | virtual int scan(const char* format, void* p) const;
67 | #endif // NCNN_STRING
68 | virtual size_t read(void* buf, size_t size) const;
69 |
70 | protected:
71 | const unsigned char*& mem;
72 | };
73 |
74 | #if __ANDROID_API__ >= 9
75 | class DataReaderFromAndroidAsset : public DataReader
76 | {
77 | public:
78 | DataReaderFromAndroidAsset(AAsset* asset);
79 |
80 | #if NCNN_STRING
81 | virtual int scan(const char* format, void* p) const;
82 | #endif // NCNN_STRING
83 | virtual size_t read(void* buf, size_t size) const;
84 |
85 | protected:
86 | AAsset* asset;
87 | mutable const unsigned char* mem;
88 | };
89 | #endif // __ANDROID_API__ >= 9
90 |
91 | } // namespace ncnn
92 |
93 | #endif // NCNN_DATAREADER_H
94 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/gpu.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_GPU_H
16 | #define NCNN_GPU_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_VULKAN
21 |
22 | #include
23 | #include
24 |
25 | namespace ncnn {
26 |
27 | // instance
28 | int create_gpu_instance();
29 | void destroy_gpu_instance();
30 |
31 | // instance extension capability
32 | extern int support_VK_KHR_external_memory_capabilities;
33 | extern int support_VK_KHR_get_physical_device_properties2;
34 | extern int support_VK_KHR_get_surface_capabilities2;
35 | extern int support_VK_KHR_surface;
36 | extern int support_VK_EXT_debug_utils;
37 | #if __ANDROID_API__ >= 26
38 | extern int support_VK_KHR_android_surface;
39 | #endif // __ANDROID_API__ >= 26
40 |
41 | // VK_KHR_external_memory_capabilities
42 | extern PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR;
43 |
44 | // VK_KHR_get_physical_device_properties2
45 | extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
46 | extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
47 | extern PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
48 | extern PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR;
49 | extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
50 | extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
51 | extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
52 |
53 | // VK_KHR_get_surface_capabilities2
54 | extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
55 | extern PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
56 |
57 | // VK_KHR_surface
58 | extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
59 | extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
60 | extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
61 | extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
62 | extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
63 |
64 | #if __ANDROID_API__ >= 26
65 | // VK_KHR_android_surface
66 | extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
67 | #endif // __ANDROID_API__ >= 26
68 |
69 | // get info
70 | int get_gpu_count();
71 | int get_default_gpu_index();
72 |
73 | class GpuInfo
74 | {
75 | public:
76 | // vulkan physical device
77 | VkPhysicalDevice physical_device;
78 |
79 | // memory properties
80 | VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
81 |
82 | // info
83 | uint32_t api_version;
84 | uint32_t driver_version;
85 | uint32_t vendor_id;
86 | uint32_t device_id;
87 | uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
88 |
89 | // 0 = discrete gpu
90 | // 1 = integrated gpu
91 | // 2 = virtual gpu
92 | // 3 = cpu
93 | int type;
94 |
95 | // hardware limit
96 | uint32_t max_shared_memory_size;
97 | uint32_t max_workgroup_count[3];
98 | uint32_t max_workgroup_invocations;
99 | uint32_t max_workgroup_size[3];
100 | size_t memory_map_alignment;
101 | size_t buffer_offset_alignment;
102 | size_t non_coherent_atom_size;
103 | float timestamp_period;
104 |
105 | // runtime
106 | uint32_t compute_queue_family_index;
107 | uint32_t graphics_queue_family_index;
108 | uint32_t transfer_queue_family_index;
109 |
110 | uint32_t compute_queue_count;
111 | uint32_t graphics_queue_count;
112 | uint32_t transfer_queue_count;
113 |
114 | // bug is not feature
115 | bool bug_local_size_spec_const;
116 |
117 | // but sometimes bug is a feature
118 | bool bug_implicit_fp16_arithmetic;
119 |
120 | // fp16 and int8 feature
121 | bool support_fp16_packed;
122 | bool support_fp16_storage;
123 | bool support_fp16_arithmetic;
124 | bool support_int8_storage;
125 | bool support_int8_arithmetic;
126 |
127 | // ycbcr conversion feature
128 | bool support_ycbcr_conversion;
129 |
130 | // extension capability
131 | int support_VK_KHR_8bit_storage;
132 | int support_VK_KHR_16bit_storage;
133 | int support_VK_KHR_bind_memory2;
134 | int support_VK_KHR_dedicated_allocation;
135 | int support_VK_KHR_descriptor_update_template;
136 | int support_VK_KHR_external_memory;
137 | int support_VK_KHR_get_memory_requirements2;
138 | int support_VK_KHR_maintenance1;
139 | int support_VK_KHR_push_descriptor;
140 | int support_VK_KHR_sampler_ycbcr_conversion;
141 | int support_VK_KHR_shader_float16_int8;
142 | int support_VK_KHR_shader_float_controls;
143 | int support_VK_KHR_storage_buffer_storage_class;
144 | int support_VK_KHR_swapchain;
145 | int support_VK_EXT_queue_family_foreign;
146 | #if __ANDROID_API__ >= 26
147 | int support_VK_ANDROID_external_memory_android_hardware_buffer;
148 | #endif // __ANDROID_API__ >= 26
149 | };
150 |
151 | const GpuInfo& get_gpu_info(int device_index = get_default_gpu_index());
152 |
153 | class VkAllocator;
154 | class VulkanDevice
155 | {
156 | public:
157 | VulkanDevice(int device_index = get_default_gpu_index());
158 | ~VulkanDevice();
159 |
160 | const GpuInfo& info;
161 |
162 | VkDevice vkdevice() const { return device; }
163 |
164 | VkShaderModule get_shader_module(const char* name) const;
165 |
166 | // with fixed workgroup size
167 | VkShaderModule create_shader_module(const char* name, uint32_t local_size_x, uint32_t local_size_y, uint32_t local_size_z) const;
168 |
169 | VkShaderModule compile_shader_module(const uint32_t* spv_data, size_t spv_data_size) const;
170 |
171 | // with fixed workgroup size
172 | VkShaderModule compile_shader_module(const uint32_t* spv_data, size_t spv_data_size, uint32_t local_size_x, uint32_t local_size_y, uint32_t local_size_z) const;
173 |
174 | uint32_t find_memory_index(uint32_t memory_type_bits, VkFlags required, VkFlags preferred, VkFlags preferred_not) const;
175 | bool is_mappable(uint32_t memory_type_index) const;
176 | bool is_coherent(uint32_t memory_type_index) const;
177 |
178 | VkQueue acquire_queue(uint32_t queue_family_index) const;
179 | void reclaim_queue(uint32_t queue_family_index, VkQueue queue) const;
180 |
181 | // allocator on this device
182 | VkAllocator* acquire_blob_allocator() const;
183 | void reclaim_blob_allocator(VkAllocator* allocator) const;
184 |
185 | VkAllocator* acquire_staging_allocator() const;
186 | void reclaim_staging_allocator(VkAllocator* allocator) const;
187 |
188 | // VK_KHR_bind_memory2
189 | PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
190 | PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
191 |
192 | // VK_KHR_descriptor_update_template
193 | PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
194 | PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
195 | PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
196 |
197 | // VK_KHR_get_memory_requirements2
198 | PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
199 | PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
200 | PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
201 |
202 | // VK_KHR_maintenance1
203 | PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
204 |
205 | // VK_KHR_push_descriptor
206 | PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
207 | PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
208 |
209 | // VK_KHR_sampler_ycbcr_conversion
210 | PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
211 | PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
212 |
213 | // VK_KHR_swapchain
214 | PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
215 | PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
216 | PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
217 | PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
218 | PFN_vkQueuePresentKHR vkQueuePresentKHR;
219 |
220 | #if __ANDROID_API__ >= 26
221 | // VK_ANDROID_external_memory_android_hardware_buffer
222 | PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
223 | PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
224 | #endif // __ANDROID_API__ >= 26
225 |
226 | protected:
227 | // shader management
228 | int create_shader_module();
229 | void destroy_shader_module();
230 |
231 | // device extension
232 | int init_device_extension();
233 |
234 | private:
235 | VkDevice device;
236 | std::vector shader_modules;
237 |
238 | // hardware queue
239 | mutable std::vector compute_queues;
240 | mutable std::vector graphics_queues;
241 | mutable std::vector transfer_queues;
242 | mutable Mutex queue_lock;
243 |
244 | // default blob allocator for each queue
245 | mutable std::vector blob_allocators;
246 | mutable Mutex blob_allocator_lock;
247 |
248 | // default staging allocator for each queue
249 | mutable std::vector staging_allocators;
250 | mutable Mutex staging_allocator_lock;
251 | };
252 |
253 | VulkanDevice* get_gpu_device(int device_index = get_default_gpu_index());
254 |
255 | } // namespace ncnn
256 |
257 | #endif // NCNN_VULKAN
258 |
259 | #endif // NCNN_GPU_H
260 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/layer.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_LAYER_H
16 | #define NCNN_LAYER_H
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "platform.h"
23 | #include "mat.h"
24 | #include "modelbin.h"
25 | #include "option.h"
26 | #include "paramdict.h"
27 |
28 | #if NCNN_VULKAN
29 | #include
30 | #include "command.h"
31 | #include "pipeline.h"
32 | #endif // NCNN_VULKAN
33 |
34 | namespace ncnn {
35 |
36 | class Layer
37 | {
38 | public:
39 | // empty
40 | Layer();
41 | // virtual destructor
42 | virtual ~Layer();
43 |
44 | // load layer specific parameter from parsed dict
45 | // return 0 if success
46 | virtual int load_param(const ParamDict& pd);
47 |
48 | // load layer specific weight data from model binary
49 | // return 0 if success
50 | virtual int load_model(const ModelBin& mb);
51 |
52 | // layer implementation specific setup
53 | // return 0 if success
54 | virtual int create_pipeline(const Option& opt);
55 |
56 | // layer implementation specific clean
57 | // return 0 if success
58 | virtual int destroy_pipeline(const Option& opt);
59 |
60 | public:
61 | // one input and one output blob
62 | bool one_blob_only;
63 |
64 | // support inplace inference
65 | bool support_inplace;
66 |
67 | // support vulkan compute
68 | bool support_vulkan;
69 |
70 | // accept input blob with packed storage
71 | bool support_packing;
72 |
73 | public:
74 | // implement inference
75 | // return 0 if success
76 | virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, const Option& opt) const;
77 | virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const;
78 |
79 | // implement inplace inference
80 | // return 0 if success
81 | virtual int forward_inplace(std::vector& bottom_top_blobs, const Option& opt) const;
82 | virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const;
83 |
84 | #if NCNN_VULKAN
85 | public:
86 | // upload weight blob from host to device
87 | virtual int upload_model(VkTransfer& cmd, const Option& opt);
88 |
89 | public:
90 | // implement inference
91 | // return 0 if success
92 | virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, VkCompute& cmd, const Option& opt) const;
93 | virtual int forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const;
94 |
95 | // implement inplace inference
96 | // return 0 if success
97 | virtual int forward_inplace(std::vector& bottom_top_blobs, VkCompute& cmd, const Option& opt) const;
98 | virtual int forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const;
99 |
100 | public:
101 | // assigned immediately after creating this layer
102 | const VulkanDevice* vkdev;
103 | #endif // NCNN_VULKAN
104 |
105 | public:
106 | // layer type index
107 | int typeindex;
108 | #if NCNN_STRING
109 | // layer type name
110 | std::string type;
111 | // layer name
112 | std::string name;
113 | #endif // NCNN_STRING
114 | // blob index which this layer needs as input
115 | std::vector bottoms;
116 | // blob index which this layer produces as output
117 | std::vector tops;
118 | // shape hint
119 | std::vector bottom_shapes;
120 | std::vector top_shapes;
121 | };
122 |
123 | // layer factory function
124 | typedef Layer* (*layer_creator_func)();
125 |
126 | struct layer_registry_entry
127 | {
128 | #if NCNN_STRING
129 | // layer type name
130 | const char* name;
131 | #endif // NCNN_STRING
132 | // layer factory entry
133 | layer_creator_func creator;
134 | };
135 |
136 | #if NCNN_STRING
137 | // get layer type from type name
138 | int layer_to_index(const char* type);
139 | // create layer from type name
140 | Layer* create_layer(const char* type);
141 | #endif // NCNN_STRING
142 | // create layer from layer type
143 | Layer* create_layer(int index);
144 |
145 | #define DEFINE_LAYER_CREATOR(name) \
146 | ::ncnn::Layer* name##_layer_creator() { return new name; }
147 |
148 | } // namespace ncnn
149 |
150 | #endif // NCNN_LAYER_H
151 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/layer_type.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_LAYER_TYPE_H
16 | #define NCNN_LAYER_TYPE_H
17 |
18 | namespace ncnn {
19 |
20 | namespace LayerType {
21 | enum
22 | {
23 | #include "layer_type_enum.h"
24 | CustomBit = (1<<8),
25 | };
26 | } // namespace LayerType
27 |
28 | } // namespace ncnn
29 |
30 | #endif // NCNN_LAYER_TYPE_H
31 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/layer_type_enum.h:
--------------------------------------------------------------------------------
1 | // Layer Type Enum header
2 | //
3 | // This file is auto-generated by cmake, don't edit it.
4 |
5 | AbsVal = 0,
6 | ArgMax = 1,
7 | BatchNorm = 2,
8 | Bias = 3,
9 | BNLL = 4,
10 | Concat = 5,
11 | Convolution = 6,
12 | Crop = 7,
13 | Deconvolution = 8,
14 | Dropout = 9,
15 | Eltwise = 10,
16 | ELU = 11,
17 | Embed = 12,
18 | Exp = 13,
19 | Flatten = 14,
20 | InnerProduct = 15,
21 | Input = 16,
22 | Log = 17,
23 | LRN = 18,
24 | MemoryData = 19,
25 | MVN = 20,
26 | Pooling = 21,
27 | Power = 22,
28 | PReLU = 23,
29 | Proposal = 24,
30 | Reduction = 25,
31 | ReLU = 26,
32 | Reshape = 27,
33 | ROIPooling = 28,
34 | Scale = 29,
35 | Sigmoid = 30,
36 | Slice = 31,
37 | Softmax = 32,
38 | Split = 33,
39 | SPP = 34,
40 | TanH = 35,
41 | Threshold = 36,
42 | Tile = 37,
43 | RNN = 38,
44 | LSTM = 39,
45 | BinaryOp = 40,
46 | UnaryOp = 41,
47 | ConvolutionDepthWise = 42,
48 | Padding = 43,
49 | Squeeze = 44,
50 | ExpandDims = 45,
51 | Normalize = 46,
52 | Permute = 47,
53 | PriorBox = 48,
54 | DetectionOutput = 49,
55 | Interp = 50,
56 | DeconvolutionDepthWise = 51,
57 | ShuffleChannel = 52,
58 | InstanceNorm = 53,
59 | Clip = 54,
60 | Reorg = 55,
61 | YoloDetectionOutput = 56,
62 | Quantize = 57,
63 | Dequantize = 58,
64 | Yolov3DetectionOutput = 59,
65 | PSROIPooling = 60,
66 | ROIAlign = 61,
67 | Packing = 62,
68 | Requantize = 63,
69 | Cast = 64,
70 | HardSigmoid = 65,
71 | SELU = 66,
72 | HardSwish = 67,
73 | Noop = 68,
74 | PixelShuffle = 69,
75 |
76 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/modelbin.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_MODELBIN_H
16 | #define NCNN_MODELBIN_H
17 |
18 | #include "mat.h"
19 |
20 | namespace ncnn {
21 |
22 | class DataReader;
23 | class ModelBin
24 | {
25 | public:
26 | virtual ~ModelBin();
27 | // element type
28 | // 0 = auto
29 | // 1 = float32
30 | // 2 = float16
31 | // 3 = int8
32 | // load vec
33 | virtual Mat load(int w, int type) const = 0;
34 | // load image
35 | virtual Mat load(int w, int h, int type) const;
36 | // load dim
37 | virtual Mat load(int w, int h, int c, int type) const;
38 | };
39 |
40 | class ModelBinFromDataReader : public ModelBin
41 | {
42 | public:
43 | ModelBinFromDataReader(const DataReader& dr);
44 |
45 | virtual Mat load(int w, int type) const;
46 |
47 | protected:
48 | const DataReader& dr;
49 | };
50 |
51 | class ModelBinFromMatArray : public ModelBin
52 | {
53 | public:
54 | // construct from weight blob array
55 | ModelBinFromMatArray(const Mat* weights);
56 |
57 | virtual Mat load(int w, int type) const;
58 |
59 | protected:
60 | mutable const Mat* weights;
61 | };
62 |
63 | } // namespace ncnn
64 |
65 | #endif // NCNN_MODELBIN_H
66 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/net.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_NET_H
16 | #define NCNN_NET_H
17 |
18 | #include
19 | #include
20 | #include "platform.h"
21 | #include "blob.h"
22 | #include "layer.h"
23 | #include "mat.h"
24 | #include "option.h"
25 |
26 | #if __ANDROID_API__ >= 9
27 | #include
28 | #endif // __ANDROID_API__ >= 9
29 |
30 | namespace ncnn {
31 |
32 | #if NCNN_VULKAN
33 | class VkCompute;
34 | #endif // NCNN_VULKAN
35 | class DataReader;
36 | class Extractor;
37 | class Net
38 | {
39 | public:
40 | // empty init
41 | Net();
42 | // clear and destroy
43 | ~Net();
44 |
45 | public:
46 | // option can be changed before loading
47 | Option opt;
48 |
49 | #if NCNN_VULKAN
50 | // set gpu device by index
51 | void set_vulkan_device(int device_index);
52 |
53 | // set gpu device by device handle, no owner transfer
54 | void set_vulkan_device(const VulkanDevice* vkdev);
55 |
56 | const VulkanDevice* vulkan_device() const;
57 | #endif // NCNN_VULKAN
58 |
59 | #if NCNN_STRING
60 | // register custom layer by layer type name
61 | // return 0 if success
62 | int register_custom_layer(const char* type, layer_creator_func creator);
63 | #endif // NCNN_STRING
64 | // register custom layer by layer type
65 | // return 0 if success
66 | int register_custom_layer(int index, layer_creator_func creator);
67 |
68 | #if NCNN_STRING
69 | int load_param(const DataReader& dr);
70 | #endif // NCNN_STRING
71 |
72 | int load_param_bin(const DataReader& dr);
73 |
74 | int load_model(const DataReader& dr);
75 |
76 | #if NCNN_STDIO
77 | #if NCNN_STRING
78 | // load network structure from plain param file
79 | // return 0 if success
80 | int load_param(FILE* fp);
81 | int load_param(const char* protopath);
82 | int load_param_mem(const char* mem);
83 | #endif // NCNN_STRING
84 | // load network structure from binary param file
85 | // return 0 if success
86 | int load_param_bin(FILE* fp);
87 | int load_param_bin(const char* protopath);
88 |
89 | // load network weight data from model file
90 | // return 0 if success
91 | int load_model(FILE* fp);
92 | int load_model(const char* modelpath);
93 | #endif // NCNN_STDIO
94 |
95 | // load network structure from external memory
96 | // memory pointer must be 32-bit aligned
97 | // return bytes consumed
98 | int load_param(const unsigned char* mem);
99 |
100 | // reference network weight data from external memory
101 | // weight data is not copied but referenced
102 | // so external memory should be retained when used
103 | // memory pointer must be 32-bit aligned
104 | // return bytes consumed
105 | int load_model(const unsigned char* mem);
106 |
107 | #if __ANDROID_API__ >= 9
108 | #if NCNN_STRING
109 | // convenient load network structure from android asset plain param file
110 | int load_param(AAsset* asset);
111 | int load_param(AAssetManager* mgr, const char* assetpath);
112 | #endif // NCNN_STRING
113 | // convenient load network structure from android asset binary param file
114 | int load_param_bin(AAsset* asset);
115 | int load_param_bin(AAssetManager* mgr, const char* assetpath);
116 |
117 | // convenient load network weight data from android asset model file
118 | int load_model(AAsset* asset);
119 | int load_model(AAssetManager* mgr, const char* assetpath);
120 | #endif // __ANDROID_API__ >= 9
121 |
122 | // unload network structure and weight data
123 | void clear();
124 |
125 | // construct an Extractor from network
126 | Extractor create_extractor() const;
127 |
128 | protected:
129 | // parse the structure of network
130 | // fuse int8 op dequantize and quantize by requantize
131 | int fuse_network();
132 |
133 | #if NCNN_VULKAN
134 |
135 | int upload_model();
136 |
137 | int create_pipeline();
138 |
139 | int destroy_pipeline();
140 |
141 | #endif // NCNN_VULKAN
142 |
143 | friend class Extractor;
144 | #if NCNN_STRING
145 | int find_blob_index_by_name(const char* name) const;
146 | int find_layer_index_by_name(const char* name) const;
147 | int custom_layer_to_index(const char* type);
148 | Layer* create_custom_layer(const char* type);
149 | #endif // NCNN_STRING
150 | Layer* create_custom_layer(int index);
151 | int forward_layer(int layer_index, std::vector& blob_mats, Option& opt) const;
152 |
153 | #if NCNN_VULKAN
154 | int forward_layer(int layer_index, std::vector& blob_mats, std::vector& blob_mats_gpu, VkCompute& cmd, Option& opt) const;
155 | #endif // NCNN_VULKAN
156 |
157 | protected:
158 | std::vector blobs;
159 | std::vector layers;
160 |
161 | std::vector custom_layer_registry;
162 |
163 | #if NCNN_VULKAN
164 | const VulkanDevice* vkdev;
165 |
166 | VkAllocator* weight_vkallocator;
167 | VkAllocator* weight_staging_vkallocator;
168 |
169 | ncnn::Layer* cast_float32_to_float16;
170 | ncnn::Layer* cast_float16_to_float32;
171 | ncnn::Layer* packing_pack1;
172 | ncnn::Layer* packing_pack4;
173 | ncnn::Layer* packing_pack8;
174 | #endif // NCNN_VULKAN
175 | };
176 |
177 | class Extractor
178 | {
179 | public:
180 | ~Extractor();
181 |
182 | // enable light mode
183 | // intermediate blob will be recycled when enabled
184 | // enabled by default
185 | void set_light_mode(bool enable);
186 |
187 | // set thread count for this extractor
188 | // this will overwrite the global setting
189 | // default count is system depended
190 | void set_num_threads(int num_threads);
191 |
192 | // set blob memory allocator
193 | void set_blob_allocator(Allocator* allocator);
194 |
195 | // set workspace memory allocator
196 | void set_workspace_allocator(Allocator* allocator);
197 |
198 | #if NCNN_VULKAN
199 | void set_vulkan_compute(bool enable);
200 |
201 | void set_blob_vkallocator(VkAllocator* allocator);
202 |
203 | void set_workspace_vkallocator(VkAllocator* allocator);
204 |
205 | void set_staging_vkallocator(VkAllocator* allocator);
206 | #endif // NCNN_VULKAN
207 |
208 | #if NCNN_STRING
209 | // set input by blob name
210 | // return 0 if success
211 | int input(const char* blob_name, const Mat& in);
212 |
213 | // get result by blob name
214 | // return 0 if success
215 | int extract(const char* blob_name, Mat& feat);
216 | #endif // NCNN_STRING
217 |
218 | // set input by blob index
219 | // return 0 if success
220 | int input(int blob_index, const Mat& in);
221 |
222 | // get result by blob index
223 | // return 0 if success
224 | int extract(int blob_index, Mat& feat);
225 |
226 | #if NCNN_VULKAN
227 | #if NCNN_STRING
228 | // set input by blob name
229 | // return 0 if success
230 | int input(const char* blob_name, const VkMat& in);
231 |
232 | // get result by blob name
233 | // return 0 if success
234 | int extract(const char* blob_name, VkMat& feat, VkCompute& cmd);
235 | #endif // NCNN_STRING
236 |
237 | // set input by blob index
238 | // return 0 if success
239 | int input(int blob_index, const VkMat& in);
240 |
241 | // get result by blob index
242 | // return 0 if success
243 | int extract(int blob_index, VkMat& feat, VkCompute& cmd);
244 | #endif // NCNN_VULKAN
245 |
246 | protected:
247 | friend Extractor Net::create_extractor() const;
248 | Extractor(const Net* net, size_t blob_count);
249 |
250 | private:
251 | const Net* net;
252 | std::vector blob_mats;
253 | Option opt;
254 |
255 | #if NCNN_VULKAN
256 | VkAllocator* local_blob_vkallocator;
257 | VkAllocator* local_staging_vkallocator;
258 |
259 | std::vector blob_mats_gpu;
260 | #endif // NCNN_VULKAN
261 | };
262 |
263 | } // namespace ncnn
264 |
265 | #endif // NCNN_NET_H
266 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/opencv.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_OPENCV_H
16 | #define NCNN_OPENCV_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_OPENCV
21 |
22 | #include
23 | #include
24 | #include "mat.h"
25 |
26 | #if defined(_MSC_VER) || defined(__GNUC__)
27 | #pragma push_macro("min")
28 | #pragma push_macro("max")
29 | #undef min
30 | #undef max
31 | #endif
32 |
33 | // minimal opencv style data structure implementation
34 | namespace cv
35 | {
36 |
37 | struct Size
38 | {
39 | Size() : width(0), height(0) {}
40 | Size(int _w, int _h) : width(_w), height(_h) {}
41 |
42 | int width;
43 | int height;
44 | };
45 |
46 | template
47 | struct Rect_
48 | {
49 | Rect_() : x(0), y(0), width(0), height(0) {}
50 | Rect_(_Tp _x, _Tp _y, _Tp _w, _Tp _h) : x(_x), y(_y), width(_w), height(_h) {}
51 |
52 | _Tp x;
53 | _Tp y;
54 | _Tp width;
55 | _Tp height;
56 |
57 | // area
58 | _Tp area() const
59 | {
60 | return width * height;
61 | }
62 | };
63 |
64 | template static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
65 | {
66 | _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
67 | a.width = std::min(a.x + a.width, b.x + b.width) - x1;
68 | a.height = std::min(a.y + a.height, b.y + b.height) - y1;
69 | a.x = x1; a.y = y1;
70 | if( a.width <= 0 || a.height <= 0 )
71 | a = Rect_<_Tp>();
72 | return a;
73 | }
74 |
75 | template static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
76 | {
77 | _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
78 | a.width = std::max(a.x + a.width, b.x + b.width) - x1;
79 | a.height = std::max(a.y + a.height, b.y + b.height) - y1;
80 | a.x = x1; a.y = y1;
81 | return a;
82 | }
83 |
84 | template static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
85 | {
86 | Rect_<_Tp> c = a;
87 | return c &= b;
88 | }
89 |
90 | template static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
91 | {
92 | Rect_<_Tp> c = a;
93 | return c |= b;
94 | }
95 |
96 | typedef Rect_ Rect;
97 | typedef Rect_ Rect2f;
98 |
99 | template
100 | struct Point_
101 | {
102 | Point_() : x(0), y(0) {}
103 | Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
104 |
105 | _Tp x;
106 | _Tp y;
107 | };
108 |
109 | typedef Point_ Point;
110 | typedef Point_ Point2f;
111 |
112 | #define CV_8UC1 1
113 | #define CV_8UC3 3
114 | #define CV_8UC4 4
115 | #define CV_32FC1 4
116 |
117 | struct Mat
118 | {
119 | Mat() : data(0), refcount(0), rows(0), cols(0), c(0) {}
120 |
121 | Mat(int _rows, int _cols, int flags) : data(0), refcount(0)
122 | {
123 | create(_rows, _cols, flags);
124 | }
125 |
126 | // copy
127 | Mat(const Mat& m) : data(m.data), refcount(m.refcount)
128 | {
129 | if (refcount)
130 | NCNN_XADD(refcount, 1);
131 |
132 | rows = m.rows;
133 | cols = m.cols;
134 | c = m.c;
135 | }
136 |
137 | Mat(int _rows, int _cols, int flags, void* _data) : data((unsigned char*)_data), refcount(0)
138 | {
139 | rows = _rows;
140 | cols = _cols;
141 | c = flags;
142 | }
143 |
144 | ~Mat()
145 | {
146 | release();
147 | }
148 |
149 | // assign
150 | Mat& operator=(const Mat& m)
151 | {
152 | if (this == &m)
153 | return *this;
154 |
155 | if (m.refcount)
156 | NCNN_XADD(m.refcount, 1);
157 |
158 | release();
159 |
160 | data = m.data;
161 | refcount = m.refcount;
162 |
163 | rows = m.rows;
164 | cols = m.cols;
165 | c = m.c;
166 |
167 | return *this;
168 | }
169 |
170 | void create(int _rows, int _cols, int flags)
171 | {
172 | release();
173 |
174 | rows = _rows;
175 | cols = _cols;
176 | c = flags;
177 |
178 | if (total() > 0)
179 | {
180 | // refcount address must be aligned, so we expand totalsize here
181 | size_t totalsize = (total() + 3) >> 2 << 2;
182 | data = (unsigned char*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount));
183 | refcount = (int*)(((unsigned char*)data) + totalsize);
184 | *refcount = 1;
185 | }
186 | }
187 |
188 | void release()
189 | {
190 | if (refcount && NCNN_XADD(refcount, -1) == 1)
191 | ncnn::fastFree(data);
192 |
193 | data = 0;
194 |
195 | rows = 0;
196 | cols = 0;
197 | c = 0;
198 |
199 | refcount = 0;
200 | }
201 |
202 | Mat clone() const
203 | {
204 | if (empty())
205 | return Mat();
206 |
207 | Mat m(rows, cols, c);
208 |
209 | if (total() > 0)
210 | {
211 | memcpy(m.data, data, total());
212 | }
213 |
214 | return m;
215 | }
216 |
217 | bool empty() const { return data == 0 || total() == 0; }
218 |
219 | int channels() const { return c; }
220 |
221 | size_t total() const { return cols * rows * c; }
222 |
223 | const unsigned char* ptr(int y) const { return data + y * cols * c; }
224 |
225 | unsigned char* ptr(int y) { return data + y * cols * c; }
226 |
227 | // roi
228 | Mat operator()( const Rect& roi ) const
229 | {
230 | if (empty())
231 | return Mat();
232 |
233 | Mat m(roi.height, roi.width, c);
234 |
235 | int sy = roi.y;
236 | for (int y = 0; y < roi.height; y++)
237 | {
238 | const unsigned char* sptr = ptr(sy) + roi.x * c;
239 | unsigned char* dptr = m.ptr(y);
240 | memcpy(dptr, sptr, roi.width * c);
241 | sy++;
242 | }
243 |
244 | return m;
245 | }
246 |
247 | unsigned char* data;
248 |
249 | // pointer to the reference counter;
250 | // when points to user-allocated data, the pointer is NULL
251 | int* refcount;
252 |
253 | int rows;
254 | int cols;
255 |
256 | int c;
257 |
258 | };
259 |
260 | #define CV_LOAD_IMAGE_GRAYSCALE 1
261 | #define CV_LOAD_IMAGE_COLOR 3
262 | Mat imread(const std::string& path, int flags);
263 | void imwrite(const std::string& path, const Mat& m);
264 |
265 | #if NCNN_PIXEL
266 | void resize(const Mat& src, Mat& dst, const Size& size, float sw = 0.f, float sh = 0.f, int flags = 0);
267 | #endif // NCNN_PIXEL
268 |
269 | } // namespace cv
270 |
271 | #if defined(_MSC_VER) || defined(__GNUC__)
272 | #pragma pop_macro("min")
273 | #pragma pop_macro("max")
274 | #endif
275 |
276 | #endif // NCNN_OPENCV
277 |
278 | #endif // NCNN_OPENCV_H
279 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/option.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_OPTION_H
16 | #define NCNN_OPTION_H
17 |
18 | #include "platform.h"
19 |
20 | namespace ncnn {
21 |
22 | #if NCNN_VULKAN
23 | class VkAllocator;
24 | #endif // NCNN_VULKAN
25 |
26 | class Allocator;
27 | class Option
28 | {
29 | public:
30 | // default option
31 | Option();
32 |
33 | public:
34 | // light mode
35 | // intermediate blob will be recycled when enabled
36 | // enabled by default
37 | bool lightmode;
38 |
39 | // thread count
40 | // default value is the one returned by get_cpu_count()
41 | int num_threads;
42 |
43 | // blob memory allocator
44 | Allocator* blob_allocator;
45 |
46 | // workspace memory allocator
47 | Allocator* workspace_allocator;
48 |
49 | #if NCNN_VULKAN
50 | // blob memory allocator
51 | VkAllocator* blob_vkallocator;
52 |
53 | // workspace memory allocator
54 | VkAllocator* workspace_vkallocator;
55 |
56 | // staging memory allocator
57 | VkAllocator* staging_vkallocator;
58 | #endif // NCNN_VULKAN
59 |
60 | // enable winograd convolution optimization
61 | // improve convolution 3x3 stride1 performace, may consume more memory
62 | // changes should be applied before loading network structure and weight
63 | // enabled by default
64 | bool use_winograd_convolution;
65 |
66 | // enable sgemm convolution optimization
67 | // improve convolution 1x1 stride1 performace, may consume more memory
68 | // changes should be applied before loading network structure and weight
69 | // enabled by default
70 | bool use_sgemm_convolution;
71 |
72 | // enable quantized int8 inference
73 | // use low-precision int8 path for quantized model
74 | // changes should be applied before loading network structure and weight
75 | // enabled by default
76 | bool use_int8_inference;
77 |
78 | // enable vulkan compute
79 | bool use_vulkan_compute;
80 |
81 | // enable options for gpu inference
82 | bool use_fp16_packed;
83 | bool use_fp16_storage;
84 | bool use_fp16_arithmetic;
85 | bool use_int8_storage;
86 | bool use_int8_arithmetic;
87 |
88 | //
89 | bool use_packing_layout;
90 |
91 | bool use_shader_pack8;
92 | };
93 |
94 | } // namespace ncnn
95 |
96 | #endif // NCNN_OPTION_H
97 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/paramdict.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PARAMDICT_H
16 | #define NCNN_PARAMDICT_H
17 |
18 | #include "mat.h"
19 |
20 | // at most 32 parameters
21 | #define NCNN_MAX_PARAM_COUNT 32
22 |
23 | namespace ncnn {
24 |
25 | class DataReader;
26 | class Net;
27 | class ParamDict
28 | {
29 | public:
30 | // empty
31 | ParamDict();
32 |
33 | // get int
34 | int get(int id, int def) const;
35 | // get float
36 | float get(int id, float def) const;
37 | // get array
38 | Mat get(int id, const Mat& def) const;
39 |
40 | // set int
41 | void set(int id, int i);
42 | // set float
43 | void set(int id, float f);
44 | // set array
45 | void set(int id, const Mat& v);
46 |
47 | protected:
48 | friend class Net;
49 |
50 | void clear();
51 |
52 | int load_param(const DataReader& dr);
53 | int load_param_bin(const DataReader& dr);
54 |
55 | protected:
56 | struct
57 | {
58 | // 0 = null
59 | // 1 = int/float
60 | // 2 = int
61 | // 3 = float
62 | // 4 = array of int/float
63 | // 5 = array of int
64 | // 6 = array of float
65 | int type;
66 | union { int i; float f; };
67 | Mat v;
68 | } params[NCNN_MAX_PARAM_COUNT];
69 | };
70 |
71 | } // namespace ncnn
72 |
73 | #endif // NCNN_PARAMDICT_H
74 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/pipeline.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PIPELINE_H
16 | #define NCNN_PIPELINE_H
17 |
18 | #include "platform.h"
19 | #include "mat.h"
20 | #if NCNN_VULKAN
21 | #include
22 | #include "gpu.h"
23 | #endif // NCNN_VULKAN
24 |
25 | namespace ncnn {
26 |
27 | #if NCNN_VULKAN
28 | class Option;
29 | class Pipeline
30 | {
31 | public:
32 | Pipeline(const VulkanDevice* vkdev);
33 | virtual ~Pipeline();
34 |
35 | public:
36 | void set_optimal_local_size_xyz(int w = 4, int h = 4, int c = 4);
37 | void set_optimal_local_size_xyz(const Mat& local_size_xyz);
38 | void set_local_size_xyz(int w, int h, int c);
39 |
40 | int create(const uint32_t* spv_data, size_t spv_data_size, const char* entry_name,
41 | const std::vector& specializations, int binding_count, int push_constant_count);
42 | int create(VkShaderModule shader_module, const char* entry_name,
43 | const std::vector& specializations, int binding_count, int push_constant_count);
44 | int create(const char* name, const Option& opt, const std::vector& specializations,
45 | int binding_count, int push_constant_count);
46 | void destroy();
47 |
48 | protected:
49 | int create_descriptorset_layout(int binding_count);
50 | int create_pipeline_layout(int push_constant_count);
51 | int create_pipeline(VkShaderModule shader_module, const char* entry_name, const std::vector& specializations);
52 | int create_descriptor_update_template(int binding_count);
53 |
54 | public:
55 | const VulkanDevice* vkdev;
56 |
57 | // local shader module
58 | VkShaderModule local_shader_module;
59 |
60 | VkDescriptorSetLayout descriptorset_layout;
61 | VkPipelineLayout pipeline_layout;
62 |
63 | // op forward TODO use pipeline cache ?
64 | VkPipeline pipeline;
65 |
66 | VkDescriptorUpdateTemplateKHR descriptor_update_template;
67 |
68 | uint32_t local_size_x;
69 | uint32_t local_size_y;
70 | uint32_t local_size_z;
71 | };
72 |
73 | #if __ANDROID_API__ >= 26
74 | class VkCompute;
75 | class ImportAndroidHardwareBufferPipeline : private Pipeline
76 | {
77 | public:
78 | ImportAndroidHardwareBufferPipeline(const VulkanDevice* vkdev);
79 | ~ImportAndroidHardwareBufferPipeline();
80 |
81 | int create(AHardwareBuffer* hb, int type_to, int rotate_from, const Option& opt);
82 | void destroy();
83 |
84 | friend class VkCompute;
85 |
86 | protected:
87 | int create_sampler(AHardwareBuffer* hb);
88 | int create_descriptorset_layout();
89 | int create_descriptor_update_template();
90 |
91 | public:
92 | int w;
93 | int h;
94 | int outw;
95 | int outh;
96 | int outc;
97 | size_t out_elemsize;
98 | int out_elempack;
99 | int type_to;
100 | int rotate_from;
101 |
102 | VkSamplerYcbcrConversionKHR samplerYcbcrConversion;
103 | VkSampler sampler;
104 | };
105 | #endif // __ANDROID_API__ >= 26
106 | #endif // NCNN_VULKAN
107 |
108 | } // namespace ncnn
109 |
110 | #endif // NCNN_PIPELINE_H
111 |
--------------------------------------------------------------------------------
/app/src/main/cpp/ncnn-android-lib/include/ncnn/platform.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PLATFORM_H
16 | #define NCNN_PLATFORM_H
17 |
18 | #define NCNN_STDIO 1
19 | #define NCNN_STRING 1
20 | #define NCNN_OPENCV 0
21 | #define NCNN_BENCHMARK 0
22 | #define NCNN_PIXEL 1
23 | #define NCNN_PIXEL_ROTATE 1
24 | #define NCNN_VULKAN 0
25 | #define NCNN_REQUANT 0
26 | #define NCNN_AVX2 0
27 |
28 | #ifdef _WIN32
29 | #define WIN32_LEAN_AND_MEAN
30 | #include
31 | #include
32 | #else
33 | #include
34 | #endif
35 |
36 | #if __ANDROID_API__ >= 26
37 | #define VK_USE_PLATFORM_ANDROID_KHR
38 | #endif // __ANDROID_API__ >= 26
39 |
40 | namespace ncnn {
41 |
42 | #ifdef _WIN32
43 | class Mutex
44 | {
45 | public:
46 | Mutex() { InitializeSRWLock(&srwlock); }
47 | ~Mutex() {}
48 | void lock() { AcquireSRWLockExclusive(&srwlock); }
49 | void unlock() { ReleaseSRWLockExclusive(&srwlock); }
50 | private:
51 | friend class ConditionVariable;
52 | // NOTE SRWLock is available from windows vista
53 | SRWLOCK srwlock;
54 | };
55 | #else // _WIN32
56 | class Mutex
57 | {
58 | public:
59 | Mutex() { pthread_mutex_init(&mutex, 0); }
60 | ~Mutex() { pthread_mutex_destroy(&mutex); }
61 | void lock() { pthread_mutex_lock(&mutex); }
62 | void unlock() { pthread_mutex_unlock(&mutex); }
63 | private:
64 | friend class ConditionVariable;
65 | pthread_mutex_t mutex;
66 | };
67 | #endif // _WIN32
68 |
69 | class MutexLockGuard
70 | {
71 | public:
72 | MutexLockGuard(Mutex& _mutex) : mutex(_mutex) { mutex.lock(); }
73 | ~MutexLockGuard() { mutex.unlock(); }
74 | private:
75 | Mutex& mutex;
76 | };
77 |
78 | #if _WIN32
79 | class ConditionVariable
80 | {
81 | public:
82 | ConditionVariable() { InitializeConditionVariable(&condvar); }
83 | ~ConditionVariable() {}
84 | void wait(Mutex& mutex) { SleepConditionVariableSRW(&condvar, &mutex.srwlock, INFINITE, 0); }
85 | void broadcast() { WakeAllConditionVariable(&condvar); }
86 | void signal() { WakeConditionVariable(&condvar); }
87 | private:
88 | CONDITION_VARIABLE condvar;
89 | };
90 | #else // _WIN32
91 | class ConditionVariable
92 | {
93 | public:
94 | ConditionVariable() { pthread_cond_init(&cond, 0); }
95 | ~ConditionVariable() { pthread_cond_destroy(&cond); }
96 | void wait(Mutex& mutex) { pthread_cond_wait(&cond, &mutex.mutex); }
97 | void broadcast() { pthread_cond_broadcast(&cond); }
98 | void signal() { pthread_cond_signal(&cond); }
99 | private:
100 | pthread_cond_t cond;
101 | };
102 | #endif // _WIN32
103 |
104 | #if _WIN32
105 | static unsigned __stdcall start_wrapper(void* args);
106 | class Thread
107 | {
108 | public:
109 | Thread(void* (*start)(void*), void* args = 0) { _start = start; _args = args; handle = (HANDLE)_beginthreadex(0, 0, start_wrapper, this, 0, 0); }
110 | ~Thread() {}
111 | void join() { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); }
112 | private:
113 | friend unsigned __stdcall start_wrapper(void* args)
114 | {
115 | Thread* t = (Thread*)args;
116 | t->_start(t->_args);
117 | return 0;
118 | }
119 | HANDLE handle;
120 | void* (*_start)(void*);
121 | void* _args;
122 | };
123 |
124 | #else // _WIN32
125 | class Thread
126 | {
127 | public:
128 | Thread(void* (*start)(void*), void* args = 0) { pthread_create(&t, 0, start, args); }
129 | ~Thread() {}
130 | void join() { pthread_join(t, 0); }
131 | private:
132 | pthread_t t;
133 | };
134 | #endif // _WIN32
135 |
136 | } // namespace ncnn
137 |
138 | #endif // NCNN_PLATFORM_H
139 |
--------------------------------------------------------------------------------
/app/src/main/java/com/chenty/testncnn/AutoFitSurfaceView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.chenty.testncnn;
18 |
19 | import android.content.Context;
20 | import android.graphics.Bitmap;
21 | import android.graphics.Canvas;
22 | import android.graphics.Color;
23 | import android.graphics.Matrix;
24 | import android.graphics.Paint;
25 | import android.graphics.Rect;
26 | import android.nfc.Tag;
27 | import android.renderscript.Allocation;
28 | import android.renderscript.Element;
29 | import android.renderscript.RenderScript;
30 | import android.renderscript.ScriptIntrinsicYuvToRGB;
31 | import android.renderscript.Type;
32 | import android.util.AttributeSet;
33 | import android.util.Log;
34 | import android.view.SurfaceHolder;
35 | import android.view.SurfaceView;
36 | import android.view.TextureView;
37 |
38 | /**
39 | * A {@link TextureView} that can be adjusted to a specified aspect ratio.
40 | */
41 | public class AutoFitSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
42 | private static final String TAG = "AutoFitSurfaceView";
43 |
44 | private SurfaceHolder mHolder;
45 | private Canvas mCanvas;
46 | private Paint paint;
47 |
48 | private RenderScript rs;
49 | private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
50 | private Type.Builder yuvType, rgbaType;
51 | private Allocation in, out;
52 |
53 | private float mWidth = 0;
54 | private float mHeight = 0;
55 |
56 | public AutoFitSurfaceView(Context context) {
57 | this(context, null);
58 | }
59 |
60 | public AutoFitSurfaceView(Context context, AttributeSet attrs) {
61 | this(context, attrs, 0);
62 | }
63 |
64 | public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyle) {
65 | super(context, attrs, defStyle);
66 | Log.i(TAG, "AutoFitSurfaceView struct");
67 | mHolder = getHolder();
68 | mHolder.addCallback(this);
69 | paint = new Paint();
70 | paint.setColor(Color.WHITE);
71 | setFocusable(true);
72 | rs = RenderScript.create(context);
73 | yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
74 | }
75 |
76 | public void setAspectRatio(int width, int height) {
77 | if (width < 0 || height < 0) {
78 | throw new IllegalArgumentException("Size cannot be negative.");
79 | }
80 | Log.i(TAG, "setAspectRatio " + width + "X" + height);
81 | requestLayout();
82 | }
83 |
84 | @Override
85 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
86 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
87 | }
88 |
89 | @Override
90 | public void surfaceCreated(SurfaceHolder holder) {
91 | Log.i(TAG, "surfaceCreated ");
92 | }
93 |
94 | @Override
95 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
96 | Log.i(TAG, "surfaceChanged " + width + "X" + height);
97 | mWidth = width;
98 | mHeight = height;
99 |
100 | }
101 |
102 | @Override
103 | public void surfaceDestroyed(SurfaceHolder holder) {
104 | Log.i(TAG, "surfaceDestroyed ");
105 | }
106 |
107 | private void DrawRect(Rect rect, int color, String string)
108 | {
109 | paint.setColor(color) ;
110 | paint.setStyle(Paint.Style.STROKE);
111 | paint.setTextSize(24f);
112 | paint.setStrokeWidth(3.6f);
113 |
114 | mCanvas.drawRect(rect, paint);
115 | paint.setStyle(Paint.Style.FILL);
116 | mCanvas.drawText(string, rect.left + 4, rect.top + 28, paint);
117 | }
118 |
119 | public void DrawDetectFace(float[] data, int width, int height, int rolatedeg) {
120 | int i,objcnt;
121 | int t,x,y,xe,ye;
122 | int prob;
123 | int gap = 20;
124 | objcnt = data.length/gap;
125 | for (i = 0 ; i < objcnt ; i++)
126 | {
127 | x = (int) (data[i*gap + 0] * (width));
128 | y = (int) (data[i*gap + 1] * (height));
129 | xe = (int) (data[i*gap + 2] * (width));
130 | ye = (int) (data[i*gap + 3] * (height));
131 | Log.d(TAG, "obj" + x + " " + y + " " + xe + " " + ye);
132 |
133 | if(x < 0) {
134 | x = 0;
135 | }
136 | if(y < 0) {
137 | y = 0;
138 | }
139 | if(xe > width) {
140 | xe = width;
141 | }
142 | if(ye > height) {
143 | ye = height;
144 | }
145 | //
146 | DrawRect(new Rect(x,y,xe,ye),Color.RED, "face");
147 |
148 | }
149 | }
150 |
151 | public void Draw(Bitmap mBitmap, float[] result, int rolatedeg) {
152 | {
153 |
154 | if (mBitmap == null) {
155 | Log.d(TAG, "data data is to bitmap error");
156 | return;
157 | }
158 |
159 | try {
160 | mCanvas = mHolder.lockCanvas();
161 | mWidth = mCanvas.getWidth();
162 | mHeight = mCanvas.getHeight();
163 | Log.d(TAG, "canvas size is " + mWidth+ " " + mHeight);
164 | float scaleWidth = mWidth/mBitmap.getWidth();
165 | float scaleHeight = mHeight/mBitmap.getHeight();
166 | Log.d(TAG, "scale size is " + scaleWidth+ " " + scaleHeight);
167 |
168 |
169 | Matrix matrix = new Matrix();
170 | matrix.setScale(scaleWidth, scaleHeight);
171 | mCanvas.drawBitmap(mBitmap, matrix, paint);
172 | if(result !=null) {
173 | DrawDetectFace(result, (int) mWidth, (int) mHeight, rolatedeg);
174 | }
175 | }catch (Exception e){
176 | Log.d(TAG, "e="+e);
177 | mHolder.unlockCanvasAndPost(mCanvas);
178 | return;
179 | }
180 | mHolder.unlockCanvasAndPost(mCanvas);
181 | }
182 | }
183 |
184 | public Bitmap yuvToBitmap(byte[] yuv, int width, int height){
185 | if (yuvType == null){
186 | yuvType = new Type.Builder(rs, Element.U8(rs)).setX(yuv.length);
187 | in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
188 | rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
189 | out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
190 | }
191 | in.copyFrom(yuv);
192 | yuvToRgbIntrinsic.setInput(in);
193 | yuvToRgbIntrinsic.forEach(out);
194 | Bitmap rgbout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
195 | out.copyTo(rgbout);
196 | return rgbout;
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/app/src/main/java/com/chenty/testncnn/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.chenty.testncnn;
2 |
3 | /**
4 | * @ClassName: MainActivity
5 | * @Description: MainActiviry to start all other things
6 | *
7 | * @author chenty
8 | * @version V1.0
9 | * @Date 2019.08.16
10 | */
11 |
12 | import android.content.pm.ActivityInfo;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.os.Bundle;
15 | import android.util.Log;
16 | import android.view.WindowManager;
17 |
18 | public class MainActivity extends AppCompatActivity {
19 |
20 | private static final String TAG = "MainActivity";
21 |
22 | @Override
23 | protected void onDestroy() {
24 | super.onDestroy();
25 | }
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | if(getRequestedOrientation()!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
31 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
32 | }
33 |
34 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
35 |
36 | setContentView(R.layout.activity_main);
37 | Log.i(TAG,"onCreate");
38 |
39 | if (null == savedInstanceState) {
40 | getSupportFragmentManager().beginTransaction()
41 | .replace(R.id.container, CameraNcnnFragment.newInstance())
42 | .commit();
43 | }
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/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_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/drawable/ic_action_info.png
--------------------------------------------------------------------------------
/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 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
21 |
22 |
28 |
29 |
30 |
38 |
39 |
43 |
44 |
50 |
51 |
60 |
61 |
71 |
72 |
73 |
79 |
80 |
85 |
86 |
91 |
92 |
97 |
98 |
103 |
104 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/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/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/fragment.glsl:
--------------------------------------------------------------------------------
1 | #extension GL_OES_EGL_image_external : require
2 |
3 | precision mediump float;
4 |
5 | varying mediump vec2 textureCoordinate;
6 |
7 | uniform samplerExternalOES inputImageTexture;
8 |
9 | void main() {
10 | gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/raw/vertex.glsl:
--------------------------------------------------------------------------------
1 | attribute vec4 position;
2 | attribute vec4 inputTextureCoordinate;
3 |
4 | varying vec2 textureCoordinate;
5 |
6 | uniform mat4 textureTransform;
7 |
8 | void main() {
9 | textureCoordinate = (textureTransform * inputTextureCoordinate).xy;
10 | gl_Position = position;
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ncnn人脸识别
4 | 这台设备太久不支持CameraAPI
5 | 信息
6 |
7 |
16 | 这个demo需要使用摄像头权限,如果出现黑屏请重起一次
17 | 目标
18 | 当前
19 | 相似度
20 | 未发现合理人脸请再试一次
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #FF000000
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | NcnnInsightFace
3 | Info
4 | This sample needs camera permission. please restart it
5 | This device doesn\'t support Camera2 API.
6 |
7 |
8 |
16 |
17 | TargetFace
18 | CaptureFace
19 | face is not detect please try again
20 | Equal
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/chenty/testncnn/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.chenty.testncnn;
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() {
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 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.4.1'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Aug 07 16:29:11 CST 2019
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-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/imgs/Screenshot_2019-08-16-12-07-00-002_com.chenty.tes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/imgs/Screenshot_2019-08-16-12-07-00-002_com.chenty.tes.png
--------------------------------------------------------------------------------
/imgs/Screenshot_2019-08-16-13-54-38-377_com.chenty.tes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/imgs/Screenshot_2019-08-16-13-54-38-377_com.chenty.tes.png
--------------------------------------------------------------------------------
/imgs/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/e0de5884d9cb4bc3e850ada16e15e82fced6082c/imgs/sample.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------