├── .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 | ![image](https://github.com/chentyjpm/InsightFaceRecognition_Demo_AndroidNCNN/blob/master/imgs/sample.gif) 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 | ![](http://www.chenty.com/wp-content/uploads/2019/08/QQ图片20190816150707.png) 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 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 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 | --------------------------------------------------------------------------------