Repository: FeiGeChuanShu/ncnn_Android_face Branch: main Commit: 83ecdf198aeb Files: 69 Total size: 324.5 KB Directory structure: gitextract_pop_0yey/ ├── README.md ├── facemesh.onnx ├── ncnn-android-scrfd-master/ │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ ├── facemesh-op.param │ │ │ ├── facemesh-op2.param │ │ │ ├── faceseg-op.param │ │ │ ├── scrfd_1g-opt2.param │ │ │ └── scrfd_500m-opt2.param │ │ ├── java/ │ │ │ └── com/ │ │ │ └── tencent/ │ │ │ └── scrfdncnn/ │ │ │ ├── MainActivity.java │ │ │ └── SCRFDNcnn.java │ │ ├── jni/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ndkcamera.cpp │ │ │ ├── ndkcamera.h │ │ │ ├── scrfd.cpp │ │ │ ├── scrfd.h │ │ │ └── scrfdncnn.cpp │ │ └── res/ │ │ ├── layout/ │ │ │ └── main.xml │ │ └── values/ │ │ └── strings.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── local.properties │ └── settings.gradle ├── ncnn-android-yolov5_face/ │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ ├── yolov5n-0.5.param │ │ │ └── yolov5n.param │ │ ├── java/ │ │ │ └── com/ │ │ │ └── tencent/ │ │ │ └── ncnnyoloface/ │ │ │ ├── MainActivity.java │ │ │ └── NcnnYoloFace.java │ │ ├── jni/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ndkcamera.cpp │ │ │ ├── ndkcamera.h │ │ │ ├── yoloface.cpp │ │ │ ├── yoloface.h │ │ │ └── yolofacencnn.cpp │ │ └── res/ │ │ ├── layout/ │ │ │ └── main.xml │ │ └── values/ │ │ └── strings.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── local.properties │ └── settings.gradle └── ncnn-android-yolov7_face/ ├── app/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ ├── yolov7-lite-e.param │ │ └── yolov7-tiny.param │ ├── java/ │ │ └── com/ │ │ └── tencent/ │ │ └── ncnnyoloface/ │ │ ├── MainActivity.java │ │ └── NcnnYoloFace.java │ ├── jni/ │ │ ├── CMakeLists.txt │ │ ├── ndkcamera.cpp │ │ ├── ndkcamera.h │ │ ├── yoloface.cpp │ │ ├── yoloface.h │ │ └── yolofacencnn.cpp │ └── res/ │ ├── layout/ │ │ └── main.xml │ └── values/ │ └── strings.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # ncnn_Android_face Face detect and segmentation, facemesh by ncnn ## model support: 1.scrfd 2.yolov5-face 3.yolov7-face ## A new mediapipe-blazeface demo in this place [new demo](https://github.com/FeiGeChuanShu/ncnn_Android_blazeface) ![image](https://github.com/FeiGeChuanShu/ncnn_Android_face/blob/main/yolov7-tiny-face.png)![image](https://github.com/FeiGeChuanShu/ncnn_Android_face/blob/main/result.gif)![image](https://github.com/FeiGeChuanShu/ncnn_Android_face/blob/main/facemesh.gif)![image](https://github.com/FeiGeChuanShu/ncnn_Android_face/blob/main/yolov5-face.gif) ## Reference: https://github.com/nihui/ncnn-android-scrfd https://github.com/deepcam-cn/yolov5-face https://github.com/Tencent/ncnn https://github.com/thepowerfuldeez/facemesh.pytorch https://github.com/derronqi/yolov7-face ================================================ FILE: ncnn-android-scrfd-master/README.md ================================================ # ncnn-android-scrfd The SCRFD face detection This is a sample ncnn android project, it depends on ncnn library and opencv https://github.com/Tencent/ncnn https://github.com/nihui/opencv-mobile ## android apk file download https://github.com/nihui/ncnn-android-scrfd/releases/download/v1/com.tencent.scrfdncnn-release.apk ## how to build and run ### step1 https://github.com/Tencent/ncnn/releases * Download ncnn-YYYYMMDD-android-vulkan.zip or build ncnn for android yourself * Extract ncnn-YYYYMMDD-android-vulkan.zip into **app/src/main/jni** and change the **ncnn_DIR** path to yours in **app/src/main/jni/CMakeLists.txt** ### step2 https://github.com/nihui/opencv-mobile * Download opencv-mobile-XYZ-android.zip * Extract opencv-mobile-XYZ-android.zip into **app/src/main/jni** and change the **OpenCV_DIR** path to yours in **app/src/main/jni/CMakeLists.txt** ### step3 * Open this project with Android Studio, build it and enjoy! ## some notes * Android ndk camera is used for best efficiency * Crash may happen on very old devices for lacking HAL3 camera interface * All models are manually modified to accept dynamic input shape * Most small models run slower on GPU than on CPU, this is common * FPS may be lower in dark environment because of longer camera exposure time ## screenshot ![](screenshot.jpg) ================================================ FILE: ncnn-android-scrfd-master/app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "29.0.2" defaultConfig { applicationId "com.tencent.scrfdncnn" archivesBaseName = "$applicationId" minSdkVersion 24 } externalNativeBuild { cmake { version "3.10.2" path file('src/main/jni/CMakeLists.txt') } } dependencies { implementation 'com.android.support:support-v4:24.0.0' } } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: ncnn-android-scrfd-master/app/src/main/assets/facemesh-op.param ================================================ 7767517 123 144 Input input.1 0 1 input.1 MemoryData 200 0 1 200 0=1 MemoryData 264 0 1 264 0=1 MemoryData 328 0 1 328 0=1 Padding Pad_13 1 1 input.1 136 0=1 1=0 2=1 3=0 4=2 5=0.000000e+00 7=0 8=0 Convolution Conv_17 1 1 136 140 0=16 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=0 16=0 5=1 6=432 PReLU PRelu_18 1 1 140 142 0=16 Split splitncnn_0 1 2 142 142_splitncnn_0 142_splitncnn_1 ConvolutionDepthWise Conv_19 1 1 142_splitncnn_1 143 0=16 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=144 7=16 Convolution Conv_20 1 1 143 144 0=16 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=256 BinaryOp Add_21 2 1 144 142_splitncnn_0 145 0=0 PReLU PRelu_22 1 1 145 147 0=16 Split splitncnn_1 1 2 147 147_splitncnn_0 147_splitncnn_1 ConvolutionDepthWise Conv_23 1 1 147_splitncnn_1 148 0=16 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=144 7=16 Convolution Conv_24 1 1 148 149 0=16 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=256 BinaryOp Add_25 2 1 149 147_splitncnn_0 150 0=0 PReLU PRelu_26 1 1 150 152 0=16 Split splitncnn_2 1 2 152 152_splitncnn_0 152_splitncnn_1 Pooling MaxPool_42 1 1 152_splitncnn_1 177 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 Padding Pad_57 2 1 177 200 201 0=0 1=0 2=0 3=0 4=0 5=0.000000e+00 7=0 8=16 ConvolutionDepthWise Conv_58 1 1 152_splitncnn_0 202 0=16 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=144 7=16 Convolution Conv_59 1 1 202 203 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=512 BinaryOp Add_60 2 1 203 201 204 0=0 PReLU PRelu_61 1 1 204 206 0=32 Split splitncnn_3 1 2 206 206_splitncnn_0 206_splitncnn_1 ConvolutionDepthWise Conv_62 1 1 206_splitncnn_1 207 0=32 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=288 7=32 Convolution Conv_63 1 1 207 208 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=1024 BinaryOp Add_64 2 1 208 206_splitncnn_0 209 0=0 PReLU PRelu_65 1 1 209 211 0=32 Split splitncnn_4 1 2 211 211_splitncnn_0 211_splitncnn_1 ConvolutionDepthWise Conv_66 1 1 211_splitncnn_1 212 0=32 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=288 7=32 Convolution Conv_67 1 1 212 213 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=1024 BinaryOp Add_68 2 1 213 211_splitncnn_0 214 0=0 PReLU PRelu_69 1 1 214 216 0=32 Split splitncnn_5 1 2 216 216_splitncnn_0 216_splitncnn_1 Pooling MaxPool_85 1 1 216_splitncnn_1 241 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 Padding Pad_100 2 1 241 264 265 0=0 1=0 2=0 3=0 4=0 5=0.000000e+00 7=0 8=32 ConvolutionDepthWise Conv_101 1 1 216_splitncnn_0 266 0=32 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=288 7=32 Convolution Conv_102 1 1 266 267 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=2048 BinaryOp Add_103 2 1 267 265 268 0=0 PReLU PRelu_104 1 1 268 270 0=64 Split splitncnn_6 1 2 270 270_splitncnn_0 270_splitncnn_1 ConvolutionDepthWise Conv_105 1 1 270_splitncnn_1 271 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=576 7=64 Convolution Conv_106 1 1 271 272 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096 BinaryOp Add_107 2 1 272 270_splitncnn_0 273 0=0 PReLU PRelu_108 1 1 273 275 0=64 Split splitncnn_7 1 2 275 275_splitncnn_0 275_splitncnn_1 ConvolutionDepthWise Conv_109 1 1 275_splitncnn_1 276 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=576 7=64 Convolution Conv_110 1 1 276 277 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096 BinaryOp Add_111 2 1 277 275_splitncnn_0 278 0=0 PReLU PRelu_112 1 1 278 280 0=64 Split splitncnn_8 1 2 280 280_splitncnn_0 280_splitncnn_1 Pooling MaxPool_128 1 1 280_splitncnn_1 305 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 Padding Pad_143 2 1 305 328 329 0=0 1=0 2=0 3=0 4=0 5=0.000000e+00 7=0 8=64 ConvolutionDepthWise Conv_144 1 1 280_splitncnn_0 330 0=64 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=576 7=64 Convolution Conv_145 1 1 330 331 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=8192 BinaryOp Add_146 2 1 331 329 332 0=0 PReLU PRelu_147 1 1 332 334 0=128 Split splitncnn_9 1 2 334 334_splitncnn_0 334_splitncnn_1 ConvolutionDepthWise Conv_148 1 1 334_splitncnn_1 335 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_149 1 1 335 336 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_150 2 1 336 334_splitncnn_0 337 0=0 PReLU PRelu_151 1 1 337 339 0=128 Split splitncnn_10 1 2 339 339_splitncnn_0 339_splitncnn_1 ConvolutionDepthWise Conv_152 1 1 339_splitncnn_1 340 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_153 1 1 340 341 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_154 2 1 341 339_splitncnn_0 342 0=0 PReLU PRelu_155 1 1 342 344 0=128 Split splitncnn_11 1 2 344 344_splitncnn_0 344_splitncnn_1 Pooling MaxPool_171 1 1 344_splitncnn_1 369 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 ConvolutionDepthWise Conv_172 1 1 344_splitncnn_0 370 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=1152 7=128 Convolution Conv_173 1 1 370 371 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_174 2 1 371 369 372 0=0 PReLU PRelu_175 1 1 372 374 0=128 Split splitncnn_12 1 2 374 374_splitncnn_0 374_splitncnn_1 ConvolutionDepthWise Conv_176 1 1 374_splitncnn_1 375 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_177 1 1 375 376 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_178 2 1 376 374_splitncnn_0 377 0=0 PReLU PRelu_179 1 1 377 379 0=128 Split splitncnn_13 1 2 379 379_splitncnn_0 379_splitncnn_1 ConvolutionDepthWise Conv_180 1 1 379_splitncnn_1 380 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_181 1 1 380 381 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_182 2 1 381 379_splitncnn_0 382 0=0 PReLU PRelu_183 1 1 382 384 0=128 Split splitncnn_14 1 4 384 384_splitncnn_0 384_splitncnn_1 384_splitncnn_2 384_splitncnn_3 Pooling MaxPool_199 1 1 384_splitncnn_3 409 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 ConvolutionDepthWise Conv_200 1 1 384_splitncnn_2 410 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=1152 7=128 Convolution Conv_201 1 1 410 411 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_202 2 1 411 409 412 0=0 PReLU PRelu_203 1 1 412 414 0=128 Convolution Conv_204 1 1 414 415 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096 PReLU PRelu_205 1 1 415 417 0=32 Split splitncnn_15 1 2 417 417_splitncnn_0 417_splitncnn_1 ConvolutionDepthWise Conv_206 1 1 417_splitncnn_1 418 0=32 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=288 7=32 Convolution Conv_207 1 1 418 419 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=1024 BinaryOp Add_208 2 1 419 417_splitncnn_0 420 0=0 PReLU PRelu_209 1 1 420 422 0=32 Convolution Conv_210 1 1 422 423 0=1 1=3 11=3 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=288 Reshape Reshape_213 1 1 423 428 0=-1 Pooling MaxPool_229 1 1 384_splitncnn_1 453 0=0 1=2 11=2 2=2 12=2 3=0 13=0 14=0 15=0 5=1 ConvolutionDepthWise Conv_230 1 1 384_splitncnn_0 454 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=2 16=2 5=1 6=1152 7=128 Convolution Conv_231 1 1 454 455 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_232 2 1 455 453 456 0=0 PReLU PRelu_233 1 1 456 458 0=128 Split splitncnn_16 1 2 458 458_splitncnn_0 458_splitncnn_1 ConvolutionDepthWise Conv_234 1 1 458_splitncnn_1 459 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_235 1 1 459 460 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_236 2 1 460 458_splitncnn_0 461 0=0 PReLU PRelu_237 1 1 461 463 0=128 Split splitncnn_17 1 2 463 463_splitncnn_0 463_splitncnn_1 ConvolutionDepthWise Conv_238 1 1 463_splitncnn_1 464 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128 Convolution Conv_239 1 1 464 465 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384 BinaryOp Add_240 2 1 465 463_splitncnn_0 466 0=0 PReLU PRelu_241 1 1 466 468 0=128 Convolution Conv_242 1 1 468 469 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096 PReLU PRelu_243 1 1 469 471 0=32 Split splitncnn_18 1 2 471 471_splitncnn_0 471_splitncnn_1 ConvolutionDepthWise Conv_244 1 1 471_splitncnn_1 472 0=32 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=288 7=32 Convolution Conv_245 1 1 472 473 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=1024 BinaryOp Add_246 2 1 473 471_splitncnn_0 474 0=0 PReLU PRelu_247 1 1 474 476 0=32 Convolution Conv_248 1 1 476 477 0=1404 1=3 11=3 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=404352 Reshape Reshape_251 1 1 477 482 0=-1 ================================================ FILE: ncnn-android-scrfd-master/app/src/main/assets/facemesh-op2.param ================================================ 7767517 166 206 Input input 0 1 input Convolution 550 1 1 input 552 0=16 1=3 3=2 4=1 5=1 6=432 9=1 Split splitncnn_0 1 2 552 552_splitncnn_0 552_splitncnn_1 Convolution 553 1 1 552_splitncnn_1 555 0=8 1=1 5=1 6=128 9=1 Split splitncnn_1 1 2 555 555_splitncnn_0 555_splitncnn_1 ConvolutionDepthWise 556 1 1 555_splitncnn_1 558 0=8 1=3 4=1 5=1 6=72 7=8 9=1 Concat 559 2 1 555_splitncnn_0 558 559 Convolution 560 1 1 559 561 0=8 1=1 5=1 6=128 Split splitncnn_2 1 2 561 561_splitncnn_0 561_splitncnn_1 ConvolutionDepthWise 562 1 1 561_splitncnn_1 563 0=8 1=3 4=1 5=1 6=72 7=8 Concat 564 2 1 561_splitncnn_0 563 564 BinaryOp 565 2 1 564 552_splitncnn_0 565 Split splitncnn_3 1 2 565 565_splitncnn_0 565_splitncnn_1 Convolution 566 1 1 565_splitncnn_1 568 0=24 1=1 5=1 6=384 9=1 Split splitncnn_4 1 2 568 568_splitncnn_0 568_splitncnn_1 ConvolutionDepthWise 569 1 1 568_splitncnn_1 571 0=24 1=3 4=1 5=1 6=216 7=24 9=1 Concat 572 2 1 568_splitncnn_0 571 572 ConvolutionDepthWise 573 1 1 572 574 0=48 1=3 3=2 4=1 5=1 6=432 7=48 Convolution 575 1 1 574 576 0=12 1=1 5=1 6=576 Split splitncnn_5 1 2 576 576_splitncnn_0 576_splitncnn_1 ConvolutionDepthWise 577 1 1 576_splitncnn_1 578 0=12 1=3 4=1 5=1 6=108 7=12 Concat 579 2 1 576_splitncnn_0 578 579 ConvolutionDepthWise 580 1 1 565_splitncnn_0 581 0=16 1=3 3=2 4=1 5=1 6=144 7=16 Convolution 582 1 1 581 583 0=24 1=1 5=1 6=384 BinaryOp 584 2 1 579 583 584 Split splitncnn_6 1 2 584 584_splitncnn_0 584_splitncnn_1 Convolution 585 1 1 584_splitncnn_1 587 0=36 1=1 5=1 6=864 9=1 Split splitncnn_7 1 2 587 587_splitncnn_0 587_splitncnn_1 ConvolutionDepthWise 588 1 1 587_splitncnn_1 590 0=36 1=3 4=1 5=1 6=324 7=36 9=1 Concat 591 2 1 587_splitncnn_0 590 591 Convolution 592 1 1 591 593 0=12 1=1 5=1 6=864 Split splitncnn_8 1 2 593 593_splitncnn_0 593_splitncnn_1 ConvolutionDepthWise 594 1 1 593_splitncnn_1 595 0=12 1=3 4=1 5=1 6=108 7=12 Concat 596 2 1 593_splitncnn_0 595 596 BinaryOp 597 2 1 596 584_splitncnn_0 597 Split splitncnn_9 1 2 597 597_splitncnn_0 597_splitncnn_1 Convolution 598 1 1 597_splitncnn_1 600 0=36 1=1 5=1 6=864 9=1 Split splitncnn_10 1 2 600 600_splitncnn_0 600_splitncnn_1 ConvolutionDepthWise 601 1 1 600_splitncnn_1 603 0=36 1=3 4=1 5=1 6=324 7=36 9=1 Concat 604 2 1 600_splitncnn_0 603 604 ConvolutionDepthWise 605 1 1 604 606 0=72 1=5 3=2 4=2 5=1 6=1800 7=72 Split splitncnn_11 1 2 606 606_splitncnn_0 606_splitncnn_1 Pooling 607 1 1 606_splitncnn_1 607 0=1 4=1 InnerProduct 608 1 1 607 609 0=20 1=1 2=1440 9=1 InnerProduct 610 1 1 609 610 0=72 1=1 2=1440 HardSigmoid 615 1 1 610 615 0=1.666667e-01 BinaryOp 616 2 1 606_splitncnn_0 615 616 0=2 Convolution 617 1 1 616 618 0=20 1=1 5=1 6=1440 Split splitncnn_12 1 2 618 618_splitncnn_0 618_splitncnn_1 ConvolutionDepthWise 619 1 1 618_splitncnn_1 620 0=20 1=3 4=1 5=1 6=180 7=20 Concat 621 2 1 618_splitncnn_0 620 621 ConvolutionDepthWise 622 1 1 597_splitncnn_0 623 0=24 1=5 3=2 4=2 5=1 6=600 7=24 Convolution 624 1 1 623 625 0=40 1=1 5=1 6=960 BinaryOp 626 2 1 621 625 626 Split splitncnn_13 1 2 626 626_splitncnn_0 626_splitncnn_1 Convolution 627 1 1 626_splitncnn_1 629 0=60 1=1 5=1 6=2400 9=1 Split splitncnn_14 1 2 629 629_splitncnn_0 629_splitncnn_1 ConvolutionDepthWise 630 1 1 629_splitncnn_1 632 0=60 1=3 4=1 5=1 6=540 7=60 9=1 Concat 633 2 1 629_splitncnn_0 632 633 Split splitncnn_15 1 2 633 633_splitncnn_0 633_splitncnn_1 Pooling 634 1 1 633_splitncnn_1 634 0=1 4=1 InnerProduct 635 1 1 634 636 0=32 1=1 2=3840 9=1 InnerProduct 637 1 1 636 637 0=120 1=1 2=3840 HardSigmoid 642 1 1 637 642 0=1.666667e-01 BinaryOp 643 2 1 633_splitncnn_0 642 643 0=2 Convolution 644 1 1 643 645 0=20 1=1 5=1 6=2400 Split splitncnn_16 1 2 645 645_splitncnn_0 645_splitncnn_1 ConvolutionDepthWise 646 1 1 645_splitncnn_1 647 0=20 1=3 4=1 5=1 6=180 7=20 Concat 648 2 1 645_splitncnn_0 647 648 BinaryOp 649 2 1 648 626_splitncnn_0 649 Split splitncnn_17 1 2 649 649_splitncnn_0 649_splitncnn_1 Convolution 650 1 1 649_splitncnn_1 652 0=120 1=1 5=1 6=4800 9=1 Split splitncnn_18 1 2 652 652_splitncnn_0 652_splitncnn_1 ConvolutionDepthWise 653 1 1 652_splitncnn_1 655 0=120 1=3 4=1 5=1 6=1080 7=120 9=1 Concat 656 2 1 652_splitncnn_0 655 656 ConvolutionDepthWise 657 1 1 656 658 0=240 1=3 3=2 4=1 5=1 6=2160 7=240 Convolution 659 1 1 658 660 0=40 1=1 5=1 6=9600 Split splitncnn_19 1 2 660 660_splitncnn_0 660_splitncnn_1 ConvolutionDepthWise 661 1 1 660_splitncnn_1 662 0=40 1=3 4=1 5=1 6=360 7=40 Concat 663 2 1 660_splitncnn_0 662 663 ConvolutionDepthWise 664 1 1 649_splitncnn_0 665 0=40 1=3 3=2 4=1 5=1 6=360 7=40 Convolution 666 1 1 665 667 0=80 1=1 5=1 6=3200 BinaryOp 668 2 1 663 667 668 Split splitncnn_20 1 2 668 668_splitncnn_0 668_splitncnn_1 Convolution 669 1 1 668_splitncnn_1 671 0=100 1=1 5=1 6=8000 9=1 Split splitncnn_21 1 2 671 671_splitncnn_0 671_splitncnn_1 ConvolutionDepthWise 672 1 1 671_splitncnn_1 674 0=100 1=3 4=1 5=1 6=900 7=100 9=1 Concat 675 2 1 671_splitncnn_0 674 675 Convolution 676 1 1 675 677 0=40 1=1 5=1 6=8000 Split splitncnn_22 1 2 677 677_splitncnn_0 677_splitncnn_1 ConvolutionDepthWise 678 1 1 677_splitncnn_1 679 0=40 1=3 4=1 5=1 6=360 7=40 Concat 680 2 1 677_splitncnn_0 679 680 BinaryOp 681 2 1 680 668_splitncnn_0 681 Split splitncnn_23 1 2 681 681_splitncnn_0 681_splitncnn_1 Convolution 682 1 1 681_splitncnn_1 684 0=92 1=1 5=1 6=7360 9=1 Split splitncnn_24 1 2 684 684_splitncnn_0 684_splitncnn_1 ConvolutionDepthWise 685 1 1 684_splitncnn_1 687 0=92 1=3 4=1 5=1 6=828 7=92 9=1 Concat 688 2 1 684_splitncnn_0 687 688 Convolution 689 1 1 688 690 0=40 1=1 5=1 6=7360 Split splitncnn_25 1 2 690 690_splitncnn_0 690_splitncnn_1 ConvolutionDepthWise 691 1 1 690_splitncnn_1 692 0=40 1=3 4=1 5=1 6=360 7=40 Concat 693 2 1 690_splitncnn_0 692 693 BinaryOp 694 2 1 693 681_splitncnn_0 694 Split splitncnn_26 1 2 694 694_splitncnn_0 694_splitncnn_1 Convolution 695 1 1 694_splitncnn_1 697 0=92 1=1 5=1 6=7360 9=1 Split splitncnn_27 1 2 697 697_splitncnn_0 697_splitncnn_1 ConvolutionDepthWise 698 1 1 697_splitncnn_1 700 0=92 1=3 4=1 5=1 6=828 7=92 9=1 Concat 701 2 1 697_splitncnn_0 700 701 Convolution 702 1 1 701 703 0=40 1=1 5=1 6=7360 Split splitncnn_28 1 2 703 703_splitncnn_0 703_splitncnn_1 ConvolutionDepthWise 704 1 1 703_splitncnn_1 705 0=40 1=3 4=1 5=1 6=360 7=40 Concat 706 2 1 703_splitncnn_0 705 706 BinaryOp 707 2 1 706 694_splitncnn_0 707 Split splitncnn_29 1 2 707 707_splitncnn_0 707_splitncnn_1 Convolution 708 1 1 707_splitncnn_1 710 0=240 1=1 5=1 6=19200 9=1 Split splitncnn_30 1 2 710 710_splitncnn_0 710_splitncnn_1 ConvolutionDepthWise 711 1 1 710_splitncnn_1 713 0=240 1=3 4=1 5=1 6=2160 7=240 9=1 Concat 714 2 1 710_splitncnn_0 713 714 Split splitncnn_31 1 2 714 714_splitncnn_0 714_splitncnn_1 Pooling 715 1 1 714_splitncnn_1 715 0=1 4=1 InnerProduct 716 1 1 715 717 0=120 1=1 2=57600 9=1 InnerProduct 718 1 1 717 718 0=480 1=1 2=57600 HardSigmoid 723 1 1 718 723 0=1.666667e-01 BinaryOp 724 2 1 714_splitncnn_0 723 724 0=2 Convolution 725 1 1 724 726 0=56 1=1 5=1 6=26880 Split splitncnn_32 1 2 726 726_splitncnn_0 726_splitncnn_1 ConvolutionDepthWise 727 1 1 726_splitncnn_1 728 0=56 1=3 4=1 5=1 6=504 7=56 Concat 729 2 1 726_splitncnn_0 728 729 ConvolutionDepthWise 730 1 1 707_splitncnn_0 731 0=80 1=3 4=1 5=1 6=720 7=80 Convolution 732 1 1 731 733 0=112 1=1 5=1 6=8960 BinaryOp 734 2 1 729 733 734 Split splitncnn_33 1 2 734 734_splitncnn_0 734_splitncnn_1 Convolution 735 1 1 734_splitncnn_1 737 0=336 1=1 5=1 6=37632 9=1 Split splitncnn_34 1 2 737 737_splitncnn_0 737_splitncnn_1 ConvolutionDepthWise 738 1 1 737_splitncnn_1 740 0=336 1=3 4=1 5=1 6=3024 7=336 9=1 Concat 741 2 1 737_splitncnn_0 740 741 Split splitncnn_35 1 2 741 741_splitncnn_0 741_splitncnn_1 Pooling 742 1 1 741_splitncnn_1 742 0=1 4=1 InnerProduct 743 1 1 742 744 0=168 1=1 2=112896 9=1 InnerProduct 745 1 1 744 745 0=672 1=1 2=112896 HardSigmoid 750 1 1 745 750 0=1.666667e-01 BinaryOp 751 2 1 741_splitncnn_0 750 751 0=2 Convolution 752 1 1 751 753 0=56 1=1 5=1 6=37632 Split splitncnn_36 1 2 753 753_splitncnn_0 753_splitncnn_1 ConvolutionDepthWise 754 1 1 753_splitncnn_1 755 0=56 1=3 4=1 5=1 6=504 7=56 Concat 756 2 1 753_splitncnn_0 755 756 BinaryOp 757 2 1 756 734_splitncnn_0 757 Split splitncnn_37 1 2 757 757_splitncnn_0 757_splitncnn_1 Pooling 758 1 1 757_splitncnn_1 758 0=1 4=1 InnerProduct 759 1 1 758 761 0=28 1=1 2=3136 9=1 InnerProduct 762 1 1 761 764 0=112 1=1 2=3136 9=4 BinaryOp 765 2 1 757_splitncnn_0 764 765 0=2 Convolution 766 1 1 765 768 0=224 1=1 5=1 6=25088 9=1 ConvolutionDepthWise 769 1 1 768 771 0=224 1=3 4=1 5=1 6=2016 7=224 9=1 Convolution 772 1 1 771 773 0=32 1=1 5=1 6=7168 Split splitncnn_38 1 2 773 773_splitncnn_0 773_splitncnn_1 Pooling 775 1 1 773_splitncnn_1 775 0=1 1=14 2=14 5=1 Reshape 783 1 1 775 783 0=-1 Convolution 784 1 1 773_splitncnn_0 786 0=64 1=3 3=2 4=1 5=1 6=18432 9=1 Split splitncnn_39 1 2 786 786_splitncnn_0 786_splitncnn_1 Pooling 788 1 1 786_splitncnn_1 788 0=1 1=7 2=7 5=1 Reshape 796 1 1 788 796 0=-1 Convolution 797 1 1 786_splitncnn_0 798 0=256 1=7 5=1 6=802816 9=1 Reshape 806 1 1 798 806 0=-1 Concat 807 3 1 783 796 806 807 InnerProduct output 1 1 807 output 0=936 1=1 2=329472 ================================================ FILE: ncnn-android-scrfd-master/app/src/main/assets/faceseg-op.param ================================================ 7767517 161 189 Input input.1 0 1 input Convolution Conv_14 1 1 input 363 0=32 1=3 3=2 4=1 5=1 6=864 9=1 Convolution Conv_17 1 1 363 366 0=32 1=3 3=2 4=1 5=1 6=9216 9=1 Split splitncnn_0 1 2 366 366_splitncnn_0 366_splitncnn_1 Convolution Conv_20 1 1 366_splitncnn_1 369 0=32 1=3 4=1 5=1 6=9216 9=1 Convolution Conv_23 1 1 369 371 0=32 1=3 4=1 5=1 6=9216 BinaryOp Add_25 2 1 371 366_splitncnn_0 372 ReLU Relu_26 1 1 372 373 Split splitncnn_1 1 2 373 373_splitncnn_0 373_splitncnn_1 Convolution Conv_27 1 1 373_splitncnn_1 376 0=32 1=3 4=1 5=1 6=9216 9=1 Convolution Conv_30 1 1 376 378 0=32 1=3 4=1 5=1 6=9216 BinaryOp Add_32 2 1 378 373_splitncnn_0 379 ReLU Relu_33 1 1 379 380 Split splitncnn_2 1 2 380 380_splitncnn_0 380_splitncnn_1 Convolution Conv_34 1 1 380_splitncnn_1 383 0=64 1=3 3=2 4=1 5=1 6=18432 9=1 Convolution Conv_37 1 1 383 385 0=64 1=3 4=1 5=1 6=36864 Convolution Conv_39 1 1 380_splitncnn_0 387 0=64 1=1 3=2 5=1 6=2048 BinaryOp Add_41 2 1 385 387 388 ReLU Relu_42 1 1 388 389 Split splitncnn_3 1 2 389 389_splitncnn_0 389_splitncnn_1 Convolution Conv_43 1 1 389_splitncnn_1 392 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_46 1 1 392 394 0=64 1=3 4=1 5=1 6=36864 BinaryOp Add_48 2 1 394 389_splitncnn_0 395 Split splitncnn_4 1 2 395 395_splitncnn_0 395_splitncnn_1 ReLU Relu_49 1 1 395_splitncnn_1 396 Split splitncnn_5 1 2 396 396_splitncnn_0 396_splitncnn_1 Convolution Conv_50 1 1 396_splitncnn_1 399 0=128 1=3 3=2 4=1 5=1 6=73728 9=1 Convolution Conv_53 1 1 399 401 0=128 1=3 4=1 5=1 6=147456 Convolution Conv_55 1 1 396_splitncnn_0 403 0=128 1=1 3=2 5=1 6=8192 BinaryOp Add_57 2 1 401 403 404 ReLU Relu_58 1 1 404 405 Split splitncnn_6 1 2 405 405_splitncnn_0 405_splitncnn_1 Convolution Conv_59 1 1 405_splitncnn_1 408 0=128 1=3 4=1 5=1 6=147456 9=1 Convolution Conv_62 1 1 408 410 0=128 1=3 4=1 5=1 6=147456 BinaryOp Add_64 2 1 410 405_splitncnn_0 411 Split splitncnn_7 1 2 411 411_splitncnn_0 411_splitncnn_1 ReLU Relu_65 1 1 395_splitncnn_0 412 Split splitncnn_8 1 2 412 412_splitncnn_0 412_splitncnn_1 Convolution Conv_66 1 1 412_splitncnn_1 415 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_69 1 1 415 417 0=64 1=3 4=1 5=1 6=36864 BinaryOp Add_71 2 1 417 412_splitncnn_0 418 ReLU Relu_72 1 1 418 419 Split splitncnn_9 1 2 419 419_splitncnn_0 419_splitncnn_1 Convolution Conv_73 1 1 419_splitncnn_1 422 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_76 1 1 422 424 0=64 1=3 4=1 5=1 6=36864 BinaryOp Add_78 2 1 424 419_splitncnn_0 425 Split splitncnn_10 1 2 425 425_splitncnn_0 425_splitncnn_1 ReLU Relu_79 1 1 425_splitncnn_1 426 Convolution Conv_80 1 1 426 428 0=128 1=3 3=2 4=1 5=1 6=73728 BinaryOp Add_82 2 1 411_splitncnn_1 428 429 ReLU Relu_83 1 1 411_splitncnn_0 430 Convolution Conv_84 1 1 430 432 0=64 1=1 5=1 6=8192 Interp Resize_98 1 1 432 445 0=2 3=32 4=32 BinaryOp Add_99 2 1 425_splitncnn_0 445 446 ReLU Relu_100 1 1 429 447 Split splitncnn_11 1 2 447 447_splitncnn_0 447_splitncnn_1 Convolution Conv_101 1 1 447_splitncnn_1 450 0=256 1=3 3=2 4=1 5=1 6=294912 9=1 Convolution Conv_104 1 1 450 452 0=256 1=3 4=1 5=1 6=589824 Convolution Conv_106 1 1 447_splitncnn_0 454 0=256 1=1 3=2 5=1 6=32768 BinaryOp Add_108 2 1 452 454 455 ReLU Relu_109 1 1 455 456 Split splitncnn_12 1 2 456 456_splitncnn_0 456_splitncnn_1 Convolution Conv_110 1 1 456_splitncnn_1 459 0=256 1=3 4=1 5=1 6=589824 9=1 Convolution Conv_113 1 1 459 461 0=256 1=3 4=1 5=1 6=589824 BinaryOp Add_115 2 1 461 456_splitncnn_0 462 Split splitncnn_13 1 2 462 462_splitncnn_0 462_splitncnn_1 ReLU Relu_116 1 1 446 463 Split splitncnn_14 1 2 463 463_splitncnn_0 463_splitncnn_1 Convolution Conv_117 1 1 463_splitncnn_1 466 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_120 1 1 466 468 0=64 1=3 4=1 5=1 6=36864 BinaryOp Add_122 2 1 468 463_splitncnn_0 469 ReLU Relu_123 1 1 469 470 Split splitncnn_15 1 2 470 470_splitncnn_0 470_splitncnn_1 Convolution Conv_124 1 1 470_splitncnn_1 473 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_127 1 1 473 475 0=64 1=3 4=1 5=1 6=36864 BinaryOp Add_129 2 1 475 470_splitncnn_0 476 Split splitncnn_16 1 2 476 476_splitncnn_0 476_splitncnn_1 ReLU Relu_130 1 1 476_splitncnn_1 477 Convolution Conv_131 1 1 477 480 0=128 1=3 3=2 4=1 5=1 6=73728 9=1 Convolution Conv_134 1 1 480 482 0=256 1=3 3=2 4=1 5=1 6=294912 BinaryOp Add_136 2 1 462_splitncnn_1 482 483 ReLU Relu_137 1 1 462_splitncnn_0 484 Convolution Conv_138 1 1 484 486 0=64 1=1 5=1 6=16384 Interp Resize_152 1 1 486 499 0=2 3=32 4=32 BinaryOp Add_153 2 1 476_splitncnn_0 499 500 ReLU Relu_154 1 1 500 501 Split splitncnn_17 1 2 501 501_splitncnn_0 501_splitncnn_1 Convolution Conv_155 1 1 501_splitncnn_1 504 0=64 1=1 5=1 6=4096 9=1 Convolution Conv_158 1 1 504 507 0=64 1=3 4=1 5=1 6=36864 9=1 Convolution Conv_161 1 1 507 509 0=128 1=1 5=1 6=8192 Convolution Conv_163 1 1 501_splitncnn_0 511 0=128 1=1 5=1 6=8192 BinaryOp Add_165 2 1 509 511 512 ReLU Relu_166 1 1 483 513 Split splitncnn_18 1 2 513 513_splitncnn_0 513_splitncnn_1 Convolution Conv_167 1 1 513_splitncnn_1 516 0=256 1=1 5=1 6=65536 9=1 Convolution Conv_170 1 1 516 519 0=256 1=3 3=2 4=1 5=1 6=589824 9=1 Convolution Conv_173 1 1 519 521 0=512 1=1 5=1 6=131072 Convolution Conv_175 1 1 513_splitncnn_0 523 0=512 1=1 3=2 5=1 6=131072 BinaryOp Add_177 2 1 521 523 524 Split splitncnn_19 1 6 524 524_splitncnn_0 524_splitncnn_1 524_splitncnn_2 524_splitncnn_3 524_splitncnn_4 524_splitncnn_5 BatchNorm BatchNormalization_184 1 1 524_splitncnn_5 531 0=512 ReLU Relu_185 1 1 531 532 Convolution Conv_186 1 1 532 533 0=128 1=1 6=65536 Split splitncnn_20 1 2 533 533_splitncnn_0 533_splitncnn_1 Padding Pad_188 1 1 524_splitncnn_4 535 0=1 1=1 2=1 3=1 Pooling AveragePool_189 1 1 535 536 0=1 1=3 2=2 5=1 BatchNorm BatchNormalization_190 1 1 536 537 0=512 ReLU Relu_191 1 1 537 538 Convolution Conv_192 1 1 538 539 0=128 1=1 6=65536 Interp Resize_205 1 1 539 552 0=2 3=4 4=4 BinaryOp Add_206 2 1 552 533_splitncnn_1 553 BatchNorm BatchNormalization_207 1 1 553 554 0=128 ReLU Relu_208 1 1 554 555 Convolution Conv_209 1 1 555 556 0=128 1=3 4=1 6=147456 Split splitncnn_21 1 2 556 556_splitncnn_0 556_splitncnn_1 Padding Pad_211 1 1 524_splitncnn_3 558 0=2 1=2 2=2 3=2 Pooling AveragePool_212 1 1 558 559 0=1 1=5 2=4 5=1 BatchNorm BatchNormalization_213 1 1 559 560 0=512 ReLU Relu_214 1 1 560 561 Convolution Conv_215 1 1 561 562 0=128 1=1 6=65536 Interp Resize_228 1 1 562 575 0=2 3=4 4=4 BinaryOp Add_229 2 1 575 556_splitncnn_1 576 BatchNorm BatchNormalization_230 1 1 576 577 0=128 ReLU Relu_231 1 1 577 578 Convolution Conv_232 1 1 578 579 0=128 1=3 4=1 6=147456 Split splitncnn_22 1 2 579 579_splitncnn_0 579_splitncnn_1 Padding Pad_234 1 1 524_splitncnn_2 581 0=4 1=4 2=4 3=4 Pooling AveragePool_235 1 1 581 582 0=1 1=9 2=8 5=1 BatchNorm BatchNormalization_236 1 1 582 583 0=512 ReLU Relu_237 1 1 583 584 Convolution Conv_238 1 1 584 585 0=128 1=1 6=65536 Interp Resize_251 1 1 585 598 0=2 3=4 4=4 BinaryOp Add_252 2 1 598 579_splitncnn_1 599 BatchNorm BatchNormalization_253 1 1 599 600 0=128 ReLU Relu_254 1 1 600 601 Convolution Conv_255 1 1 601 602 0=128 1=3 4=1 6=147456 Split splitncnn_23 1 2 602 602_splitncnn_0 602_splitncnn_1 Pooling GlobalAveragePool_256 1 1 524_splitncnn_1 603 0=1 4=1 BatchNorm BatchNormalization_257 1 1 603 604 0=512 ReLU Relu_258 1 1 604 605 Convolution Conv_259 1 1 605 606 0=128 1=1 6=65536 Interp Resize_272 1 1 606 619 0=2 3=4 4=4 BinaryOp Add_273 2 1 619 602_splitncnn_1 620 BatchNorm BatchNormalization_274 1 1 620 621 0=128 ReLU Relu_275 1 1 621 622 Convolution Conv_276 1 1 622 623 0=128 1=3 4=1 6=147456 Concat Concat_277 5 1 533_splitncnn_0 556_splitncnn_0 579_splitncnn_0 602_splitncnn_0 623 624 BatchNorm BatchNormalization_278 1 1 624 625 0=640 ReLU Relu_279 1 1 625 626 Convolution Conv_280 1 1 626 627 0=128 1=1 6=81920 BatchNorm BatchNormalization_281 1 1 524_splitncnn_0 628 0=512 ReLU Relu_282 1 1 628 629 Convolution Conv_283 1 1 629 630 0=128 1=1 6=65536 BinaryOp Add_284 2 1 627 630 631 Interp Resize_297 1 1 631 644 0=2 3=32 4=32 BinaryOp Add_298 2 1 644 512 645 BatchNorm BatchNormalization_299 1 1 645 646 0=128 ReLU Relu_300 1 1 646 647 Convolution Conv_301 1 1 647 650 0=64 1=3 4=1 5=1 6=73728 9=1 Convolution Conv_304 1 1 650 651 0=8 1=1 5=1 6=512 Interp Resize_313 1 1 651 output 0=2 3=256 4=256 ================================================ FILE: ncnn-android-scrfd-master/app/src/main/assets/scrfd_1g-opt2.param ================================================ 7767517 99 108 Input input.1 0 1 input.1 Convolution Conv_0 1 1 input.1 193 0=32 1=3 3=2 4=1 5=1 6=864 9=1 ConvolutionDepthWise Conv_2 1 1 193 196 0=32 1=3 4=1 5=1 6=288 7=32 9=1 Convolution Conv_4 1 1 196 199 0=48 1=1 5=1 6=1536 9=1 ConvolutionDepthWise Conv_6 1 1 199 202 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1 Convolution Conv_8 1 1 202 205 0=48 1=1 5=1 6=2304 9=1 ConvolutionDepthWise Conv_10 1 1 205 208 0=48 1=3 4=1 5=1 6=432 7=48 9=1 Convolution Conv_12 1 1 208 211 0=48 1=1 5=1 6=2304 9=1 ConvolutionDepthWise Conv_14 1 1 211 214 0=48 1=3 4=1 5=1 6=432 7=48 9=1 Convolution Conv_16 1 1 214 217 0=48 1=1 5=1 6=2304 9=1 ConvolutionDepthWise Conv_18 1 1 217 220 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1 Convolution Conv_20 1 1 220 223 0=160 1=1 5=1 6=7680 9=1 ConvolutionDepthWise Conv_22 1 1 223 226 0=160 1=3 4=1 5=1 6=1440 7=160 9=1 Convolution Conv_24 1 1 226 229 0=160 1=1 5=1 6=25600 9=1 Split splitncnn_0 1 2 229 229_splitncnn_0 229_splitncnn_1 ConvolutionDepthWise Conv_26 1 1 229_splitncnn_1 232 0=160 1=3 3=2 4=1 5=1 6=1440 7=160 9=1 Convolution Conv_28 1 1 232 235 0=216 1=1 5=1 6=34560 9=1 Split splitncnn_1 1 2 235 235_splitncnn_0 235_splitncnn_1 ConvolutionDepthWise Conv_30 1 1 235_splitncnn_1 238 0=216 1=3 3=2 4=1 5=1 6=1944 7=216 9=1 Convolution Conv_32 1 1 238 241 0=312 1=1 5=1 6=67392 9=1 ConvolutionDepthWise Conv_34 1 1 241 244 0=312 1=3 4=1 5=1 6=2808 7=312 9=1 Convolution Conv_36 1 1 244 247 0=312 1=1 5=1 6=97344 9=1 ConvolutionDepthWise Conv_38 1 1 247 250 0=312 1=3 4=1 5=1 6=2808 7=312 9=1 Convolution Conv_40 1 1 250 253 0=312 1=1 5=1 6=97344 9=1 ConvolutionDepthWise Conv_42 1 1 253 256 0=312 1=3 4=1 5=1 6=2808 7=312 9=1 Convolution Conv_44 1 1 256 259 0=312 1=1 5=1 6=97344 9=1 ConvolutionDepthWise Conv_46 1 1 259 262 0=312 1=3 4=1 5=1 6=2808 7=312 9=1 Convolution Conv_48 1 1 262 265 0=312 1=1 5=1 6=97344 9=1 Convolution Conv_50 1 1 229_splitncnn_0 266 0=24 1=1 5=1 6=3840 Convolution Conv_51 1 1 235_splitncnn_0 267 0=24 1=1 5=1 6=5184 Convolution Conv_52 1 1 265 268 0=24 1=1 5=1 6=7488 Split splitncnn_2 1 2 268 268_splitncnn_0 268_splitncnn_1 Interp Resize_71 1 1 268_splitncnn_1 287 0=1 1=2.000000e+00 2=2.000000e+00 BinaryOp Add_72 2 1 267 287 288 Split splitncnn_3 1 2 288 288_splitncnn_0 288_splitncnn_1 Interp Resize_91 1 1 288_splitncnn_1 307 0=1 1=2.000000e+00 2=2.000000e+00 BinaryOp Add_92 2 1 266 307 308 Convolution Conv_93 1 1 308 309 0=24 1=3 4=1 5=1 6=5184 Split splitncnn_4 1 2 309 309_splitncnn_0 309_splitncnn_1 Convolution Conv_94 1 1 288_splitncnn_0 310 0=24 1=3 4=1 5=1 6=5184 Convolution Conv_95 1 1 268_splitncnn_0 311 0=24 1=3 4=1 5=1 6=5184 Convolution Conv_96 1 1 309_splitncnn_1 312 0=24 1=3 3=2 4=1 5=1 6=5184 BinaryOp Add_97 2 1 310 312 313 Split splitncnn_5 1 2 313 313_splitncnn_0 313_splitncnn_1 Convolution Conv_98 1 1 313_splitncnn_1 314 0=24 1=3 3=2 4=1 5=1 6=5184 BinaryOp Add_99 2 1 311 314 315 Convolution Conv_100 1 1 313_splitncnn_0 316 0=24 1=3 4=1 5=1 6=5184 Convolution Conv_101 1 1 315 317 0=24 1=3 4=1 5=1 6=5184 ConvolutionDepthWise Conv_102 1 1 309_splitncnn_0 318 0=24 1=3 4=1 6=216 7=24 GroupNorm Add_111 1 1 318 329 0=8 1=24 2=1.000000e-05 ReLU Relu_112 1 1 329 330 Convolution Conv_113 1 1 330 331 0=96 1=1 6=2304 GroupNorm Add_122 1 1 331 342 0=8 1=96 2=1.000000e-05 ReLU Relu_123 1 1 342 343 ConvolutionDepthWise Conv_124 1 1 343 344 0=96 1=3 4=1 6=864 7=96 GroupNorm Add_133 1 1 344 355 0=8 1=96 2=1.000000e-05 ReLU Relu_134 1 1 355 356 Convolution Conv_135 1 1 356 357 0=96 1=1 6=9216 GroupNorm Add_144 1 1 357 368 0=8 1=96 2=1.000000e-05 ReLU Relu_145 1 1 368 369 Split splitncnn_6 1 2 369 369_splitncnn_0 369_splitncnn_1 Convolution Conv_146 1 1 369_splitncnn_1 375 0=2 1=3 4=1 5=1 6=1728 Convolution Conv_147 1 1 369_splitncnn_0 371 0=8 1=3 4=1 5=1 6=6912 BinaryOp Mul_148 1 1 371 bbox_8 0=2 1=1 2=8.200800e-01 Sigmoid Sigmoid_152 1 1 375 score_8 ConvolutionDepthWise Conv_156 1 1 316 380 0=24 1=3 4=1 6=216 7=24 GroupNorm Add_165 1 1 380 391 0=8 1=24 2=1.000000e-05 ReLU Relu_166 1 1 391 392 Convolution Conv_167 1 1 392 393 0=96 1=1 6=2304 GroupNorm Add_176 1 1 393 404 0=8 1=96 2=1.000000e-05 ReLU Relu_177 1 1 404 405 ConvolutionDepthWise Conv_178 1 1 405 406 0=96 1=3 4=1 6=864 7=96 GroupNorm Add_187 1 1 406 417 0=8 1=96 2=1.000000e-05 ReLU Relu_188 1 1 417 418 Convolution Conv_189 1 1 418 419 0=96 1=1 6=9216 GroupNorm Add_198 1 1 419 430 0=8 1=96 2=1.000000e-05 ReLU Relu_199 1 1 430 431 Split splitncnn_7 1 2 431 431_splitncnn_0 431_splitncnn_1 Convolution Conv_200 1 1 431_splitncnn_1 437 0=2 1=3 4=1 5=1 6=1728 Convolution Conv_201 1 1 431_splitncnn_0 433 0=8 1=3 4=1 5=1 6=6912 BinaryOp Mul_202 1 1 433 bbox_16 0=2 1=1 2=1.225648e+00 Sigmoid Sigmoid_206 1 1 437 score_16 ConvolutionDepthWise Conv_210 1 1 317 442 0=24 1=3 4=1 6=216 7=24 GroupNorm Add_219 1 1 442 453 0=8 1=24 2=1.000000e-05 ReLU Relu_220 1 1 453 454 Convolution Conv_221 1 1 454 455 0=96 1=1 6=2304 GroupNorm Add_230 1 1 455 466 0=8 1=96 2=1.000000e-05 ReLU Relu_231 1 1 466 467 ConvolutionDepthWise Conv_232 1 1 467 468 0=96 1=3 4=1 6=864 7=96 GroupNorm Add_241 1 1 468 479 0=8 1=96 2=1.000000e-05 ReLU Relu_242 1 1 479 480 Convolution Conv_243 1 1 480 481 0=96 1=1 6=9216 GroupNorm Add_252 1 1 481 492 0=8 1=96 2=1.000000e-05 ReLU Relu_253 1 1 492 493 Split splitncnn_8 1 2 493 493_splitncnn_0 493_splitncnn_1 Convolution Conv_254 1 1 493_splitncnn_1 499 0=2 1=3 4=1 5=1 6=1728 Convolution Conv_255 1 1 493_splitncnn_0 495 0=8 1=3 4=1 5=1 6=6912 BinaryOp Mul_256 1 1 495 bbox_32 0=2 1=1 2=1.842380e+00 Sigmoid Sigmoid_260 1 1 499 score_32 ================================================ FILE: ncnn-android-scrfd-master/app/src/main/assets/scrfd_500m-opt2.param ================================================ 7767517 103 112 Input input.1 0 1 input.1 Convolution Conv_0 1 1 input.1 217 0=16 1=3 3=2 4=1 5=1 6=432 9=1 ConvolutionDepthWise Conv_2 1 1 217 220 0=16 1=3 4=1 5=1 6=144 7=16 9=1 Convolution Conv_4 1 1 220 223 0=16 1=1 5=1 6=256 9=1 ConvolutionDepthWise Conv_6 1 1 223 226 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1 Convolution Conv_8 1 1 226 229 0=40 1=1 5=1 6=640 9=1 ConvolutionDepthWise Conv_10 1 1 229 232 0=40 1=3 4=1 5=1 6=360 7=40 9=1 Convolution Conv_12 1 1 232 235 0=40 1=1 5=1 6=1600 9=1 ConvolutionDepthWise Conv_14 1 1 235 238 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1 Convolution Conv_16 1 1 238 241 0=72 1=1 5=1 6=2880 9=1 ConvolutionDepthWise Conv_18 1 1 241 244 0=72 1=3 4=1 5=1 6=648 7=72 9=1 Convolution Conv_20 1 1 244 247 0=72 1=1 5=1 6=5184 9=1 ConvolutionDepthWise Conv_22 1 1 247 250 0=72 1=3 4=1 5=1 6=648 7=72 9=1 Convolution Conv_24 1 1 250 253 0=72 1=1 5=1 6=5184 9=1 Split splitncnn_0 1 2 253 253_splitncnn_0 253_splitncnn_1 ConvolutionDepthWise Conv_26 1 1 253_splitncnn_1 256 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1 Convolution Conv_28 1 1 256 259 0=152 1=1 5=1 6=10944 9=1 ConvolutionDepthWise Conv_30 1 1 259 262 0=152 1=3 4=1 5=1 6=1368 7=152 9=1 Convolution Conv_32 1 1 262 265 0=152 1=1 5=1 6=23104 9=1 Split splitncnn_1 1 2 265 265_splitncnn_0 265_splitncnn_1 ConvolutionDepthWise Conv_34 1 1 265_splitncnn_1 268 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1 Convolution Conv_36 1 1 268 271 0=288 1=1 5=1 6=43776 9=1 ConvolutionDepthWise Conv_38 1 1 271 274 0=288 1=3 4=1 5=1 6=2592 7=288 9=1 Convolution Conv_40 1 1 274 277 0=288 1=1 5=1 6=82944 9=1 ConvolutionDepthWise Conv_42 1 1 277 280 0=288 1=3 4=1 5=1 6=2592 7=288 9=1 Convolution Conv_44 1 1 280 283 0=288 1=1 5=1 6=82944 9=1 ConvolutionDepthWise Conv_46 1 1 283 286 0=288 1=3 4=1 5=1 6=2592 7=288 9=1 Convolution Conv_48 1 1 286 289 0=288 1=1 5=1 6=82944 9=1 ConvolutionDepthWise Conv_50 1 1 289 292 0=288 1=3 4=1 5=1 6=2592 7=288 9=1 Convolution Conv_52 1 1 292 295 0=288 1=1 5=1 6=82944 9=1 ConvolutionDepthWise Conv_54 1 1 295 298 0=288 1=3 4=1 5=1 6=2592 7=288 9=1 Convolution Conv_56 1 1 298 301 0=288 1=1 5=1 6=82944 9=1 Convolution Conv_58 1 1 253_splitncnn_0 302 0=16 1=1 5=1 6=1152 Convolution Conv_59 1 1 265_splitncnn_0 303 0=16 1=1 5=1 6=2432 Convolution Conv_60 1 1 301 304 0=16 1=1 5=1 6=4608 Split splitncnn_2 1 2 304 304_splitncnn_0 304_splitncnn_1 Interp Resize_79 1 1 304_splitncnn_1 323 0=1 1=2.000000e+00 2=2.000000e+00 BinaryOp Add_80 2 1 303 323 324 Split splitncnn_3 1 2 324 324_splitncnn_0 324_splitncnn_1 Interp Resize_99 1 1 324_splitncnn_1 343 0=1 1=2.000000e+00 2=2.000000e+00 BinaryOp Add_100 2 1 302 343 344 Convolution Conv_101 1 1 344 345 0=16 1=3 4=1 5=1 6=2304 Split splitncnn_4 1 2 345 345_splitncnn_0 345_splitncnn_1 Convolution Conv_102 1 1 324_splitncnn_0 346 0=16 1=3 4=1 5=1 6=2304 Convolution Conv_103 1 1 304_splitncnn_0 347 0=16 1=3 4=1 5=1 6=2304 Convolution Conv_104 1 1 345_splitncnn_1 348 0=16 1=3 3=2 4=1 5=1 6=2304 BinaryOp Add_105 2 1 346 348 349 Split splitncnn_5 1 2 349 349_splitncnn_0 349_splitncnn_1 Convolution Conv_106 1 1 349_splitncnn_1 350 0=16 1=3 3=2 4=1 5=1 6=2304 BinaryOp Add_107 2 1 347 350 351 Convolution Conv_108 1 1 349_splitncnn_0 352 0=16 1=3 4=1 5=1 6=2304 Convolution Conv_109 1 1 351 353 0=16 1=3 4=1 5=1 6=2304 ConvolutionDepthWise Conv_110 1 1 345_splitncnn_0 354 0=16 1=3 4=1 6=144 7=16 GroupNorm Add_119 1 1 354 365 0=16 1=16 2=1.000000e-05 ReLU Relu_120 1 1 365 366 Convolution Conv_121 1 1 366 367 0=64 1=1 6=1024 GroupNorm Add_130 1 1 367 378 0=16 1=64 2=1.000000e-05 ReLU Relu_131 1 1 378 379 ConvolutionDepthWise Conv_132 1 1 379 380 0=64 1=3 4=1 6=576 7=64 GroupNorm Add_141 1 1 380 391 0=16 1=64 2=1.000000e-05 ReLU Relu_142 1 1 391 392 Convolution Conv_143 1 1 392 393 0=64 1=1 6=4096 GroupNorm Add_152 1 1 393 404 0=16 1=64 2=1.000000e-05 ReLU Relu_153 1 1 404 405 Split splitncnn_6 1 2 405 405_splitncnn_0 405_splitncnn_1 Convolution Conv_154 1 1 405_splitncnn_1 411 0=2 1=3 4=1 5=1 6=1152 Convolution Conv_155 1 1 405_splitncnn_0 407 0=8 1=3 4=1 5=1 6=4608 BinaryOp Mul_156 1 1 407 bbox_8 0=2 1=1 2=7.957783e-01 Sigmoid Sigmoid_160 1 1 411 score_8 ConvolutionDepthWise Conv_164 1 1 352 416 0=16 1=3 4=1 6=144 7=16 GroupNorm Add_173 1 1 416 427 0=16 1=16 2=1.000000e-05 ReLU Relu_174 1 1 427 428 Convolution Conv_175 1 1 428 429 0=64 1=1 6=1024 GroupNorm Add_184 1 1 429 440 0=16 1=64 2=1.000000e-05 ReLU Relu_185 1 1 440 441 ConvolutionDepthWise Conv_186 1 1 441 442 0=64 1=3 4=1 6=576 7=64 GroupNorm Add_195 1 1 442 453 0=16 1=64 2=1.000000e-05 ReLU Relu_196 1 1 453 454 Convolution Conv_197 1 1 454 455 0=64 1=1 6=4096 GroupNorm Add_206 1 1 455 466 0=16 1=64 2=1.000000e-05 ReLU Relu_207 1 1 466 467 Split splitncnn_7 1 2 467 467_splitncnn_0 467_splitncnn_1 Convolution Conv_208 1 1 467_splitncnn_1 473 0=2 1=3 4=1 5=1 6=1152 Convolution Conv_209 1 1 467_splitncnn_0 469 0=8 1=3 4=1 5=1 6=4608 BinaryOp Mul_210 1 1 469 bbox_16 0=2 1=1 2=1.201926e+00 Sigmoid Sigmoid_214 1 1 473 score_16 ConvolutionDepthWise Conv_218 1 1 353 478 0=16 1=3 4=1 6=144 7=16 GroupNorm Add_227 1 1 478 489 0=16 1=16 2=1.000000e-05 ReLU Relu_228 1 1 489 490 Convolution Conv_229 1 1 490 491 0=64 1=1 6=1024 GroupNorm Add_238 1 1 491 502 0=16 1=64 2=1.000000e-05 ReLU Relu_239 1 1 502 503 ConvolutionDepthWise Conv_240 1 1 503 504 0=64 1=3 4=1 6=576 7=64 GroupNorm Add_249 1 1 504 515 0=16 1=64 2=1.000000e-05 ReLU Relu_250 1 1 515 516 Convolution Conv_251 1 1 516 517 0=64 1=1 6=4096 GroupNorm Add_260 1 1 517 528 0=16 1=64 2=1.000000e-05 ReLU Relu_261 1 1 528 529 Split splitncnn_8 1 2 529 529_splitncnn_0 529_splitncnn_1 Convolution Conv_262 1 1 529_splitncnn_1 535 0=2 1=3 4=1 5=1 6=1152 Convolution Conv_263 1 1 529_splitncnn_0 531 0=8 1=3 4=1 5=1 6=4608 BinaryOp Mul_264 1 1 531 bbox_32 0=2 1=1 2=1.992024e+00 Sigmoid Sigmoid_268 1 1 535 score_32 ================================================ FILE: ncnn-android-scrfd-master/app/src/main/java/com/tencent/scrfdncnn/MainActivity.java ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. package com.tencent.scrfdncnn; import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import android.graphics.PixelFormat; import android.os.Bundle; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.Button; import android.widget.Spinner; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; public class MainActivity extends Activity implements SurfaceHolder.Callback { public static final int REQUEST_CAMERA = 100; private SCRFDNcnn scrfdncnn = new SCRFDNcnn(); private int facing = 0; private Spinner spinnerModel; private Spinner spinnerCPUGPU; private int current_model = 0; private int current_cpugpu = 0; private SurfaceView cameraView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); cameraView = (SurfaceView) findViewById(R.id.cameraview); cameraView.getHolder().setFormat(PixelFormat.RGBA_8888); cameraView.getHolder().addCallback(this); Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera); buttonSwitchCamera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { int new_facing = 1 - facing; scrfdncnn.closeCamera(); scrfdncnn.openCamera(new_facing); facing = new_facing; } }); spinnerModel = (Spinner) findViewById(R.id.spinnerModel); spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView arg0, View arg1, int position, long id) { if (position != current_model) { current_model = position; reload(); } } @Override public void onNothingSelected(AdapterView arg0) { } }); spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU); spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView arg0, View arg1, int position, long id) { if (position != current_cpugpu) { current_cpugpu = position; reload(); } } @Override public void onNothingSelected(AdapterView arg0) { } }); reload(); } private void reload() { boolean ret_init = scrfdncnn.loadModel(getAssets(), current_model, current_cpugpu); if (!ret_init) { Log.e("MainActivity", "scrfdncnn loadModel failed"); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { scrfdncnn.setOutputWindow(holder.getSurface()); } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } @Override public void onResume() { super.onResume(); if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) { ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA); } scrfdncnn.openCamera(facing); } @Override public void onPause() { super.onPause(); scrfdncnn.closeCamera(); } } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. package com.tencent.scrfdncnn; import android.content.res.AssetManager; import android.view.Surface; public class SCRFDNcnn { public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu); public native boolean openCamera(int facing); public native boolean closeCamera(); public native boolean setOutputWindow(Surface surface); static { System.loadLibrary("scrfdncnn"); } } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/CMakeLists.txt ================================================ project(scrfdncnn) cmake_minimum_required(VERSION 3.10) set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni) find_package(OpenCV REQUIRED core imgproc) set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210322-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn) find_package(ncnn REQUIRED) add_library(scrfdncnn SHARED scrfdncnn.cpp scrfd.cpp ndkcamera.cpp) target_link_libraries(scrfdncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk) ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/ndkcamera.cpp ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include "ndkcamera.h" #include #include #include #include "mat.h" static void onDisconnected(void* context, ACameraDevice* device) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onDisconnected %p", device); } static void onError(void* context, ACameraDevice* device, int error) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onError %p %d", device, error); } static void onImageAvailable(void* context, AImageReader* reader) { // __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onImageAvailable %p", reader); AImage* image = 0; media_status_t status = AImageReader_acquireLatestImage(reader, &image); if (status != AMEDIA_OK) { // error return; } int32_t format; AImage_getFormat(image, &format); // assert format == AIMAGE_FORMAT_YUV_420_888 int32_t width = 0; int32_t height = 0; AImage_getWidth(image, &width); AImage_getHeight(image, &height); int32_t y_pixelStride = 0; int32_t u_pixelStride = 0; int32_t v_pixelStride = 0; AImage_getPlanePixelStride(image, 0, &y_pixelStride); AImage_getPlanePixelStride(image, 1, &u_pixelStride); AImage_getPlanePixelStride(image, 2, &v_pixelStride); int32_t y_rowStride = 0; int32_t u_rowStride = 0; int32_t v_rowStride = 0; AImage_getPlaneRowStride(image, 0, &y_rowStride); AImage_getPlaneRowStride(image, 1, &u_rowStride); AImage_getPlaneRowStride(image, 2, &v_rowStride); uint8_t* y_data = 0; uint8_t* u_data = 0; uint8_t* v_data = 0; int y_len = 0; int u_len = 0; int v_len = 0; AImage_getPlaneData(image, 0, &y_data, &y_len); AImage_getPlaneData(image, 1, &u_data, &u_len); AImage_getPlaneData(image, 2, &v_data, &v_len); if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width) { // already nv21 :) ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height); } else { // construct nv21 unsigned char* nv21 = new unsigned char[width * height + width * height / 2]; { // Y unsigned char* yptr = nv21; for (int y=0; yon_image((unsigned char*)nv21, (int)width, (int)height); delete[] nv21; } AImage_delete(image); } static void onSessionActive(void* context, ACameraCaptureSession *session) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionActive %p", session); } static void onSessionReady(void* context, ACameraCaptureSession *session) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionReady %p", session); } static void onSessionClosed(void* context, ACameraCaptureSession *session) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionClosed %p", session); } void onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureFailed %p %p %p", session, request, failure); } void onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureSequenceCompleted %p %d %ld", session, sequenceId, frameNumber); } void onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureSequenceAborted %p %d", session, sequenceId); } void onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result) { // __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureCompleted %p %p %p", session, request, result); } NdkCamera::NdkCamera() { camera_facing = 0; camera_orientation = 0; camera_manager = 0; camera_device = 0; image_reader = 0; image_reader_surface = 0; image_reader_target = 0; capture_request = 0; capture_session_output_container = 0; capture_session_output = 0; capture_session = 0; // setup imagereader and its surface { AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader); AImageReader_ImageListener listener; listener.context = this; listener.onImageAvailable = onImageAvailable; AImageReader_setImageListener(image_reader, &listener); AImageReader_getWindow(image_reader, &image_reader_surface); ANativeWindow_acquire(image_reader_surface); } } NdkCamera::~NdkCamera() { close(); if (image_reader) { AImageReader_delete(image_reader); image_reader = 0; } if (image_reader_surface) { ANativeWindow_release(image_reader_surface); image_reader_surface = 0; } } int NdkCamera::open(int _camera_facing) { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open"); camera_facing = _camera_facing; camera_manager = ACameraManager_create(); // find front camera std::string camera_id; { ACameraIdList* camera_id_list = 0; ACameraManager_getCameraIdList(camera_manager, &camera_id_list); for (int i = 0; i < camera_id_list->numCameras; ++i) { const char* id = camera_id_list->cameraIds[i]; ACameraMetadata* camera_metadata = 0; ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata); // query faceing acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT; { ACameraMetadata_const_entry e = { 0 }; ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e); facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0]; } if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT) { ACameraMetadata_free(camera_metadata); continue; } if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK) { ACameraMetadata_free(camera_metadata); continue; } camera_id = id; // query orientation int orientation = 0; { ACameraMetadata_const_entry e = { 0 }; ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e); orientation = (int)e.data.i32[0]; } camera_orientation = orientation; ACameraMetadata_free(camera_metadata); break; } ACameraManager_deleteCameraIdList(camera_id_list); } __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open %s %d", camera_id.c_str(), camera_orientation); // open camera { ACameraDevice_StateCallbacks camera_device_state_callbacks; camera_device_state_callbacks.context = this; camera_device_state_callbacks.onDisconnected = onDisconnected; camera_device_state_callbacks.onError = onError; ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device); } // capture request { ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request); ACameraOutputTarget_create(image_reader_surface, &image_reader_target); ACaptureRequest_addTarget(capture_request, image_reader_target); } // capture session { ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks; camera_capture_session_state_callbacks.context = this; camera_capture_session_state_callbacks.onActive = onSessionActive; camera_capture_session_state_callbacks.onReady = onSessionReady; camera_capture_session_state_callbacks.onClosed = onSessionClosed; ACaptureSessionOutputContainer_create(&capture_session_output_container); ACaptureSessionOutput_create(image_reader_surface, &capture_session_output); ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output); ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session); ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks; camera_capture_session_capture_callbacks.context = this; camera_capture_session_capture_callbacks.onCaptureStarted = 0; camera_capture_session_capture_callbacks.onCaptureProgressed = 0; camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted; camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed; camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted; camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted; camera_capture_session_capture_callbacks.onCaptureBufferLost = 0; ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr); } return 0; } void NdkCamera::close() { __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "close"); if (capture_session) { ACameraCaptureSession_stopRepeating(capture_session); ACameraCaptureSession_close(capture_session); capture_session = 0; } if (camera_device) { ACameraDevice_close(camera_device); camera_device = 0; } if (capture_session_output_container) { ACaptureSessionOutputContainer_free(capture_session_output_container); capture_session_output_container = 0; } if (capture_session_output) { ACaptureSessionOutput_free(capture_session_output); capture_session_output = 0; } if (capture_request) { ACaptureRequest_free(capture_request); capture_request = 0; } if (image_reader_target) { ACameraOutputTarget_free(image_reader_target); image_reader_target = 0; } if (camera_manager) { ACameraManager_delete(camera_manager); camera_manager = 0; } } void NdkCamera::on_image(const cv::Mat& rgb) const { } void NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const { // rotate nv21 int w = 0; int h = 0; int rotate_type = 0; { if (camera_orientation == 0) { w = nv21_width; h = nv21_height; rotate_type = camera_facing == 0 ? 2 : 1; } if (camera_orientation == 90) { w = nv21_height; h = nv21_width; rotate_type = camera_facing == 0 ? 5 : 6; } if (camera_orientation == 180) { w = nv21_width; h = nv21_height; rotate_type = camera_facing == 0 ? 4 : 3; } if (camera_orientation == 270) { w = nv21_height; h = nv21_width; rotate_type = camera_facing == 0 ? 7 : 8; } } cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1); ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type); // nv21_rotated to rgb cv::Mat rgb(h, w, CV_8UC3); ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data); on_image(rgb); } static const int NDKCAMERAWINDOW_ID = 233; NdkCameraWindow::NdkCameraWindow() : NdkCamera() { sensor_manager = 0; sensor_event_queue = 0; accelerometer_sensor = 0; win = 0; accelerometer_orientation = 0; // sensor sensor_manager = ASensorManager_getInstance(); accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER); } NdkCameraWindow::~NdkCameraWindow() { if (accelerometer_sensor) { ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor); accelerometer_sensor = 0; } if (sensor_event_queue) { ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue); sensor_event_queue = 0; } if (win) { ANativeWindow_release(win); } } void NdkCameraWindow::set_window(ANativeWindow* _win) { if (win) { ANativeWindow_release(win); } win = _win; ANativeWindow_acquire(win); } void NdkCameraWindow::on_image_render(cv::Mat& rgb) const { } void NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const { // resolve orientation from camera_orientation and accelerometer_sensor { if (!sensor_event_queue) { sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0); ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor); } int id = ALooper_pollAll(0, 0, 0, 0); if (id == NDKCAMERAWINDOW_ID) { ASensorEvent e[8]; ssize_t num_event = 0; while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1) { num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8); if (num_event < 0) break; } if (num_event > 0) { float acceleration_x = e[num_event - 1].acceleration.x; float acceleration_y = e[num_event - 1].acceleration.y; float acceleration_z = e[num_event - 1].acceleration.z; // __android_log_print(ANDROID_LOG_WARN, "NdkCameraWindow", "x = %f, y = %f, z = %f", x, y, z); if (acceleration_y > 7) { accelerometer_orientation = 0; } if (acceleration_x < -7) { accelerometer_orientation = 90; } if (acceleration_y < -7) { accelerometer_orientation = 180; } if (acceleration_x > 7) { accelerometer_orientation = 270; } } } } // roi crop and rotate nv21 int nv21_roi_x = 0; int nv21_roi_y = 0; int nv21_roi_w = 0; int nv21_roi_h = 0; int roi_x = 0; int roi_y = 0; int roi_w = 0; int roi_h = 0; int rotate_type = 0; int render_w = 0; int render_h = 0; int render_rotate_type = 0; { int win_w = ANativeWindow_getWidth(win); int win_h = ANativeWindow_getHeight(win); if (accelerometer_orientation == 90 || accelerometer_orientation == 270) { std::swap(win_w, win_h); } const int final_orientation = (camera_orientation + accelerometer_orientation) % 360; if (final_orientation == 0 || final_orientation == 180) { if (win_w * nv21_height > win_h * nv21_width) { roi_w = nv21_width; roi_h = (nv21_width * win_h / win_w) / 2 * 2; roi_x = 0; roi_y = ((nv21_height - roi_h) / 2) / 2 * 2; } else { roi_h = nv21_height; roi_w = (nv21_height * win_w / win_h) / 2 * 2; roi_x = ((nv21_width - roi_w) / 2) / 2 * 2; roi_y = 0; } nv21_roi_x = roi_x; nv21_roi_y = roi_y; nv21_roi_w = roi_w; nv21_roi_h = roi_h; } if (final_orientation == 90 || final_orientation == 270) { if (win_w * nv21_width > win_h * nv21_height) { roi_w = nv21_height; roi_h = (nv21_height * win_h / win_w) / 2 * 2; roi_x = 0; roi_y = ((nv21_width - roi_h) / 2) / 2 * 2; } else { roi_h = nv21_width; roi_w = (nv21_width * win_w / win_h) / 2 * 2; roi_x = ((nv21_height - roi_w) / 2) / 2 * 2; roi_y = 0; } nv21_roi_x = roi_y; nv21_roi_y = roi_x; nv21_roi_w = roi_h; nv21_roi_h = roi_w; } if (camera_facing == 0) { if (camera_orientation == 0 && accelerometer_orientation == 0) { rotate_type = 2; } if (camera_orientation == 0 && accelerometer_orientation == 90) { rotate_type = 7; } if (camera_orientation == 0 && accelerometer_orientation == 180) { rotate_type = 4; } if (camera_orientation == 0 && accelerometer_orientation == 270) { rotate_type = 5; } if (camera_orientation == 90 && accelerometer_orientation == 0) { rotate_type = 5; } if (camera_orientation == 90 && accelerometer_orientation == 90) { rotate_type = 2; } if (camera_orientation == 90 && accelerometer_orientation == 180) { rotate_type = 7; } if (camera_orientation == 90 && accelerometer_orientation == 270) { rotate_type = 4; } if (camera_orientation == 180 && accelerometer_orientation == 0) { rotate_type = 4; } if (camera_orientation == 180 && accelerometer_orientation == 90) { rotate_type = 5; } if (camera_orientation == 180 && accelerometer_orientation == 180) { rotate_type = 2; } if (camera_orientation == 180 && accelerometer_orientation == 270) { rotate_type = 7; } if (camera_orientation == 270 && accelerometer_orientation == 0) { rotate_type = 7; } if (camera_orientation == 270 && accelerometer_orientation == 90) { rotate_type = 4; } if (camera_orientation == 270 && accelerometer_orientation == 180) { rotate_type = 5; } if (camera_orientation == 270 && accelerometer_orientation == 270) { rotate_type = 2; } } else { if (final_orientation == 0) { rotate_type = 1; } if (final_orientation == 90) { rotate_type = 6; } if (final_orientation == 180) { rotate_type = 3; } if (final_orientation == 270) { rotate_type = 8; } } if (accelerometer_orientation == 0) { render_w = roi_w; render_h = roi_h; render_rotate_type = 1; } if (accelerometer_orientation == 90) { render_w = roi_h; render_h = roi_w; render_rotate_type = 8; } if (accelerometer_orientation == 180) { render_w = roi_w; render_h = roi_h; render_rotate_type = 3; } if (accelerometer_orientation == 270) { render_w = roi_h; render_h = roi_w; render_rotate_type = 6; } } // crop and rotate nv21 cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1); { const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x; unsigned char* dstY = nv21_croprotated.data; ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type); const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x; unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h; ncnn::kanna_rotate_c2(srcUV, nv21_roi_w / 2, nv21_roi_h / 2, nv21_width, dstUV, roi_w / 2, roi_h / 2, roi_w, rotate_type); } // nv21_croprotated to rgb cv::Mat rgb(roi_h, roi_w, CV_8UC3); ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data); on_image_render(rgb); // rotate to native window orientation cv::Mat rgb_render(render_h, render_w, CV_8UC3); ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type); ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM); ANativeWindow_Buffer buf; ANativeWindow_lock(win, &buf, NULL); // scale to target size if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { for (int y = 0; y < render_h; y++) { const unsigned char* ptr = rgb_render.ptr(y); unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y; int x = 0; #if __ARM_NEON for (; x + 7 < render_w; x += 8) { uint8x8x3_t _rgb = vld3_u8(ptr); uint8x8x4_t _rgba; _rgba.val[0] = _rgb.val[0]; _rgba.val[1] = _rgb.val[1]; _rgba.val[2] = _rgb.val[2]; _rgba.val[3] = vdup_n_u8(255); vst4_u8(outptr, _rgba); ptr += 24; outptr += 32; } #endif // __ARM_NEON for (; x < render_w; x++) { outptr[0] = ptr[0]; outptr[1] = ptr[1]; outptr[2] = ptr[2]; outptr[3] = 255; ptr += 3; outptr += 4; } } } ANativeWindow_unlockAndPost(win); } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/ndkcamera.h ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #ifndef NDKCAMERA_H #define NDKCAMERA_H #include #include #include #include #include #include #include #include class NdkCamera { public: NdkCamera(); virtual ~NdkCamera(); // facing 0=front 1=back int open(int camera_facing = 0); void close(); virtual void on_image(const cv::Mat& rgb) const; virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const; public: int camera_facing; int camera_orientation; private: ACameraManager* camera_manager; ACameraDevice* camera_device; AImageReader* image_reader; ANativeWindow* image_reader_surface; ACameraOutputTarget* image_reader_target; ACaptureRequest* capture_request; ACaptureSessionOutputContainer* capture_session_output_container; ACaptureSessionOutput* capture_session_output; ACameraCaptureSession* capture_session; }; class NdkCameraWindow : public NdkCamera { public: NdkCameraWindow(); virtual ~NdkCameraWindow(); void set_window(ANativeWindow* win); virtual void on_image_render(cv::Mat& rgb) const; virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const; public: mutable int accelerometer_orientation; private: ASensorManager* sensor_manager; mutable ASensorEventQueue* sensor_event_queue; const ASensor* accelerometer_sensor; ANativeWindow* win; }; #endif // NDKCAMERA_H ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/scrfd.cpp ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include "scrfd.h" #include #include #include #include "cpu.h" static inline float intersection_area(const FaceObject& a, const FaceObject& b) { cv::Rect_ inter = a.rect & b.rect; return inter.area(); } static void qsort_descent_inplace(std::vector& faceobjects, int left, int right) { int i = left; int j = right; float p = faceobjects[(left + right) / 2].prob; while (i <= j) { while (faceobjects[i].prob > p) i++; while (faceobjects[j].prob < p) j--; if (i <= j) { // swap std::swap(faceobjects[i], faceobjects[j]); i++; j--; } } // #pragma omp parallel sections { // #pragma omp section { if (left < j) qsort_descent_inplace(faceobjects, left, j); } // #pragma omp section { if (i < right) qsort_descent_inplace(faceobjects, i, right); } } } static void qsort_descent_inplace(std::vector& faceobjects) { if (faceobjects.empty()) return; qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1); } static void nms_sorted_bboxes(const std::vector& faceobjects, std::vector& picked, float nms_threshold) { picked.clear(); const int n = faceobjects.size(); std::vector areas(n); for (int i = 0; i < n; i++) { areas[i] = faceobjects[i].rect.area(); } for (int i = 0; i < n; i++) { const FaceObject& a = faceobjects[i]; int keep = 1; for (int j = 0; j < (int)picked.size(); j++) { const FaceObject& b = faceobjects[picked[j]]; // intersection over union float inter_area = intersection_area(a, b); float union_area = areas[i] + areas[picked[j]] - inter_area; // float IoU = inter_area / union_area if (inter_area / union_area > nms_threshold) keep = 0; } if (keep) picked.push_back(i); } } // insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py gen_single_level_base_anchors() static ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales) { int num_ratio = ratios.w; int num_scale = scales.w; ncnn::Mat anchors; anchors.create(4, num_ratio * num_scale); const float cx = 0; const float cy = 0; for (int i = 0; i < num_ratio; i++) { float ar = ratios[i]; int r_w = round(base_size / sqrt(ar)); int r_h = round(r_w * ar); //round(base_size * sqrt(ar)); for (int j = 0; j < num_scale; j++) { float scale = scales[j]; float rs_w = r_w * scale; float rs_h = r_h * scale; float* anchor = anchors.row(i * num_scale + j); anchor[0] = cx - rs_w * 0.5f; anchor[1] = cy - rs_h * 0.5f; anchor[2] = cx + rs_w * 0.5f; anchor[3] = cy + rs_h * 0.5f; } } return anchors; } static void generate_proposals(const ncnn::Mat& anchors, int feat_stride, const ncnn::Mat& score_blob, const ncnn::Mat& bbox_blob, const ncnn::Mat& kps_blob, float prob_threshold, std::vector& faceobjects) { int w = score_blob.w; int h = score_blob.h; // generate face proposal from bbox deltas and shifted anchors const int num_anchors = anchors.h; for (int q = 0; q < num_anchors; q++) { const float* anchor = anchors.row(q); const ncnn::Mat score = score_blob.channel(q); const ncnn::Mat bbox = bbox_blob.channel_range(q * 4, 4); // shifted anchor float anchor_y = anchor[1]; float anchor_w = anchor[2] - anchor[0]; float anchor_h = anchor[3] - anchor[1]; for (int i = 0; i < h; i++) { float anchor_x = anchor[0]; for (int j = 0; j < w; j++) { int index = i * w + j; float prob = score[index]; if (prob >= prob_threshold) { // insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py _get_bboxes_single() float dx = bbox.channel(0)[index] * feat_stride; float dy = bbox.channel(1)[index] * feat_stride; float dw = bbox.channel(2)[index] * feat_stride; float dh = bbox.channel(3)[index] * feat_stride; // insightface/detection/scrfd/mmdet/core/bbox/transforms.py distance2bbox() float cx = anchor_x + anchor_w * 0.5f; float cy = anchor_y + anchor_h * 0.5f; float x0 = cx - dx; float y0 = cy - dy; float x1 = cx + dw; float y1 = cy + dh; FaceObject obj; obj.rect.x = x0; obj.rect.y = y0; obj.rect.width = x1 - x0 + 1; obj.rect.height = y1 - y0 + 1; obj.prob = prob; if (!kps_blob.empty()) { const ncnn::Mat kps = kps_blob.channel_range(q * 10, 10); obj.landmark[0].x = cx + kps.channel(0)[index] * feat_stride; obj.landmark[0].y = cy + kps.channel(1)[index] * feat_stride; obj.landmark[1].x = cx + kps.channel(2)[index] * feat_stride; obj.landmark[1].y = cy + kps.channel(3)[index] * feat_stride; obj.landmark[2].x = cx + kps.channel(4)[index] * feat_stride; obj.landmark[2].y = cy + kps.channel(5)[index] * feat_stride; obj.landmark[3].x = cx + kps.channel(6)[index] * feat_stride; obj.landmark[3].y = cy + kps.channel(7)[index] * feat_stride; obj.landmark[4].x = cx + kps.channel(8)[index] * feat_stride; obj.landmark[4].y = cy + kps.channel(9)[index] * feat_stride; } faceobjects.push_back(obj); } anchor_x += feat_stride; } anchor_y += feat_stride; } } } int SCRFD::load(const char* modeltype, bool use_gpu) { scrfd.clear(); ncnn::set_cpu_powersave(2); ncnn::set_omp_num_threads(ncnn::get_big_cpu_count()); scrfd.opt = ncnn::Option(); #if NCNN_VULKAN scrfd.opt.use_vulkan_compute = use_gpu; #endif scrfd.opt.num_threads = ncnn::get_big_cpu_count(); char parampath[256]; char modelpath[256]; sprintf(parampath, "scrfd_%s-opt2.param", modeltype); sprintf(modelpath, "scrfd_%s-opt2.bin", modeltype); scrfd.load_param(parampath); scrfd.load_model(modelpath); has_kps = strstr(modeltype, "_kps") != NULL; return 0; } int SCRFD::load(AAssetManager* mgr, const char* modeltype, bool use_gpu) { scrfd.clear(); ncnn::set_cpu_powersave(2); ncnn::set_omp_num_threads(ncnn::get_big_cpu_count()); scrfd.opt = ncnn::Option(); faceseg.opt = ncnn::Option(); facept.opt = ncnn::Option(); #if NCNN_VULKAN scrfd.opt.use_vulkan_compute = use_gpu; faceseg.opt.num_threads = ncnn::get_big_cpu_count(); #endif scrfd.opt.num_threads = ncnn::get_big_cpu_count(); faceseg.opt.num_threads = ncnn::get_big_cpu_count(); facept.opt.num_threads = ncnn::get_big_cpu_count(); char parampath[256]; char modelpath[256]; sprintf(parampath, "scrfd_%s-opt2.param", modeltype); sprintf(modelpath, "scrfd_%s-opt2.bin", modeltype); scrfd.load_param(mgr, parampath); scrfd.load_model(mgr, modelpath); faceseg.load_param(mgr,"faceseg-op.param"); faceseg.load_model(mgr,"faceseg-op.bin"); facept.load_param(mgr,"facemesh-op.param"); facept.load_model(mgr,"facemesh-op.bin"); has_kps = strstr(modeltype, "_kps") != NULL; return 0; } int SCRFD::detect(const cv::Mat& rgb, std::vector& faceobjects, float prob_threshold, float nms_threshold) { int width = rgb.cols; int height = rgb.rows; // insightface/detection/scrfd/configs/scrfd/scrfd_500m.py const int target_size = 640; // pad to multiple of 32 int w = width; int h = height; float scale = 1.f; if (w > h) { scale = (float)target_size / w; w = target_size; h = h * scale; } else { scale = (float)target_size / h; h = target_size; w = w * scale; } ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, width, height, w, h); // pad to target_size rectangle int wpad = (w + 31) / 32 * 32 - w; int hpad = (h + 31) / 32 * 32 - h; ncnn::Mat in_pad; ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f); const float mean_vals[3] = {127.5f, 127.5f, 127.5f}; const float norm_vals[3] = {1/128.f, 1/128.f, 1/128.f}; in_pad.substract_mean_normalize(mean_vals, norm_vals); ncnn::Extractor ex = scrfd.create_extractor(); ex.input("input.1", in_pad); std::vector faceproposals; // stride 8 { ncnn::Mat score_blob, bbox_blob, kps_blob; ex.extract("score_8", score_blob); ex.extract("bbox_8", bbox_blob); if (has_kps) ex.extract("kps_8", kps_blob); const int base_size = 16; const int feat_stride = 8; ncnn::Mat ratios(1); ratios[0] = 1.f; ncnn::Mat scales(2); scales[0] = 1.f; scales[1] = 2.f; ncnn::Mat anchors = generate_anchors(base_size, ratios, scales); std::vector faceobjects32; generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects32); faceproposals.insert(faceproposals.end(), faceobjects32.begin(), faceobjects32.end()); } // stride 16 { ncnn::Mat score_blob, bbox_blob, kps_blob; ex.extract("score_16", score_blob); ex.extract("bbox_16", bbox_blob); if (has_kps) ex.extract("kps_16", kps_blob); const int base_size = 64; const int feat_stride = 16; ncnn::Mat ratios(1); ratios[0] = 1.f; ncnn::Mat scales(2); scales[0] = 1.f; scales[1] = 2.f; ncnn::Mat anchors = generate_anchors(base_size, ratios, scales); std::vector faceobjects16; generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects16); faceproposals.insert(faceproposals.end(), faceobjects16.begin(), faceobjects16.end()); } // stride 32 { ncnn::Mat score_blob, bbox_blob, kps_blob; ex.extract("score_32", score_blob); ex.extract("bbox_32", bbox_blob); if (has_kps) ex.extract("kps_32", kps_blob); const int base_size = 256; const int feat_stride = 32; ncnn::Mat ratios(1); ratios[0] = 1.f; ncnn::Mat scales(2); scales[0] = 1.f; scales[1] = 2.f; ncnn::Mat anchors = generate_anchors(base_size, ratios, scales); std::vector faceobjects8; generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects8); faceproposals.insert(faceproposals.end(), faceobjects8.begin(), faceobjects8.end()); } // sort all proposals by score from highest to lowest qsort_descent_inplace(faceproposals); // apply nms with nms_threshold std::vector picked; nms_sorted_bboxes(faceproposals, picked, nms_threshold); int face_count = picked.size(); faceobjects.resize(face_count); for (int i = 0; i < face_count; i++) { faceobjects[i] = faceproposals[picked[i]]; // adjust offset to original unpadded float x0 = (faceobjects[i].rect.x - (wpad / 2)) / scale; float y0 = (faceobjects[i].rect.y - (hpad / 2)) / scale; float x1 = (faceobjects[i].rect.x + faceobjects[i].rect.width - (wpad / 2)) / scale; float y1 = (faceobjects[i].rect.y + faceobjects[i].rect.height - (hpad / 2)) / scale; x0 = std::max(std::min(x0, (float)width - 1), 0.f); y0 = std::max(std::min(y0, (float)height - 1), 0.f); x1 = std::max(std::min(x1, (float)width - 1), 0.f); y1 = std::max(std::min(y1, (float)height - 1), 0.f); faceobjects[i].rect.x = x0; faceobjects[i].rect.y = y0; faceobjects[i].rect.width = x1 - x0; faceobjects[i].rect.height = y1 - y0; if (has_kps) { float x0 = (faceobjects[i].landmark[0].x - (wpad / 2)) / scale; float y0 = (faceobjects[i].landmark[0].y - (hpad / 2)) / scale; float x1 = (faceobjects[i].landmark[1].x - (wpad / 2)) / scale; float y1 = (faceobjects[i].landmark[1].y - (hpad / 2)) / scale; float x2 = (faceobjects[i].landmark[2].x - (wpad / 2)) / scale; float y2 = (faceobjects[i].landmark[2].y - (hpad / 2)) / scale; float x3 = (faceobjects[i].landmark[3].x - (wpad / 2)) / scale; float y3 = (faceobjects[i].landmark[3].y - (hpad / 2)) / scale; float x4 = (faceobjects[i].landmark[4].x - (wpad / 2)) / scale; float y4 = (faceobjects[i].landmark[4].y - (hpad / 2)) / scale; faceobjects[i].landmark[0].x = std::max(std::min(x0, (float)width - 1), 0.f); faceobjects[i].landmark[0].y = std::max(std::min(y0, (float)height - 1), 0.f); faceobjects[i].landmark[1].x = std::max(std::min(x1, (float)width - 1), 0.f); faceobjects[i].landmark[1].y = std::max(std::min(y1, (float)height - 1), 0.f); faceobjects[i].landmark[2].x = std::max(std::min(x2, (float)width - 1), 0.f); faceobjects[i].landmark[2].y = std::max(std::min(y2, (float)height - 1), 0.f); faceobjects[i].landmark[3].x = std::max(std::min(x3, (float)width - 1), 0.f); faceobjects[i].landmark[3].y = std::max(std::min(y3, (float)height - 1), 0.f); faceobjects[i].landmark[4].x = std::max(std::min(x4, (float)width - 1), 0.f); faceobjects[i].landmark[4].y = std::max(std::min(y4, (float)height - 1), 0.f); } } return 0; } void SCRFD::seg(cv::Mat &rgb, const FaceObject &obj,cv::Mat &mask,cv::Rect &box) { int pad = obj.rect.height; box.x = (obj.rect.x+obj.rect.width/2)-pad/2-20; box.y = obj.rect.y-80; box.width = obj.rect.height+40; box.height = obj.rect.height+80; box.x = std::max(0.f,(float)box.x); box.y = std::max(0.f,(float)box.y); box.width = box.x+box.width &landmarks) { int pad = obj.rect.height; cv::Rect box; box.x = (obj.rect.x+obj.rect.width/2)-pad/2; box.y = obj.rect.y; box.width = obj.rect.height; box.height = obj.rect.height; box.x = std::max(0.f,(float)box.x); box.y = std::max(0.f,(float)box.y); box.width = box.x+box.width& faceobjects) { static const unsigned char face_part_colors[8][3] = {{0, 0, 255}, {255, 85, 0}, {255, 170, 0}, {255, 0, 85}, {255, 0, 170}, {0, 255, 0}, {170, 255, 255}, {255, 255, 255}}; for (size_t i = 0; i < faceobjects.size(); i++) { const FaceObject& obj = faceobjects[i]; //face segmentation /* cv::Mat mask = cv::Mat::zeros(256, 256, CV_8UC1); cv::Rect box; seg(rgb,obj,mask,box); cv::Mat maskResize; cv::resize(mask,maskResize,cv::Size(box.width,box.height),0,0,cv::INTER_NEAREST); for(size_t h = 0; h < maskResize.rows; h++) { cv::Vec3b* pRgb = rgb(box).ptr(h); for(size_t w = 0; w < maskResize.cols; w++) { int index = maskResize.at(h,w); if(index == 0) continue; pRgb[w] = cv::Vec3b(face_part_colors[index][2]*0.3+pRgb[w][2]*0.7, face_part_colors[index][1]*0.3+pRgb[w][1]*0.7, face_part_colors[index][0]*0.3+pRgb[w][0]*0.7); } } */ //mediapipe face mesh std::vector pts; landmark(rgb,obj,pts); for(int i = 0; i < pts.size(); i++) cv::circle(rgb,pts[i],2,cv::Scalar(255,255,0),-1); cv::rectangle(rgb, obj.rect, cv::Scalar(0, 255, 0)); if (has_kps) { cv::circle(rgb, obj.landmark[0], 2, cv::Scalar(255, 255, 0), -1); cv::circle(rgb, obj.landmark[1], 2, cv::Scalar(255, 255, 0), -1); cv::circle(rgb, obj.landmark[2], 2, cv::Scalar(255, 255, 0), -1); cv::circle(rgb, obj.landmark[3], 2, cv::Scalar(255, 255, 0), -1); cv::circle(rgb, obj.landmark[4], 2, cv::Scalar(255, 255, 0), -1); } char text[256]; sprintf(text, "%.1f%%", obj.prob * 100); int baseLine = 0; cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; if (y < 0) y = 0; if (x + label_size.width > rgb.cols) x = rgb.cols - label_size.width; cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1); cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1); } return 0; } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/scrfd.h ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #ifndef SCRFD_H #define SCRFD_H #include #include struct FaceObject { cv::Rect_ rect; cv::Point2f landmark[5]; float prob; }; class SCRFD { public: int load(const char* modeltype, bool use_gpu = false); int load(AAssetManager* mgr, const char* modeltype, bool use_gpu = false); int detect(const cv::Mat& rgb, std::vector& faceobjects, float prob_threshold = 0.5f, float nms_threshold = 0.45f); int draw(cv::Mat& rgb, const std::vector& faceobjects); void seg(cv::Mat &rgb,const FaceObject &obj,cv::Mat &mask,cv::Rect &box); void landmark(cv::Mat &rgb, const FaceObject &obj, std::vector &landmarks); private: const float meanVals[3] = { 123.675f, 116.28f, 103.53f }; const float normVals[3] = { 0.01712475f, 0.0175f, 0.01742919f }; ncnn::Net facept; ncnn::Net faceseg; ncnn::Net scrfd; bool has_kps; }; #endif // SCRFD_H ================================================ FILE: ncnn-android-scrfd-master/app/src/main/jni/scrfdncnn.cpp ================================================ // Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include #include #include #include #include #include #include #include #include #include "scrfd.h" #include "ndkcamera.h" #include #include #if __ARM_NEON #include #endif // __ARM_NEON static int draw_unsupported(cv::Mat& rgb) { const char text[] = "unsupported"; int baseLine = 0; cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine); int y = (rgb.rows - label_size.height) / 2; int x = (rgb.cols - label_size.width) / 2; cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1); cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0)); return 0; } static int draw_fps(cv::Mat& rgb) { // resolve moving average float avg_fps = 0.f; { static double t0 = 0.f; static float fps_history[10] = {0.f}; double t1 = ncnn::get_current_time(); if (t0 == 0.f) { t0 = t1; return 0; } float fps = 1000.f / (t1 - t0); t0 = t1; for (int i = 9; i >= 1; i--) { fps_history[i] = fps_history[i - 1]; } fps_history[0] = fps; if (fps_history[9] == 0.f) { return 0; } for (int i = 0; i < 10; i++) { avg_fps += fps_history[i]; } avg_fps /= 10.f; } char text[32]; sprintf(text, "FPS=%.2f", avg_fps); int baseLine = 0; cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); int y = 0; int x = rgb.cols - label_size.width; cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1); cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0)); return 0; } static SCRFD* g_scrfd = 0; static ncnn::Mutex lock; class MyNdkCamera : public NdkCameraWindow { public: virtual void on_image_render(cv::Mat& rgb) const; }; void MyNdkCamera::on_image_render(cv::Mat& rgb) const { // scrfd { ncnn::MutexLockGuard g(lock); if (g_scrfd) { std::vector faceobjects; g_scrfd->detect(rgb, faceobjects); g_scrfd->draw(rgb, faceobjects); } else { draw_unsupported(rgb); } } draw_fps(rgb); } static MyNdkCamera* g_camera = 0; extern "C" { JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnLoad"); g_camera = new MyNdkCamera; return JNI_VERSION_1_4; } JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved) { __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnUnload"); { ncnn::MutexLockGuard g(lock); delete g_scrfd; g_scrfd = 0; } delete g_camera; g_camera = 0; } // public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu); JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu) { if (modelid < 0 || modelid > 6 || cpugpu < 0 || cpugpu > 1) { return JNI_FALSE; } AAssetManager* mgr = AAssetManager_fromJava(env, assetManager); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "loadModel %p", mgr); const char* modeltypes[] = { "500m", "1g", }; const char* modeltype = modeltypes[(int)modelid]; bool use_gpu = (int)cpugpu == 1; // reload { ncnn::MutexLockGuard g(lock); if (use_gpu && ncnn::get_gpu_count() == 0) { // no gpu delete g_scrfd; g_scrfd = 0; } else { if (!g_scrfd) g_scrfd = new SCRFD; g_scrfd->load(mgr, modeltype, use_gpu); } } return JNI_TRUE; } // public native boolean openCamera(int facing); JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing) { if (facing < 0 || facing > 1) return JNI_FALSE; __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "openCamera %d", facing); g_camera->open((int)facing); return JNI_TRUE; } // public native boolean closeCamera(); JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_closeCamera(JNIEnv* env, jobject thiz) { __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "closeCamera"); g_camera->close(); return JNI_TRUE; } // public native boolean setOutputWindow(Surface surface); JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface) { ANativeWindow* win = ANativeWindow_fromSurface(env, surface); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "setOutputWindow %p", win); g_camera->set_window(win); return JNI_TRUE; } } ================================================ FILE: ncnn-android-scrfd-master/app/src/main/res/layout/main.xml ================================================