[
  {
    "path": "README.md",
    "content": "# ncnn_Android_face\nFace detect and segmentation, facemesh by ncnn  \n\n## model support:  \n1.scrfd  \n2.yolov5-face  \n3.yolov7-face  \n\n## A new mediapipe-blazeface demo in this place [new demo](https://github.com/FeiGeChuanShu/ncnn_Android_blazeface)  \n![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)  \n\n## Reference:  \nhttps://github.com/nihui/ncnn-android-scrfd  \nhttps://github.com/deepcam-cn/yolov5-face  \nhttps://github.com/Tencent/ncnn  \nhttps://github.com/thepowerfuldeez/facemesh.pytorch  \nhttps://github.com/derronqi/yolov7-face  \n"
  },
  {
    "path": "ncnn-android-scrfd-master/README.md",
    "content": "# ncnn-android-scrfd\n\nThe SCRFD face detection\n\nThis is a sample ncnn android project, it depends on ncnn library and opencv\n\nhttps://github.com/Tencent/ncnn\n\nhttps://github.com/nihui/opencv-mobile\n\n## android apk file download\nhttps://github.com/nihui/ncnn-android-scrfd/releases/download/v1/com.tencent.scrfdncnn-release.apk\n\n## how to build and run\n### step1\nhttps://github.com/Tencent/ncnn/releases\n\n* Download ncnn-YYYYMMDD-android-vulkan.zip or build ncnn for android yourself\n* 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**\n\n### step2\nhttps://github.com/nihui/opencv-mobile\n\n* Download opencv-mobile-XYZ-android.zip\n* 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**\n\n### step3\n* Open this project with Android Studio, build it and enjoy!\n\n## some notes\n* Android ndk camera is used for best efficiency\n* Crash may happen on very old devices for lacking HAL3 camera interface\n* All models are manually modified to accept dynamic input shape\n* Most small models run slower on GPU than on CPU, this is common\n* FPS may be lower in dark environment because of longer camera exposure time\n\n## screenshot\n![](screenshot.jpg)\n\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"29.0.2\"\n\n    defaultConfig {\n        applicationId \"com.tencent.scrfdncnn\"\n        archivesBaseName = \"$applicationId\"\n\n        minSdkVersion 24\n    }\n\n    externalNativeBuild {\n        cmake {\n            version \"3.10.2\"\n            path file('src/main/jni/CMakeLists.txt')\n        }\n    }\n\n    dependencies {\n        implementation 'com.android.support:support-v4:24.0.0'\n    }\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      package=\"com.tencent.scrfdncnn\"\n      android:versionCode=\"1\"\n      android:versionName=\"1.1\">\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-feature android:name=\"android.hardware.camera2.full\" />\n\n    <application android:label=\"@string/app_name\">\n        <activity android:name=\"MainActivity\"\n                  android:label=\"@string/app_name\"\n                  android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest> \n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/assets/facemesh-op.param",
    "content": "7767517\n123 144\nInput            input.1                  0 1 input.1\nMemoryData       200                      0 1 200 0=1\nMemoryData       264                      0 1 264 0=1\nMemoryData       328                      0 1 328 0=1\nPadding          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\nConvolution      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\nPReLU            PRelu_18                 1 1 140 142 0=16\nSplit            splitncnn_0              1 2 142 142_splitncnn_0 142_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_21                   2 1 144 142_splitncnn_0 145 0=0\nPReLU            PRelu_22                 1 1 145 147 0=16\nSplit            splitncnn_1              1 2 147 147_splitncnn_0 147_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_25                   2 1 149 147_splitncnn_0 150 0=0\nPReLU            PRelu_26                 1 1 150 152 0=16\nSplit            splitncnn_2              1 2 152 152_splitncnn_0 152_splitncnn_1\nPooling          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\nPadding          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_60                   2 1 203 201 204 0=0\nPReLU            PRelu_61                 1 1 204 206 0=32\nSplit            splitncnn_3              1 2 206 206_splitncnn_0 206_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_64                   2 1 208 206_splitncnn_0 209 0=0\nPReLU            PRelu_65                 1 1 209 211 0=32\nSplit            splitncnn_4              1 2 211 211_splitncnn_0 211_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_68                   2 1 213 211_splitncnn_0 214 0=0\nPReLU            PRelu_69                 1 1 214 216 0=32\nSplit            splitncnn_5              1 2 216 216_splitncnn_0 216_splitncnn_1\nPooling          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\nPadding          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_103                  2 1 267 265 268 0=0\nPReLU            PRelu_104                1 1 268 270 0=64\nSplit            splitncnn_6              1 2 270 270_splitncnn_0 270_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_107                  2 1 272 270_splitncnn_0 273 0=0\nPReLU            PRelu_108                1 1 273 275 0=64\nSplit            splitncnn_7              1 2 275 275_splitncnn_0 275_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_111                  2 1 277 275_splitncnn_0 278 0=0\nPReLU            PRelu_112                1 1 278 280 0=64\nSplit            splitncnn_8              1 2 280 280_splitncnn_0 280_splitncnn_1\nPooling          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\nPadding          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_146                  2 1 331 329 332 0=0\nPReLU            PRelu_147                1 1 332 334 0=128\nSplit            splitncnn_9              1 2 334 334_splitncnn_0 334_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_150                  2 1 336 334_splitncnn_0 337 0=0\nPReLU            PRelu_151                1 1 337 339 0=128\nSplit            splitncnn_10             1 2 339 339_splitncnn_0 339_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_154                  2 1 341 339_splitncnn_0 342 0=0\nPReLU            PRelu_155                1 1 342 344 0=128\nSplit            splitncnn_11             1 2 344 344_splitncnn_0 344_splitncnn_1\nPooling          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_174                  2 1 371 369 372 0=0\nPReLU            PRelu_175                1 1 372 374 0=128\nSplit            splitncnn_12             1 2 374 374_splitncnn_0 374_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_178                  2 1 376 374_splitncnn_0 377 0=0\nPReLU            PRelu_179                1 1 377 379 0=128\nSplit            splitncnn_13             1 2 379 379_splitncnn_0 379_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_182                  2 1 381 379_splitncnn_0 382 0=0\nPReLU            PRelu_183                1 1 382 384 0=128\nSplit            splitncnn_14             1 4 384 384_splitncnn_0 384_splitncnn_1 384_splitncnn_2 384_splitncnn_3\nPooling          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_202                  2 1 411 409 412 0=0\nPReLU            PRelu_203                1 1 412 414 0=128\nConvolution      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\nPReLU            PRelu_205                1 1 415 417 0=32\nSplit            splitncnn_15             1 2 417 417_splitncnn_0 417_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_208                  2 1 419 417_splitncnn_0 420 0=0\nPReLU            PRelu_209                1 1 420 422 0=32\nConvolution      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\nReshape          Reshape_213              1 1 423 428 0=-1\nPooling          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\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_232                  2 1 455 453 456 0=0\nPReLU            PRelu_233                1 1 456 458 0=128\nSplit            splitncnn_16             1 2 458 458_splitncnn_0 458_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_236                  2 1 460 458_splitncnn_0 461 0=0\nPReLU            PRelu_237                1 1 461 463 0=128\nSplit            splitncnn_17             1 2 463 463_splitncnn_0 463_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_240                  2 1 465 463_splitncnn_0 466 0=0\nPReLU            PRelu_241                1 1 466 468 0=128\nConvolution      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\nPReLU            PRelu_243                1 1 469 471 0=32\nSplit            splitncnn_18             1 2 471 471_splitncnn_0 471_splitncnn_1\nConvolutionDepthWise 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\nConvolution      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\nBinaryOp         Add_246                  2 1 473 471_splitncnn_0 474 0=0\nPReLU            PRelu_247                1 1 474 476 0=32\nConvolution      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\nReshape          Reshape_251              1 1 477 482 0=-1\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/assets/facemesh-op2.param",
    "content": "7767517\n166 206\nInput                    input                    0 1 input\nConvolution              550                      1 1 input 552 0=16 1=3 3=2 4=1 5=1 6=432 9=1\nSplit                    splitncnn_0              1 2 552 552_splitncnn_0 552_splitncnn_1\nConvolution              553                      1 1 552_splitncnn_1 555 0=8 1=1 5=1 6=128 9=1\nSplit                    splitncnn_1              1 2 555 555_splitncnn_0 555_splitncnn_1\nConvolutionDepthWise     556                      1 1 555_splitncnn_1 558 0=8 1=3 4=1 5=1 6=72 7=8 9=1\nConcat                   559                      2 1 555_splitncnn_0 558 559\nConvolution              560                      1 1 559 561 0=8 1=1 5=1 6=128\nSplit                    splitncnn_2              1 2 561 561_splitncnn_0 561_splitncnn_1\nConvolutionDepthWise     562                      1 1 561_splitncnn_1 563 0=8 1=3 4=1 5=1 6=72 7=8\nConcat                   564                      2 1 561_splitncnn_0 563 564\nBinaryOp                 565                      2 1 564 552_splitncnn_0 565\nSplit                    splitncnn_3              1 2 565 565_splitncnn_0 565_splitncnn_1\nConvolution              566                      1 1 565_splitncnn_1 568 0=24 1=1 5=1 6=384 9=1\nSplit                    splitncnn_4              1 2 568 568_splitncnn_0 568_splitncnn_1\nConvolutionDepthWise     569                      1 1 568_splitncnn_1 571 0=24 1=3 4=1 5=1 6=216 7=24 9=1\nConcat                   572                      2 1 568_splitncnn_0 571 572\nConvolutionDepthWise     573                      1 1 572 574 0=48 1=3 3=2 4=1 5=1 6=432 7=48\nConvolution              575                      1 1 574 576 0=12 1=1 5=1 6=576\nSplit                    splitncnn_5              1 2 576 576_splitncnn_0 576_splitncnn_1\nConvolutionDepthWise     577                      1 1 576_splitncnn_1 578 0=12 1=3 4=1 5=1 6=108 7=12\nConcat                   579                      2 1 576_splitncnn_0 578 579\nConvolutionDepthWise     580                      1 1 565_splitncnn_0 581 0=16 1=3 3=2 4=1 5=1 6=144 7=16\nConvolution              582                      1 1 581 583 0=24 1=1 5=1 6=384\nBinaryOp                 584                      2 1 579 583 584\nSplit                    splitncnn_6              1 2 584 584_splitncnn_0 584_splitncnn_1\nConvolution              585                      1 1 584_splitncnn_1 587 0=36 1=1 5=1 6=864 9=1\nSplit                    splitncnn_7              1 2 587 587_splitncnn_0 587_splitncnn_1\nConvolutionDepthWise     588                      1 1 587_splitncnn_1 590 0=36 1=3 4=1 5=1 6=324 7=36 9=1\nConcat                   591                      2 1 587_splitncnn_0 590 591\nConvolution              592                      1 1 591 593 0=12 1=1 5=1 6=864\nSplit                    splitncnn_8              1 2 593 593_splitncnn_0 593_splitncnn_1\nConvolutionDepthWise     594                      1 1 593_splitncnn_1 595 0=12 1=3 4=1 5=1 6=108 7=12\nConcat                   596                      2 1 593_splitncnn_0 595 596\nBinaryOp                 597                      2 1 596 584_splitncnn_0 597\nSplit                    splitncnn_9              1 2 597 597_splitncnn_0 597_splitncnn_1\nConvolution              598                      1 1 597_splitncnn_1 600 0=36 1=1 5=1 6=864 9=1\nSplit                    splitncnn_10             1 2 600 600_splitncnn_0 600_splitncnn_1\nConvolutionDepthWise     601                      1 1 600_splitncnn_1 603 0=36 1=3 4=1 5=1 6=324 7=36 9=1\nConcat                   604                      2 1 600_splitncnn_0 603 604\nConvolutionDepthWise     605                      1 1 604 606 0=72 1=5 3=2 4=2 5=1 6=1800 7=72\nSplit                    splitncnn_11             1 2 606 606_splitncnn_0 606_splitncnn_1\nPooling                  607                      1 1 606_splitncnn_1 607 0=1 4=1\nInnerProduct             608                      1 1 607 609 0=20 1=1 2=1440 9=1\nInnerProduct             610                      1 1 609 610 0=72 1=1 2=1440\nHardSigmoid              615                      1 1 610 615 0=1.666667e-01\nBinaryOp                 616                      2 1 606_splitncnn_0 615 616 0=2\nConvolution              617                      1 1 616 618 0=20 1=1 5=1 6=1440\nSplit                    splitncnn_12             1 2 618 618_splitncnn_0 618_splitncnn_1\nConvolutionDepthWise     619                      1 1 618_splitncnn_1 620 0=20 1=3 4=1 5=1 6=180 7=20\nConcat                   621                      2 1 618_splitncnn_0 620 621\nConvolutionDepthWise     622                      1 1 597_splitncnn_0 623 0=24 1=5 3=2 4=2 5=1 6=600 7=24\nConvolution              624                      1 1 623 625 0=40 1=1 5=1 6=960\nBinaryOp                 626                      2 1 621 625 626\nSplit                    splitncnn_13             1 2 626 626_splitncnn_0 626_splitncnn_1\nConvolution              627                      1 1 626_splitncnn_1 629 0=60 1=1 5=1 6=2400 9=1\nSplit                    splitncnn_14             1 2 629 629_splitncnn_0 629_splitncnn_1\nConvolutionDepthWise     630                      1 1 629_splitncnn_1 632 0=60 1=3 4=1 5=1 6=540 7=60 9=1\nConcat                   633                      2 1 629_splitncnn_0 632 633\nSplit                    splitncnn_15             1 2 633 633_splitncnn_0 633_splitncnn_1\nPooling                  634                      1 1 633_splitncnn_1 634 0=1 4=1\nInnerProduct             635                      1 1 634 636 0=32 1=1 2=3840 9=1\nInnerProduct             637                      1 1 636 637 0=120 1=1 2=3840\nHardSigmoid              642                      1 1 637 642 0=1.666667e-01\nBinaryOp                 643                      2 1 633_splitncnn_0 642 643 0=2\nConvolution              644                      1 1 643 645 0=20 1=1 5=1 6=2400\nSplit                    splitncnn_16             1 2 645 645_splitncnn_0 645_splitncnn_1\nConvolutionDepthWise     646                      1 1 645_splitncnn_1 647 0=20 1=3 4=1 5=1 6=180 7=20\nConcat                   648                      2 1 645_splitncnn_0 647 648\nBinaryOp                 649                      2 1 648 626_splitncnn_0 649\nSplit                    splitncnn_17             1 2 649 649_splitncnn_0 649_splitncnn_1\nConvolution              650                      1 1 649_splitncnn_1 652 0=120 1=1 5=1 6=4800 9=1\nSplit                    splitncnn_18             1 2 652 652_splitncnn_0 652_splitncnn_1\nConvolutionDepthWise     653                      1 1 652_splitncnn_1 655 0=120 1=3 4=1 5=1 6=1080 7=120 9=1\nConcat                   656                      2 1 652_splitncnn_0 655 656\nConvolutionDepthWise     657                      1 1 656 658 0=240 1=3 3=2 4=1 5=1 6=2160 7=240\nConvolution              659                      1 1 658 660 0=40 1=1 5=1 6=9600\nSplit                    splitncnn_19             1 2 660 660_splitncnn_0 660_splitncnn_1\nConvolutionDepthWise     661                      1 1 660_splitncnn_1 662 0=40 1=3 4=1 5=1 6=360 7=40\nConcat                   663                      2 1 660_splitncnn_0 662 663\nConvolutionDepthWise     664                      1 1 649_splitncnn_0 665 0=40 1=3 3=2 4=1 5=1 6=360 7=40\nConvolution              666                      1 1 665 667 0=80 1=1 5=1 6=3200\nBinaryOp                 668                      2 1 663 667 668\nSplit                    splitncnn_20             1 2 668 668_splitncnn_0 668_splitncnn_1\nConvolution              669                      1 1 668_splitncnn_1 671 0=100 1=1 5=1 6=8000 9=1\nSplit                    splitncnn_21             1 2 671 671_splitncnn_0 671_splitncnn_1\nConvolutionDepthWise     672                      1 1 671_splitncnn_1 674 0=100 1=3 4=1 5=1 6=900 7=100 9=1\nConcat                   675                      2 1 671_splitncnn_0 674 675\nConvolution              676                      1 1 675 677 0=40 1=1 5=1 6=8000\nSplit                    splitncnn_22             1 2 677 677_splitncnn_0 677_splitncnn_1\nConvolutionDepthWise     678                      1 1 677_splitncnn_1 679 0=40 1=3 4=1 5=1 6=360 7=40\nConcat                   680                      2 1 677_splitncnn_0 679 680\nBinaryOp                 681                      2 1 680 668_splitncnn_0 681\nSplit                    splitncnn_23             1 2 681 681_splitncnn_0 681_splitncnn_1\nConvolution              682                      1 1 681_splitncnn_1 684 0=92 1=1 5=1 6=7360 9=1\nSplit                    splitncnn_24             1 2 684 684_splitncnn_0 684_splitncnn_1\nConvolutionDepthWise     685                      1 1 684_splitncnn_1 687 0=92 1=3 4=1 5=1 6=828 7=92 9=1\nConcat                   688                      2 1 684_splitncnn_0 687 688\nConvolution              689                      1 1 688 690 0=40 1=1 5=1 6=7360\nSplit                    splitncnn_25             1 2 690 690_splitncnn_0 690_splitncnn_1\nConvolutionDepthWise     691                      1 1 690_splitncnn_1 692 0=40 1=3 4=1 5=1 6=360 7=40\nConcat                   693                      2 1 690_splitncnn_0 692 693\nBinaryOp                 694                      2 1 693 681_splitncnn_0 694\nSplit                    splitncnn_26             1 2 694 694_splitncnn_0 694_splitncnn_1\nConvolution              695                      1 1 694_splitncnn_1 697 0=92 1=1 5=1 6=7360 9=1\nSplit                    splitncnn_27             1 2 697 697_splitncnn_0 697_splitncnn_1\nConvolutionDepthWise     698                      1 1 697_splitncnn_1 700 0=92 1=3 4=1 5=1 6=828 7=92 9=1\nConcat                   701                      2 1 697_splitncnn_0 700 701\nConvolution              702                      1 1 701 703 0=40 1=1 5=1 6=7360\nSplit                    splitncnn_28             1 2 703 703_splitncnn_0 703_splitncnn_1\nConvolutionDepthWise     704                      1 1 703_splitncnn_1 705 0=40 1=3 4=1 5=1 6=360 7=40\nConcat                   706                      2 1 703_splitncnn_0 705 706\nBinaryOp                 707                      2 1 706 694_splitncnn_0 707\nSplit                    splitncnn_29             1 2 707 707_splitncnn_0 707_splitncnn_1\nConvolution              708                      1 1 707_splitncnn_1 710 0=240 1=1 5=1 6=19200 9=1\nSplit                    splitncnn_30             1 2 710 710_splitncnn_0 710_splitncnn_1\nConvolutionDepthWise     711                      1 1 710_splitncnn_1 713 0=240 1=3 4=1 5=1 6=2160 7=240 9=1\nConcat                   714                      2 1 710_splitncnn_0 713 714\nSplit                    splitncnn_31             1 2 714 714_splitncnn_0 714_splitncnn_1\nPooling                  715                      1 1 714_splitncnn_1 715 0=1 4=1\nInnerProduct             716                      1 1 715 717 0=120 1=1 2=57600 9=1\nInnerProduct             718                      1 1 717 718 0=480 1=1 2=57600\nHardSigmoid              723                      1 1 718 723 0=1.666667e-01\nBinaryOp                 724                      2 1 714_splitncnn_0 723 724 0=2\nConvolution              725                      1 1 724 726 0=56 1=1 5=1 6=26880\nSplit                    splitncnn_32             1 2 726 726_splitncnn_0 726_splitncnn_1\nConvolutionDepthWise     727                      1 1 726_splitncnn_1 728 0=56 1=3 4=1 5=1 6=504 7=56\nConcat                   729                      2 1 726_splitncnn_0 728 729\nConvolutionDepthWise     730                      1 1 707_splitncnn_0 731 0=80 1=3 4=1 5=1 6=720 7=80\nConvolution              732                      1 1 731 733 0=112 1=1 5=1 6=8960\nBinaryOp                 734                      2 1 729 733 734\nSplit                    splitncnn_33             1 2 734 734_splitncnn_0 734_splitncnn_1\nConvolution              735                      1 1 734_splitncnn_1 737 0=336 1=1 5=1 6=37632 9=1\nSplit                    splitncnn_34             1 2 737 737_splitncnn_0 737_splitncnn_1\nConvolutionDepthWise     738                      1 1 737_splitncnn_1 740 0=336 1=3 4=1 5=1 6=3024 7=336 9=1\nConcat                   741                      2 1 737_splitncnn_0 740 741\nSplit                    splitncnn_35             1 2 741 741_splitncnn_0 741_splitncnn_1\nPooling                  742                      1 1 741_splitncnn_1 742 0=1 4=1\nInnerProduct             743                      1 1 742 744 0=168 1=1 2=112896 9=1\nInnerProduct             745                      1 1 744 745 0=672 1=1 2=112896\nHardSigmoid              750                      1 1 745 750 0=1.666667e-01\nBinaryOp                 751                      2 1 741_splitncnn_0 750 751 0=2\nConvolution              752                      1 1 751 753 0=56 1=1 5=1 6=37632\nSplit                    splitncnn_36             1 2 753 753_splitncnn_0 753_splitncnn_1\nConvolutionDepthWise     754                      1 1 753_splitncnn_1 755 0=56 1=3 4=1 5=1 6=504 7=56\nConcat                   756                      2 1 753_splitncnn_0 755 756\nBinaryOp                 757                      2 1 756 734_splitncnn_0 757\nSplit                    splitncnn_37             1 2 757 757_splitncnn_0 757_splitncnn_1\nPooling                  758                      1 1 757_splitncnn_1 758 0=1 4=1\nInnerProduct             759                      1 1 758 761 0=28 1=1 2=3136 9=1\nInnerProduct             762                      1 1 761 764 0=112 1=1 2=3136 9=4\nBinaryOp                 765                      2 1 757_splitncnn_0 764 765 0=2\nConvolution              766                      1 1 765 768 0=224 1=1 5=1 6=25088 9=1\nConvolutionDepthWise     769                      1 1 768 771 0=224 1=3 4=1 5=1 6=2016 7=224 9=1\nConvolution              772                      1 1 771 773 0=32 1=1 5=1 6=7168\nSplit                    splitncnn_38             1 2 773 773_splitncnn_0 773_splitncnn_1\nPooling                  775                      1 1 773_splitncnn_1 775 0=1 1=14 2=14 5=1\nReshape                  783                      1 1 775 783 0=-1\nConvolution              784                      1 1 773_splitncnn_0 786 0=64 1=3 3=2 4=1 5=1 6=18432 9=1\nSplit                    splitncnn_39             1 2 786 786_splitncnn_0 786_splitncnn_1\nPooling                  788                      1 1 786_splitncnn_1 788 0=1 1=7 2=7 5=1\nReshape                  796                      1 1 788 796 0=-1\nConvolution              797                      1 1 786_splitncnn_0 798 0=256 1=7 5=1 6=802816 9=1\nReshape                  806                      1 1 798 806 0=-1\nConcat                   807                      3 1 783 796 806 807\nInnerProduct             output                   1 1 807 output 0=936 1=1 2=329472\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/assets/faceseg-op.param",
    "content": "7767517\n161 189\nInput                    input.1                  0 1 input\nConvolution              Conv_14                  1 1 input 363 0=32 1=3 3=2 4=1 5=1 6=864 9=1\nConvolution              Conv_17                  1 1 363 366 0=32 1=3 3=2 4=1 5=1 6=9216 9=1\nSplit                    splitncnn_0              1 2 366 366_splitncnn_0 366_splitncnn_1\nConvolution              Conv_20                  1 1 366_splitncnn_1 369 0=32 1=3 4=1 5=1 6=9216 9=1\nConvolution              Conv_23                  1 1 369 371 0=32 1=3 4=1 5=1 6=9216\nBinaryOp                 Add_25                   2 1 371 366_splitncnn_0 372\nReLU                     Relu_26                  1 1 372 373\nSplit                    splitncnn_1              1 2 373 373_splitncnn_0 373_splitncnn_1\nConvolution              Conv_27                  1 1 373_splitncnn_1 376 0=32 1=3 4=1 5=1 6=9216 9=1\nConvolution              Conv_30                  1 1 376 378 0=32 1=3 4=1 5=1 6=9216\nBinaryOp                 Add_32                   2 1 378 373_splitncnn_0 379\nReLU                     Relu_33                  1 1 379 380\nSplit                    splitncnn_2              1 2 380 380_splitncnn_0 380_splitncnn_1\nConvolution              Conv_34                  1 1 380_splitncnn_1 383 0=64 1=3 3=2 4=1 5=1 6=18432 9=1\nConvolution              Conv_37                  1 1 383 385 0=64 1=3 4=1 5=1 6=36864\nConvolution              Conv_39                  1 1 380_splitncnn_0 387 0=64 1=1 3=2 5=1 6=2048\nBinaryOp                 Add_41                   2 1 385 387 388\nReLU                     Relu_42                  1 1 388 389\nSplit                    splitncnn_3              1 2 389 389_splitncnn_0 389_splitncnn_1\nConvolution              Conv_43                  1 1 389_splitncnn_1 392 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_46                  1 1 392 394 0=64 1=3 4=1 5=1 6=36864\nBinaryOp                 Add_48                   2 1 394 389_splitncnn_0 395\nSplit                    splitncnn_4              1 2 395 395_splitncnn_0 395_splitncnn_1\nReLU                     Relu_49                  1 1 395_splitncnn_1 396\nSplit                    splitncnn_5              1 2 396 396_splitncnn_0 396_splitncnn_1\nConvolution              Conv_50                  1 1 396_splitncnn_1 399 0=128 1=3 3=2 4=1 5=1 6=73728 9=1\nConvolution              Conv_53                  1 1 399 401 0=128 1=3 4=1 5=1 6=147456\nConvolution              Conv_55                  1 1 396_splitncnn_0 403 0=128 1=1 3=2 5=1 6=8192\nBinaryOp                 Add_57                   2 1 401 403 404\nReLU                     Relu_58                  1 1 404 405\nSplit                    splitncnn_6              1 2 405 405_splitncnn_0 405_splitncnn_1\nConvolution              Conv_59                  1 1 405_splitncnn_1 408 0=128 1=3 4=1 5=1 6=147456 9=1\nConvolution              Conv_62                  1 1 408 410 0=128 1=3 4=1 5=1 6=147456\nBinaryOp                 Add_64                   2 1 410 405_splitncnn_0 411\nSplit                    splitncnn_7              1 2 411 411_splitncnn_0 411_splitncnn_1\nReLU                     Relu_65                  1 1 395_splitncnn_0 412\nSplit                    splitncnn_8              1 2 412 412_splitncnn_0 412_splitncnn_1\nConvolution              Conv_66                  1 1 412_splitncnn_1 415 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_69                  1 1 415 417 0=64 1=3 4=1 5=1 6=36864\nBinaryOp                 Add_71                   2 1 417 412_splitncnn_0 418\nReLU                     Relu_72                  1 1 418 419\nSplit                    splitncnn_9              1 2 419 419_splitncnn_0 419_splitncnn_1\nConvolution              Conv_73                  1 1 419_splitncnn_1 422 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_76                  1 1 422 424 0=64 1=3 4=1 5=1 6=36864\nBinaryOp                 Add_78                   2 1 424 419_splitncnn_0 425\nSplit                    splitncnn_10             1 2 425 425_splitncnn_0 425_splitncnn_1\nReLU                     Relu_79                  1 1 425_splitncnn_1 426\nConvolution              Conv_80                  1 1 426 428 0=128 1=3 3=2 4=1 5=1 6=73728\nBinaryOp                 Add_82                   2 1 411_splitncnn_1 428 429\nReLU                     Relu_83                  1 1 411_splitncnn_0 430\nConvolution              Conv_84                  1 1 430 432 0=64 1=1 5=1 6=8192\nInterp                   Resize_98                1 1 432 445 0=2 3=32 4=32\nBinaryOp                 Add_99                   2 1 425_splitncnn_0 445 446\nReLU                     Relu_100                 1 1 429 447\nSplit                    splitncnn_11             1 2 447 447_splitncnn_0 447_splitncnn_1\nConvolution              Conv_101                 1 1 447_splitncnn_1 450 0=256 1=3 3=2 4=1 5=1 6=294912 9=1\nConvolution              Conv_104                 1 1 450 452 0=256 1=3 4=1 5=1 6=589824\nConvolution              Conv_106                 1 1 447_splitncnn_0 454 0=256 1=1 3=2 5=1 6=32768\nBinaryOp                 Add_108                  2 1 452 454 455\nReLU                     Relu_109                 1 1 455 456\nSplit                    splitncnn_12             1 2 456 456_splitncnn_0 456_splitncnn_1\nConvolution              Conv_110                 1 1 456_splitncnn_1 459 0=256 1=3 4=1 5=1 6=589824 9=1\nConvolution              Conv_113                 1 1 459 461 0=256 1=3 4=1 5=1 6=589824\nBinaryOp                 Add_115                  2 1 461 456_splitncnn_0 462\nSplit                    splitncnn_13             1 2 462 462_splitncnn_0 462_splitncnn_1\nReLU                     Relu_116                 1 1 446 463\nSplit                    splitncnn_14             1 2 463 463_splitncnn_0 463_splitncnn_1\nConvolution              Conv_117                 1 1 463_splitncnn_1 466 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_120                 1 1 466 468 0=64 1=3 4=1 5=1 6=36864\nBinaryOp                 Add_122                  2 1 468 463_splitncnn_0 469\nReLU                     Relu_123                 1 1 469 470\nSplit                    splitncnn_15             1 2 470 470_splitncnn_0 470_splitncnn_1\nConvolution              Conv_124                 1 1 470_splitncnn_1 473 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_127                 1 1 473 475 0=64 1=3 4=1 5=1 6=36864\nBinaryOp                 Add_129                  2 1 475 470_splitncnn_0 476\nSplit                    splitncnn_16             1 2 476 476_splitncnn_0 476_splitncnn_1\nReLU                     Relu_130                 1 1 476_splitncnn_1 477\nConvolution              Conv_131                 1 1 477 480 0=128 1=3 3=2 4=1 5=1 6=73728 9=1\nConvolution              Conv_134                 1 1 480 482 0=256 1=3 3=2 4=1 5=1 6=294912\nBinaryOp                 Add_136                  2 1 462_splitncnn_1 482 483\nReLU                     Relu_137                 1 1 462_splitncnn_0 484\nConvolution              Conv_138                 1 1 484 486 0=64 1=1 5=1 6=16384\nInterp                   Resize_152               1 1 486 499 0=2 3=32 4=32\nBinaryOp                 Add_153                  2 1 476_splitncnn_0 499 500\nReLU                     Relu_154                 1 1 500 501\nSplit                    splitncnn_17             1 2 501 501_splitncnn_0 501_splitncnn_1\nConvolution              Conv_155                 1 1 501_splitncnn_1 504 0=64 1=1 5=1 6=4096 9=1\nConvolution              Conv_158                 1 1 504 507 0=64 1=3 4=1 5=1 6=36864 9=1\nConvolution              Conv_161                 1 1 507 509 0=128 1=1 5=1 6=8192\nConvolution              Conv_163                 1 1 501_splitncnn_0 511 0=128 1=1 5=1 6=8192\nBinaryOp                 Add_165                  2 1 509 511 512\nReLU                     Relu_166                 1 1 483 513\nSplit                    splitncnn_18             1 2 513 513_splitncnn_0 513_splitncnn_1\nConvolution              Conv_167                 1 1 513_splitncnn_1 516 0=256 1=1 5=1 6=65536 9=1\nConvolution              Conv_170                 1 1 516 519 0=256 1=3 3=2 4=1 5=1 6=589824 9=1\nConvolution              Conv_173                 1 1 519 521 0=512 1=1 5=1 6=131072\nConvolution              Conv_175                 1 1 513_splitncnn_0 523 0=512 1=1 3=2 5=1 6=131072\nBinaryOp                 Add_177                  2 1 521 523 524\nSplit                    splitncnn_19             1 6 524 524_splitncnn_0 524_splitncnn_1 524_splitncnn_2 524_splitncnn_3 524_splitncnn_4 524_splitncnn_5\nBatchNorm                BatchNormalization_184   1 1 524_splitncnn_5 531 0=512\nReLU                     Relu_185                 1 1 531 532\nConvolution              Conv_186                 1 1 532 533 0=128 1=1 6=65536\nSplit                    splitncnn_20             1 2 533 533_splitncnn_0 533_splitncnn_1\nPadding                  Pad_188                  1 1 524_splitncnn_4 535 0=1 1=1 2=1 3=1\nPooling                  AveragePool_189          1 1 535 536 0=1 1=3 2=2 5=1\nBatchNorm                BatchNormalization_190   1 1 536 537 0=512\nReLU                     Relu_191                 1 1 537 538\nConvolution              Conv_192                 1 1 538 539 0=128 1=1 6=65536\nInterp                   Resize_205               1 1 539 552 0=2 3=4 4=4\nBinaryOp                 Add_206                  2 1 552 533_splitncnn_1 553\nBatchNorm                BatchNormalization_207   1 1 553 554 0=128\nReLU                     Relu_208                 1 1 554 555\nConvolution              Conv_209                 1 1 555 556 0=128 1=3 4=1 6=147456\nSplit                    splitncnn_21             1 2 556 556_splitncnn_0 556_splitncnn_1\nPadding                  Pad_211                  1 1 524_splitncnn_3 558 0=2 1=2 2=2 3=2\nPooling                  AveragePool_212          1 1 558 559 0=1 1=5 2=4 5=1\nBatchNorm                BatchNormalization_213   1 1 559 560 0=512\nReLU                     Relu_214                 1 1 560 561\nConvolution              Conv_215                 1 1 561 562 0=128 1=1 6=65536\nInterp                   Resize_228               1 1 562 575 0=2 3=4 4=4\nBinaryOp                 Add_229                  2 1 575 556_splitncnn_1 576\nBatchNorm                BatchNormalization_230   1 1 576 577 0=128\nReLU                     Relu_231                 1 1 577 578\nConvolution              Conv_232                 1 1 578 579 0=128 1=3 4=1 6=147456\nSplit                    splitncnn_22             1 2 579 579_splitncnn_0 579_splitncnn_1\nPadding                  Pad_234                  1 1 524_splitncnn_2 581 0=4 1=4 2=4 3=4\nPooling                  AveragePool_235          1 1 581 582 0=1 1=9 2=8 5=1\nBatchNorm                BatchNormalization_236   1 1 582 583 0=512\nReLU                     Relu_237                 1 1 583 584\nConvolution              Conv_238                 1 1 584 585 0=128 1=1 6=65536\nInterp                   Resize_251               1 1 585 598 0=2 3=4 4=4\nBinaryOp                 Add_252                  2 1 598 579_splitncnn_1 599\nBatchNorm                BatchNormalization_253   1 1 599 600 0=128\nReLU                     Relu_254                 1 1 600 601\nConvolution              Conv_255                 1 1 601 602 0=128 1=3 4=1 6=147456\nSplit                    splitncnn_23             1 2 602 602_splitncnn_0 602_splitncnn_1\nPooling                  GlobalAveragePool_256    1 1 524_splitncnn_1 603 0=1 4=1\nBatchNorm                BatchNormalization_257   1 1 603 604 0=512\nReLU                     Relu_258                 1 1 604 605\nConvolution              Conv_259                 1 1 605 606 0=128 1=1 6=65536\nInterp                   Resize_272               1 1 606 619 0=2 3=4 4=4\nBinaryOp                 Add_273                  2 1 619 602_splitncnn_1 620\nBatchNorm                BatchNormalization_274   1 1 620 621 0=128\nReLU                     Relu_275                 1 1 621 622\nConvolution              Conv_276                 1 1 622 623 0=128 1=3 4=1 6=147456\nConcat                   Concat_277               5 1 533_splitncnn_0 556_splitncnn_0 579_splitncnn_0 602_splitncnn_0 623 624\nBatchNorm                BatchNormalization_278   1 1 624 625 0=640\nReLU                     Relu_279                 1 1 625 626\nConvolution              Conv_280                 1 1 626 627 0=128 1=1 6=81920\nBatchNorm                BatchNormalization_281   1 1 524_splitncnn_0 628 0=512\nReLU                     Relu_282                 1 1 628 629\nConvolution              Conv_283                 1 1 629 630 0=128 1=1 6=65536\nBinaryOp                 Add_284                  2 1 627 630 631\nInterp                   Resize_297               1 1 631 644 0=2 3=32 4=32\nBinaryOp                 Add_298                  2 1 644 512 645\nBatchNorm                BatchNormalization_299   1 1 645 646 0=128\nReLU                     Relu_300                 1 1 646 647\nConvolution              Conv_301                 1 1 647 650 0=64 1=3 4=1 5=1 6=73728 9=1\nConvolution              Conv_304                 1 1 650 651 0=8 1=1 5=1 6=512\nInterp                   Resize_313               1 1 651 output 0=2 3=256 4=256\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/assets/scrfd_1g-opt2.param",
    "content": "7767517\n99 108\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 193 0=32 1=3 3=2 4=1 5=1 6=864 9=1\nConvolutionDepthWise     Conv_2                   1 1 193 196 0=32 1=3 4=1 5=1 6=288 7=32 9=1\nConvolution              Conv_4                   1 1 196 199 0=48 1=1 5=1 6=1536 9=1\nConvolutionDepthWise     Conv_6                   1 1 199 202 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_8                   1 1 202 205 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_10                  1 1 205 208 0=48 1=3 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_12                  1 1 208 211 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_14                  1 1 211 214 0=48 1=3 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_16                  1 1 214 217 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_18                  1 1 217 220 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_20                  1 1 220 223 0=160 1=1 5=1 6=7680 9=1\nConvolutionDepthWise     Conv_22                  1 1 223 226 0=160 1=3 4=1 5=1 6=1440 7=160 9=1\nConvolution              Conv_24                  1 1 226 229 0=160 1=1 5=1 6=25600 9=1\nSplit                    splitncnn_0              1 2 229 229_splitncnn_0 229_splitncnn_1\nConvolutionDepthWise     Conv_26                  1 1 229_splitncnn_1 232 0=160 1=3 3=2 4=1 5=1 6=1440 7=160 9=1\nConvolution              Conv_28                  1 1 232 235 0=216 1=1 5=1 6=34560 9=1\nSplit                    splitncnn_1              1 2 235 235_splitncnn_0 235_splitncnn_1\nConvolutionDepthWise     Conv_30                  1 1 235_splitncnn_1 238 0=216 1=3 3=2 4=1 5=1 6=1944 7=216 9=1\nConvolution              Conv_32                  1 1 238 241 0=312 1=1 5=1 6=67392 9=1\nConvolutionDepthWise     Conv_34                  1 1 241 244 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_36                  1 1 244 247 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_38                  1 1 247 250 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_40                  1 1 250 253 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_42                  1 1 253 256 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_44                  1 1 256 259 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_46                  1 1 259 262 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_48                  1 1 262 265 0=312 1=1 5=1 6=97344 9=1\nConvolution              Conv_50                  1 1 229_splitncnn_0 266 0=24 1=1 5=1 6=3840\nConvolution              Conv_51                  1 1 235_splitncnn_0 267 0=24 1=1 5=1 6=5184\nConvolution              Conv_52                  1 1 265 268 0=24 1=1 5=1 6=7488\nSplit                    splitncnn_2              1 2 268 268_splitncnn_0 268_splitncnn_1\nInterp                   Resize_71                1 1 268_splitncnn_1 287 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_72                   2 1 267 287 288\nSplit                    splitncnn_3              1 2 288 288_splitncnn_0 288_splitncnn_1\nInterp                   Resize_91                1 1 288_splitncnn_1 307 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_92                   2 1 266 307 308\nConvolution              Conv_93                  1 1 308 309 0=24 1=3 4=1 5=1 6=5184\nSplit                    splitncnn_4              1 2 309 309_splitncnn_0 309_splitncnn_1\nConvolution              Conv_94                  1 1 288_splitncnn_0 310 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_95                  1 1 268_splitncnn_0 311 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_96                  1 1 309_splitncnn_1 312 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_97                   2 1 310 312 313\nSplit                    splitncnn_5              1 2 313 313_splitncnn_0 313_splitncnn_1\nConvolution              Conv_98                  1 1 313_splitncnn_1 314 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_99                   2 1 311 314 315\nConvolution              Conv_100                 1 1 313_splitncnn_0 316 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_101                 1 1 315 317 0=24 1=3 4=1 5=1 6=5184\nConvolutionDepthWise     Conv_102                 1 1 309_splitncnn_0 318 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_111                  1 1 318 329 0=8 1=24 2=1.000000e-05\nReLU                     Relu_112                 1 1 329 330\nConvolution              Conv_113                 1 1 330 331 0=96 1=1 6=2304\nGroupNorm                Add_122                  1 1 331 342 0=8 1=96 2=1.000000e-05\nReLU                     Relu_123                 1 1 342 343\nConvolutionDepthWise     Conv_124                 1 1 343 344 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_133                  1 1 344 355 0=8 1=96 2=1.000000e-05\nReLU                     Relu_134                 1 1 355 356\nConvolution              Conv_135                 1 1 356 357 0=96 1=1 6=9216\nGroupNorm                Add_144                  1 1 357 368 0=8 1=96 2=1.000000e-05\nReLU                     Relu_145                 1 1 368 369\nSplit                    splitncnn_6              1 2 369 369_splitncnn_0 369_splitncnn_1\nConvolution              Conv_146                 1 1 369_splitncnn_1 375 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_147                 1 1 369_splitncnn_0 371 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_148                  1 1 371 bbox_8 0=2 1=1 2=8.200800e-01\nSigmoid                  Sigmoid_152              1 1 375 score_8\nConvolutionDepthWise     Conv_156                 1 1 316 380 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_165                  1 1 380 391 0=8 1=24 2=1.000000e-05\nReLU                     Relu_166                 1 1 391 392\nConvolution              Conv_167                 1 1 392 393 0=96 1=1 6=2304\nGroupNorm                Add_176                  1 1 393 404 0=8 1=96 2=1.000000e-05\nReLU                     Relu_177                 1 1 404 405\nConvolutionDepthWise     Conv_178                 1 1 405 406 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_187                  1 1 406 417 0=8 1=96 2=1.000000e-05\nReLU                     Relu_188                 1 1 417 418\nConvolution              Conv_189                 1 1 418 419 0=96 1=1 6=9216\nGroupNorm                Add_198                  1 1 419 430 0=8 1=96 2=1.000000e-05\nReLU                     Relu_199                 1 1 430 431\nSplit                    splitncnn_7              1 2 431 431_splitncnn_0 431_splitncnn_1\nConvolution              Conv_200                 1 1 431_splitncnn_1 437 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_201                 1 1 431_splitncnn_0 433 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_202                  1 1 433 bbox_16 0=2 1=1 2=1.225648e+00\nSigmoid                  Sigmoid_206              1 1 437 score_16\nConvolutionDepthWise     Conv_210                 1 1 317 442 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_219                  1 1 442 453 0=8 1=24 2=1.000000e-05\nReLU                     Relu_220                 1 1 453 454\nConvolution              Conv_221                 1 1 454 455 0=96 1=1 6=2304\nGroupNorm                Add_230                  1 1 455 466 0=8 1=96 2=1.000000e-05\nReLU                     Relu_231                 1 1 466 467\nConvolutionDepthWise     Conv_232                 1 1 467 468 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_241                  1 1 468 479 0=8 1=96 2=1.000000e-05\nReLU                     Relu_242                 1 1 479 480\nConvolution              Conv_243                 1 1 480 481 0=96 1=1 6=9216\nGroupNorm                Add_252                  1 1 481 492 0=8 1=96 2=1.000000e-05\nReLU                     Relu_253                 1 1 492 493\nSplit                    splitncnn_8              1 2 493 493_splitncnn_0 493_splitncnn_1\nConvolution              Conv_254                 1 1 493_splitncnn_1 499 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_255                 1 1 493_splitncnn_0 495 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_256                  1 1 495 bbox_32 0=2 1=1 2=1.842380e+00\nSigmoid                  Sigmoid_260              1 1 499 score_32\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/assets/scrfd_500m-opt2.param",
    "content": "7767517\n103 112\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 217 0=16 1=3 3=2 4=1 5=1 6=432 9=1\nConvolutionDepthWise     Conv_2                   1 1 217 220 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_4                   1 1 220 223 0=16 1=1 5=1 6=256 9=1\nConvolutionDepthWise     Conv_6                   1 1 223 226 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_8                   1 1 226 229 0=40 1=1 5=1 6=640 9=1\nConvolutionDepthWise     Conv_10                  1 1 229 232 0=40 1=3 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_12                  1 1 232 235 0=40 1=1 5=1 6=1600 9=1\nConvolutionDepthWise     Conv_14                  1 1 235 238 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_16                  1 1 238 241 0=72 1=1 5=1 6=2880 9=1\nConvolutionDepthWise     Conv_18                  1 1 241 244 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_20                  1 1 244 247 0=72 1=1 5=1 6=5184 9=1\nConvolutionDepthWise     Conv_22                  1 1 247 250 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_24                  1 1 250 253 0=72 1=1 5=1 6=5184 9=1\nSplit                    splitncnn_0              1 2 253 253_splitncnn_0 253_splitncnn_1\nConvolutionDepthWise     Conv_26                  1 1 253_splitncnn_1 256 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_28                  1 1 256 259 0=152 1=1 5=1 6=10944 9=1\nConvolutionDepthWise     Conv_30                  1 1 259 262 0=152 1=3 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_32                  1 1 262 265 0=152 1=1 5=1 6=23104 9=1\nSplit                    splitncnn_1              1 2 265 265_splitncnn_0 265_splitncnn_1\nConvolutionDepthWise     Conv_34                  1 1 265_splitncnn_1 268 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_36                  1 1 268 271 0=288 1=1 5=1 6=43776 9=1\nConvolutionDepthWise     Conv_38                  1 1 271 274 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_40                  1 1 274 277 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_42                  1 1 277 280 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_44                  1 1 280 283 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_46                  1 1 283 286 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_48                  1 1 286 289 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_50                  1 1 289 292 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_52                  1 1 292 295 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_54                  1 1 295 298 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_56                  1 1 298 301 0=288 1=1 5=1 6=82944 9=1\nConvolution              Conv_58                  1 1 253_splitncnn_0 302 0=16 1=1 5=1 6=1152\nConvolution              Conv_59                  1 1 265_splitncnn_0 303 0=16 1=1 5=1 6=2432\nConvolution              Conv_60                  1 1 301 304 0=16 1=1 5=1 6=4608\nSplit                    splitncnn_2              1 2 304 304_splitncnn_0 304_splitncnn_1\nInterp                   Resize_79                1 1 304_splitncnn_1 323 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_80                   2 1 303 323 324\nSplit                    splitncnn_3              1 2 324 324_splitncnn_0 324_splitncnn_1\nInterp                   Resize_99                1 1 324_splitncnn_1 343 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_100                  2 1 302 343 344\nConvolution              Conv_101                 1 1 344 345 0=16 1=3 4=1 5=1 6=2304\nSplit                    splitncnn_4              1 2 345 345_splitncnn_0 345_splitncnn_1\nConvolution              Conv_102                 1 1 324_splitncnn_0 346 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_103                 1 1 304_splitncnn_0 347 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_104                 1 1 345_splitncnn_1 348 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_105                  2 1 346 348 349\nSplit                    splitncnn_5              1 2 349 349_splitncnn_0 349_splitncnn_1\nConvolution              Conv_106                 1 1 349_splitncnn_1 350 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_107                  2 1 347 350 351\nConvolution              Conv_108                 1 1 349_splitncnn_0 352 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_109                 1 1 351 353 0=16 1=3 4=1 5=1 6=2304\nConvolutionDepthWise     Conv_110                 1 1 345_splitncnn_0 354 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_119                  1 1 354 365 0=16 1=16 2=1.000000e-05\nReLU                     Relu_120                 1 1 365 366\nConvolution              Conv_121                 1 1 366 367 0=64 1=1 6=1024\nGroupNorm                Add_130                  1 1 367 378 0=16 1=64 2=1.000000e-05\nReLU                     Relu_131                 1 1 378 379\nConvolutionDepthWise     Conv_132                 1 1 379 380 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_141                  1 1 380 391 0=16 1=64 2=1.000000e-05\nReLU                     Relu_142                 1 1 391 392\nConvolution              Conv_143                 1 1 392 393 0=64 1=1 6=4096\nGroupNorm                Add_152                  1 1 393 404 0=16 1=64 2=1.000000e-05\nReLU                     Relu_153                 1 1 404 405\nSplit                    splitncnn_6              1 2 405 405_splitncnn_0 405_splitncnn_1\nConvolution              Conv_154                 1 1 405_splitncnn_1 411 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_155                 1 1 405_splitncnn_0 407 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_156                  1 1 407 bbox_8 0=2 1=1 2=7.957783e-01\nSigmoid                  Sigmoid_160              1 1 411 score_8\nConvolutionDepthWise     Conv_164                 1 1 352 416 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_173                  1 1 416 427 0=16 1=16 2=1.000000e-05\nReLU                     Relu_174                 1 1 427 428\nConvolution              Conv_175                 1 1 428 429 0=64 1=1 6=1024\nGroupNorm                Add_184                  1 1 429 440 0=16 1=64 2=1.000000e-05\nReLU                     Relu_185                 1 1 440 441\nConvolutionDepthWise     Conv_186                 1 1 441 442 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_195                  1 1 442 453 0=16 1=64 2=1.000000e-05\nReLU                     Relu_196                 1 1 453 454\nConvolution              Conv_197                 1 1 454 455 0=64 1=1 6=4096\nGroupNorm                Add_206                  1 1 455 466 0=16 1=64 2=1.000000e-05\nReLU                     Relu_207                 1 1 466 467\nSplit                    splitncnn_7              1 2 467 467_splitncnn_0 467_splitncnn_1\nConvolution              Conv_208                 1 1 467_splitncnn_1 473 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_209                 1 1 467_splitncnn_0 469 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_210                  1 1 469 bbox_16 0=2 1=1 2=1.201926e+00\nSigmoid                  Sigmoid_214              1 1 473 score_16\nConvolutionDepthWise     Conv_218                 1 1 353 478 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_227                  1 1 478 489 0=16 1=16 2=1.000000e-05\nReLU                     Relu_228                 1 1 489 490\nConvolution              Conv_229                 1 1 490 491 0=64 1=1 6=1024\nGroupNorm                Add_238                  1 1 491 502 0=16 1=64 2=1.000000e-05\nReLU                     Relu_239                 1 1 502 503\nConvolutionDepthWise     Conv_240                 1 1 503 504 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_249                  1 1 504 515 0=16 1=64 2=1.000000e-05\nReLU                     Relu_250                 1 1 515 516\nConvolution              Conv_251                 1 1 516 517 0=64 1=1 6=4096\nGroupNorm                Add_260                  1 1 517 528 0=16 1=64 2=1.000000e-05\nReLU                     Relu_261                 1 1 528 529\nSplit                    splitncnn_8              1 2 529 529_splitncnn_0 529_splitncnn_1\nConvolution              Conv_262                 1 1 529_splitncnn_1 535 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_263                 1 1 529_splitncnn_0 531 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_264                  1 1 531 bbox_32 0=2 1=1 2=1.992024e+00\nSigmoid                  Sigmoid_268              1 1 535 score_32\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/java/com/tencent/scrfdncnn/MainActivity.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.scrfdncnn;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.pm.PackageManager;\nimport android.graphics.PixelFormat;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.Surface;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.AdapterView;\nimport android.widget.Button;\nimport android.widget.Spinner;\n\nimport android.support.v4.app.ActivityCompat;\nimport android.support.v4.content.ContextCompat;\n\npublic class MainActivity extends Activity implements SurfaceHolder.Callback\n{\n    public static final int REQUEST_CAMERA = 100;\n\n    private SCRFDNcnn scrfdncnn = new SCRFDNcnn();\n    private int facing = 0;\n\n    private Spinner spinnerModel;\n    private Spinner spinnerCPUGPU;\n    private int current_model = 0;\n    private int current_cpugpu = 0;\n\n    private SurfaceView cameraView;\n\n    /** Called when the activity is first created. */\n    @Override\n    public void onCreate(Bundle savedInstanceState)\n    {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        cameraView = (SurfaceView) findViewById(R.id.cameraview);\n\n        cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);\n        cameraView.getHolder().addCallback(this);\n\n        Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);\n        buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View arg0) {\n\n                int new_facing = 1 - facing;\n\n                scrfdncnn.closeCamera();\n\n                scrfdncnn.openCamera(new_facing);\n\n                facing = new_facing;\n            }\n        });\n\n        spinnerModel = (Spinner) findViewById(R.id.spinnerModel);\n        spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_model)\n                {\n                    current_model = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);\n        spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_cpugpu)\n                {\n                    current_cpugpu = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        reload();\n    }\n\n    private void reload()\n    {\n        boolean ret_init = scrfdncnn.loadModel(getAssets(), current_model, current_cpugpu);\n        if (!ret_init)\n        {\n            Log.e(\"MainActivity\", \"scrfdncnn loadModel failed\");\n        }\n    }\n\n    @Override\n    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)\n    {\n        scrfdncnn.setOutputWindow(holder.getSurface());\n    }\n\n    @Override\n    public void surfaceCreated(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void surfaceDestroyed(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void onResume()\n    {\n        super.onResume();\n\n        if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED)\n        {\n            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA);\n        }\n\n        scrfdncnn.openCamera(facing);\n    }\n\n    @Override\n    public void onPause()\n    {\n        super.onPause();\n\n        scrfdncnn.closeCamera();\n    }\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.scrfdncnn;\n\nimport android.content.res.AssetManager;\nimport android.view.Surface;\n\npublic class SCRFDNcnn\n{\n    public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\n    public native boolean openCamera(int facing);\n    public native boolean closeCamera();\n    public native boolean setOutputWindow(Surface surface);\n\n    static {\n        System.loadLibrary(\"scrfdncnn\");\n    }\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/CMakeLists.txt",
    "content": "project(scrfdncnn)\n\ncmake_minimum_required(VERSION 3.10)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni)\nfind_package(OpenCV REQUIRED core imgproc)\n\nset(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210322-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)\nfind_package(ncnn REQUIRED)\n\nadd_library(scrfdncnn SHARED scrfdncnn.cpp scrfd.cpp ndkcamera.cpp)\n\ntarget_link_libraries(scrfdncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/ndkcamera.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"ndkcamera.h\"\n\n#include <string>\n\n#include <android/log.h>\n\n#include <opencv2/core/core.hpp>\n\n#include \"mat.h\"\n\nstatic void onDisconnected(void* context, ACameraDevice* device)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onDisconnected %p\", device);\n}\n\nstatic void onError(void* context, ACameraDevice* device, int error)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onError %p %d\", device, error);\n}\n\nstatic void onImageAvailable(void* context, AImageReader* reader)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onImageAvailable %p\", reader);\n\n    AImage* image = 0;\n    media_status_t status = AImageReader_acquireLatestImage(reader, &image);\n\n    if (status != AMEDIA_OK)\n    {\n        // error\n        return;\n    }\n\n    int32_t format;\n    AImage_getFormat(image, &format);\n\n    // assert format == AIMAGE_FORMAT_YUV_420_888\n\n    int32_t width = 0;\n    int32_t height = 0;\n    AImage_getWidth(image, &width);\n    AImage_getHeight(image, &height);\n\n    int32_t y_pixelStride = 0;\n    int32_t u_pixelStride = 0;\n    int32_t v_pixelStride = 0;\n    AImage_getPlanePixelStride(image, 0, &y_pixelStride);\n    AImage_getPlanePixelStride(image, 1, &u_pixelStride);\n    AImage_getPlanePixelStride(image, 2, &v_pixelStride);\n\n    int32_t y_rowStride = 0;\n    int32_t u_rowStride = 0;\n    int32_t v_rowStride = 0;\n    AImage_getPlaneRowStride(image, 0, &y_rowStride);\n    AImage_getPlaneRowStride(image, 1, &u_rowStride);\n    AImage_getPlaneRowStride(image, 2, &v_rowStride);\n\n    uint8_t* y_data = 0;\n    uint8_t* u_data = 0;\n    uint8_t* v_data = 0;\n    int y_len = 0;\n    int u_len = 0;\n    int v_len = 0;\n    AImage_getPlaneData(image, 0, &y_data, &y_len);\n    AImage_getPlaneData(image, 1, &u_data, &u_len);\n    AImage_getPlaneData(image, 2, &v_data, &v_len);\n\n    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)\n    {\n        // already nv21  :)\n        ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height);\n    }\n    else\n    {\n        // construct nv21\n        unsigned char* nv21 = new unsigned char[width * height + width * height / 2];\n        {\n            // Y\n            unsigned char* yptr = nv21;\n            for (int y=0; y<height; y++)\n            {\n                const unsigned char* y_data_ptr = y_data + y_rowStride * y;\n                for (int x=0; x<width; x++)\n                {\n                    yptr[0] = y_data_ptr[0];\n                    yptr++;\n                    y_data_ptr += y_pixelStride;\n                }\n            }\n\n            // UV\n            unsigned char* uvptr = nv21 + width * height;\n            for (int y=0; y<height/2; y++)\n            {\n                const unsigned char* v_data_ptr = v_data + v_rowStride * y;\n                const unsigned char* u_data_ptr = u_data + u_rowStride * y;\n                for (int x=0; x<width/2; x++)\n                {\n                    uvptr[0] = v_data_ptr[0];\n                    uvptr[1] = u_data_ptr[0];\n                    uvptr += 2;\n                    v_data_ptr += v_pixelStride;\n                    u_data_ptr += u_pixelStride;\n                }\n            }\n        }\n\n        ((NdkCamera*)context)->on_image((unsigned char*)nv21, (int)width, (int)height);\n\n        delete[] nv21;\n    }\n\n    AImage_delete(image);\n}\n\nstatic void onSessionActive(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionActive %p\", session);\n}\n\nstatic void onSessionReady(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionReady %p\", session);\n}\n\nstatic void onSessionClosed(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionClosed %p\", session);\n}\n\nvoid onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureFailed %p %p %p\", session, request, failure);\n}\n\nvoid onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceCompleted %p %d %ld\", session, sequenceId, frameNumber);\n}\n\nvoid onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceAborted %p %d\", session, sequenceId);\n}\n\nvoid onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureCompleted %p %p %p\", session, request, result);\n}\n\nNdkCamera::NdkCamera()\n{\n    camera_facing = 0;\n    camera_orientation = 0;\n\n    camera_manager = 0;\n    camera_device = 0;\n    image_reader = 0;\n    image_reader_surface = 0;\n    image_reader_target = 0;\n    capture_request = 0;\n    capture_session_output_container = 0;\n    capture_session_output = 0;\n    capture_session = 0;\n\n\n    // setup imagereader and its surface\n    {\n        AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader);\n\n        AImageReader_ImageListener listener;\n        listener.context = this;\n        listener.onImageAvailable = onImageAvailable;\n\n        AImageReader_setImageListener(image_reader, &listener);\n\n        AImageReader_getWindow(image_reader, &image_reader_surface);\n\n        ANativeWindow_acquire(image_reader_surface);\n    }\n}\n\nNdkCamera::~NdkCamera()\n{\n    close();\n\n    if (image_reader)\n    {\n        AImageReader_delete(image_reader);\n        image_reader = 0;\n    }\n\n    if (image_reader_surface)\n    {\n        ANativeWindow_release(image_reader_surface);\n        image_reader_surface = 0;\n    }\n}\n\nint NdkCamera::open(int _camera_facing)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open\");\n\n    camera_facing = _camera_facing;\n\n    camera_manager = ACameraManager_create();\n\n    // find front camera\n    std::string camera_id;\n    {\n        ACameraIdList* camera_id_list = 0;\n        ACameraManager_getCameraIdList(camera_manager, &camera_id_list);\n\n        for (int i = 0; i < camera_id_list->numCameras; ++i)\n        {\n            const char* id = camera_id_list->cameraIds[i];\n            ACameraMetadata* camera_metadata = 0;\n            ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata);\n\n            // query faceing\n            acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e);\n                facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];\n            }\n\n            if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            camera_id = id;\n\n            // query orientation\n            int orientation = 0;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e);\n\n                orientation = (int)e.data.i32[0];\n            }\n\n            camera_orientation = orientation;\n\n            ACameraMetadata_free(camera_metadata);\n\n            break;\n        }\n\n        ACameraManager_deleteCameraIdList(camera_id_list);\n    }\n\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open %s %d\", camera_id.c_str(), camera_orientation);\n\n    // open camera\n    {\n        ACameraDevice_StateCallbacks camera_device_state_callbacks;\n        camera_device_state_callbacks.context = this;\n        camera_device_state_callbacks.onDisconnected = onDisconnected;\n        camera_device_state_callbacks.onError = onError;\n\n        ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device);\n    }\n\n    // capture request\n    {\n        ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request);\n\n        ACameraOutputTarget_create(image_reader_surface, &image_reader_target);\n        ACaptureRequest_addTarget(capture_request, image_reader_target);\n    }\n\n    // capture session\n    {\n        ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks;\n        camera_capture_session_state_callbacks.context = this;\n        camera_capture_session_state_callbacks.onActive = onSessionActive;\n        camera_capture_session_state_callbacks.onReady = onSessionReady;\n        camera_capture_session_state_callbacks.onClosed = onSessionClosed;\n\n        ACaptureSessionOutputContainer_create(&capture_session_output_container);\n\n        ACaptureSessionOutput_create(image_reader_surface, &capture_session_output);\n\n        ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output);\n\n        ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);\n\n        ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks;\n        camera_capture_session_capture_callbacks.context = this;\n        camera_capture_session_capture_callbacks.onCaptureStarted = 0;\n        camera_capture_session_capture_callbacks.onCaptureProgressed = 0;\n        camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted;\n        camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed;\n        camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted;\n        camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted;\n        camera_capture_session_capture_callbacks.onCaptureBufferLost = 0;\n\n        ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr);\n    }\n\n    return 0;\n}\n\nvoid NdkCamera::close()\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"close\");\n\n    if (capture_session)\n    {\n        ACameraCaptureSession_stopRepeating(capture_session);\n        ACameraCaptureSession_close(capture_session);\n        capture_session = 0;\n    }\n\n    if (camera_device)\n    {\n        ACameraDevice_close(camera_device);\n        camera_device = 0;\n    }\n\n    if (capture_session_output_container)\n    {\n        ACaptureSessionOutputContainer_free(capture_session_output_container);\n        capture_session_output_container = 0;\n    }\n\n    if (capture_session_output)\n    {\n        ACaptureSessionOutput_free(capture_session_output);\n        capture_session_output = 0;\n    }\n\n    if (capture_request)\n    {\n        ACaptureRequest_free(capture_request);\n        capture_request = 0;\n    }\n\n    if (image_reader_target)\n    {\n        ACameraOutputTarget_free(image_reader_target);\n        image_reader_target = 0;\n    }\n\n    if (camera_manager)\n    {\n        ACameraManager_delete(camera_manager);\n        camera_manager = 0;\n    }\n}\n\nvoid NdkCamera::on_image(const cv::Mat& rgb) const\n{\n}\n\nvoid NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // rotate nv21\n    int w = 0;\n    int h = 0;\n    int rotate_type = 0;\n    {\n        if (camera_orientation == 0)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 2 : 1;\n        }\n        if (camera_orientation == 90)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 5 : 6;\n        }\n        if (camera_orientation == 180)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 4 : 3;\n        }\n        if (camera_orientation == 270)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 7 : 8;\n        }\n    }\n\n    cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1);\n    ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type);\n\n    // nv21_rotated to rgb\n    cv::Mat rgb(h, w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data);\n\n    on_image(rgb);\n}\n\nstatic const int NDKCAMERAWINDOW_ID = 233;\n\nNdkCameraWindow::NdkCameraWindow() : NdkCamera()\n{\n    sensor_manager = 0;\n    sensor_event_queue = 0;\n    accelerometer_sensor = 0;\n    win = 0;\n\n    accelerometer_orientation = 0;\n\n    // sensor\n    sensor_manager = ASensorManager_getInstance();\n\n    accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER);\n}\n\nNdkCameraWindow::~NdkCameraWindow()\n{\n    if (accelerometer_sensor)\n    {\n        ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor);\n        accelerometer_sensor = 0;\n    }\n\n    if (sensor_event_queue)\n    {\n        ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue);\n        sensor_event_queue = 0;\n    }\n\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n}\n\nvoid NdkCameraWindow::set_window(ANativeWindow* _win)\n{\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n\n    win = _win;\n    ANativeWindow_acquire(win);\n}\n\nvoid NdkCameraWindow::on_image_render(cv::Mat& rgb) const\n{\n}\n\nvoid NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // resolve orientation from camera_orientation and accelerometer_sensor\n    {\n        if (!sensor_event_queue)\n        {\n            sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0);\n\n            ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor);\n        }\n\n        int id = ALooper_pollAll(0, 0, 0, 0);\n        if (id == NDKCAMERAWINDOW_ID)\n        {\n            ASensorEvent e[8];\n            ssize_t num_event = 0;\n            while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1)\n            {\n                num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8);\n                if (num_event < 0)\n                    break;\n            }\n\n            if (num_event > 0)\n            {\n                float acceleration_x = e[num_event - 1].acceleration.x;\n                float acceleration_y = e[num_event - 1].acceleration.y;\n                float acceleration_z = e[num_event - 1].acceleration.z;\n//                 __android_log_print(ANDROID_LOG_WARN, \"NdkCameraWindow\", \"x = %f, y = %f, z = %f\", x, y, z);\n\n                if (acceleration_y > 7)\n                {\n                    accelerometer_orientation = 0;\n                }\n                if (acceleration_x < -7)\n                {\n                    accelerometer_orientation = 90;\n                }\n                if (acceleration_y < -7)\n                {\n                    accelerometer_orientation = 180;\n                }\n                if (acceleration_x > 7)\n                {\n                    accelerometer_orientation = 270;\n                }\n            }\n        }\n    }\n\n    // roi crop and rotate nv21\n    int nv21_roi_x = 0;\n    int nv21_roi_y = 0;\n    int nv21_roi_w = 0;\n    int nv21_roi_h = 0;\n    int roi_x = 0;\n    int roi_y = 0;\n    int roi_w = 0;\n    int roi_h = 0;\n    int rotate_type = 0;\n    int render_w = 0;\n    int render_h = 0;\n    int render_rotate_type = 0;\n    {\n        int win_w = ANativeWindow_getWidth(win);\n        int win_h = ANativeWindow_getHeight(win);\n\n        if (accelerometer_orientation == 90 || accelerometer_orientation == 270)\n        {\n            std::swap(win_w, win_h);\n        }\n\n        const int final_orientation = (camera_orientation + accelerometer_orientation) % 360;\n\n        if (final_orientation == 0 || final_orientation == 180)\n        {\n            if (win_w * nv21_height > win_h * nv21_width)\n            {\n                roi_w = nv21_width;\n                roi_h = (nv21_width * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_height - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_height;\n                roi_w = (nv21_height * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_width - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_x;\n            nv21_roi_y = roi_y;\n            nv21_roi_w = roi_w;\n            nv21_roi_h = roi_h;\n        }\n        if (final_orientation == 90 || final_orientation == 270)\n        {\n            if (win_w * nv21_width > win_h * nv21_height)\n            {\n                roi_w = nv21_height;\n                roi_h = (nv21_height * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_width - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_width;\n                roi_w = (nv21_width * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_height - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_y;\n            nv21_roi_y = roi_x;\n            nv21_roi_w = roi_h;\n            nv21_roi_h = roi_w;\n        }\n\n        if (camera_facing == 0)\n        {\n            if (camera_orientation == 0 && accelerometer_orientation == 0)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 90)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 180)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 270)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 0)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 90)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 180)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 270)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 0)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 90)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 180)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 270)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 0)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 90)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 180)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 270)\n            {\n                rotate_type = 2;\n            }\n        }\n        else\n        {\n            if (final_orientation == 0)\n            {\n                rotate_type = 1;\n            }\n            if (final_orientation == 90)\n            {\n                rotate_type = 6;\n            }\n            if (final_orientation == 180)\n            {\n                rotate_type = 3;\n            }\n            if (final_orientation == 270)\n            {\n                rotate_type = 8;\n            }\n        }\n\n        if (accelerometer_orientation == 0)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 1;\n        }\n        if (accelerometer_orientation == 90)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 8;\n        }\n        if (accelerometer_orientation == 180)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 3;\n        }\n        if (accelerometer_orientation == 270)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 6;\n        }\n    }\n\n    // crop and rotate nv21\n    cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1);\n    {\n        const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x;\n        unsigned char* dstY = nv21_croprotated.data;\n        ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type);\n\n        const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x;\n        unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h;\n        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);\n    }\n\n    // nv21_croprotated to rgb\n    cv::Mat rgb(roi_h, roi_w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data);\n\n    on_image_render(rgb);\n\n    // rotate to native window orientation\n    cv::Mat rgb_render(render_h, render_w, CV_8UC3);\n    ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type);\n\n    ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);\n\n    ANativeWindow_Buffer buf;\n    ANativeWindow_lock(win, &buf, NULL);\n\n    // scale to target size\n    if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)\n    {\n        for (int y = 0; y < render_h; y++)\n        {\n            const unsigned char* ptr = rgb_render.ptr<const unsigned char>(y);\n            unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y;\n\n            int x = 0;\n#if __ARM_NEON\n            for (; x + 7 < render_w; x += 8)\n            {\n                uint8x8x3_t _rgb = vld3_u8(ptr);\n                uint8x8x4_t _rgba;\n                _rgba.val[0] = _rgb.val[0];\n                _rgba.val[1] = _rgb.val[1];\n                _rgba.val[2] = _rgb.val[2];\n                _rgba.val[3] = vdup_n_u8(255);\n                vst4_u8(outptr, _rgba);\n\n                ptr += 24;\n                outptr += 32;\n            }\n#endif // __ARM_NEON\n            for (; x < render_w; x++)\n            {\n                outptr[0] = ptr[0];\n                outptr[1] = ptr[1];\n                outptr[2] = ptr[2];\n                outptr[3] = 255;\n\n                ptr += 3;\n                outptr += 4;\n            }\n        }\n    }\n\n    ANativeWindow_unlockAndPost(win);\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/ndkcamera.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef NDKCAMERA_H\n#define NDKCAMERA_H\n\n#include <android/looper.h>\n#include <android/native_window.h>\n#include <android/sensor.h>\n#include <camera/NdkCameraDevice.h>\n#include <camera/NdkCameraManager.h>\n#include <camera/NdkCameraMetadata.h>\n#include <media/NdkImageReader.h>\n\n#include <opencv2/core/core.hpp>\n\nclass NdkCamera\n{\npublic:\n    NdkCamera();\n    virtual ~NdkCamera();\n\n    // facing 0=front 1=back\n    int open(int camera_facing = 0);\n    void close();\n\n    virtual void on_image(const cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    int camera_facing;\n    int camera_orientation;\n\nprivate:\n    ACameraManager* camera_manager;\n    ACameraDevice* camera_device;\n    AImageReader* image_reader;\n    ANativeWindow* image_reader_surface;\n    ACameraOutputTarget* image_reader_target;\n    ACaptureRequest* capture_request;\n    ACaptureSessionOutputContainer* capture_session_output_container;\n    ACaptureSessionOutput* capture_session_output;\n    ACameraCaptureSession* capture_session;\n};\n\nclass NdkCameraWindow : public NdkCamera\n{\npublic:\n    NdkCameraWindow();\n    virtual ~NdkCameraWindow();\n\n    void set_window(ANativeWindow* win);\n\n    virtual void on_image_render(cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    mutable int accelerometer_orientation;\n\nprivate:\n    ASensorManager* sensor_manager;\n    mutable ASensorEventQueue* sensor_event_queue;\n    const ASensor* accelerometer_sensor;\n    ANativeWindow* win;\n};\n\n#endif // NDKCAMERA_H\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/scrfd.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"scrfd.h\"\n\n#include <string.h>\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#include \"cpu.h\"\n\nstatic inline float intersection_area(const FaceObject& a, const FaceObject& b)\n{\n    cv::Rect_<float> inter = a.rect & b.rect;\n    return inter.area();\n}\n\nstatic void qsort_descent_inplace(std::vector<FaceObject>& faceobjects, int left, int right)\n{\n    int i = left;\n    int j = right;\n    float p = faceobjects[(left + right) / 2].prob;\n\n    while (i <= j)\n    {\n        while (faceobjects[i].prob > p)\n            i++;\n\n        while (faceobjects[j].prob < p)\n            j--;\n\n        if (i <= j)\n        {\n            // swap\n            std::swap(faceobjects[i], faceobjects[j]);\n\n            i++;\n            j--;\n        }\n    }\n\n//     #pragma omp parallel sections\n    {\n//         #pragma omp section\n        {\n            if (left < j) qsort_descent_inplace(faceobjects, left, j);\n        }\n//         #pragma omp section\n        {\n            if (i < right) qsort_descent_inplace(faceobjects, i, right);\n        }\n    }\n}\n\nstatic void qsort_descent_inplace(std::vector<FaceObject>& faceobjects)\n{\n    if (faceobjects.empty())\n        return;\n\n    qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);\n}\n\nstatic void nms_sorted_bboxes(const std::vector<FaceObject>& faceobjects, std::vector<int>& picked, float nms_threshold)\n{\n    picked.clear();\n\n    const int n = faceobjects.size();\n\n    std::vector<float> areas(n);\n    for (int i = 0; i < n; i++)\n    {\n        areas[i] = faceobjects[i].rect.area();\n    }\n\n    for (int i = 0; i < n; i++)\n    {\n        const FaceObject& a = faceobjects[i];\n\n        int keep = 1;\n        for (int j = 0; j < (int)picked.size(); j++)\n        {\n            const FaceObject& b = faceobjects[picked[j]];\n\n            // intersection over union\n            float inter_area = intersection_area(a, b);\n            float union_area = areas[i] + areas[picked[j]] - inter_area;\n            //             float IoU = inter_area / union_area\n            if (inter_area / union_area > nms_threshold)\n                keep = 0;\n        }\n\n        if (keep)\n            picked.push_back(i);\n    }\n}\n\n// insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py gen_single_level_base_anchors()\nstatic ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales)\n{\n    int num_ratio = ratios.w;\n    int num_scale = scales.w;\n\n    ncnn::Mat anchors;\n    anchors.create(4, num_ratio * num_scale);\n\n    const float cx = 0;\n    const float cy = 0;\n\n    for (int i = 0; i < num_ratio; i++)\n    {\n        float ar = ratios[i];\n\n        int r_w = round(base_size / sqrt(ar));\n        int r_h = round(r_w * ar); //round(base_size * sqrt(ar));\n\n        for (int j = 0; j < num_scale; j++)\n        {\n            float scale = scales[j];\n\n            float rs_w = r_w * scale;\n            float rs_h = r_h * scale;\n\n            float* anchor = anchors.row(i * num_scale + j);\n\n            anchor[0] = cx - rs_w * 0.5f;\n            anchor[1] = cy - rs_h * 0.5f;\n            anchor[2] = cx + rs_w * 0.5f;\n            anchor[3] = cy + rs_h * 0.5f;\n        }\n    }\n\n    return anchors;\n}\n\nstatic 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<FaceObject>& faceobjects)\n{\n    int w = score_blob.w;\n    int h = score_blob.h;\n\n    // generate face proposal from bbox deltas and shifted anchors\n    const int num_anchors = anchors.h;\n\n    for (int q = 0; q < num_anchors; q++)\n    {\n        const float* anchor = anchors.row(q);\n\n        const ncnn::Mat score = score_blob.channel(q);\n        const ncnn::Mat bbox = bbox_blob.channel_range(q * 4, 4);\n\n        // shifted anchor\n        float anchor_y = anchor[1];\n\n        float anchor_w = anchor[2] - anchor[0];\n        float anchor_h = anchor[3] - anchor[1];\n\n        for (int i = 0; i < h; i++)\n        {\n            float anchor_x = anchor[0];\n\n            for (int j = 0; j < w; j++)\n            {\n                int index = i * w + j;\n\n                float prob = score[index];\n\n                if (prob >= prob_threshold)\n                {\n                    // insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py _get_bboxes_single()\n                    float dx = bbox.channel(0)[index] * feat_stride;\n                    float dy = bbox.channel(1)[index] * feat_stride;\n                    float dw = bbox.channel(2)[index] * feat_stride;\n                    float dh = bbox.channel(3)[index] * feat_stride;\n\n                    // insightface/detection/scrfd/mmdet/core/bbox/transforms.py distance2bbox()\n                    float cx = anchor_x + anchor_w * 0.5f;\n                    float cy = anchor_y + anchor_h * 0.5f;\n\n                    float x0 = cx - dx;\n                    float y0 = cy - dy;\n                    float x1 = cx + dw;\n                    float y1 = cy + dh;\n\n                    FaceObject obj;\n                    obj.rect.x = x0;\n                    obj.rect.y = y0;\n                    obj.rect.width = x1 - x0 + 1;\n                    obj.rect.height = y1 - y0 + 1;\n                    obj.prob = prob;\n\n                    if (!kps_blob.empty())\n                    {\n                        const ncnn::Mat kps = kps_blob.channel_range(q * 10, 10);\n\n                        obj.landmark[0].x = cx + kps.channel(0)[index] * feat_stride;\n                        obj.landmark[0].y = cy + kps.channel(1)[index] * feat_stride;\n                        obj.landmark[1].x = cx + kps.channel(2)[index] * feat_stride;\n                        obj.landmark[1].y = cy + kps.channel(3)[index] * feat_stride;\n                        obj.landmark[2].x = cx + kps.channel(4)[index] * feat_stride;\n                        obj.landmark[2].y = cy + kps.channel(5)[index] * feat_stride;\n                        obj.landmark[3].x = cx + kps.channel(6)[index] * feat_stride;\n                        obj.landmark[3].y = cy + kps.channel(7)[index] * feat_stride;\n                        obj.landmark[4].x = cx + kps.channel(8)[index] * feat_stride;\n                        obj.landmark[4].y = cy + kps.channel(9)[index] * feat_stride;\n                    }\n\n                    faceobjects.push_back(obj);\n                }\n\n                anchor_x += feat_stride;\n            }\n\n            anchor_y += feat_stride;\n        }\n    }\n}\n\nint SCRFD::load(const char* modeltype, bool use_gpu)\n{\n    scrfd.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    scrfd.opt = ncnn::Option();\n\n#if NCNN_VULKAN\n    scrfd.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    scrfd.opt.num_threads = ncnn::get_big_cpu_count();\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"scrfd_%s-opt2.param\", modeltype);\n    sprintf(modelpath, \"scrfd_%s-opt2.bin\", modeltype);\n\n    scrfd.load_param(parampath);\n    scrfd.load_model(modelpath);\n\n    has_kps = strstr(modeltype, \"_kps\") != NULL;\n\n    return 0;\n}\n\nint SCRFD::load(AAssetManager* mgr, const char* modeltype, bool use_gpu)\n{\n    scrfd.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    scrfd.opt = ncnn::Option();\n    faceseg.opt = ncnn::Option();\n    facept.opt = ncnn::Option();\n#if NCNN_VULKAN\n    scrfd.opt.use_vulkan_compute = use_gpu;\n    faceseg.opt.num_threads = ncnn::get_big_cpu_count();\n#endif\n\n    scrfd.opt.num_threads = ncnn::get_big_cpu_count();\n    faceseg.opt.num_threads = ncnn::get_big_cpu_count();\n    facept.opt.num_threads = ncnn::get_big_cpu_count();\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"scrfd_%s-opt2.param\", modeltype);\n    sprintf(modelpath, \"scrfd_%s-opt2.bin\", modeltype);\n\n    scrfd.load_param(mgr, parampath);\n    scrfd.load_model(mgr, modelpath);\n    faceseg.load_param(mgr,\"faceseg-op.param\");\n    faceseg.load_model(mgr,\"faceseg-op.bin\");\n    facept.load_param(mgr,\"facemesh-op.param\");\n    facept.load_model(mgr,\"facemesh-op.bin\");\n    has_kps = strstr(modeltype, \"_kps\") != NULL;\n\n    return 0;\n}\n\nint SCRFD::detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold, float nms_threshold)\n{\n    int width = rgb.cols;\n    int height = rgb.rows;\n\n    // insightface/detection/scrfd/configs/scrfd/scrfd_500m.py\n    const int target_size = 640;\n\n    // pad to multiple of 32\n    int w = width;\n    int h = height;\n    float scale = 1.f;\n    if (w > h)\n    {\n        scale = (float)target_size / w;\n        w = target_size;\n        h = h * scale;\n    }\n    else\n    {\n        scale = (float)target_size / h;\n        h = target_size;\n        w = w * scale;\n    }\n\n    ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, width, height, w, h);\n\n    // pad to target_size rectangle\n    int wpad = (w + 31) / 32 * 32 - w;\n    int hpad = (h + 31) / 32 * 32 - h;\n    ncnn::Mat in_pad;\n    ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f);\n\n    const float mean_vals[3] = {127.5f, 127.5f, 127.5f};\n    const float norm_vals[3] = {1/128.f, 1/128.f, 1/128.f};\n    in_pad.substract_mean_normalize(mean_vals, norm_vals);\n\n    ncnn::Extractor ex = scrfd.create_extractor();\n\n    ex.input(\"input.1\", in_pad);\n\n    std::vector<FaceObject> faceproposals;\n\n    // stride 8\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_8\", score_blob);\n        ex.extract(\"bbox_8\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_8\", kps_blob);\n\n        const int base_size = 16;\n        const int feat_stride = 8;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects32;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects32);\n\n        faceproposals.insert(faceproposals.end(), faceobjects32.begin(), faceobjects32.end());\n    }\n\n    // stride 16\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_16\", score_blob);\n        ex.extract(\"bbox_16\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_16\", kps_blob);\n\n        const int base_size = 64;\n        const int feat_stride = 16;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects16;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects16);\n\n        faceproposals.insert(faceproposals.end(), faceobjects16.begin(), faceobjects16.end());\n    }\n\n    // stride 32\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_32\", score_blob);\n        ex.extract(\"bbox_32\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_32\", kps_blob);\n\n        const int base_size = 256;\n        const int feat_stride = 32;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects8;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects8);\n\n        faceproposals.insert(faceproposals.end(), faceobjects8.begin(), faceobjects8.end());\n    }\n\n    // sort all proposals by score from highest to lowest\n    qsort_descent_inplace(faceproposals);\n\n    // apply nms with nms_threshold\n    std::vector<int> picked;\n    nms_sorted_bboxes(faceproposals, picked, nms_threshold);\n\n    int face_count = picked.size();\n\n    faceobjects.resize(face_count);\n    for (int i = 0; i < face_count; i++)\n    {\n        faceobjects[i] = faceproposals[picked[i]];\n\n        // adjust offset to original unpadded\n        float x0 = (faceobjects[i].rect.x - (wpad / 2)) / scale;\n        float y0 = (faceobjects[i].rect.y - (hpad / 2)) / scale;\n        float x1 = (faceobjects[i].rect.x + faceobjects[i].rect.width - (wpad / 2)) / scale;\n        float y1 = (faceobjects[i].rect.y + faceobjects[i].rect.height - (hpad / 2)) / scale;\n\n        x0 = std::max(std::min(x0, (float)width - 1), 0.f);\n        y0 = std::max(std::min(y0, (float)height - 1), 0.f);\n        x1 = std::max(std::min(x1, (float)width - 1), 0.f);\n        y1 = std::max(std::min(y1, (float)height - 1), 0.f);\n\n        faceobjects[i].rect.x = x0;\n        faceobjects[i].rect.y = y0;\n        faceobjects[i].rect.width = x1 - x0;\n        faceobjects[i].rect.height = y1 - y0;\n\n        if (has_kps)\n        {\n            float x0 = (faceobjects[i].landmark[0].x - (wpad / 2)) / scale;\n            float y0 = (faceobjects[i].landmark[0].y - (hpad / 2)) / scale;\n            float x1 = (faceobjects[i].landmark[1].x - (wpad / 2)) / scale;\n            float y1 = (faceobjects[i].landmark[1].y - (hpad / 2)) / scale;\n            float x2 = (faceobjects[i].landmark[2].x - (wpad / 2)) / scale;\n            float y2 = (faceobjects[i].landmark[2].y - (hpad / 2)) / scale;\n            float x3 = (faceobjects[i].landmark[3].x - (wpad / 2)) / scale;\n            float y3 = (faceobjects[i].landmark[3].y - (hpad / 2)) / scale;\n            float x4 = (faceobjects[i].landmark[4].x - (wpad / 2)) / scale;\n            float y4 = (faceobjects[i].landmark[4].y - (hpad / 2)) / scale;\n\n            faceobjects[i].landmark[0].x = std::max(std::min(x0, (float)width - 1), 0.f);\n            faceobjects[i].landmark[0].y = std::max(std::min(y0, (float)height - 1), 0.f);\n            faceobjects[i].landmark[1].x = std::max(std::min(x1, (float)width - 1), 0.f);\n            faceobjects[i].landmark[1].y = std::max(std::min(y1, (float)height - 1), 0.f);\n            faceobjects[i].landmark[2].x = std::max(std::min(x2, (float)width - 1), 0.f);\n            faceobjects[i].landmark[2].y = std::max(std::min(y2, (float)height - 1), 0.f);\n            faceobjects[i].landmark[3].x = std::max(std::min(x3, (float)width - 1), 0.f);\n            faceobjects[i].landmark[3].y = std::max(std::min(y3, (float)height - 1), 0.f);\n            faceobjects[i].landmark[4].x = std::max(std::min(x4, (float)width - 1), 0.f);\n            faceobjects[i].landmark[4].y = std::max(std::min(y4, (float)height - 1), 0.f);\n        }\n    }\n\n    return 0;\n}\nvoid SCRFD::seg(cv::Mat &rgb, const FaceObject &obj,cv::Mat &mask,cv::Rect &box)\n{\n    int pad = obj.rect.height;\n    box.x = (obj.rect.x+obj.rect.width/2)-pad/2-20;\n    box.y = obj.rect.y-80;\n    box.width = obj.rect.height+40;\n    box.height = obj.rect.height+80;\n\n    box.x = std::max(0.f,(float)box.x);\n    box.y = std::max(0.f,(float)box.y);\n    box.width = box.x+box.width<rgb.cols?box.width:rgb.cols-box.x-1;\n    box.height = box.y+box.height<rgb.rows?box.height:rgb.rows-box.y-1;\n\n    cv::Mat faceRoiImage = rgb(box).clone();\n    ncnn::Extractor ex_face = faceseg.create_extractor();\n    ncnn::Mat ncnn_in = ncnn::Mat::from_pixels_resize(faceRoiImage.data,ncnn::Mat::PIXEL_RGB, faceRoiImage.cols, faceRoiImage.rows,256,256);\n\n    ncnn_in.substract_mean_normalize(meanVals, normVals);\n    ex_face.input(\"input\",ncnn_in);\n    ncnn::Mat ncnn_out;\n    ex_face.extract(\"output\",ncnn_out);\n    float *scoredata = (float*)ncnn_out.data;\n\n    unsigned char * maskIndex = mask.data;\n    int h = mask.rows;\n    int w = mask.cols;\n    for (int i = 0; i < h; i++)\n    {\n        for (int j = 0; j < w; j++)\n        {\n            int maxk = 0;\n            float tmp = scoredata[0 * w * h + i * w + j];\n            for (int k = 0; k < 8; k++)\n            {\n                if (tmp < scoredata[k * w * h + i * w + j])\n                {\n                    tmp = scoredata[k * w * h + i * w + j];\n                    maxk = k;\n                }\n            }\n            maskIndex[i * w + j] = maxk;\n        }\n    }\n    //cv::resize(mask,mask,faceRoiImage.size(),0,0,cv::INTER_NEAREST);\n\n}\n\nvoid SCRFD::landmark(cv::Mat &rgb, const FaceObject &obj, std::vector<cv::Point2f> &landmarks)\n{\n    int pad = obj.rect.height;\n    cv::Rect box;\n\n    box.x = (obj.rect.x+obj.rect.width/2)-pad/2;\n    box.y = obj.rect.y;\n    box.width = obj.rect.height;\n    box.height = obj.rect.height;\n\n    box.x = std::max(0.f,(float)box.x);\n    box.y = std::max(0.f,(float)box.y);\n    box.width = box.x+box.width<rgb.cols?box.width:rgb.cols-box.x-1;\n    box.height = box.y+box.height<rgb.rows?box.height:rgb.rows-box.y-1;\n\n    cv::Mat faceRoiImage = rgb(box).clone();\n    ncnn::Extractor ex_face = facept.create_extractor();\n    ncnn::Mat ncnn_in = ncnn::Mat::from_pixels_resize(faceRoiImage.data,ncnn::Mat::PIXEL_RGB, faceRoiImage.cols, faceRoiImage.rows,192,192);\n    const float means[3] = { 127.5f, 127.5f,  127.5f };\n    const float norms[3] = { 1/127.5f, 1 / 127.5f, 1 / 127.5f };\n    ncnn_in.substract_mean_normalize(means, norms);\n    ex_face.input(\"input.1\",ncnn_in);\n    ncnn::Mat ncnn_out;\n    ex_face.extract(\"482\",ncnn_out);\n    float *scoredata = (float*)ncnn_out.data;\n    for(int i = 0; i < 468; i++)\n    {\n        cv::Point2f pt;\n        pt.x = scoredata[i*3]*box.width/192+box.x;\n        pt.y = scoredata[i*3+1]*box.width/192+box.y;\n        landmarks.push_back(pt);\n    }\n\n}\nint SCRFD::draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects)\n{\n    static const unsigned  char face_part_colors[8][3] = {{0, 0, 255}, {255, 85, 0}, {255, 170, 0},\n                                                     {255, 0, 85}, {255, 0, 170},\n                                                     {0, 255, 0}, {170, 255, 255}, {255, 255, 255}};\n    for (size_t i = 0; i < faceobjects.size(); i++)\n    {\n        const FaceObject& obj = faceobjects[i];\n        //face segmentation\n        /*\n        cv::Mat mask = cv::Mat::zeros(256, 256, CV_8UC1);\n        cv::Rect  box;\n        seg(rgb,obj,mask,box);\n        cv::Mat maskResize;\n        cv::resize(mask,maskResize,cv::Size(box.width,box.height),0,0,cv::INTER_NEAREST);\n\n        for(size_t h = 0; h < maskResize.rows; h++)\n        {\n            cv::Vec3b* pRgb = rgb(box).ptr<cv::Vec3b >(h);\n            for(size_t w = 0; w < maskResize.cols; w++)\n            {\n                int index = maskResize.at<uchar>(h,w);\n                if(index == 0)\n                    continue;\n                pRgb[w] = cv::Vec3b(face_part_colors[index][2]*0.3+pRgb[w][2]*0.7,\n                                    face_part_colors[index][1]*0.3+pRgb[w][1]*0.7,\n                                    face_part_colors[index][0]*0.3+pRgb[w][0]*0.7);\n            }\n        }\n         */\n\n        //mediapipe face mesh\n        std::vector<cv::Point2f> pts;\n        landmark(rgb,obj,pts);\n        for(int i = 0; i < pts.size(); i++)\n            cv::circle(rgb,pts[i],2,cv::Scalar(255,255,0),-1);\n\n        cv::rectangle(rgb, obj.rect, cv::Scalar(0, 255, 0));\n\n        if (has_kps)\n        {\n            cv::circle(rgb, obj.landmark[0], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[1], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[2], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[3], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[4], 2, cv::Scalar(255, 255, 0), -1);\n        }\n\n        char text[256];\n        sprintf(text, \"%.1f%%\", obj.prob * 100);\n\n        int baseLine = 0;\n        cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n        int x = obj.rect.x;\n        int y = obj.rect.y - label_size.height - baseLine;\n        if (y < 0)\n            y = 0;\n        if (x + label_size.width > rgb.cols)\n            x = rgb.cols - label_size.width;\n\n        cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1);\n\n        cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/scrfd.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef SCRFD_H\n#define SCRFD_H\n\n#include <opencv2/core/core.hpp>\n\n#include <net.h>\n\nstruct FaceObject\n{\n    cv::Rect_<float> rect;\n    cv::Point2f landmark[5];\n    float prob;\n};\n\nclass SCRFD\n{\npublic:\n    int load(const char* modeltype, bool use_gpu = false);\n\n    int load(AAssetManager* mgr, const char* modeltype, bool use_gpu = false);\n\n    int detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold = 0.5f, float nms_threshold = 0.45f);\n\n    int draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects);\n    void seg(cv::Mat &rgb,const FaceObject &obj,cv::Mat &mask,cv::Rect &box);\n    void landmark(cv::Mat &rgb, const FaceObject &obj, std::vector<cv::Point2f> &landmarks);\nprivate:\n    const float meanVals[3] = { 123.675f, 116.28f,  103.53f };\n    const float normVals[3] = { 0.01712475f, 0.0175f, 0.01742919f };\n    ncnn::Net facept;\n    ncnn::Net faceseg;\n    ncnn::Net scrfd;\n    bool has_kps;\n};\n\n#endif // SCRFD_H\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/jni/scrfdncnn.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include <android/asset_manager_jni.h>\n#include <android/native_window_jni.h>\n#include <android/native_window.h>\n\n#include <android/log.h>\n\n#include <jni.h>\n\n#include <string>\n#include <vector>\n\n#include <platform.h>\n#include <benchmark.h>\n\n#include \"scrfd.h\"\n\n#include \"ndkcamera.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#if __ARM_NEON\n#include <arm_neon.h>\n#endif // __ARM_NEON\n\nstatic int draw_unsupported(cv::Mat& rgb)\n{\n    const char text[] = \"unsupported\";\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine);\n\n    int y = (rgb.rows - label_size.height) / 2;\n    int x = (rgb.cols - label_size.width) / 2;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic int draw_fps(cv::Mat& rgb)\n{\n    // resolve moving average\n    float avg_fps = 0.f;\n    {\n        static double t0 = 0.f;\n        static float fps_history[10] = {0.f};\n\n        double t1 = ncnn::get_current_time();\n        if (t0 == 0.f)\n        {\n            t0 = t1;\n            return 0;\n        }\n\n        float fps = 1000.f / (t1 - t0);\n        t0 = t1;\n\n        for (int i = 9; i >= 1; i--)\n        {\n            fps_history[i] = fps_history[i - 1];\n        }\n        fps_history[0] = fps;\n\n        if (fps_history[9] == 0.f)\n        {\n            return 0;\n        }\n\n        for (int i = 0; i < 10; i++)\n        {\n            avg_fps += fps_history[i];\n        }\n        avg_fps /= 10.f;\n    }\n\n    char text[32];\n    sprintf(text, \"FPS=%.2f\", avg_fps);\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n    int y = 0;\n    int x = rgb.cols - label_size.width;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic SCRFD* g_scrfd = 0;\nstatic ncnn::Mutex lock;\n\nclass MyNdkCamera : public NdkCameraWindow\n{\npublic:\n    virtual void on_image_render(cv::Mat& rgb) const;\n};\n\nvoid MyNdkCamera::on_image_render(cv::Mat& rgb) const\n{\n    // scrfd\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (g_scrfd)\n        {\n            std::vector<FaceObject> faceobjects;\n            g_scrfd->detect(rgb, faceobjects);\n\n            g_scrfd->draw(rgb, faceobjects);\n        }\n        else\n        {\n            draw_unsupported(rgb);\n        }\n    }\n\n    draw_fps(rgb);\n}\n\nstatic MyNdkCamera* g_camera = 0;\n\nextern \"C\" {\n\nJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnLoad\");\n\n    g_camera = new MyNdkCamera;\n\n    return JNI_VERSION_1_4;\n}\n\nJNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnUnload\");\n\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        delete g_scrfd;\n        g_scrfd = 0;\n    }\n\n    delete g_camera;\n    g_camera = 0;\n}\n\n// public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu)\n{\n    if (modelid < 0 || modelid > 6 || cpugpu < 0 || cpugpu > 1)\n    {\n        return JNI_FALSE;\n    }\n\n    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"loadModel %p\", mgr);\n\n    const char* modeltypes[] =\n    {\n        \"500m\",\n        \"1g\",\n    };\n\n    const char* modeltype = modeltypes[(int)modelid];\n    bool use_gpu = (int)cpugpu == 1;\n\n    // reload\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (use_gpu && ncnn::get_gpu_count() == 0)\n        {\n            // no gpu\n            delete g_scrfd;\n            g_scrfd = 0;\n        }\n        else\n        {\n            if (!g_scrfd)\n                g_scrfd = new SCRFD;\n            g_scrfd->load(mgr, modeltype, use_gpu);\n        }\n    }\n\n    return JNI_TRUE;\n}\n\n// public native boolean openCamera(int facing);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing)\n{\n    if (facing < 0 || facing > 1)\n        return JNI_FALSE;\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"openCamera %d\", facing);\n\n    g_camera->open((int)facing);\n\n    return JNI_TRUE;\n}\n\n// public native boolean closeCamera();\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_closeCamera(JNIEnv* env, jobject thiz)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"closeCamera\");\n\n    g_camera->close();\n\n    return JNI_TRUE;\n}\n\n// public native boolean setOutputWindow(Surface surface);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)\n{\n    ANativeWindow* win = ANativeWindow_fromSurface(env, surface);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"setOutputWindow %p\", win);\n\n    g_camera->set_window(win);\n\n    return JNI_TRUE;\n}\n\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Button\n        android:id=\"@+id/buttonSwitchCamera\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"切换摄像头\" />\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Spinner\n        android:id=\"@+id/spinnerModel\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/model_array\" />\n\n    <Spinner\n        android:id=\"@+id/spinnerCPUGPU\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/cpugpu_array\" />\n\n    </LinearLayout>\n\n    <SurfaceView\n        android:id=\"@+id/cameraview\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "ncnn-android-scrfd-master/app/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">scrfdncnn</string>\n    <string-array name=\"model_array\">\n        <item>500m</item>\n        <item>1g</item>\n    </string-array>\n    <string-array name=\"cpugpu_array\">\n        <item>CPU</item>\n        <item>GPU</item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "ncnn-android-scrfd-master/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    repositories {\n        jcenter()\n        google()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        google()\n    }\n}\n"
  },
  {
    "path": "ncnn-android-scrfd-master/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sun Sep 08 23:09:42 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "ncnn-android-scrfd-master/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "ncnn-android-scrfd-master/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "ncnn-android-scrfd-master/local.properties",
    "content": "## This file must *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local configuration.\n#\n# Location of the SDK. This is only used by Gradle.\n# For customization when using a Version Control System, please read the\n# header note.\n#Mon May 17 14:14:17 CST 2021\nsdk.dir=D\\:\\\\Android\n"
  },
  {
    "path": "ncnn-android-scrfd-master/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"29.0.2\"\n\n    defaultConfig {\n        applicationId \"com.tencent.ncnnyoloface\"\n        archivesBaseName = \"$applicationId\"\n\n        minSdkVersion 24\n    }\n\n    externalNativeBuild {\n        cmake {\n            version \"3.10.2\"\n            path file('src/main/jni/CMakeLists.txt')\n        }\n    }\n\n    dependencies {\n        implementation 'com.android.support:support-v4:24.0.0'\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      package=\"com.tencent.ncnnyoloface\"\n      android:versionCode=\"1\"\n      android:versionName=\"1.1\">\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-feature android:name=\"android.hardware.camera2.full\" />\n\n    <application android:label=\"@string/app_name\">\n        <activity android:name=\"MainActivity\"\n                  android:label=\"@string/app_name\"\n                  android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest> \n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/assets/yolov5n-0.5.param",
    "content": "7767517\n224 251\nInput                    data                     0 1 data\nConvolution              Conv_0                   1 1 data 389 0=16 1=3 3=2 4=1 5=1 6=432\nSwish                    Mul_2                    1 1 389 391\nSplit                    splitncnn_0              1 2 391 391_splitncnn_0 391_splitncnn_1\nConvolution              Conv_3                   1 1 391_splitncnn_1 392 0=8 1=1 5=1 6=128\nSwish                    Mul_5                    1 1 392 394\nConvolution              Conv_6                   1 1 394 395 0=16 1=3 3=2 4=1 5=1 6=1152\nSwish                    Mul_8                    1 1 395 397\nPooling                  MaxPool_9                1 1 391_splitncnn_0 398 1=2 2=2\nConcat                   Concat_10                2 1 397 398 399\nConvolution              Conv_11                  1 1 399 400 0=16 1=1 5=1 6=512\nSwish                    Mul_13                   1 1 400 402\nSplit                    splitncnn_1              1 2 402 402_splitncnn_0 402_splitncnn_1\nConvolutionDepthWise     Conv_14                  1 1 402_splitncnn_1 796 0=16 1=3 3=2 4=1 5=1 6=144 7=16\nConvolution              Conv_15                  1 1 796 799 0=32 1=1 5=1 6=512\nSwish                    Mul_17                   1 1 799 408\nConvolution              Conv_18                  1 1 402_splitncnn_0 802 0=32 1=1 5=1 6=512\nSwish                    Mul_20                   1 1 802 412\nConvolutionDepthWise     Conv_21                  1 1 412 805 0=32 1=3 3=2 4=1 5=1 6=288 7=32\nConvolution              Conv_22                  1 1 805 808 0=32 1=1 5=1 6=1024\nSwish                    Mul_24                   1 1 808 418\nConcat                   Concat_25                2 1 408 418 419\nShuffleChannel           Reshape_30               1 1 419 424 0=2\nSlice                    Split_31                 1 2 424 425 426 -23300=2,32,-233\nConvolution              Conv_32                  1 1 426 811 0=32 1=1 5=1 6=1024\nSwish                    Mul_34                   1 1 811 430\nConvolutionDepthWise     Conv_35                  1 1 430 814 0=32 1=3 4=1 5=1 6=288 7=32\nConvolution              Conv_36                  1 1 814 817 0=32 1=1 5=1 6=1024\nSwish                    Mul_38                   1 1 817 436\nConcat                   Concat_39                2 1 425 436 437\nShuffleChannel           Reshape_44               1 1 437 442 0=2\nSlice                    Split_45                 1 2 442 443 444 -23300=2,32,-233\nConvolution              Conv_46                  1 1 444 820 0=32 1=1 5=1 6=1024\nSwish                    Mul_48                   1 1 820 448\nConvolutionDepthWise     Conv_49                  1 1 448 823 0=32 1=3 4=1 5=1 6=288 7=32\nConvolution              Conv_50                  1 1 823 826 0=32 1=1 5=1 6=1024\nSwish                    Mul_52                   1 1 826 454\nConcat                   Concat_53                2 1 443 454 455\nShuffleChannel           Reshape_58               1 1 455 460 0=2\nSlice                    Split_59                 1 2 460 461 462 -23300=2,32,-233\nConvolution              Conv_60                  1 1 462 829 0=32 1=1 5=1 6=1024\nSwish                    Mul_62                   1 1 829 466\nConvolutionDepthWise     Conv_63                  1 1 466 832 0=32 1=3 4=1 5=1 6=288 7=32\nConvolution              Conv_64                  1 1 832 835 0=32 1=1 5=1 6=1024\nSwish                    Mul_66                   1 1 835 472\nConcat                   Concat_67                2 1 461 472 473\nShuffleChannel           Reshape_72               1 1 473 478 0=2\nSplit                    splitncnn_2              1 3 478 478_splitncnn_0 478_splitncnn_1 478_splitncnn_2\nConvolutionDepthWise     Conv_73                  1 1 478_splitncnn_2 838 0=64 1=3 3=2 4=1 5=1 6=576 7=64\nConvolution              Conv_74                  1 1 838 841 0=64 1=1 5=1 6=4096\nSwish                    Mul_76                   1 1 841 484\nConvolution              Conv_77                  1 1 478_splitncnn_1 844 0=64 1=1 5=1 6=4096\nSwish                    Mul_79                   1 1 844 488\nConvolutionDepthWise     Conv_80                  1 1 488 847 0=64 1=3 3=2 4=1 5=1 6=576 7=64\nConvolution              Conv_81                  1 1 847 850 0=64 1=1 5=1 6=4096\nSwish                    Mul_83                   1 1 850 494\nConcat                   Concat_84                2 1 484 494 495\nShuffleChannel           Reshape_89               1 1 495 500 0=2\nSlice                    Split_90                 1 2 500 501 502 -23300=2,64,-233\nConvolution              Conv_91                  1 1 502 853 0=64 1=1 5=1 6=4096\nSwish                    Mul_93                   1 1 853 506\nConvolutionDepthWise     Conv_94                  1 1 506 856 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_95                  1 1 856 859 0=64 1=1 5=1 6=4096\nSwish                    Mul_97                   1 1 859 512\nConcat                   Concat_98                2 1 501 512 513\nShuffleChannel           Reshape_103              1 1 513 518 0=2\nSlice                    Split_104                1 2 518 519 520 -23300=2,64,-233\nConvolution              Conv_105                 1 1 520 862 0=64 1=1 5=1 6=4096\nSwish                    Mul_107                  1 1 862 524\nConvolutionDepthWise     Conv_108                 1 1 524 865 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_109                 1 1 865 868 0=64 1=1 5=1 6=4096\nSwish                    Mul_111                  1 1 868 530\nConcat                   Concat_112               2 1 519 530 531\nShuffleChannel           Reshape_117              1 1 531 536 0=2\nSlice                    Split_118                1 2 536 537 538 -23300=2,64,-233\nConvolution              Conv_119                 1 1 538 871 0=64 1=1 5=1 6=4096\nSwish                    Mul_121                  1 1 871 542\nConvolutionDepthWise     Conv_122                 1 1 542 874 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_123                 1 1 874 877 0=64 1=1 5=1 6=4096\nSwish                    Mul_125                  1 1 877 548\nConcat                   Concat_126               2 1 537 548 549\nShuffleChannel           Reshape_131              1 1 549 554 0=2\nSlice                    Split_132                1 2 554 555 556 -23300=2,64,-233\nConvolution              Conv_133                 1 1 556 880 0=64 1=1 5=1 6=4096\nSwish                    Mul_135                  1 1 880 560\nConvolutionDepthWise     Conv_136                 1 1 560 883 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_137                 1 1 883 886 0=64 1=1 5=1 6=4096\nSwish                    Mul_139                  1 1 886 566\nConcat                   Concat_140               2 1 555 566 567\nShuffleChannel           Reshape_145              1 1 567 572 0=2\nSlice                    Split_146                1 2 572 573 574 -23300=2,64,-233\nConvolution              Conv_147                 1 1 574 889 0=64 1=1 5=1 6=4096\nSwish                    Mul_149                  1 1 889 578\nConvolutionDepthWise     Conv_150                 1 1 578 892 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_151                 1 1 892 895 0=64 1=1 5=1 6=4096\nSwish                    Mul_153                  1 1 895 584\nConcat                   Concat_154               2 1 573 584 585\nShuffleChannel           Reshape_159              1 1 585 590 0=2\nSlice                    Split_160                1 2 590 591 592 -23300=2,64,-233\nConvolution              Conv_161                 1 1 592 898 0=64 1=1 5=1 6=4096\nSwish                    Mul_163                  1 1 898 596\nConvolutionDepthWise     Conv_164                 1 1 596 901 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_165                 1 1 901 904 0=64 1=1 5=1 6=4096\nSwish                    Mul_167                  1 1 904 602\nConcat                   Concat_168               2 1 591 602 603\nShuffleChannel           Reshape_173              1 1 603 608 0=2\nSlice                    Split_174                1 2 608 609 610 -23300=2,64,-233\nConvolution              Conv_175                 1 1 610 907 0=64 1=1 5=1 6=4096\nSwish                    Mul_177                  1 1 907 614\nConvolutionDepthWise     Conv_178                 1 1 614 910 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_179                 1 1 910 913 0=64 1=1 5=1 6=4096\nSwish                    Mul_181                  1 1 913 620\nConcat                   Concat_182               2 1 609 620 621\nShuffleChannel           Reshape_187              1 1 621 626 0=2\nSplit                    splitncnn_3              1 3 626 626_splitncnn_0 626_splitncnn_1 626_splitncnn_2\nConvolutionDepthWise     Conv_188                 1 1 626_splitncnn_2 916 0=128 1=3 3=2 4=1 5=1 6=1152 7=128\nConvolution              Conv_189                 1 1 916 919 0=128 1=1 5=1 6=16384\nSwish                    Mul_191                  1 1 919 632\nConvolution              Conv_192                 1 1 626_splitncnn_1 922 0=128 1=1 5=1 6=16384\nSwish                    Mul_194                  1 1 922 636\nConvolutionDepthWise     Conv_195                 1 1 636 925 0=128 1=3 3=2 4=1 5=1 6=1152 7=128\nConvolution              Conv_196                 1 1 925 928 0=128 1=1 5=1 6=16384\nSwish                    Mul_198                  1 1 928 642\nConcat                   Concat_199               2 1 632 642 643\nShuffleChannel           Reshape_204              1 1 643 648 0=2\nSlice                    Split_205                1 2 648 649 650 -23300=2,128,-233\nConvolution              Conv_206                 1 1 650 931 0=128 1=1 5=1 6=16384\nSwish                    Mul_208                  1 1 931 654\nConvolutionDepthWise     Conv_209                 1 1 654 934 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_210                 1 1 934 937 0=128 1=1 5=1 6=16384\nSwish                    Mul_212                  1 1 937 660\nConcat                   Concat_213               2 1 649 660 661\nShuffleChannel           Reshape_218              1 1 661 666 0=2\nSlice                    Split_219                1 2 666 667 668 -23300=2,128,-233\nConvolution              Conv_220                 1 1 668 940 0=128 1=1 5=1 6=16384\nSwish                    Mul_222                  1 1 940 672\nConvolutionDepthWise     Conv_223                 1 1 672 943 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_224                 1 1 943 946 0=128 1=1 5=1 6=16384\nSwish                    Mul_226                  1 1 946 678\nConcat                   Concat_227               2 1 667 678 679\nShuffleChannel           Reshape_232              1 1 679 684 0=2\nSlice                    Split_233                1 2 684 685 686 -23300=2,128,-233\nConvolution              Conv_234                 1 1 686 949 0=128 1=1 5=1 6=16384\nSwish                    Mul_236                  1 1 949 690\nConvolutionDepthWise     Conv_237                 1 1 690 952 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_238                 1 1 952 955 0=128 1=1 5=1 6=16384\nSwish                    Mul_240                  1 1 955 696\nConcat                   Concat_241               2 1 685 696 697\nShuffleChannel           Reshape_246              1 1 697 702 0=2\nConvolution              Conv_247                 1 1 702 703 0=64 1=1 5=1 6=16384\nSwish                    Mul_249                  1 1 703 705\nSplit                    splitncnn_4              1 2 705 705_splitncnn_0 705_splitncnn_1\nInterp                   Resize_251               1 1 705_splitncnn_1 710 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_252               2 1 710 626_splitncnn_0 711\nSplit                    splitncnn_5              1 2 711 711_splitncnn_0 711_splitncnn_1\nConvolution              Conv_253                 1 1 711_splitncnn_1 712 0=32 1=1 5=1 6=6144\nSwish                    Mul_255                  1 1 712 714\nConvolution              Conv_256                 1 1 714 715 0=32 1=1 5=1 6=1024\nSwish                    Mul_258                  1 1 715 717\nConvolution              Conv_259                 1 1 717 718 0=32 1=3 4=1 5=1 6=9216\nSwish                    Mul_261                  1 1 718 720\nConvolution              Conv_262                 1 1 711_splitncnn_0 721 0=32 1=1 5=1 6=6144\nSwish                    Mul_264                  1 1 721 723\nConcat                   Concat_265               2 1 720 723 724\nConvolution              Conv_266                 1 1 724 725 0=64 1=1 5=1 6=4096\nSwish                    Mul_268                  1 1 725 727\nConvolution              Conv_269                 1 1 727 728 0=64 1=1 5=1 6=4096\nSwish                    Mul_271                  1 1 728 730\nSplit                    splitncnn_6              1 2 730 730_splitncnn_0 730_splitncnn_1\nInterp                   Resize_273               1 1 730_splitncnn_1 735 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_274               2 1 735 478_splitncnn_0 736\nSplit                    splitncnn_7              1 2 736 736_splitncnn_0 736_splitncnn_1\nConvolution              Conv_275                 1 1 736_splitncnn_1 737 0=32 1=1 5=1 6=4096\nSwish                    Mul_277                  1 1 737 739\nConvolution              Conv_278                 1 1 739 740 0=32 1=1 5=1 6=1024\nSwish                    Mul_280                  1 1 740 742\nConvolution              Conv_281                 1 1 742 743 0=32 1=3 4=1 5=1 6=9216\nSwish                    Mul_283                  1 1 743 745\nConvolution              Conv_284                 1 1 736_splitncnn_0 746 0=32 1=1 5=1 6=4096\nSwish                    Mul_286                  1 1 746 748\nConcat                   Concat_287               2 1 745 748 749\nConvolution              Conv_288                 1 1 749 750 0=64 1=1 5=1 6=4096\nSwish                    Mul_290                  1 1 750 752\nSplit                    splitncnn_8              1 2 752 752_splitncnn_0 752_splitncnn_1\nConvolution              Conv_291                 1 1 752_splitncnn_1 753 0=64 1=3 3=2 4=1 5=1 6=36864\nSwish                    Mul_293                  1 1 753 755\nConcat                   Concat_294               2 1 755 730_splitncnn_0 756\nSplit                    splitncnn_9              1 2 756 756_splitncnn_0 756_splitncnn_1\nConvolution              Conv_295                 1 1 756_splitncnn_1 757 0=32 1=1 5=1 6=4096\nSwish                    Mul_297                  1 1 757 759\nConvolution              Conv_298                 1 1 759 760 0=32 1=1 5=1 6=1024\nSwish                    Mul_300                  1 1 760 762\nConvolution              Conv_301                 1 1 762 763 0=32 1=3 4=1 5=1 6=9216\nSwish                    Mul_303                  1 1 763 765\nConvolution              Conv_304                 1 1 756_splitncnn_0 766 0=32 1=1 5=1 6=4096\nSwish                    Mul_306                  1 1 766 768\nConcat                   Concat_307               2 1 765 768 769\nConvolution              Conv_308                 1 1 769 770 0=64 1=1 5=1 6=4096\nSwish                    Mul_310                  1 1 770 772\nSplit                    splitncnn_10             1 2 772 772_splitncnn_0 772_splitncnn_1\nConvolution              Conv_311                 1 1 772_splitncnn_1 773 0=64 1=3 3=2 4=1 5=1 6=36864\nSwish                    Mul_313                  1 1 773 775\nConcat                   Concat_314               2 1 775 705_splitncnn_0 776\nSplit                    splitncnn_11             1 2 776 776_splitncnn_0 776_splitncnn_1\nConvolution              Conv_315                 1 1 776_splitncnn_1 777 0=32 1=1 5=1 6=4096\nSwish                    Mul_317                  1 1 777 779\nConvolution              Conv_318                 1 1 779 780 0=32 1=1 5=1 6=1024\nSwish                    Mul_320                  1 1 780 782\nConvolution              Conv_321                 1 1 782 783 0=32 1=3 4=1 5=1 6=9216\nSwish                    Mul_323                  1 1 783 785\nConvolution              Conv_324                 1 1 776_splitncnn_0 786 0=32 1=1 5=1 6=4096\nSwish                    Mul_326                  1 1 786 788\nConcat                   Concat_327               2 1 785 788 789\nConvolution              Conv_328                 1 1 789 790 0=64 1=1 5=1 6=4096\nSwish                    Mul_330                  1 1 790 792\nConvolution              Conv_331                 1 1 752_splitncnn_0 stride_8 0=48 1=1 5=1 6=3072\nConvolution              Conv_332                 1 1 772_splitncnn_0 stride_16 0=48 1=1 5=1 6=3072\nConvolution              Conv_333                 1 1 792 stride_32 0=48 1=1 5=1 6=3072\nReshape                  Reshape_573              1 1 stride_8 980 0=-1 1=16 2=3\nPermute                  Transpose_574            1 1 980 981 0=1\nReshape                  Reshape_589              1 1 stride_16 982 0=-1 1=16 2=3\nPermute                  Transpose_590            1 1 982 983 0=1\nReshape                  Reshape_605              1 1 stride_32 984 0=-1 1=16 2=3\nPermute                  Transpose_606            1 1 984 985 0=1"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/assets/yolov5n.param",
    "content": "7767517\n224 251\nInput                    data                     0 1 data\nConvolution              Conv_0                   1 1 data 389 0=32 1=3 3=2 4=1 5=1 6=864\nSwish                    Mul_2                    1 1 389 391\nSplit                    splitncnn_0              1 2 391 391_splitncnn_0 391_splitncnn_1\nConvolution              Conv_3                   1 1 391_splitncnn_1 392 0=16 1=1 5=1 6=512\nSwish                    Mul_5                    1 1 392 394\nConvolution              Conv_6                   1 1 394 395 0=32 1=3 3=2 4=1 5=1 6=4608\nSwish                    Mul_8                    1 1 395 397\nPooling                  MaxPool_9                1 1 391_splitncnn_0 398 1=2 2=2\nConcat                   Concat_10                2 1 397 398 399\nConvolution              Conv_11                  1 1 399 400 0=32 1=1 5=1 6=2048\nSwish                    Mul_13                   1 1 400 402\nSplit                    splitncnn_1              1 2 402 402_splitncnn_0 402_splitncnn_1\nConvolutionDepthWise     Conv_14                  1 1 402_splitncnn_1 796 0=32 1=3 3=2 4=1 5=1 6=288 7=32\nConvolution              Conv_15                  1 1 796 799 0=64 1=1 5=1 6=2048\nSwish                    Mul_17                   1 1 799 408\nConvolution              Conv_18                  1 1 402_splitncnn_0 802 0=64 1=1 5=1 6=2048\nSwish                    Mul_20                   1 1 802 412\nConvolutionDepthWise     Conv_21                  1 1 412 805 0=64 1=3 3=2 4=1 5=1 6=576 7=64\nConvolution              Conv_22                  1 1 805 808 0=64 1=1 5=1 6=4096\nSwish                    Mul_24                   1 1 808 418\nConcat                   Concat_25                2 1 408 418 419\nShuffleChannel           Reshape_30               1 1 419 424 0=2\nSlice                    Split_31                 1 2 424 425 426 -23300=2,64,-233\nConvolution              Conv_32                  1 1 426 811 0=64 1=1 5=1 6=4096\nSwish                    Mul_34                   1 1 811 430\nConvolutionDepthWise     Conv_35                  1 1 430 814 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_36                  1 1 814 817 0=64 1=1 5=1 6=4096\nSwish                    Mul_38                   1 1 817 436\nConcat                   Concat_39                2 1 425 436 437\nShuffleChannel           Reshape_44               1 1 437 442 0=2\nSlice                    Split_45                 1 2 442 443 444 -23300=2,64,-233\nConvolution              Conv_46                  1 1 444 820 0=64 1=1 5=1 6=4096\nSwish                    Mul_48                   1 1 820 448\nConvolutionDepthWise     Conv_49                  1 1 448 823 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_50                  1 1 823 826 0=64 1=1 5=1 6=4096\nSwish                    Mul_52                   1 1 826 454\nConcat                   Concat_53                2 1 443 454 455\nShuffleChannel           Reshape_58               1 1 455 460 0=2\nSlice                    Split_59                 1 2 460 461 462 -23300=2,64,-233\nConvolution              Conv_60                  1 1 462 829 0=64 1=1 5=1 6=4096\nSwish                    Mul_62                   1 1 829 466\nConvolutionDepthWise     Conv_63                  1 1 466 832 0=64 1=3 4=1 5=1 6=576 7=64\nConvolution              Conv_64                  1 1 832 835 0=64 1=1 5=1 6=4096\nSwish                    Mul_66                   1 1 835 472\nConcat                   Concat_67                2 1 461 472 473\nShuffleChannel           Reshape_72               1 1 473 478 0=2\nSplit                    splitncnn_2              1 3 478 478_splitncnn_0 478_splitncnn_1 478_splitncnn_2\nConvolutionDepthWise     Conv_73                  1 1 478_splitncnn_2 838 0=128 1=3 3=2 4=1 5=1 6=1152 7=128\nConvolution              Conv_74                  1 1 838 841 0=128 1=1 5=1 6=16384\nSwish                    Mul_76                   1 1 841 484\nConvolution              Conv_77                  1 1 478_splitncnn_1 844 0=128 1=1 5=1 6=16384\nSwish                    Mul_79                   1 1 844 488\nConvolutionDepthWise     Conv_80                  1 1 488 847 0=128 1=3 3=2 4=1 5=1 6=1152 7=128\nConvolution              Conv_81                  1 1 847 850 0=128 1=1 5=1 6=16384\nSwish                    Mul_83                   1 1 850 494\nConcat                   Concat_84                2 1 484 494 495\nShuffleChannel           Reshape_89               1 1 495 500 0=2\nSlice                    Split_90                 1 2 500 501 502 -23300=2,128,-233\nConvolution              Conv_91                  1 1 502 853 0=128 1=1 5=1 6=16384\nSwish                    Mul_93                   1 1 853 506\nConvolutionDepthWise     Conv_94                  1 1 506 856 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_95                  1 1 856 859 0=128 1=1 5=1 6=16384\nSwish                    Mul_97                   1 1 859 512\nConcat                   Concat_98                2 1 501 512 513\nShuffleChannel           Reshape_103              1 1 513 518 0=2\nSlice                    Split_104                1 2 518 519 520 -23300=2,128,-233\nConvolution              Conv_105                 1 1 520 862 0=128 1=1 5=1 6=16384\nSwish                    Mul_107                  1 1 862 524\nConvolutionDepthWise     Conv_108                 1 1 524 865 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_109                 1 1 865 868 0=128 1=1 5=1 6=16384\nSwish                    Mul_111                  1 1 868 530\nConcat                   Concat_112               2 1 519 530 531\nShuffleChannel           Reshape_117              1 1 531 536 0=2\nSlice                    Split_118                1 2 536 537 538 -23300=2,128,-233\nConvolution              Conv_119                 1 1 538 871 0=128 1=1 5=1 6=16384\nSwish                    Mul_121                  1 1 871 542\nConvolutionDepthWise     Conv_122                 1 1 542 874 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_123                 1 1 874 877 0=128 1=1 5=1 6=16384\nSwish                    Mul_125                  1 1 877 548\nConcat                   Concat_126               2 1 537 548 549\nShuffleChannel           Reshape_131              1 1 549 554 0=2\nSlice                    Split_132                1 2 554 555 556 -23300=2,128,-233\nConvolution              Conv_133                 1 1 556 880 0=128 1=1 5=1 6=16384\nSwish                    Mul_135                  1 1 880 560\nConvolutionDepthWise     Conv_136                 1 1 560 883 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_137                 1 1 883 886 0=128 1=1 5=1 6=16384\nSwish                    Mul_139                  1 1 886 566\nConcat                   Concat_140               2 1 555 566 567\nShuffleChannel           Reshape_145              1 1 567 572 0=2\nSlice                    Split_146                1 2 572 573 574 -23300=2,128,-233\nConvolution              Conv_147                 1 1 574 889 0=128 1=1 5=1 6=16384\nSwish                    Mul_149                  1 1 889 578\nConvolutionDepthWise     Conv_150                 1 1 578 892 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_151                 1 1 892 895 0=128 1=1 5=1 6=16384\nSwish                    Mul_153                  1 1 895 584\nConcat                   Concat_154               2 1 573 584 585\nShuffleChannel           Reshape_159              1 1 585 590 0=2\nSlice                    Split_160                1 2 590 591 592 -23300=2,128,-233\nConvolution              Conv_161                 1 1 592 898 0=128 1=1 5=1 6=16384\nSwish                    Mul_163                  1 1 898 596\nConvolutionDepthWise     Conv_164                 1 1 596 901 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_165                 1 1 901 904 0=128 1=1 5=1 6=16384\nSwish                    Mul_167                  1 1 904 602\nConcat                   Concat_168               2 1 591 602 603\nShuffleChannel           Reshape_173              1 1 603 608 0=2\nSlice                    Split_174                1 2 608 609 610 -23300=2,128,-233\nConvolution              Conv_175                 1 1 610 907 0=128 1=1 5=1 6=16384\nSwish                    Mul_177                  1 1 907 614\nConvolutionDepthWise     Conv_178                 1 1 614 910 0=128 1=3 4=1 5=1 6=1152 7=128\nConvolution              Conv_179                 1 1 910 913 0=128 1=1 5=1 6=16384\nSwish                    Mul_181                  1 1 913 620\nConcat                   Concat_182               2 1 609 620 621\nShuffleChannel           Reshape_187              1 1 621 626 0=2\nSplit                    splitncnn_3              1 3 626 626_splitncnn_0 626_splitncnn_1 626_splitncnn_2\nConvolutionDepthWise     Conv_188                 1 1 626_splitncnn_2 916 0=256 1=3 3=2 4=1 5=1 6=2304 7=256\nConvolution              Conv_189                 1 1 916 919 0=256 1=1 5=1 6=65536\nSwish                    Mul_191                  1 1 919 632\nConvolution              Conv_192                 1 1 626_splitncnn_1 922 0=256 1=1 5=1 6=65536\nSwish                    Mul_194                  1 1 922 636\nConvolutionDepthWise     Conv_195                 1 1 636 925 0=256 1=3 3=2 4=1 5=1 6=2304 7=256\nConvolution              Conv_196                 1 1 925 928 0=256 1=1 5=1 6=65536\nSwish                    Mul_198                  1 1 928 642\nConcat                   Concat_199               2 1 632 642 643\nShuffleChannel           Reshape_204              1 1 643 648 0=2\nSlice                    Split_205                1 2 648 649 650 -23300=2,256,-233\nConvolution              Conv_206                 1 1 650 931 0=256 1=1 5=1 6=65536\nSwish                    Mul_208                  1 1 931 654\nConvolutionDepthWise     Conv_209                 1 1 654 934 0=256 1=3 4=1 5=1 6=2304 7=256\nConvolution              Conv_210                 1 1 934 937 0=256 1=1 5=1 6=65536\nSwish                    Mul_212                  1 1 937 660\nConcat                   Concat_213               2 1 649 660 661\nShuffleChannel           Reshape_218              1 1 661 666 0=2\nSlice                    Split_219                1 2 666 667 668 -23300=2,256,-233\nConvolution              Conv_220                 1 1 668 940 0=256 1=1 5=1 6=65536\nSwish                    Mul_222                  1 1 940 672\nConvolutionDepthWise     Conv_223                 1 1 672 943 0=256 1=3 4=1 5=1 6=2304 7=256\nConvolution              Conv_224                 1 1 943 946 0=256 1=1 5=1 6=65536\nSwish                    Mul_226                  1 1 946 678\nConcat                   Concat_227               2 1 667 678 679\nShuffleChannel           Reshape_232              1 1 679 684 0=2\nSlice                    Split_233                1 2 684 685 686 -23300=2,256,-233\nConvolution              Conv_234                 1 1 686 949 0=256 1=1 5=1 6=65536\nSwish                    Mul_236                  1 1 949 690\nConvolutionDepthWise     Conv_237                 1 1 690 952 0=256 1=3 4=1 5=1 6=2304 7=256\nConvolution              Conv_238                 1 1 952 955 0=256 1=1 5=1 6=65536\nSwish                    Mul_240                  1 1 955 696\nConcat                   Concat_241               2 1 685 696 697\nShuffleChannel           Reshape_246              1 1 697 702 0=2\nConvolution              Conv_247                 1 1 702 703 0=128 1=1 5=1 6=65536\nSwish                    Mul_249                  1 1 703 705\nSplit                    splitncnn_4              1 2 705 705_splitncnn_0 705_splitncnn_1\nInterp                   Resize_251               1 1 705_splitncnn_1 710 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_252               2 1 710 626_splitncnn_0 711\nSplit                    splitncnn_5              1 2 711 711_splitncnn_0 711_splitncnn_1\nConvolution              Conv_253                 1 1 711_splitncnn_1 712 0=64 1=1 5=1 6=24576\nSwish                    Mul_255                  1 1 712 714\nConvolution              Conv_256                 1 1 714 715 0=64 1=1 5=1 6=4096\nSwish                    Mul_258                  1 1 715 717\nConvolution              Conv_259                 1 1 717 718 0=64 1=3 4=1 5=1 6=36864\nSwish                    Mul_261                  1 1 718 720\nConvolution              Conv_262                 1 1 711_splitncnn_0 721 0=64 1=1 5=1 6=24576\nSwish                    Mul_264                  1 1 721 723\nConcat                   Concat_265               2 1 720 723 724\nConvolution              Conv_266                 1 1 724 725 0=128 1=1 5=1 6=16384\nSwish                    Mul_268                  1 1 725 727\nConvolution              Conv_269                 1 1 727 728 0=128 1=1 5=1 6=16384\nSwish                    Mul_271                  1 1 728 730\nSplit                    splitncnn_6              1 2 730 730_splitncnn_0 730_splitncnn_1\nInterp                   Resize_273               1 1 730_splitncnn_1 735 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_274               2 1 735 478_splitncnn_0 736\nSplit                    splitncnn_7              1 2 736 736_splitncnn_0 736_splitncnn_1\nConvolution              Conv_275                 1 1 736_splitncnn_1 737 0=64 1=1 5=1 6=16384\nSwish                    Mul_277                  1 1 737 739\nConvolution              Conv_278                 1 1 739 740 0=64 1=1 5=1 6=4096\nSwish                    Mul_280                  1 1 740 742\nConvolution              Conv_281                 1 1 742 743 0=64 1=3 4=1 5=1 6=36864\nSwish                    Mul_283                  1 1 743 745\nConvolution              Conv_284                 1 1 736_splitncnn_0 746 0=64 1=1 5=1 6=16384\nSwish                    Mul_286                  1 1 746 748\nConcat                   Concat_287               2 1 745 748 749\nConvolution              Conv_288                 1 1 749 750 0=128 1=1 5=1 6=16384\nSwish                    Mul_290                  1 1 750 752\nSplit                    splitncnn_8              1 2 752 752_splitncnn_0 752_splitncnn_1\nConvolution              Conv_291                 1 1 752_splitncnn_1 753 0=128 1=3 3=2 4=1 5=1 6=147456\nSwish                    Mul_293                  1 1 753 755\nConcat                   Concat_294               2 1 755 730_splitncnn_0 756\nSplit                    splitncnn_9              1 2 756 756_splitncnn_0 756_splitncnn_1\nConvolution              Conv_295                 1 1 756_splitncnn_1 757 0=64 1=1 5=1 6=16384\nSwish                    Mul_297                  1 1 757 759\nConvolution              Conv_298                 1 1 759 760 0=64 1=1 5=1 6=4096\nSwish                    Mul_300                  1 1 760 762\nConvolution              Conv_301                 1 1 762 763 0=64 1=3 4=1 5=1 6=36864\nSwish                    Mul_303                  1 1 763 765\nConvolution              Conv_304                 1 1 756_splitncnn_0 766 0=64 1=1 5=1 6=16384\nSwish                    Mul_306                  1 1 766 768\nConcat                   Concat_307               2 1 765 768 769\nConvolution              Conv_308                 1 1 769 770 0=128 1=1 5=1 6=16384\nSwish                    Mul_310                  1 1 770 772\nSplit                    splitncnn_10             1 2 772 772_splitncnn_0 772_splitncnn_1\nConvolution              Conv_311                 1 1 772_splitncnn_1 773 0=128 1=3 3=2 4=1 5=1 6=147456\nSwish                    Mul_313                  1 1 773 775\nConcat                   Concat_314               2 1 775 705_splitncnn_0 776\nSplit                    splitncnn_11             1 2 776 776_splitncnn_0 776_splitncnn_1\nConvolution              Conv_315                 1 1 776_splitncnn_1 777 0=64 1=1 5=1 6=16384\nSwish                    Mul_317                  1 1 777 779\nConvolution              Conv_318                 1 1 779 780 0=64 1=1 5=1 6=4096\nSwish                    Mul_320                  1 1 780 782\nConvolution              Conv_321                 1 1 782 783 0=64 1=3 4=1 5=1 6=36864\nSwish                    Mul_323                  1 1 783 785\nConvolution              Conv_324                 1 1 776_splitncnn_0 786 0=64 1=1 5=1 6=16384\nSwish                    Mul_326                  1 1 786 788\nConcat                   Concat_327               2 1 785 788 789\nConvolution              Conv_328                 1 1 789 790 0=128 1=1 5=1 6=16384\nSwish                    Mul_330                  1 1 790 792\nConvolution              Conv_331                 1 1 752_splitncnn_0 stride_8 0=48 1=1 5=1 6=6144\nConvolution              Conv_332                 1 1 772_splitncnn_0 stride_16 0=48 1=1 5=1 6=6144\nConvolution              Conv_333                 1 1 792 stride_32 0=48 1=1 5=1 6=6144\nReshape                  Reshape_573              1 1 stride_8 980 0=-1 1=16 2=3\nPermute                  Transpose_574            1 1 980 981 0=1\nReshape                  Reshape_589              1 1 stride_16 982 0=-1 1=16 2=3\nPermute                  Transpose_590            1 1 982 983 0=1\nReshape                  Reshape_605              1 1 stride_32 984 0=-1 1=16 2=3\nPermute                  Transpose_606            1 1 984 985 0=1\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/java/com/tencent/ncnnyoloface/MainActivity.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.ncnnyoloface;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.pm.PackageManager;\nimport android.graphics.PixelFormat;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.Surface;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.AdapterView;\nimport android.widget.Button;\nimport android.widget.Spinner;\n\nimport android.support.v4.app.ActivityCompat;\nimport android.support.v4.content.ContextCompat;\n\npublic class MainActivity extends Activity implements SurfaceHolder.Callback\n{\n    public static final int REQUEST_CAMERA = 100;\n\n    private NcnnYoloFace ncnnyoloface = new NcnnYoloFace();\n    private int facing = 0;\n\n    private Spinner spinnerModel;\n    private Spinner spinnerCPUGPU;\n    private int current_model = 0;\n    private int current_cpugpu = 0;\n\n    private SurfaceView cameraView;\n\n    /** Called when the activity is first created. */\n    @Override\n    public void onCreate(Bundle savedInstanceState)\n    {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        cameraView = (SurfaceView) findViewById(R.id.cameraview);\n\n        cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);\n        cameraView.getHolder().addCallback(this);\n\n        Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);\n        buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View arg0) {\n\n                int new_facing = 1 - facing;\n\n                ncnnyoloface.closeCamera();\n\n                ncnnyoloface.openCamera(new_facing);\n\n                facing = new_facing;\n            }\n        });\n\n        spinnerModel = (Spinner) findViewById(R.id.spinnerModel);\n        spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_model)\n                {\n                    current_model = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);\n        spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_cpugpu)\n                {\n                    current_cpugpu = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        reload();\n    }\n\n    private void reload()\n    {\n        boolean ret_init = ncnnyoloface.loadModel(getAssets(), current_model, current_cpugpu);\n        if (!ret_init)\n        {\n            Log.e(\"MainActivity\", \"ncnnyoloface loadModel failed\");\n        }\n    }\n\n    @Override\n    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)\n    {\n        ncnnyoloface.setOutputWindow(holder.getSurface());\n    }\n\n    @Override\n    public void surfaceCreated(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void surfaceDestroyed(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void onResume()\n    {\n        super.onResume();\n\n        if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED)\n        {\n            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA);\n        }\n\n        ncnnyoloface.openCamera(facing);\n    }\n\n    @Override\n    public void onPause()\n    {\n        super.onPause();\n\n        ncnnyoloface.closeCamera();\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/java/com/tencent/ncnnyoloface/NcnnYoloFace.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.ncnnyoloface;\n\nimport android.content.res.AssetManager;\nimport android.view.Surface;\n\npublic class NcnnYoloFace\n{\n    public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\n    public native boolean openCamera(int facing);\n    public native boolean closeCamera();\n    public native boolean setOutputWindow(Surface surface);\n\n    static {\n        System.loadLibrary(\"ncnnyoloface\");\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/CMakeLists.txt",
    "content": "project(ncnnyoloface)\n\ncmake_minimum_required(VERSION 3.10)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni)\nfind_package(OpenCV REQUIRED core imgproc)\n\nset(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210322-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)\nfind_package(ncnn REQUIRED)\n\nadd_library(ncnnyoloface SHARED yolofacencnn.cpp yoloface.cpp ndkcamera.cpp)\n\ntarget_link_libraries(ncnnyoloface ncnn ${OpenCV_LIBS} camera2ndk mediandk)\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/ndkcamera.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"ndkcamera.h\"\n\n#include <string>\n\n#include <android/log.h>\n\n#include <opencv2/core/core.hpp>\n\n#include \"mat.h\"\n\nstatic void onDisconnected(void* context, ACameraDevice* device)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onDisconnected %p\", device);\n}\n\nstatic void onError(void* context, ACameraDevice* device, int error)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onError %p %d\", device, error);\n}\n\nstatic void onImageAvailable(void* context, AImageReader* reader)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onImageAvailable %p\", reader);\n\n    AImage* image = 0;\n    media_status_t status = AImageReader_acquireLatestImage(reader, &image);\n\n    if (status != AMEDIA_OK)\n    {\n        // error\n        return;\n    }\n\n    int32_t format;\n    AImage_getFormat(image, &format);\n\n    // assert format == AIMAGE_FORMAT_YUV_420_888\n\n    int32_t width = 0;\n    int32_t height = 0;\n    AImage_getWidth(image, &width);\n    AImage_getHeight(image, &height);\n\n    int32_t y_pixelStride = 0;\n    int32_t u_pixelStride = 0;\n    int32_t v_pixelStride = 0;\n    AImage_getPlanePixelStride(image, 0, &y_pixelStride);\n    AImage_getPlanePixelStride(image, 1, &u_pixelStride);\n    AImage_getPlanePixelStride(image, 2, &v_pixelStride);\n\n    int32_t y_rowStride = 0;\n    int32_t u_rowStride = 0;\n    int32_t v_rowStride = 0;\n    AImage_getPlaneRowStride(image, 0, &y_rowStride);\n    AImage_getPlaneRowStride(image, 1, &u_rowStride);\n    AImage_getPlaneRowStride(image, 2, &v_rowStride);\n\n    uint8_t* y_data = 0;\n    uint8_t* u_data = 0;\n    uint8_t* v_data = 0;\n    int y_len = 0;\n    int u_len = 0;\n    int v_len = 0;\n    AImage_getPlaneData(image, 0, &y_data, &y_len);\n    AImage_getPlaneData(image, 1, &u_data, &u_len);\n    AImage_getPlaneData(image, 2, &v_data, &v_len);\n\n    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)\n    {\n        // already nv21  :)\n        ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height);\n    }\n    else\n    {\n        // construct nv21\n        unsigned char* nv21 = new unsigned char[width * height + width * height / 2];\n        {\n            // Y\n            unsigned char* yptr = nv21;\n            for (int y=0; y<height; y++)\n            {\n                const unsigned char* y_data_ptr = y_data + y_rowStride * y;\n                for (int x=0; x<width; x++)\n                {\n                    yptr[0] = y_data_ptr[0];\n                    yptr++;\n                    y_data_ptr += y_pixelStride;\n                }\n            }\n\n            // UV\n            unsigned char* uvptr = nv21 + width * height;\n            for (int y=0; y<height/2; y++)\n            {\n                const unsigned char* v_data_ptr = v_data + v_rowStride * y;\n                const unsigned char* u_data_ptr = u_data + u_rowStride * y;\n                for (int x=0; x<width/2; x++)\n                {\n                    uvptr[0] = v_data_ptr[0];\n                    uvptr[1] = u_data_ptr[0];\n                    uvptr += 2;\n                    v_data_ptr += v_pixelStride;\n                    u_data_ptr += u_pixelStride;\n                }\n            }\n        }\n\n        ((NdkCamera*)context)->on_image((unsigned char*)nv21, (int)width, (int)height);\n\n        delete[] nv21;\n    }\n\n    AImage_delete(image);\n}\n\nstatic void onSessionActive(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionActive %p\", session);\n}\n\nstatic void onSessionReady(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionReady %p\", session);\n}\n\nstatic void onSessionClosed(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionClosed %p\", session);\n}\n\nvoid onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureFailed %p %p %p\", session, request, failure);\n}\n\nvoid onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceCompleted %p %d %ld\", session, sequenceId, frameNumber);\n}\n\nvoid onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceAborted %p %d\", session, sequenceId);\n}\n\nvoid onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureCompleted %p %p %p\", session, request, result);\n}\n\nNdkCamera::NdkCamera()\n{\n    camera_facing = 0;\n    camera_orientation = 0;\n\n    camera_manager = 0;\n    camera_device = 0;\n    image_reader = 0;\n    image_reader_surface = 0;\n    image_reader_target = 0;\n    capture_request = 0;\n    capture_session_output_container = 0;\n    capture_session_output = 0;\n    capture_session = 0;\n\n\n    // setup imagereader and its surface\n    {\n        AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader);\n\n        AImageReader_ImageListener listener;\n        listener.context = this;\n        listener.onImageAvailable = onImageAvailable;\n\n        AImageReader_setImageListener(image_reader, &listener);\n\n        AImageReader_getWindow(image_reader, &image_reader_surface);\n\n        ANativeWindow_acquire(image_reader_surface);\n    }\n}\n\nNdkCamera::~NdkCamera()\n{\n    close();\n\n    if (image_reader)\n    {\n        AImageReader_delete(image_reader);\n        image_reader = 0;\n    }\n\n    if (image_reader_surface)\n    {\n        ANativeWindow_release(image_reader_surface);\n        image_reader_surface = 0;\n    }\n}\n\nint NdkCamera::open(int _camera_facing)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open\");\n\n    camera_facing = _camera_facing;\n\n    camera_manager = ACameraManager_create();\n\n    // find front camera\n    std::string camera_id;\n    {\n        ACameraIdList* camera_id_list = 0;\n        ACameraManager_getCameraIdList(camera_manager, &camera_id_list);\n\n        for (int i = 0; i < camera_id_list->numCameras; ++i)\n        {\n            const char* id = camera_id_list->cameraIds[i];\n            ACameraMetadata* camera_metadata = 0;\n            ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata);\n\n            // query faceing\n            acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e);\n                facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];\n            }\n\n            if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            camera_id = id;\n\n            // query orientation\n            int orientation = 0;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e);\n\n                orientation = (int)e.data.i32[0];\n            }\n\n            camera_orientation = orientation;\n\n            ACameraMetadata_free(camera_metadata);\n\n            break;\n        }\n\n        ACameraManager_deleteCameraIdList(camera_id_list);\n    }\n\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open %s %d\", camera_id.c_str(), camera_orientation);\n\n    // open camera\n    {\n        ACameraDevice_StateCallbacks camera_device_state_callbacks;\n        camera_device_state_callbacks.context = this;\n        camera_device_state_callbacks.onDisconnected = onDisconnected;\n        camera_device_state_callbacks.onError = onError;\n\n        ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device);\n    }\n\n    // capture request\n    {\n        ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request);\n\n        ACameraOutputTarget_create(image_reader_surface, &image_reader_target);\n        ACaptureRequest_addTarget(capture_request, image_reader_target);\n    }\n\n    // capture session\n    {\n        ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks;\n        camera_capture_session_state_callbacks.context = this;\n        camera_capture_session_state_callbacks.onActive = onSessionActive;\n        camera_capture_session_state_callbacks.onReady = onSessionReady;\n        camera_capture_session_state_callbacks.onClosed = onSessionClosed;\n\n        ACaptureSessionOutputContainer_create(&capture_session_output_container);\n\n        ACaptureSessionOutput_create(image_reader_surface, &capture_session_output);\n\n        ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output);\n\n        ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);\n\n        ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks;\n        camera_capture_session_capture_callbacks.context = this;\n        camera_capture_session_capture_callbacks.onCaptureStarted = 0;\n        camera_capture_session_capture_callbacks.onCaptureProgressed = 0;\n        camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted;\n        camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed;\n        camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted;\n        camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted;\n        camera_capture_session_capture_callbacks.onCaptureBufferLost = 0;\n\n        ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr);\n    }\n\n    return 0;\n}\n\nvoid NdkCamera::close()\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"close\");\n\n    if (capture_session)\n    {\n        ACameraCaptureSession_stopRepeating(capture_session);\n        ACameraCaptureSession_close(capture_session);\n        capture_session = 0;\n    }\n\n    if (camera_device)\n    {\n        ACameraDevice_close(camera_device);\n        camera_device = 0;\n    }\n\n    if (capture_session_output_container)\n    {\n        ACaptureSessionOutputContainer_free(capture_session_output_container);\n        capture_session_output_container = 0;\n    }\n\n    if (capture_session_output)\n    {\n        ACaptureSessionOutput_free(capture_session_output);\n        capture_session_output = 0;\n    }\n\n    if (capture_request)\n    {\n        ACaptureRequest_free(capture_request);\n        capture_request = 0;\n    }\n\n    if (image_reader_target)\n    {\n        ACameraOutputTarget_free(image_reader_target);\n        image_reader_target = 0;\n    }\n\n    if (camera_manager)\n    {\n        ACameraManager_delete(camera_manager);\n        camera_manager = 0;\n    }\n}\n\nvoid NdkCamera::on_image(const cv::Mat& rgb) const\n{\n}\n\nvoid NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // rotate nv21\n    int w = 0;\n    int h = 0;\n    int rotate_type = 0;\n    {\n        if (camera_orientation == 0)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 2 : 1;\n        }\n        if (camera_orientation == 90)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 5 : 6;\n        }\n        if (camera_orientation == 180)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 4 : 3;\n        }\n        if (camera_orientation == 270)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 7 : 8;\n        }\n    }\n\n    cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1);\n    ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type);\n\n    // nv21_rotated to rgb\n    cv::Mat rgb(h, w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data);\n\n    on_image(rgb);\n}\n\nstatic const int NDKCAMERAWINDOW_ID = 233;\n\nNdkCameraWindow::NdkCameraWindow() : NdkCamera()\n{\n    sensor_manager = 0;\n    sensor_event_queue = 0;\n    accelerometer_sensor = 0;\n    win = 0;\n\n    accelerometer_orientation = 0;\n\n    // sensor\n    sensor_manager = ASensorManager_getInstance();\n\n    accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER);\n}\n\nNdkCameraWindow::~NdkCameraWindow()\n{\n    if (accelerometer_sensor)\n    {\n        ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor);\n        accelerometer_sensor = 0;\n    }\n\n    if (sensor_event_queue)\n    {\n        ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue);\n        sensor_event_queue = 0;\n    }\n\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n}\n\nvoid NdkCameraWindow::set_window(ANativeWindow* _win)\n{\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n\n    win = _win;\n    ANativeWindow_acquire(win);\n}\n\nvoid NdkCameraWindow::on_image_render(cv::Mat& rgb) const\n{\n}\n\nvoid NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // resolve orientation from camera_orientation and accelerometer_sensor\n    {\n        if (!sensor_event_queue)\n        {\n            sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0);\n\n            ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor);\n        }\n\n        int id = ALooper_pollAll(0, 0, 0, 0);\n        if (id == NDKCAMERAWINDOW_ID)\n        {\n            ASensorEvent e[8];\n            ssize_t num_event = 0;\n            while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1)\n            {\n                num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8);\n                if (num_event < 0)\n                    break;\n            }\n\n            if (num_event > 0)\n            {\n                float acceleration_x = e[num_event - 1].acceleration.x;\n                float acceleration_y = e[num_event - 1].acceleration.y;\n                float acceleration_z = e[num_event - 1].acceleration.z;\n//                 __android_log_print(ANDROID_LOG_WARN, \"NdkCameraWindow\", \"x = %f, y = %f, z = %f\", x, y, z);\n\n                if (acceleration_y > 7)\n                {\n                    accelerometer_orientation = 0;\n                }\n                if (acceleration_x < -7)\n                {\n                    accelerometer_orientation = 90;\n                }\n                if (acceleration_y < -7)\n                {\n                    accelerometer_orientation = 180;\n                }\n                if (acceleration_x > 7)\n                {\n                    accelerometer_orientation = 270;\n                }\n            }\n        }\n    }\n\n    // roi crop and rotate nv21\n    int nv21_roi_x = 0;\n    int nv21_roi_y = 0;\n    int nv21_roi_w = 0;\n    int nv21_roi_h = 0;\n    int roi_x = 0;\n    int roi_y = 0;\n    int roi_w = 0;\n    int roi_h = 0;\n    int rotate_type = 0;\n    int render_w = 0;\n    int render_h = 0;\n    int render_rotate_type = 0;\n    {\n        int win_w = ANativeWindow_getWidth(win);\n        int win_h = ANativeWindow_getHeight(win);\n\n        if (accelerometer_orientation == 90 || accelerometer_orientation == 270)\n        {\n            std::swap(win_w, win_h);\n        }\n\n        const int final_orientation = (camera_orientation + accelerometer_orientation) % 360;\n\n        if (final_orientation == 0 || final_orientation == 180)\n        {\n            if (win_w * nv21_height > win_h * nv21_width)\n            {\n                roi_w = nv21_width;\n                roi_h = (nv21_width * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_height - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_height;\n                roi_w = (nv21_height * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_width - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_x;\n            nv21_roi_y = roi_y;\n            nv21_roi_w = roi_w;\n            nv21_roi_h = roi_h;\n        }\n        if (final_orientation == 90 || final_orientation == 270)\n        {\n            if (win_w * nv21_width > win_h * nv21_height)\n            {\n                roi_w = nv21_height;\n                roi_h = (nv21_height * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_width - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_width;\n                roi_w = (nv21_width * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_height - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_y;\n            nv21_roi_y = roi_x;\n            nv21_roi_w = roi_h;\n            nv21_roi_h = roi_w;\n        }\n\n        if (camera_facing == 0)\n        {\n            if (camera_orientation == 0 && accelerometer_orientation == 0)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 90)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 180)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 270)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 0)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 90)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 180)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 270)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 0)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 90)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 180)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 270)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 0)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 90)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 180)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 270)\n            {\n                rotate_type = 2;\n            }\n        }\n        else\n        {\n            if (final_orientation == 0)\n            {\n                rotate_type = 1;\n            }\n            if (final_orientation == 90)\n            {\n                rotate_type = 6;\n            }\n            if (final_orientation == 180)\n            {\n                rotate_type = 3;\n            }\n            if (final_orientation == 270)\n            {\n                rotate_type = 8;\n            }\n        }\n\n        if (accelerometer_orientation == 0)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 1;\n        }\n        if (accelerometer_orientation == 90)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 8;\n        }\n        if (accelerometer_orientation == 180)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 3;\n        }\n        if (accelerometer_orientation == 270)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 6;\n        }\n    }\n\n    // crop and rotate nv21\n    cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1);\n    {\n        const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x;\n        unsigned char* dstY = nv21_croprotated.data;\n        ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type);\n\n        const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x;\n        unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h;\n        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);\n    }\n\n    // nv21_croprotated to rgb\n    cv::Mat rgb(roi_h, roi_w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data);\n\n    on_image_render(rgb);\n\n    // rotate to native window orientation\n    cv::Mat rgb_render(render_h, render_w, CV_8UC3);\n    ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type);\n\n    ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);\n\n    ANativeWindow_Buffer buf;\n    ANativeWindow_lock(win, &buf, NULL);\n\n    // scale to target size\n    if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)\n    {\n        for (int y = 0; y < render_h; y++)\n        {\n            const unsigned char* ptr = rgb_render.ptr<const unsigned char>(y);\n            unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y;\n\n            int x = 0;\n#if __ARM_NEON\n            for (; x + 7 < render_w; x += 8)\n            {\n                uint8x8x3_t _rgb = vld3_u8(ptr);\n                uint8x8x4_t _rgba;\n                _rgba.val[0] = _rgb.val[0];\n                _rgba.val[1] = _rgb.val[1];\n                _rgba.val[2] = _rgb.val[2];\n                _rgba.val[3] = vdup_n_u8(255);\n                vst4_u8(outptr, _rgba);\n\n                ptr += 24;\n                outptr += 32;\n            }\n#endif // __ARM_NEON\n            for (; x < render_w; x++)\n            {\n                outptr[0] = ptr[0];\n                outptr[1] = ptr[1];\n                outptr[2] = ptr[2];\n                outptr[3] = 255;\n\n                ptr += 3;\n                outptr += 4;\n            }\n        }\n    }\n\n    ANativeWindow_unlockAndPost(win);\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/ndkcamera.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef NDKCAMERA_H\n#define NDKCAMERA_H\n\n#include <android/looper.h>\n#include <android/native_window.h>\n#include <android/sensor.h>\n#include <camera/NdkCameraDevice.h>\n#include <camera/NdkCameraManager.h>\n#include <camera/NdkCameraMetadata.h>\n#include <media/NdkImageReader.h>\n\n#include <opencv2/core/core.hpp>\n\nclass NdkCamera\n{\npublic:\n    NdkCamera();\n    virtual ~NdkCamera();\n\n    // facing 0=front 1=back\n    int open(int camera_facing = 0);\n    void close();\n\n    virtual void on_image(const cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    int camera_facing;\n    int camera_orientation;\n\nprivate:\n    ACameraManager* camera_manager;\n    ACameraDevice* camera_device;\n    AImageReader* image_reader;\n    ANativeWindow* image_reader_surface;\n    ACameraOutputTarget* image_reader_target;\n    ACaptureRequest* capture_request;\n    ACaptureSessionOutputContainer* capture_session_output_container;\n    ACaptureSessionOutput* capture_session_output;\n    ACameraCaptureSession* capture_session;\n};\n\nclass NdkCameraWindow : public NdkCamera\n{\npublic:\n    NdkCameraWindow();\n    virtual ~NdkCameraWindow();\n\n    void set_window(ANativeWindow* win);\n\n    virtual void on_image_render(cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    mutable int accelerometer_orientation;\n\nprivate:\n    ASensorManager* sensor_manager;\n    mutable ASensorEventQueue* sensor_event_queue;\n    const ASensor* accelerometer_sensor;\n    ANativeWindow* win;\n};\n\n#endif // NDKCAMERA_H\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/yoloface.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"yoloface.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#include \"cpu.h\"\n#define clip(x, y) (x < 0 ? 0 : (x > y ? y : x))\n\n\nstatic inline float intersection_area(const Object& a, const Object& b)\n{\n    cv::Rect_<float> inter = a.rect & b.rect;\n    return inter.area();\n}\n\nstatic void qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right)\n{\n    int i = left;\n    int j = right;\n    float p = faceobjects[(left + right) / 2].prob;\n\n    while (i <= j)\n    {\n        while (faceobjects[i].prob > p)\n            i++;\n\n        while (faceobjects[j].prob < p)\n            j--;\n\n        if (i <= j)\n        {\n            // swap\n            std::swap(faceobjects[i], faceobjects[j]);\n\n            i++;\n            j--;\n        }\n    }\n\n    #pragma omp parallel sections\n    {\n        #pragma omp section\n        {\n            if (left < j) qsort_descent_inplace(faceobjects, left, j);\n        }\n        #pragma omp section\n        {\n            if (i < right) qsort_descent_inplace(faceobjects, i, right);\n        }\n    }\n}\n\nstatic void qsort_descent_inplace(std::vector<Object>& faceobjects)\n{\n    if (faceobjects.empty())\n        return;\n\n    qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);\n}\n\nstatic void nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold)\n{\n    picked.clear();\n\n    const int n = faceobjects.size();\n\n    std::vector<float> areas(n);\n    for (int i = 0; i < n; i++)\n    {\n        areas[i] = faceobjects[i].rect.area();\n    }\n\n    for (int i = 0; i < n; i++)\n    {\n        const Object& a = faceobjects[i];\n\n        int keep = 1;\n        for (int j = 0; j < (int)picked.size(); j++)\n        {\n            const Object& b = faceobjects[picked[j]];\n\n            // intersection over union\n            float inter_area = intersection_area(a, b);\n            float union_area = areas[i] + areas[picked[j]] - inter_area;\n            // float IoU = inter_area / union_area\n            if (inter_area / union_area > nms_threshold)\n                keep = 0;\n        }\n\n        if (keep)\n            picked.push_back(i);\n    }\n}\n\nstatic inline float sigmoid(float x)\n{\n    return static_cast<float>(1.f / (1.f + exp(-x)));\n}\n\nstatic void generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects)\n{\n    const int num_grid = feat_blob.h;\n\n    int num_grid_x;\n    int num_grid_y;\n    if (in_pad.w > in_pad.h)\n    {\n        num_grid_x = in_pad.w / stride;\n        num_grid_y = num_grid / num_grid_x;\n    }\n    else\n    {\n        num_grid_y = in_pad.h / stride;\n        num_grid_x = num_grid / num_grid_y;\n    }\n\n    const int num_class = feat_blob.w - 5-10;\n\n    const int num_anchors = anchors.w / 2;\n\n    for (int q = 0; q < num_anchors; q++)\n    {\n        const float anchor_w = anchors[q * 2];\n        const float anchor_h = anchors[q * 2 + 1];\n\n        const ncnn::Mat feat = feat_blob.channel(q);\n\n        for (int i = 0; i < num_grid_y; i++)\n        {\n            for (int j = 0; j < num_grid_x; j++)\n            {\n                const float* featptr = feat.row(i * num_grid_x + j);\n\n                // find class index with max class score\n                int class_index = 0;\n                float class_score = -FLT_MAX;\n                for (int k = 0; k < num_class; k++)\n                {\n                    float score = featptr[5 +10+ k];\n                    if (score > class_score)\n                    {\n                        class_index = k;\n                        class_score = score;\n                    }\n                }\n\n                float box_score = featptr[4];\n\n\t\tfloat confidence = sigmoid(box_score); //* sigmoid(class_score);\n\n                if (confidence >= prob_threshold)\n                {\n                    // yolov5/models/yolo.py Detect forward\n                    // y = x[i].sigmoid()\n                    // y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i]  # xy\n                    // y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh\n\n                    float dx = sigmoid(featptr[0]);\n                    float dy = sigmoid(featptr[1]);\n                    float dw = sigmoid(featptr[2]);\n                    float dh = sigmoid(featptr[3]);\n\n                    float pb_cx = (dx * 2.f - 0.5f + j) * stride;\n                    float pb_cy = (dy * 2.f - 0.5f + i) * stride;\n\n                    float pb_w = pow(dw * 2.f, 2) * anchor_w;\n                    float pb_h = pow(dh * 2.f, 2) * anchor_h;\n\n                    float x0 = pb_cx - pb_w * 0.5f;\n                    float y0 = pb_cy - pb_h * 0.5f;\n                    float x1 = pb_cx + pb_w * 0.5f;\n                    float y1 = pb_cy + pb_h * 0.5f;\n\n                    Object obj;\n                    obj.rect.x = x0;\n                    obj.rect.y = y0;\n                    obj.rect.width = x1 - x0;\n                    obj.rect.height = y1 - y0;\n                    obj.label = class_index;\n                    obj.prob = confidence;\n\n                    for (int l = 0; l < 5; l++)\n                    {\n                        float x = featptr[2 * l + 5] * anchor_w + j * stride;\n                        float y = featptr[2 * l + 1 + 5] * anchor_h + i * stride;\n                        obj.pts.push_back(cv::Point2f(x, y));\n                    }\n                    objects.push_back(obj);\n                }\n            }\n        }\n    }\n}\n\n\n\nYoloFace::YoloFace()\n{\n    blob_pool_allocator.set_size_compare_ratio(0.f);\n    workspace_pool_allocator.set_size_compare_ratio(0.f);\n}\n\nint YoloFace::load(const char* modeltype, int _target_size, const float* _mean_vals, const float* _norm_vals, bool use_gpu)\n{\n    yoloface.clear();\n    blob_pool_allocator.clear();\n    workspace_pool_allocator.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    yoloface.opt = ncnn::Option();\n\n#if NCNN_VULKAN\n    yoloface.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    yoloface.opt.num_threads = ncnn::get_big_cpu_count();\n    yoloface.opt.blob_allocator = &blob_pool_allocator;\n    yoloface.opt.workspace_allocator = &workspace_pool_allocator;\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"%s.param\", modeltype);\n    sprintf(modelpath, \"%s.bin\", modeltype);\n\n    yoloface.load_param(parampath);\n    yoloface.load_model(modelpath);\n\n    target_size = _target_size;\n    mean_vals[0] = _mean_vals[0];\n    mean_vals[1] = _mean_vals[1];\n    mean_vals[2] = _mean_vals[2];\n    norm_vals[0] = _norm_vals[0];\n    norm_vals[1] = _norm_vals[1];\n    norm_vals[2] = _norm_vals[2];\n\n    return 0;\n}\n\nint YoloFace::load(AAssetManager* mgr, const char* modeltype, int _target_size, const float* _mean_vals, const float* _norm_vals, bool use_gpu)\n{\n    yoloface.clear();\n    blob_pool_allocator.clear();\n    workspace_pool_allocator.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    yoloface.opt = ncnn::Option();\n#if NCNN_VULKAN\n    yoloface.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    yoloface.opt.num_threads = ncnn::get_big_cpu_count();\n    yoloface.opt.blob_allocator = &blob_pool_allocator;\n    yoloface.opt.workspace_allocator = &workspace_pool_allocator;\n\n    yoloface.load_param(mgr, \"yolov5n-0.5.param\");\n    yoloface.load_model(mgr, \"yolov5n-0.5.bin\");\n\n\n    target_size = _target_size;\n    mean_vals[0] = _mean_vals[0];\n    mean_vals[1] = _mean_vals[1];\n    mean_vals[2] = _mean_vals[2];\n    norm_vals[0] = _norm_vals[0];\n    norm_vals[1] = _norm_vals[1];\n    norm_vals[2] = _norm_vals[2];\n\n    return 0;\n}\n\n\nint YoloFace::detect(const cv::Mat& rgb, std::vector<Object>& objects, float prob_threshold, float nms_threshold)\n{\n  \n    target_size = 640;\n    int img_w = rgb.cols;\n    int img_h = rgb.rows;\n\n    // letterbox pad to multiple of 32\n    int w = img_w;\n    int h = img_h;\n    float scale = 1.f;\n    if (w > h)\n    {\n        scale = (float)target_size / w;\n        w = target_size;\n        h = h * scale;\n    }\n    else\n    {\n        scale = (float)target_size / h;\n        h = target_size;\n        w = w * scale;\n    }\n\n    ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, img_w, img_h, w, h);\n\n    // pad to target_size rectangle\n    // yolov5/utils/datasets.py letterbox\n    int wpad = (w + 31) / 32 * 32 - w;\n    int hpad = (h + 31) / 32 * 32 - h;\n    ncnn::Mat in_pad;\n    ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 114.f);\n\n\n    in_pad.substract_mean_normalize(0, norm_vals);\n\n    ncnn::Extractor ex = yoloface.create_extractor();\n\n    ex.input(\"data\", in_pad);\n\n    std::vector<Object> proposals;\n\n    // anchor setting from yolov5/models/yolov5s.yaml\n\n    // stride 8\n    {\n        ncnn::Mat out;\n        ex.extract(\"981\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 4.f;\n        anchors[1] = 5.f;\n        anchors[2] = 8.f;\n        anchors[3] = 10.f;\n        anchors[4] = 13.f;\n        anchors[5] = 16.f;\n\n        std::vector<Object> objects8;\n        generate_proposals(anchors, 8, in_pad, out, prob_threshold, objects8);\n\n        proposals.insert(proposals.end(), objects8.begin(), objects8.end());\n    }\n\n    // stride 16\n    {\n        ncnn::Mat out;\n        ex.extract(\"983\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 23.f;\n        anchors[1] = 29.f;\n        anchors[2] = 43.f;\n        anchors[3] = 55.f;\n        anchors[4] = 73.f;\n        anchors[5] = 105.f;\n\n        std::vector<Object> objects16;\n        generate_proposals(anchors, 16, in_pad, out, prob_threshold, objects16);\n\n        proposals.insert(proposals.end(), objects16.begin(), objects16.end());\n    }\n\n    // stride 32\n    {\n        ncnn::Mat out;\n        ex.extract(\"985\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 146.f;\n        anchors[1] = 217.f;\n        anchors[2] = 231.f;\n        anchors[3] = 300.f;\n        anchors[4] = 335.f;\n        anchors[5] = 433.f;\n\n        std::vector<Object> objects32;\n        generate_proposals(anchors, 32, in_pad, out, prob_threshold, objects32);\n\n        proposals.insert(proposals.end(), objects32.begin(), objects32.end());\n    }\n\n    // sort all proposals by score from highest to lowest\n    qsort_descent_inplace(proposals);\n\n    // apply nms with nms_threshold\n    std::vector<int> picked;\n    nms_sorted_bboxes(proposals, picked, nms_threshold);\n\n    int count = picked.size();\n\n    objects.resize(count);\n    for (int i = 0; i < count; i++)\n    {\n        objects[i] = proposals[picked[i]];\n\n        // adjust offset to original unpadded\n        float x0 = (objects[i].rect.x - (wpad / 2)) / scale;\n        float y0 = (objects[i].rect.y - (hpad / 2)) / scale;\n        float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale;\n        float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale;\n\n        for (int j = 0; j < objects[i].pts.size(); j++)\n        {\n            float ptx = (objects[i].pts[j].x - (wpad / 2)) / scale;\n            float pty = (objects[i].pts[j].y - (hpad / 2)) / scale;\n            objects[i].pts[j] = cv::Point2f(ptx, pty);\n        }\n\n        // clip\n        x0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);\n        y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);\n        x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);\n        y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);\n\n        objects[i].rect.x = x0;\n        objects[i].rect.y = y0;\n        objects[i].rect.width = x1 - x0;\n        objects[i].rect.height = y1 - y0;\n    }\n\n\n    return 0;\n}\n\nint YoloFace::draw(cv::Mat& rgb, const std::vector<Object>& objects)\n{\n\n    static const unsigned char colors[19][3] = {\n        { 54,  67, 244},\n        { 99,  30, 233},\n        {176,  39, 156},\n        {183,  58, 103},\n        {181,  81,  63},\n        {243, 150,  33},\n        {244, 169,   3},\n        {212, 188,   0},\n        {136, 150,   0},\n        { 80, 175,  76},\n        { 74, 195, 139},\n        { 57, 220, 205},\n        { 59, 235, 255},\n        {  7, 193, 255},\n        {  0, 152, 255},\n        { 34,  87, 255},\n        { 72,  85, 121},\n        {158, 158, 158},\n        {139, 125,  96}\n    };\n\n    int color_index = 0;\n\n    for (size_t i = 0; i < objects.size(); i++)\n    {\n        const Object& obj = objects[i];\n\n        const unsigned char* color = colors[color_index % 19];\n        color_index++;\n\n        cv::Scalar cc(color[0], color[1], color[2]);\n\n        cv::rectangle(rgb,obj.rect, cc, 2);\n\n        char text[256];\n        sprintf(text, \"%.1f%%\",  obj.prob * 100);\n\n        int baseLine = 0;\n        cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n        int x = obj.rect.x;\n        int y = obj.rect.y - label_size.height - baseLine;\n        if (y < 0)\n            y = 0;\n        if (x + label_size.width > rgb.cols)\n            x = rgb.cols - label_size.width;\n\n        cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cc, -1);\n\n        cv::Scalar textcc = (color[0] + color[1] + color[2] >= 381) ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255);\n\n        cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, textcc, 1);\n        for (int j = 0; j < obj.pts.size(); j++)\n        {\n            cv::circle(rgb, obj.pts[j], 2, cv::Scalar(0, 255, 0), -1);\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/yoloface.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef YOLOFACE_H\n#define YOLOFACE_H\n\n#include <opencv2/core/core.hpp>\n\n#include <net.h>\n\nstruct Object\n{\n    cv::Rect_<float> rect;\n    int label;\n    float prob;\n    std::vector<cv::Point2f> pts;\n};\n\n\nclass YoloFace\n{\npublic:\n    YoloFace();\n\n    int load(const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);\n\n    int load(AAssetManager* mgr, const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);\n\n    int detect(const cv::Mat& rgb, std::vector<Object>& objects, float prob_threshold = 0.25f, float nms_threshold = 0.45f);\n\n    int draw(cv::Mat& rgb, const std::vector<Object>& objects);\n\nprivate:\n\n    ncnn::Net yoloface;\n\n    int target_size;\n    float mean_vals[3];\n    float norm_vals[3];\n    int image_w;\n    int image_h;\n    int in_w;\n    int in_h;\n\n    ncnn::UnlockedPoolAllocator blob_pool_allocator;\n    ncnn::PoolAllocator workspace_pool_allocator;\n};\n\n#endif // NANODET_H\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/jni/yolofacencnn.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include <android/asset_manager_jni.h>\n#include <android/native_window_jni.h>\n#include <android/native_window.h>\n\n#include <android/log.h>\n\n#include <jni.h>\n\n#include <string>\n#include <vector>\n\n#include <platform.h>\n#include <benchmark.h>\n\n#include \"yoloface.h\"\n\n#include \"ndkcamera.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#if __ARM_NEON\n#include <arm_neon.h>\n#endif // __ARM_NEON\n\nstatic int draw_unsupported(cv::Mat& rgb)\n{\n    const char text[] = \"unsupported\";\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine);\n\n    int y = (rgb.rows - label_size.height) / 2;\n    int x = (rgb.cols - label_size.width) / 2;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic int draw_fps(cv::Mat& rgb)\n{\n    // resolve moving average\n    float avg_fps = 0.f;\n    {\n        static double t0 = 0.f;\n        static float fps_history[10] = {0.f};\n\n        double t1 = ncnn::get_current_time();\n        if (t0 == 0.f)\n        {\n            t0 = t1;\n            return 0;\n        }\n\n        float fps = 1000.f / (t1 - t0);\n        t0 = t1;\n\n        for (int i = 9; i >= 1; i--)\n        {\n            fps_history[i] = fps_history[i - 1];\n        }\n        fps_history[0] = fps;\n\n        if (fps_history[9] == 0.f)\n        {\n            return 0;\n        }\n\n        for (int i = 0; i < 10; i++)\n        {\n            avg_fps += fps_history[i];\n        }\n        avg_fps /= 10.f;\n    }\n\n    char text[32];\n    sprintf(text, \"FPS=%.2f\", avg_fps);\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n    int y = 0;\n    int x = rgb.cols - label_size.width;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic YoloFace* g_yoloface = 0;\nstatic ncnn::Mutex lock;\n\nclass MyNdkCamera : public NdkCameraWindow\n{\npublic:\n    virtual void on_image_render(cv::Mat& rgb) const;\n};\n\nvoid MyNdkCamera::on_image_render(cv::Mat& rgb) const\n{\n    // nanodet\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (g_yoloface)\n        {\n            std::vector<Object> objects;\n            g_yoloface->detect(rgb, objects);\n\n            g_yoloface->draw(rgb, objects);\n        }\n        else\n        {\n            draw_unsupported(rgb);\n        }\n    }\n\n    draw_fps(rgb);\n}\n\nstatic MyNdkCamera* g_camera = 0;\n\nextern \"C\" {\n\nJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnLoad\");\n\n    g_camera = new MyNdkCamera;\n\n    return JNI_VERSION_1_4;\n}\n\nJNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnUnload\");\n\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        delete g_yoloface;\n        g_yoloface = 0;\n    }\n\n    delete g_camera;\n    g_camera = 0;\n}\n\n// public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu)\n{\n    if (modelid < 0 || modelid > 6 || cpugpu < 0 || cpugpu > 1)\n    {\n        return JNI_FALSE;\n    }\n\n    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"loadModel %p\", mgr);\n\n    const char* modeltypes[] =\n    {\n        \"yolov5n-0.5\",\n    };\n\n    const int target_sizes[] =\n    {\n        320,\n    };\n\n    const float mean_vals[][3] =\n    {\n        {127.f, 127.f, 127.f},\n    };\n\n    const float norm_vals[][3] =\n    {\n        {1 / 255.f, 1 / 255.f, 1 / 255.f},\n    };\n\n    const char* modeltype = modeltypes[(int)modelid];\n    int target_size = target_sizes[(int)modelid];\n    bool use_gpu = (int)cpugpu == 1;\n\n    // reload\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (use_gpu && ncnn::get_gpu_count() == 0)\n        {\n            // no gpu\n            delete g_yoloface;\n            g_yoloface = 0;\n        }\n        else\n        {\n            if (!g_yoloface)\n                g_yoloface = new YoloFace;\n            g_yoloface->load(mgr, modeltype, target_size, mean_vals[(int)modelid], norm_vals[(int)modelid], use_gpu);\n        }\n    }\n\n    return JNI_TRUE;\n}\n\n// public native boolean openCamera(int facing);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_openCamera(JNIEnv* env, jobject thiz, jint facing)\n{\n    if (facing < 0 || facing > 1)\n        return JNI_FALSE;\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"openCamera %d\", facing);\n\n    g_camera->open((int)facing);\n\n    return JNI_TRUE;\n}\n\n// public native boolean closeCamera();\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_closeCamera(JNIEnv* env, jobject thiz)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"closeCamera\");\n\n    g_camera->close();\n\n    return JNI_TRUE;\n}\n\n// public native boolean setOutputWindow(Surface surface);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)\n{\n    ANativeWindow* win = ANativeWindow_fromSurface(env, surface);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"setOutputWindow %p\", win);\n\n    g_camera->set_window(win);\n\n    return JNI_TRUE;\n}\n\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Button\n        android:id=\"@+id/buttonSwitchCamera\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"切换摄像头\" />\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Spinner\n        android:id=\"@+id/spinnerModel\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/model_array\" />\n\n    <Spinner\n        android:id=\"@+id/spinnerCPUGPU\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/cpugpu_array\" />\n\n    </LinearLayout>\n\n    <SurfaceView\n        android:id=\"@+id/cameraview\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "ncnn-android-yolov5_face/app/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">yoloface_demo</string>\n    <string-array name=\"model_array\">\n        <item>face</item>\n    </string-array>\n    <string-array name=\"cpugpu_array\">\n        <item>CPU</item>\n        <item>GPU</item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "ncnn-android-yolov5_face/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    repositories {\n        jcenter()\n        google()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        google()\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov5_face/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sun Sep 08 23:09:42 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "ncnn-android-yolov5_face/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "ncnn-android-yolov5_face/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "ncnn-android-yolov5_face/local.properties",
    "content": "## This file must *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local configuration.\n#\n# Location of the SDK. This is only used by Gradle.\n# For customization when using a Version Control System, please read the\n# header note.\n#Mon Mar 29 09:07:23 CST 2021\nsdk.dir=D\\:\\\\Android\n"
  },
  {
    "path": "ncnn-android-yolov5_face/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"29.0.2\"\n\n    defaultConfig {\n        applicationId \"com.tencent.ncnnyoloface\"\n        archivesBaseName = \"$applicationId\"\n\n        minSdkVersion 24\n    }\n\n    externalNativeBuild {\n        cmake {\n            version \"3.10.2\"\n            path file('src/main/jni/CMakeLists.txt')\n        }\n    }\n\n    dependencies {\n        implementation 'com.android.support:support-v4:24.0.0'\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      package=\"com.tencent.ncnnyoloface\"\n      android:versionCode=\"1\"\n      android:versionName=\"1.1\">\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-feature android:name=\"android.hardware.camera2.full\" />\n\n    <application android:label=\"@string/app_name\">\n        <activity android:name=\"MainActivity\"\n                  android:label=\"@string/app_name\"\n                  android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest> \n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/assets/yolov7-lite-e.param",
    "content": "7767517\n169 192\nInput                    images                   0 1 images\nMemoryData               817                      0 1 817 0=80 1=80 2=96\nMemoryData               821                      0 1 821 0=80 1=80 2=18\nMemoryData               845                      0 1 845 0=40 1=40 2=96\nMemoryData               849                      0 1 849 0=40 1=40 2=18\nMemoryData               873                      0 1 873 0=20 1=20 2=96\nMemoryData               877                      0 1 877 0=20 1=20 2=18\nConvolution              Conv_0                   1 1 images 393 0=32 1=3 3=2 4=1 5=1 6=864 9=1\nPooling                  MaxPool_2                1 1 393 394 1=3 2=2 3=1 5=1\nSplit                    splitncnn_0              1 2 394 394_splitncnn_0 394_splitncnn_1\nConvolutionDepthWise     Conv_3                   1 1 394_splitncnn_1 903 0=32 1=3 3=2 4=1 5=1 6=288 7=32\nConvolution              Conv_4                   1 1 903 399 0=60 1=1 5=1 6=1920 9=1\nConvolution              Conv_6                   1 1 394_splitncnn_0 402 0=60 1=1 5=1 6=1920 9=1\nConvolutionDepthWise     Conv_8                   1 1 402 912 0=60 1=3 3=2 4=1 5=1 6=540 7=60\nConvolution              Conv_9                   1 1 912 407 0=60 1=1 5=1 6=3600 9=1\nConcat                   Concat_11                2 1 399 407 408\nShuffleChannel           Reshape_16               1 1 408 413 0=2\nSplit                    splitncnn_1              1 2 413 413_splitncnn_0 413_splitncnn_1\nCrop                     Slice_27                 1 1 413_splitncnn_1 424 -23309=1,0 -23310=1,60 -23311=1,0\nCrop                     Slice_30                 1 1 413_splitncnn_0 427 -23309=1,60 -23310=1,120 -23311=1,0\nConvolution              Conv_31                  1 1 427 430 0=60 1=1 5=1 6=3600 9=1\nConvolutionDepthWise     Conv_33                  1 1 430 921 0=60 1=3 4=1 5=1 6=540 7=60\nConvolution              Conv_34                  1 1 921 435 0=60 1=1 5=1 6=3600 9=1\nConcat                   Concat_36                2 1 424 435 436\nShuffleChannel           Reshape_41               1 1 436 441 0=2\nSplit                    splitncnn_2              1 2 441 441_splitncnn_0 441_splitncnn_1\nCrop                     Slice_52                 1 1 441_splitncnn_1 452 -23309=1,0 -23310=1,60 -23311=1,0\nCrop                     Slice_55                 1 1 441_splitncnn_0 455 -23309=1,60 -23310=1,120 -23311=1,0\nConvolution              Conv_56                  1 1 455 458 0=60 1=1 5=1 6=3600 9=1\nConvolutionDepthWise     Conv_58                  1 1 458 930 0=60 1=3 4=1 5=1 6=540 7=60\nConvolution              Conv_59                  1 1 930 463 0=60 1=1 5=1 6=3600 9=1\nConcat                   Concat_61                2 1 452 463 464\nShuffleChannel           Reshape_66               1 1 464 469 0=2\nSplit                    splitncnn_3              1 2 469 469_splitncnn_0 469_splitncnn_1\nCrop                     Slice_77                 1 1 469_splitncnn_1 480 -23309=1,0 -23310=1,60 -23311=1,0\nCrop                     Slice_80                 1 1 469_splitncnn_0 483 -23309=1,60 -23310=1,120 -23311=1,0\nConvolution              Conv_81                  1 1 483 486 0=60 1=1 5=1 6=3600 9=1\nConvolutionDepthWise     Conv_83                  1 1 486 939 0=60 1=3 4=1 5=1 6=540 7=60\nConvolution              Conv_84                  1 1 939 491 0=60 1=1 5=1 6=3600 9=1\nConcat                   Concat_86                2 1 480 491 492\nShuffleChannel           Reshape_91               1 1 492 497 0=2\nSplit                    splitncnn_4              1 3 497 497_splitncnn_0 497_splitncnn_1 497_splitncnn_2\nConvolutionDepthWise     Conv_92                  1 1 497_splitncnn_2 945 0=120 1=3 3=2 4=1 5=1 6=1080 7=120\nConvolution              Conv_93                  1 1 945 502 0=116 1=1 5=1 6=13920 9=1\nConvolution              Conv_95                  1 1 497_splitncnn_1 505 0=116 1=1 5=1 6=13920 9=1\nConvolutionDepthWise     Conv_97                  1 1 505 954 0=116 1=3 3=2 4=1 5=1 6=1044 7=116\nConvolution              Conv_98                  1 1 954 510 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_100               2 1 502 510 511\nShuffleChannel           Reshape_105              1 1 511 516 0=2\nSplit                    splitncnn_5              1 2 516 516_splitncnn_0 516_splitncnn_1\nCrop                     Slice_116                1 1 516_splitncnn_1 527 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_119                1 1 516_splitncnn_0 530 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_120                 1 1 530 533 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_122                 1 1 533 963 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_123                 1 1 963 538 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_125               2 1 527 538 539\nShuffleChannel           Reshape_130              1 1 539 544 0=2\nSplit                    splitncnn_6              1 2 544 544_splitncnn_0 544_splitncnn_1\nCrop                     Slice_141                1 1 544_splitncnn_1 555 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_144                1 1 544_splitncnn_0 558 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_145                 1 1 558 561 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_147                 1 1 561 972 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_148                 1 1 972 566 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_150               2 1 555 566 567\nShuffleChannel           Reshape_155              1 1 567 572 0=2\nSplit                    splitncnn_7              1 2 572 572_splitncnn_0 572_splitncnn_1\nCrop                     Slice_166                1 1 572_splitncnn_1 583 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_169                1 1 572_splitncnn_0 586 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_170                 1 1 586 589 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_172                 1 1 589 981 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_173                 1 1 981 594 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_175               2 1 583 594 595\nShuffleChannel           Reshape_180              1 1 595 600 0=2\nSplit                    splitncnn_8              1 2 600 600_splitncnn_0 600_splitncnn_1\nCrop                     Slice_191                1 1 600_splitncnn_1 611 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_194                1 1 600_splitncnn_0 614 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_195                 1 1 614 617 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_197                 1 1 617 990 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_198                 1 1 990 622 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_200               2 1 611 622 623\nShuffleChannel           Reshape_205              1 1 623 628 0=2\nSplit                    splitncnn_9              1 2 628 628_splitncnn_0 628_splitncnn_1\nCrop                     Slice_216                1 1 628_splitncnn_1 639 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_219                1 1 628_splitncnn_0 642 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_220                 1 1 642 645 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_222                 1 1 645 999 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_223                 1 1 999 650 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_225               2 1 639 650 651\nShuffleChannel           Reshape_230              1 1 651 656 0=2\nSplit                    splitncnn_10             1 2 656 656_splitncnn_0 656_splitncnn_1\nCrop                     Slice_241                1 1 656_splitncnn_1 667 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_244                1 1 656_splitncnn_0 670 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_245                 1 1 670 673 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_247                 1 1 673 1008 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_248                 1 1 1008 678 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_250               2 1 667 678 679\nShuffleChannel           Reshape_255              1 1 679 684 0=2\nSplit                    splitncnn_11             1 2 684 684_splitncnn_0 684_splitncnn_1\nCrop                     Slice_266                1 1 684_splitncnn_1 695 -23309=1,0 -23310=1,116 -23311=1,0\nCrop                     Slice_269                1 1 684_splitncnn_0 698 -23309=1,116 -23310=1,232 -23311=1,0\nConvolution              Conv_270                 1 1 698 701 0=116 1=1 5=1 6=13456 9=1\nConvolutionDepthWise     Conv_272                 1 1 701 1017 0=116 1=3 4=1 5=1 6=1044 7=116\nConvolution              Conv_273                 1 1 1017 706 0=116 1=1 5=1 6=13456 9=1\nConcat                   Concat_275               2 1 695 706 707\nShuffleChannel           Reshape_280              1 1 707 712 0=2\nSplit                    splitncnn_12             1 3 712 712_splitncnn_0 712_splitncnn_1 712_splitncnn_2\nConvolutionDepthWise     Conv_281                 1 1 712_splitncnn_2 1023 0=232 1=3 3=2 4=1 5=1 6=2088 7=232\nConvolution              Conv_282                 1 1 1023 717 0=232 1=1 5=1 6=53824 9=1\nConvolution              Conv_284                 1 1 712_splitncnn_1 720 0=232 1=1 5=1 6=53824 9=1\nConvolutionDepthWise     Conv_286                 1 1 720 1032 0=232 1=3 3=2 4=1 5=1 6=2088 7=232\nConvolution              Conv_287                 1 1 1032 725 0=232 1=1 5=1 6=53824 9=1\nConcat                   Concat_289               2 1 717 725 726\nShuffleChannel           Reshape_294              1 1 726 731 0=2\nSplit                    splitncnn_13             1 2 731 731_splitncnn_0 731_splitncnn_1\nCrop                     Slice_305                1 1 731_splitncnn_1 742 -23309=1,0 -23310=1,232 -23311=1,0\nCrop                     Slice_308                1 1 731_splitncnn_0 745 -23309=1,232 -23310=1,464 -23311=1,0\nConvolution              Conv_309                 1 1 745 748 0=232 1=1 5=1 6=53824 9=1\nConvolutionDepthWise     Conv_311                 1 1 748 1041 0=232 1=3 4=1 5=1 6=2088 7=232\nConvolution              Conv_312                 1 1 1041 753 0=232 1=1 5=1 6=53824 9=1\nConcat                   Concat_314               2 1 742 753 754\nShuffleChannel           Reshape_319              1 1 754 759 0=2\nConvolution              Conv_320                 1 1 759 760 0=96 1=1 5=1 6=44544\nSwish                    Mul_322                  1 1 760 762\nSplit                    splitncnn_14             1 2 762 762_splitncnn_0 762_splitncnn_1\nInterp                   Resize_324               1 1 762_splitncnn_1 767 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_325               2 1 767 712_splitncnn_0 768\nConvolutionDepthWise     Conv_326                 1 1 768 771 0=328 1=3 4=1 5=1 6=2952 7=328 9=1\nConvolution              Conv_328                 1 1 771 774 0=96 1=1 5=1 6=31488 9=1\nConvolution              Conv_330                 1 1 774 775 0=96 1=1 5=1 6=9216\nSwish                    Mul_332                  1 1 775 777\nSplit                    splitncnn_15             1 2 777 777_splitncnn_0 777_splitncnn_1\nInterp                   Resize_334               1 1 777_splitncnn_1 782 0=1 1=2.000000e+00 2=2.000000e+00\nConcat                   Concat_335               2 1 782 497_splitncnn_0 783\nConvolutionDepthWise     Conv_336                 1 1 783 786 0=216 1=3 4=1 5=1 6=1944 7=216 9=1\nConvolution              Conv_338                 1 1 786 789 0=96 1=1 5=1 6=20736 9=1\nSplit                    splitncnn_16             1 3 789 789_splitncnn_0 789_splitncnn_1 789_splitncnn_2\nConvolutionDepthWise     Conv_340                 1 1 789_splitncnn_2 792 0=96 1=3 3=2 4=1 5=1 6=864 7=96 9=1\nConvolution              Conv_342                 1 1 792 795 0=96 1=1 5=1 6=9216 9=1\nBinaryOp                 Add_344                  2 1 795 777_splitncnn_0 796\nConvolutionDepthWise     Conv_345                 1 1 796 799 0=96 1=3 4=1 5=1 6=864 7=96 9=1\nConvolution              Conv_347                 1 1 799 802 0=96 1=1 5=1 6=9216 9=1\nSplit                    splitncnn_17             1 3 802 802_splitncnn_0 802_splitncnn_1 802_splitncnn_2\nConvolutionDepthWise     Conv_349                 1 1 802_splitncnn_2 805 0=96 1=3 3=2 4=1 5=1 6=864 7=96 9=1\nConvolution              Conv_351                 1 1 805 808 0=96 1=1 5=1 6=9216 9=1\nBinaryOp                 Add_353                  2 1 808 762_splitncnn_0 809\nConvolutionDepthWise     Conv_354                 1 1 809 812 0=96 1=3 4=1 5=1 6=864 7=96 9=1\nConvolution              Conv_356                 1 1 812 815 0=96 1=1 5=1 6=9216 9=1\nSplit                    splitncnn_18             1 2 815 815_splitncnn_0 815_splitncnn_1\nBinaryOp                 Add_360                  2 1 817 789_splitncnn_1 818\nConvolution              Conv_361                 1 1 818 819 0=18 1=1 5=1 6=1728\nBinaryOp                 Mul_364                  2 1 821 819 822 0=2\nConvolution              Conv_365                 1 1 789_splitncnn_0 823 0=45 1=1 5=1 6=4320\nConcat                   Concat_366               2 1 822 823 824\nReshape                  Reshape_380              1 1 824 842 0=6400 1=21 2=3\nPermute                  Transpose_381            1 1 842 stride_8 0=1\nBinaryOp                 Add_384                  2 1 845 802_splitncnn_1 846\nConvolution              Conv_385                 1 1 846 847 0=18 1=1 5=1 6=1728\nBinaryOp                 Mul_388                  2 1 849 847 850 0=2\nConvolution              Conv_389                 1 1 802_splitncnn_0 851 0=45 1=1 5=1 6=4320\nConcat                   Concat_390               2 1 850 851 852\nReshape                  Reshape_404              1 1 852 870 0=1600 1=21 2=3\nPermute                  Transpose_405            1 1 870 stride_16 0=1\nBinaryOp                 Add_408                  2 1 873 815_splitncnn_1 874\nConvolution              Conv_409                 1 1 874 875 0=18 1=1 5=1 6=1728\nBinaryOp                 Mul_412                  2 1 877 875 878 0=2\nConvolution              Conv_413                 1 1 815_splitncnn_0 879 0=45 1=1 5=1 6=4320\nConcat                   Concat_414               2 1 878 879 880\nReshape                  Reshape_428              1 1 880 898 0=400 1=21 2=3\nPermute                  Transpose_429            1 1 898 stride_32 0=1\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/assets/yolov7-tiny.param",
    "content": "7767517\n206 243\nInput                    images                   0 1 images\nMemoryData               338                      0 1 338 0=80 1=80 2=128\nMemoryData               342                      0 1 342 0=80 1=80 2=18\nMemoryData               399                      0 1 399 0=40 1=40 2=256\nMemoryData               403                      0 1 403 0=40 1=40 2=18\nMemoryData               460                      0 1 460 0=20 1=20 2=512\nMemoryData               464                      0 1 464 0=20 1=20 2=18\nConvolution              Conv_0                   1 1 images 198 0=32 1=3 3=2 4=1 5=1 6=864 9=2 -23310=1,1.000000e-01\nConvolution              Conv_2                   1 1 198 200 0=64 1=3 3=2 4=1 5=1 6=18432 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_0              1 2 200 200_splitncnn_0 200_splitncnn_1\nConvolution              Conv_4                   1 1 200_splitncnn_1 202 0=32 1=1 5=1 6=2048 9=2 -23310=1,1.000000e-01\nConvolution              Conv_6                   1 1 200_splitncnn_0 204 0=32 1=1 5=1 6=2048 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_1              1 2 204 204_splitncnn_0 204_splitncnn_1\nConvolution              Conv_8                   1 1 204_splitncnn_1 206 0=32 1=3 4=1 5=1 6=9216 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_2              1 2 206 206_splitncnn_0 206_splitncnn_1\nConvolution              Conv_10                  1 1 206_splitncnn_1 208 0=32 1=3 4=1 5=1 6=9216 9=2 -23310=1,1.000000e-01\nConcat                   Concat_12                4 1 208 206_splitncnn_0 204_splitncnn_0 202 209\nConvolution              Conv_13                  1 1 209 211 0=64 1=1 5=1 6=8192 9=2 -23310=1,1.000000e-01\nPooling                  MaxPool_15               1 1 211 212 1=2 2=2 5=1\nSplit                    splitncnn_3              1 2 212 212_splitncnn_0 212_splitncnn_1\nConvolution              Conv_16                  1 1 212_splitncnn_1 214 0=64 1=1 5=1 6=4096 9=2 -23310=1,1.000000e-01\nConvolution              Conv_18                  1 1 212_splitncnn_0 216 0=64 1=1 5=1 6=4096 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_4              1 2 216 216_splitncnn_0 216_splitncnn_1\nConvolution              Conv_20                  1 1 216_splitncnn_1 218 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_5              1 2 218 218_splitncnn_0 218_splitncnn_1\nConvolution              Conv_22                  1 1 218_splitncnn_1 220 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nConcat                   Concat_24                4 1 220 218_splitncnn_0 216_splitncnn_0 214 221\nConvolution              Conv_25                  1 1 221 223 0=128 1=1 5=1 6=32768 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_6              1 2 223 223_splitncnn_0 223_splitncnn_1\nPooling                  MaxPool_27               1 1 223_splitncnn_1 224 1=2 2=2 5=1\nSplit                    splitncnn_7              1 2 224 224_splitncnn_0 224_splitncnn_1\nConvolution              Conv_28                  1 1 224_splitncnn_1 226 0=128 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nConvolution              Conv_30                  1 1 224_splitncnn_0 228 0=128 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_8              1 2 228 228_splitncnn_0 228_splitncnn_1\nConvolution              Conv_32                  1 1 228_splitncnn_1 230 0=128 1=3 4=1 5=1 6=147456 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_9              1 2 230 230_splitncnn_0 230_splitncnn_1\nConvolution              Conv_34                  1 1 230_splitncnn_1 232 0=128 1=3 4=1 5=1 6=147456 9=2 -23310=1,1.000000e-01\nConcat                   Concat_36                4 1 232 230_splitncnn_0 228_splitncnn_0 226 233\nConvolution              Conv_37                  1 1 233 235 0=256 1=1 5=1 6=131072 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_10             1 2 235 235_splitncnn_0 235_splitncnn_1\nPooling                  MaxPool_39               1 1 235_splitncnn_1 236 1=2 2=2 5=1\nSplit                    splitncnn_11             1 2 236 236_splitncnn_0 236_splitncnn_1\nConvolution              Conv_40                  1 1 236_splitncnn_1 238 0=256 1=1 5=1 6=65536 9=2 -23310=1,1.000000e-01\nConvolution              Conv_42                  1 1 236_splitncnn_0 240 0=256 1=1 5=1 6=65536 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_12             1 2 240 240_splitncnn_0 240_splitncnn_1\nConvolution              Conv_44                  1 1 240_splitncnn_1 242 0=256 1=3 4=1 5=1 6=589824 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_13             1 2 242 242_splitncnn_0 242_splitncnn_1\nConvolution              Conv_46                  1 1 242_splitncnn_1 244 0=256 1=3 4=1 5=1 6=589824 9=2 -23310=1,1.000000e-01\nConcat                   Concat_48                4 1 244 242_splitncnn_0 240_splitncnn_0 238 245\nConvolution              Conv_49                  1 1 245 247 0=512 1=1 5=1 6=524288 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_14             1 2 247 247_splitncnn_0 247_splitncnn_1\nConvolution              Conv_51                  1 1 247_splitncnn_1 249 0=256 1=1 5=1 6=131072 9=2 -23310=1,1.000000e-01\nConvolution              Conv_53                  1 1 247_splitncnn_0 251 0=256 1=1 5=1 6=131072 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_15             1 4 251 251_splitncnn_0 251_splitncnn_1 251_splitncnn_2 251_splitncnn_3\nPooling                  MaxPool_55               1 1 251_splitncnn_3 252 1=5 3=2 5=1\nPooling                  MaxPool_56               1 1 251_splitncnn_2 253 1=9 3=4 5=1\nPooling                  MaxPool_57               1 1 251_splitncnn_1 254 1=13 3=6 5=1\nConcat                   Concat_58                4 1 254 253 252 251_splitncnn_0 255\nConvolution              Conv_59                  1 1 255 257 0=256 1=1 5=1 6=262144 9=2 -23310=1,1.000000e-01\nConcat                   Concat_61                2 1 257 249 258\nConvolution              Conv_62                  1 1 258 260 0=256 1=1 5=1 6=131072 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_16             1 2 260 260_splitncnn_0 260_splitncnn_1\nConvolution              Conv_64                  1 1 260_splitncnn_1 262 0=128 1=1 5=1 6=32768 9=2 -23310=1,1.000000e-01\nInterp                   Resize_67                1 1 262 267 0=1 1=2.000000e+00 2=2.000000e+00\nConvolution              Conv_68                  1 1 235_splitncnn_0 269 0=128 1=1 5=1 6=32768 9=2 -23310=1,1.000000e-01\nConcat                   Concat_70                2 1 269 267 270\nSplit                    splitncnn_17             1 2 270 270_splitncnn_0 270_splitncnn_1\nConvolution              Conv_71                  1 1 270_splitncnn_1 272 0=64 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nConvolution              Conv_73                  1 1 270_splitncnn_0 274 0=64 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_18             1 2 274 274_splitncnn_0 274_splitncnn_1\nConvolution              Conv_75                  1 1 274_splitncnn_1 276 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_19             1 2 276 276_splitncnn_0 276_splitncnn_1\nConvolution              Conv_77                  1 1 276_splitncnn_1 278 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nConcat                   Concat_79                4 1 278 276_splitncnn_0 274_splitncnn_0 272 279\nConvolution              Conv_80                  1 1 279 281 0=128 1=1 5=1 6=32768 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_20             1 2 281 281_splitncnn_0 281_splitncnn_1\nConvolution              Conv_82                  1 1 281_splitncnn_1 283 0=64 1=1 5=1 6=8192 9=2 -23310=1,1.000000e-01\nInterp                   Resize_85                1 1 283 288 0=1 1=2.000000e+00 2=2.000000e+00\nConvolution              Conv_86                  1 1 223_splitncnn_0 290 0=64 1=1 5=1 6=8192 9=2 -23310=1,1.000000e-01\nConcat                   Concat_88                2 1 290 288 291\nSplit                    splitncnn_21             1 2 291 291_splitncnn_0 291_splitncnn_1\nConvolution              Conv_89                  1 1 291_splitncnn_1 293 0=32 1=1 5=1 6=4096 9=2 -23310=1,1.000000e-01\nConvolution              Conv_91                  1 1 291_splitncnn_0 295 0=32 1=1 5=1 6=4096 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_22             1 2 295 295_splitncnn_0 295_splitncnn_1\nConvolution              Conv_93                  1 1 295_splitncnn_1 297 0=32 1=3 4=1 5=1 6=9216 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_23             1 2 297 297_splitncnn_0 297_splitncnn_1\nConvolution              Conv_95                  1 1 297_splitncnn_1 299 0=32 1=3 4=1 5=1 6=9216 9=2 -23310=1,1.000000e-01\nConcat                   Concat_97                4 1 299 297_splitncnn_0 295_splitncnn_0 293 300\nConvolution              Conv_98                  1 1 300 302 0=64 1=1 5=1 6=8192 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_24             1 2 302 302_splitncnn_0 302_splitncnn_1\nConvolution              Conv_100                 1 1 302_splitncnn_1 304 0=128 1=3 3=2 4=1 5=1 6=73728 9=2 -23310=1,1.000000e-01\nConcat                   Concat_102               2 1 304 281_splitncnn_0 305\nSplit                    splitncnn_25             1 2 305 305_splitncnn_0 305_splitncnn_1\nConvolution              Conv_103                 1 1 305_splitncnn_1 307 0=64 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nConvolution              Conv_105                 1 1 305_splitncnn_0 309 0=64 1=1 5=1 6=16384 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_26             1 2 309 309_splitncnn_0 309_splitncnn_1\nConvolution              Conv_107                 1 1 309_splitncnn_1 311 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_27             1 2 311 311_splitncnn_0 311_splitncnn_1\nConvolution              Conv_109                 1 1 311_splitncnn_1 313 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,1.000000e-01\nConcat                   Concat_111               4 1 313 311_splitncnn_0 309_splitncnn_0 307 314\nConvolution              Conv_112                 1 1 314 316 0=128 1=1 5=1 6=32768 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_28             1 2 316 316_splitncnn_0 316_splitncnn_1\nConvolution              Conv_114                 1 1 316_splitncnn_1 318 0=256 1=3 3=2 4=1 5=1 6=294912 9=2 -23310=1,1.000000e-01\nConcat                   Concat_116               2 1 318 260_splitncnn_0 319\nSplit                    splitncnn_29             1 2 319 319_splitncnn_0 319_splitncnn_1\nConvolution              Conv_117                 1 1 319_splitncnn_1 321 0=128 1=1 5=1 6=65536 9=2 -23310=1,1.000000e-01\nConvolution              Conv_119                 1 1 319_splitncnn_0 323 0=128 1=1 5=1 6=65536 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_30             1 2 323 323_splitncnn_0 323_splitncnn_1\nConvolution              Conv_121                 1 1 323_splitncnn_1 325 0=128 1=3 4=1 5=1 6=147456 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_31             1 2 325 325_splitncnn_0 325_splitncnn_1\nConvolution              Conv_123                 1 1 325_splitncnn_1 327 0=128 1=3 4=1 5=1 6=147456 9=2 -23310=1,1.000000e-01\nConcat                   Concat_125               4 1 327 325_splitncnn_0 323_splitncnn_0 321 328\nConvolution              Conv_126                 1 1 328 330 0=256 1=1 5=1 6=131072 9=2 -23310=1,1.000000e-01\nConvolution              Conv_128                 1 1 302_splitncnn_0 332 0=128 1=3 4=1 5=1 6=73728 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_32             1 2 332 332_splitncnn_0 332_splitncnn_1\nConvolution              Conv_130                 1 1 316_splitncnn_0 334 0=256 1=3 4=1 5=1 6=294912 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_33             1 2 334 334_splitncnn_0 334_splitncnn_1\nConvolution              Conv_132                 1 1 330 336 0=512 1=3 4=1 5=1 6=1179648 9=2 -23310=1,1.000000e-01\nSplit                    splitncnn_34             1 2 336 336_splitncnn_0 336_splitncnn_1\nBinaryOp                 Add_136                  2 1 338 332_splitncnn_1 339\nConvolution              Conv_137                 1 1 339 340 0=18 1=1 5=1 6=2304\nBinaryOp                 Mul_140                  2 1 342 340 343 0=2\nConvolutionDepthWise     Conv_141                 1 1 332_splitncnn_0 344 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_143                  1 1 344 346\nConvolution              Conv_144                 1 1 346 347 0=128 1=1 5=1 6=16384\nSwish                    Mul_146                  1 1 347 349\nConvolutionDepthWise     Conv_147                 1 1 349 350 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_149                  1 1 350 352\nConvolution              Conv_150                 1 1 352 353 0=128 1=1 5=1 6=16384\nSwish                    Mul_152                  1 1 353 355\nConvolutionDepthWise     Conv_153                 1 1 355 356 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_155                  1 1 356 358\nConvolution              Conv_156                 1 1 358 359 0=128 1=1 5=1 6=16384\nSwish                    Mul_158                  1 1 359 361\nConvolutionDepthWise     Conv_159                 1 1 361 362 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_161                  1 1 362 364\nConvolution              Conv_162                 1 1 364 365 0=128 1=1 5=1 6=16384\nSwish                    Mul_164                  1 1 365 367\nConvolutionDepthWise     Conv_165                 1 1 367 368 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_167                  1 1 368 370\nConvolution              Conv_168                 1 1 370 371 0=128 1=1 5=1 6=16384\nSwish                    Mul_170                  1 1 371 373\nConvolutionDepthWise     Conv_171                 1 1 373 374 0=128 1=3 4=1 5=1 6=1152 7=128\nSwish                    Mul_173                  1 1 374 376\nConvolution              Conv_174                 1 1 376 377 0=45 1=1 5=1 6=5760\nConcat                   Concat_175               2 1 343 377 378\nReshape                  Reshape_189              1 1 378 396 0=-1 1=21 2=3\nPermute                  Transpose_190            1 1 396 stride_8 0=1\nBinaryOp                 Add_193                  2 1 399 334_splitncnn_1 400\nConvolution              Conv_194                 1 1 400 401 0=18 1=1 5=1 6=4608\nBinaryOp                 Mul_197                  2 1 403 401 404 0=2\nConvolutionDepthWise     Conv_198                 1 1 334_splitncnn_0 405 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_200                  1 1 405 407\nConvolution              Conv_201                 1 1 407 408 0=256 1=1 5=1 6=65536\nSwish                    Mul_203                  1 1 408 410\nConvolutionDepthWise     Conv_204                 1 1 410 411 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_206                  1 1 411 413\nConvolution              Conv_207                 1 1 413 414 0=256 1=1 5=1 6=65536\nSwish                    Mul_209                  1 1 414 416\nConvolutionDepthWise     Conv_210                 1 1 416 417 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_212                  1 1 417 419\nConvolution              Conv_213                 1 1 419 420 0=256 1=1 5=1 6=65536\nSwish                    Mul_215                  1 1 420 422\nConvolutionDepthWise     Conv_216                 1 1 422 423 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_218                  1 1 423 425\nConvolution              Conv_219                 1 1 425 426 0=256 1=1 5=1 6=65536\nSwish                    Mul_221                  1 1 426 428\nConvolutionDepthWise     Conv_222                 1 1 428 429 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_224                  1 1 429 431\nConvolution              Conv_225                 1 1 431 432 0=256 1=1 5=1 6=65536\nSwish                    Mul_227                  1 1 432 434\nConvolutionDepthWise     Conv_228                 1 1 434 435 0=256 1=3 4=1 5=1 6=2304 7=256\nSwish                    Mul_230                  1 1 435 437\nConvolution              Conv_231                 1 1 437 438 0=45 1=1 5=1 6=11520\nConcat                   Concat_232               2 1 404 438 439\nReshape                  Reshape_246              1 1 439 457 0=-1 1=21 2=3\nPermute                  Transpose_247            1 1 457 stride_16 0=1\nBinaryOp                 Add_250                  2 1 460 336_splitncnn_1 461\nConvolution              Conv_251                 1 1 461 462 0=18 1=1 5=1 6=9216\nBinaryOp                 Mul_254                  2 1 464 462 465 0=2\nConvolutionDepthWise     Conv_255                 1 1 336_splitncnn_0 466 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_257                  1 1 466 468\nConvolution              Conv_258                 1 1 468 469 0=512 1=1 5=1 6=262144\nSwish                    Mul_260                  1 1 469 471\nConvolutionDepthWise     Conv_261                 1 1 471 472 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_263                  1 1 472 474\nConvolution              Conv_264                 1 1 474 475 0=512 1=1 5=1 6=262144\nSwish                    Mul_266                  1 1 475 477\nConvolutionDepthWise     Conv_267                 1 1 477 478 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_269                  1 1 478 480\nConvolution              Conv_270                 1 1 480 481 0=512 1=1 5=1 6=262144\nSwish                    Mul_272                  1 1 481 483\nConvolutionDepthWise     Conv_273                 1 1 483 484 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_275                  1 1 484 486\nConvolution              Conv_276                 1 1 486 487 0=512 1=1 5=1 6=262144\nSwish                    Mul_278                  1 1 487 489\nConvolutionDepthWise     Conv_279                 1 1 489 490 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_281                  1 1 490 492\nConvolution              Conv_282                 1 1 492 493 0=512 1=1 5=1 6=262144\nSwish                    Mul_284                  1 1 493 495\nConvolutionDepthWise     Conv_285                 1 1 495 496 0=512 1=3 4=1 5=1 6=4608 7=512\nSwish                    Mul_287                  1 1 496 498\nConvolution              Conv_288                 1 1 498 499 0=45 1=1 5=1 6=23040\nConcat                   Concat_289               2 1 465 499 500\nReshape                  Reshape_303              1 1 500 518 0=-1 1=21 2=3\nPermute                  Transpose_304            1 1 518 stride_32 0=1\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/java/com/tencent/ncnnyoloface/MainActivity.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.ncnnyoloface;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.pm.PackageManager;\nimport android.graphics.PixelFormat;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.Surface;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.AdapterView;\nimport android.widget.Button;\nimport android.widget.Spinner;\n\nimport android.support.v4.app.ActivityCompat;\nimport android.support.v4.content.ContextCompat;\n\npublic class MainActivity extends Activity implements SurfaceHolder.Callback\n{\n    public static final int REQUEST_CAMERA = 100;\n\n    private NcnnYoloFace ncnnyoloface = new NcnnYoloFace();\n    private int facing = 0;\n\n    private Spinner spinnerModel;\n    private Spinner spinnerCPUGPU;\n    private int current_model = 0;\n    private int current_cpugpu = 0;\n\n    private SurfaceView cameraView;\n\n    /** Called when the activity is first created. */\n    @Override\n    public void onCreate(Bundle savedInstanceState)\n    {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        cameraView = (SurfaceView) findViewById(R.id.cameraview);\n\n        cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);\n        cameraView.getHolder().addCallback(this);\n\n        Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);\n        buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View arg0) {\n\n                int new_facing = 1 - facing;\n\n                ncnnyoloface.closeCamera();\n\n                ncnnyoloface.openCamera(new_facing);\n\n                facing = new_facing;\n            }\n        });\n\n        spinnerModel = (Spinner) findViewById(R.id.spinnerModel);\n        spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_model)\n                {\n                    current_model = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);\n        spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_cpugpu)\n                {\n                    current_cpugpu = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        reload();\n    }\n\n    private void reload()\n    {\n        boolean ret_init = ncnnyoloface.loadModel(getAssets(), current_model, current_cpugpu);\n        if (!ret_init)\n        {\n            Log.e(\"MainActivity\", \"ncnnyoloface loadModel failed\");\n        }\n    }\n\n    @Override\n    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)\n    {\n        ncnnyoloface.setOutputWindow(holder.getSurface());\n    }\n\n    @Override\n    public void surfaceCreated(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void surfaceDestroyed(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void onResume()\n    {\n        super.onResume();\n\n        if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED)\n        {\n            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA);\n        }\n\n        ncnnyoloface.openCamera(facing);\n    }\n\n    @Override\n    public void onPause()\n    {\n        super.onPause();\n\n        ncnnyoloface.closeCamera();\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/java/com/tencent/ncnnyoloface/NcnnYoloFace.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.ncnnyoloface;\n\nimport android.content.res.AssetManager;\nimport android.view.Surface;\n\npublic class NcnnYoloFace\n{\n    public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\n    public native boolean openCamera(int facing);\n    public native boolean closeCamera();\n    public native boolean setOutputWindow(Surface surface);\n\n    static {\n        System.loadLibrary(\"ncnnyoloface\");\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/CMakeLists.txt",
    "content": "project(ncnnyoloface)\n\ncmake_minimum_required(VERSION 3.10)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni)\nfind_package(OpenCV REQUIRED core imgproc)\n\nset(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)\nfind_package(ncnn REQUIRED)\n\nadd_library(ncnnyoloface SHARED yolofacencnn.cpp yoloface.cpp ndkcamera.cpp)\n\ntarget_link_libraries(ncnnyoloface ncnn ${OpenCV_LIBS} camera2ndk mediandk)\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/ndkcamera.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"ndkcamera.h\"\n\n#include <string>\n\n#include <android/log.h>\n\n#include <opencv2/core/core.hpp>\n\n#include \"mat.h\"\n\nstatic void onDisconnected(void* context, ACameraDevice* device)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onDisconnected %p\", device);\n}\n\nstatic void onError(void* context, ACameraDevice* device, int error)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onError %p %d\", device, error);\n}\n\nstatic void onImageAvailable(void* context, AImageReader* reader)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onImageAvailable %p\", reader);\n\n    AImage* image = 0;\n    media_status_t status = AImageReader_acquireLatestImage(reader, &image);\n\n    if (status != AMEDIA_OK)\n    {\n        // error\n        return;\n    }\n\n    int32_t format;\n    AImage_getFormat(image, &format);\n\n    // assert format == AIMAGE_FORMAT_YUV_420_888\n\n    int32_t width = 0;\n    int32_t height = 0;\n    AImage_getWidth(image, &width);\n    AImage_getHeight(image, &height);\n\n    int32_t y_pixelStride = 0;\n    int32_t u_pixelStride = 0;\n    int32_t v_pixelStride = 0;\n    AImage_getPlanePixelStride(image, 0, &y_pixelStride);\n    AImage_getPlanePixelStride(image, 1, &u_pixelStride);\n    AImage_getPlanePixelStride(image, 2, &v_pixelStride);\n\n    int32_t y_rowStride = 0;\n    int32_t u_rowStride = 0;\n    int32_t v_rowStride = 0;\n    AImage_getPlaneRowStride(image, 0, &y_rowStride);\n    AImage_getPlaneRowStride(image, 1, &u_rowStride);\n    AImage_getPlaneRowStride(image, 2, &v_rowStride);\n\n    uint8_t* y_data = 0;\n    uint8_t* u_data = 0;\n    uint8_t* v_data = 0;\n    int y_len = 0;\n    int u_len = 0;\n    int v_len = 0;\n    AImage_getPlaneData(image, 0, &y_data, &y_len);\n    AImage_getPlaneData(image, 1, &u_data, &u_len);\n    AImage_getPlaneData(image, 2, &v_data, &v_len);\n\n    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)\n    {\n        // already nv21  :)\n        ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height);\n    }\n    else\n    {\n        // construct nv21\n        unsigned char* nv21 = new unsigned char[width * height + width * height / 2];\n        {\n            // Y\n            unsigned char* yptr = nv21;\n            for (int y=0; y<height; y++)\n            {\n                const unsigned char* y_data_ptr = y_data + y_rowStride * y;\n                for (int x=0; x<width; x++)\n                {\n                    yptr[0] = y_data_ptr[0];\n                    yptr++;\n                    y_data_ptr += y_pixelStride;\n                }\n            }\n\n            // UV\n            unsigned char* uvptr = nv21 + width * height;\n            for (int y=0; y<height/2; y++)\n            {\n                const unsigned char* v_data_ptr = v_data + v_rowStride * y;\n                const unsigned char* u_data_ptr = u_data + u_rowStride * y;\n                for (int x=0; x<width/2; x++)\n                {\n                    uvptr[0] = v_data_ptr[0];\n                    uvptr[1] = u_data_ptr[0];\n                    uvptr += 2;\n                    v_data_ptr += v_pixelStride;\n                    u_data_ptr += u_pixelStride;\n                }\n            }\n        }\n\n        ((NdkCamera*)context)->on_image((unsigned char*)nv21, (int)width, (int)height);\n\n        delete[] nv21;\n    }\n\n    AImage_delete(image);\n}\n\nstatic void onSessionActive(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionActive %p\", session);\n}\n\nstatic void onSessionReady(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionReady %p\", session);\n}\n\nstatic void onSessionClosed(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionClosed %p\", session);\n}\n\nvoid onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureFailed %p %p %p\", session, request, failure);\n}\n\nvoid onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceCompleted %p %d %ld\", session, sequenceId, frameNumber);\n}\n\nvoid onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceAborted %p %d\", session, sequenceId);\n}\n\nvoid onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureCompleted %p %p %p\", session, request, result);\n}\n\nNdkCamera::NdkCamera()\n{\n    camera_facing = 0;\n    camera_orientation = 0;\n\n    camera_manager = 0;\n    camera_device = 0;\n    image_reader = 0;\n    image_reader_surface = 0;\n    image_reader_target = 0;\n    capture_request = 0;\n    capture_session_output_container = 0;\n    capture_session_output = 0;\n    capture_session = 0;\n\n\n    // setup imagereader and its surface\n    {\n        AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader);\n\n        AImageReader_ImageListener listener;\n        listener.context = this;\n        listener.onImageAvailable = onImageAvailable;\n\n        AImageReader_setImageListener(image_reader, &listener);\n\n        AImageReader_getWindow(image_reader, &image_reader_surface);\n\n        ANativeWindow_acquire(image_reader_surface);\n    }\n}\n\nNdkCamera::~NdkCamera()\n{\n    close();\n\n    if (image_reader)\n    {\n        AImageReader_delete(image_reader);\n        image_reader = 0;\n    }\n\n    if (image_reader_surface)\n    {\n        ANativeWindow_release(image_reader_surface);\n        image_reader_surface = 0;\n    }\n}\n\nint NdkCamera::open(int _camera_facing)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open\");\n\n    camera_facing = _camera_facing;\n\n    camera_manager = ACameraManager_create();\n\n    // find front camera\n    std::string camera_id;\n    {\n        ACameraIdList* camera_id_list = 0;\n        ACameraManager_getCameraIdList(camera_manager, &camera_id_list);\n\n        for (int i = 0; i < camera_id_list->numCameras; ++i)\n        {\n            const char* id = camera_id_list->cameraIds[i];\n            ACameraMetadata* camera_metadata = 0;\n            ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata);\n\n            // query faceing\n            acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e);\n                facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];\n            }\n\n            if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            camera_id = id;\n\n            // query orientation\n            int orientation = 0;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e);\n\n                orientation = (int)e.data.i32[0];\n            }\n\n            camera_orientation = orientation;\n\n            ACameraMetadata_free(camera_metadata);\n\n            break;\n        }\n\n        ACameraManager_deleteCameraIdList(camera_id_list);\n    }\n\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open %s %d\", camera_id.c_str(), camera_orientation);\n\n    // open camera\n    {\n        ACameraDevice_StateCallbacks camera_device_state_callbacks;\n        camera_device_state_callbacks.context = this;\n        camera_device_state_callbacks.onDisconnected = onDisconnected;\n        camera_device_state_callbacks.onError = onError;\n\n        ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device);\n    }\n\n    // capture request\n    {\n        ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request);\n\n        ACameraOutputTarget_create(image_reader_surface, &image_reader_target);\n        ACaptureRequest_addTarget(capture_request, image_reader_target);\n    }\n\n    // capture session\n    {\n        ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks;\n        camera_capture_session_state_callbacks.context = this;\n        camera_capture_session_state_callbacks.onActive = onSessionActive;\n        camera_capture_session_state_callbacks.onReady = onSessionReady;\n        camera_capture_session_state_callbacks.onClosed = onSessionClosed;\n\n        ACaptureSessionOutputContainer_create(&capture_session_output_container);\n\n        ACaptureSessionOutput_create(image_reader_surface, &capture_session_output);\n\n        ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output);\n\n        ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);\n\n        ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks;\n        camera_capture_session_capture_callbacks.context = this;\n        camera_capture_session_capture_callbacks.onCaptureStarted = 0;\n        camera_capture_session_capture_callbacks.onCaptureProgressed = 0;\n        camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted;\n        camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed;\n        camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted;\n        camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted;\n        camera_capture_session_capture_callbacks.onCaptureBufferLost = 0;\n\n        ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr);\n    }\n\n    return 0;\n}\n\nvoid NdkCamera::close()\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"close\");\n\n    if (capture_session)\n    {\n        ACameraCaptureSession_stopRepeating(capture_session);\n        ACameraCaptureSession_close(capture_session);\n        capture_session = 0;\n    }\n\n    if (camera_device)\n    {\n        ACameraDevice_close(camera_device);\n        camera_device = 0;\n    }\n\n    if (capture_session_output_container)\n    {\n        ACaptureSessionOutputContainer_free(capture_session_output_container);\n        capture_session_output_container = 0;\n    }\n\n    if (capture_session_output)\n    {\n        ACaptureSessionOutput_free(capture_session_output);\n        capture_session_output = 0;\n    }\n\n    if (capture_request)\n    {\n        ACaptureRequest_free(capture_request);\n        capture_request = 0;\n    }\n\n    if (image_reader_target)\n    {\n        ACameraOutputTarget_free(image_reader_target);\n        image_reader_target = 0;\n    }\n\n    if (camera_manager)\n    {\n        ACameraManager_delete(camera_manager);\n        camera_manager = 0;\n    }\n}\n\nvoid NdkCamera::on_image(const cv::Mat& rgb) const\n{\n}\n\nvoid NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // rotate nv21\n    int w = 0;\n    int h = 0;\n    int rotate_type = 0;\n    {\n        if (camera_orientation == 0)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 2 : 1;\n        }\n        if (camera_orientation == 90)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 5 : 6;\n        }\n        if (camera_orientation == 180)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 4 : 3;\n        }\n        if (camera_orientation == 270)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 7 : 8;\n        }\n    }\n\n    cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1);\n    ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type);\n\n    // nv21_rotated to rgb\n    cv::Mat rgb(h, w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data);\n\n    on_image(rgb);\n}\n\nstatic const int NDKCAMERAWINDOW_ID = 233;\n\nNdkCameraWindow::NdkCameraWindow() : NdkCamera()\n{\n    sensor_manager = 0;\n    sensor_event_queue = 0;\n    accelerometer_sensor = 0;\n    win = 0;\n\n    accelerometer_orientation = 0;\n\n    // sensor\n    sensor_manager = ASensorManager_getInstance();\n\n    accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER);\n}\n\nNdkCameraWindow::~NdkCameraWindow()\n{\n    if (accelerometer_sensor)\n    {\n        ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor);\n        accelerometer_sensor = 0;\n    }\n\n    if (sensor_event_queue)\n    {\n        ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue);\n        sensor_event_queue = 0;\n    }\n\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n}\n\nvoid NdkCameraWindow::set_window(ANativeWindow* _win)\n{\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n\n    win = _win;\n    ANativeWindow_acquire(win);\n}\n\nvoid NdkCameraWindow::on_image_render(cv::Mat& rgb) const\n{\n}\n\nvoid NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // resolve orientation from camera_orientation and accelerometer_sensor\n    {\n        if (!sensor_event_queue)\n        {\n            sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0);\n\n            ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor);\n        }\n\n        int id = ALooper_pollAll(0, 0, 0, 0);\n        if (id == NDKCAMERAWINDOW_ID)\n        {\n            ASensorEvent e[8];\n            ssize_t num_event = 0;\n            while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1)\n            {\n                num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8);\n                if (num_event < 0)\n                    break;\n            }\n\n            if (num_event > 0)\n            {\n                float acceleration_x = e[num_event - 1].acceleration.x;\n                float acceleration_y = e[num_event - 1].acceleration.y;\n                float acceleration_z = e[num_event - 1].acceleration.z;\n//                 __android_log_print(ANDROID_LOG_WARN, \"NdkCameraWindow\", \"x = %f, y = %f, z = %f\", x, y, z);\n\n                if (acceleration_y > 7)\n                {\n                    accelerometer_orientation = 0;\n                }\n                if (acceleration_x < -7)\n                {\n                    accelerometer_orientation = 90;\n                }\n                if (acceleration_y < -7)\n                {\n                    accelerometer_orientation = 180;\n                }\n                if (acceleration_x > 7)\n                {\n                    accelerometer_orientation = 270;\n                }\n            }\n        }\n    }\n\n    // roi crop and rotate nv21\n    int nv21_roi_x = 0;\n    int nv21_roi_y = 0;\n    int nv21_roi_w = 0;\n    int nv21_roi_h = 0;\n    int roi_x = 0;\n    int roi_y = 0;\n    int roi_w = 0;\n    int roi_h = 0;\n    int rotate_type = 0;\n    int render_w = 0;\n    int render_h = 0;\n    int render_rotate_type = 0;\n    {\n        int win_w = ANativeWindow_getWidth(win);\n        int win_h = ANativeWindow_getHeight(win);\n\n        if (accelerometer_orientation == 90 || accelerometer_orientation == 270)\n        {\n            std::swap(win_w, win_h);\n        }\n\n        const int final_orientation = (camera_orientation + accelerometer_orientation) % 360;\n\n        if (final_orientation == 0 || final_orientation == 180)\n        {\n            if (win_w * nv21_height > win_h * nv21_width)\n            {\n                roi_w = nv21_width;\n                roi_h = (nv21_width * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_height - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_height;\n                roi_w = (nv21_height * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_width - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_x;\n            nv21_roi_y = roi_y;\n            nv21_roi_w = roi_w;\n            nv21_roi_h = roi_h;\n        }\n        if (final_orientation == 90 || final_orientation == 270)\n        {\n            if (win_w * nv21_width > win_h * nv21_height)\n            {\n                roi_w = nv21_height;\n                roi_h = (nv21_height * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_width - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_width;\n                roi_w = (nv21_width * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_height - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_y;\n            nv21_roi_y = roi_x;\n            nv21_roi_w = roi_h;\n            nv21_roi_h = roi_w;\n        }\n\n        if (camera_facing == 0)\n        {\n            if (camera_orientation == 0 && accelerometer_orientation == 0)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 90)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 180)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 270)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 0)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 90)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 180)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 270)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 0)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 90)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 180)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 270)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 0)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 90)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 180)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 270)\n            {\n                rotate_type = 2;\n            }\n        }\n        else\n        {\n            if (final_orientation == 0)\n            {\n                rotate_type = 1;\n            }\n            if (final_orientation == 90)\n            {\n                rotate_type = 6;\n            }\n            if (final_orientation == 180)\n            {\n                rotate_type = 3;\n            }\n            if (final_orientation == 270)\n            {\n                rotate_type = 8;\n            }\n        }\n\n        if (accelerometer_orientation == 0)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 1;\n        }\n        if (accelerometer_orientation == 90)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 8;\n        }\n        if (accelerometer_orientation == 180)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 3;\n        }\n        if (accelerometer_orientation == 270)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 6;\n        }\n    }\n\n    // crop and rotate nv21\n    cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1);\n    {\n        const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x;\n        unsigned char* dstY = nv21_croprotated.data;\n        ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type);\n\n        const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x;\n        unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h;\n        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);\n    }\n\n    // nv21_croprotated to rgb\n    cv::Mat rgb(roi_h, roi_w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data);\n\n    on_image_render(rgb);\n\n    // rotate to native window orientation\n    cv::Mat rgb_render(render_h, render_w, CV_8UC3);\n    ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type);\n\n    ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);\n\n    ANativeWindow_Buffer buf;\n    ANativeWindow_lock(win, &buf, NULL);\n\n    // scale to target size\n    if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)\n    {\n        for (int y = 0; y < render_h; y++)\n        {\n            const unsigned char* ptr = rgb_render.ptr<const unsigned char>(y);\n            unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y;\n\n            int x = 0;\n#if __ARM_NEON\n            for (; x + 7 < render_w; x += 8)\n            {\n                uint8x8x3_t _rgb = vld3_u8(ptr);\n                uint8x8x4_t _rgba;\n                _rgba.val[0] = _rgb.val[0];\n                _rgba.val[1] = _rgb.val[1];\n                _rgba.val[2] = _rgb.val[2];\n                _rgba.val[3] = vdup_n_u8(255);\n                vst4_u8(outptr, _rgba);\n\n                ptr += 24;\n                outptr += 32;\n            }\n#endif // __ARM_NEON\n            for (; x < render_w; x++)\n            {\n                outptr[0] = ptr[0];\n                outptr[1] = ptr[1];\n                outptr[2] = ptr[2];\n                outptr[3] = 255;\n\n                ptr += 3;\n                outptr += 4;\n            }\n        }\n    }\n\n    ANativeWindow_unlockAndPost(win);\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/ndkcamera.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef NDKCAMERA_H\n#define NDKCAMERA_H\n\n#include <android/looper.h>\n#include <android/native_window.h>\n#include <android/sensor.h>\n#include <camera/NdkCameraDevice.h>\n#include <camera/NdkCameraManager.h>\n#include <camera/NdkCameraMetadata.h>\n#include <media/NdkImageReader.h>\n\n#include <opencv2/core/core.hpp>\n\nclass NdkCamera\n{\npublic:\n    NdkCamera();\n    virtual ~NdkCamera();\n\n    // facing 0=front 1=back\n    int open(int camera_facing = 0);\n    void close();\n\n    virtual void on_image(const cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    int camera_facing;\n    int camera_orientation;\n\nprivate:\n    ACameraManager* camera_manager;\n    ACameraDevice* camera_device;\n    AImageReader* image_reader;\n    ANativeWindow* image_reader_surface;\n    ACameraOutputTarget* image_reader_target;\n    ACaptureRequest* capture_request;\n    ACaptureSessionOutputContainer* capture_session_output_container;\n    ACaptureSessionOutput* capture_session_output;\n    ACameraCaptureSession* capture_session;\n};\n\nclass NdkCameraWindow : public NdkCamera\n{\npublic:\n    NdkCameraWindow();\n    virtual ~NdkCameraWindow();\n\n    void set_window(ANativeWindow* win);\n\n    virtual void on_image_render(cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    mutable int accelerometer_orientation;\n\nprivate:\n    ASensorManager* sensor_manager;\n    mutable ASensorEventQueue* sensor_event_queue;\n    const ASensor* accelerometer_sensor;\n    ANativeWindow* win;\n};\n\n#endif // NDKCAMERA_H\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/yoloface.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"yoloface.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#include \"cpu.h\"\n#define clip(x, y) (x < 0 ? 0 : (x > y ? y : x))\n\n\nstatic inline float intersection_area(const Object& a, const Object& b)\n{\n    cv::Rect_<float> inter = a.rect & b.rect;\n    return inter.area();\n}\n\nstatic void qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right)\n{\n    int i = left;\n    int j = right;\n    float p = faceobjects[(left + right) / 2].prob;\n\n    while (i <= j)\n    {\n        while (faceobjects[i].prob > p)\n            i++;\n\n        while (faceobjects[j].prob < p)\n            j--;\n\n        if (i <= j)\n        {\n            // swap\n            std::swap(faceobjects[i], faceobjects[j]);\n\n            i++;\n            j--;\n        }\n    }\n\n    #pragma omp parallel sections\n    {\n        #pragma omp section\n        {\n            if (left < j) qsort_descent_inplace(faceobjects, left, j);\n        }\n        #pragma omp section\n        {\n            if (i < right) qsort_descent_inplace(faceobjects, i, right);\n        }\n    }\n}\n\nstatic void qsort_descent_inplace(std::vector<Object>& faceobjects)\n{\n    if (faceobjects.empty())\n        return;\n\n    qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);\n}\n\nstatic void nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold)\n{\n    picked.clear();\n\n    const int n = faceobjects.size();\n\n    std::vector<float> areas(n);\n    for (int i = 0; i < n; i++)\n    {\n        areas[i] = faceobjects[i].rect.area();\n    }\n\n    for (int i = 0; i < n; i++)\n    {\n        const Object& a = faceobjects[i];\n\n        int keep = 1;\n        for (int j = 0; j < (int)picked.size(); j++)\n        {\n            const Object& b = faceobjects[picked[j]];\n\n            // intersection over union\n            float inter_area = intersection_area(a, b);\n            float union_area = areas[i] + areas[picked[j]] - inter_area;\n            // float IoU = inter_area / union_area\n            if (inter_area / union_area > nms_threshold)\n                keep = 0;\n        }\n\n        if (keep)\n            picked.push_back(i);\n    }\n}\n\nstatic inline float sigmoid(float x)\n{\n    return static_cast<float>(1.f / (1.f + exp(-x)));\n}\n\nstatic void generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects)\n{\n    const int num_grid = feat_blob.h;\n\n    int num_grid_x;\n    int num_grid_y;\n    if (in_pad.w > in_pad.h)\n    {\n        num_grid_x = in_pad.w / stride;\n        num_grid_y = num_grid / num_grid_x;\n    }\n    else\n    {\n        num_grid_y = in_pad.h / stride;\n        num_grid_x = num_grid / num_grid_y;\n    }\n\n    const int num_class = feat_blob.w - 5-15;\n\n    const int num_anchors = anchors.w / 2;\n\n    for (int q = 0; q < num_anchors; q++)\n    {\n        const float anchor_w = anchors[q * 2];\n        const float anchor_h = anchors[q * 2 + 1];\n\n        const ncnn::Mat feat = feat_blob.channel(q);\n\n        for (int i = 0; i < num_grid_y; i++)\n        {\n            for (int j = 0; j < num_grid_x; j++)\n            {\n                const float* featptr = feat.row(i * num_grid_x + j);\n                float box_confidence = sigmoid(featptr[4]);\n                if (box_confidence >= prob_threshold)\n                {\n                    // find class index with max class score\n                    int class_index = 0;\n                    float class_score = -FLT_MAX;\n                    for (int k = 0; k < num_class; k++)\n                    {\n                        float score = featptr[5 + k];// +15];\n                        if (score > class_score)\n                        {\n                            class_index = k;\n                            class_score = score;\n                        }\n                    }\n                    float confidence = box_confidence * sigmoid(class_score);\n                    if (confidence >= prob_threshold)\n                    {\n                        float dx = sigmoid(featptr[0]);\n                        float dy = sigmoid(featptr[1]);\n                        float dw = sigmoid(featptr[2]);\n                        float dh = sigmoid(featptr[3]);\n\n                        float pb_cx = (dx * 2.f - 0.5f + j) * stride;\n                        float pb_cy = (dy * 2.f - 0.5f + i) * stride;\n\n                        float pb_w = pow(dw * 2.f, 2) * anchor_w;\n                        float pb_h = pow(dh * 2.f, 2) * anchor_h;\n\n                        float x0 = pb_cx - pb_w * 0.5f;\n                        float y0 = pb_cy - pb_h * 0.5f;\n                        float x1 = pb_cx + pb_w * 0.5f;\n                        float y1 = pb_cy + pb_h * 0.5f;\n\n                        Object obj;\n                        obj.rect.x = x0;\n                        obj.rect.y = y0;\n                        obj.rect.width = x1 - x0;\n                        obj.rect.height = y1 - y0;\n                        obj.label = class_index;\n                        obj.prob = confidence;\n                        for (int l = 0; l < 5; l++)\n                        {\n                            Landmarks pt;\n                            pt.x = (featptr[3 * l + 6] * 2-0.5 +  j) * stride;\n                            pt.y = (featptr[3 * l + 1 + 6] * 2-0.5 + i) * stride;\n                            pt.score = sigmoid(featptr[3 * l + 2 + 6]);\n                            obj.pts.push_back(pt);\n                        }\n                        objects.push_back(obj);\n                    }\n                }\n            }\n        }\n    }\n}\n\n\n\n\nYoloFace::YoloFace()\n{\n    blob_pool_allocator.set_size_compare_ratio(0.f);\n    workspace_pool_allocator.set_size_compare_ratio(0.f);\n}\n\nint YoloFace::load(AAssetManager* mgr, const char* modeltype, int _target_size, const float* _mean_vals, const float* _norm_vals, bool use_gpu)\n{\n    yoloface.clear();\n    blob_pool_allocator.clear();\n    workspace_pool_allocator.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    yoloface.opt = ncnn::Option();\n#if NCNN_VULKAN\n    yoloface.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    yoloface.opt.num_threads = ncnn::get_big_cpu_count();\n    yoloface.opt.blob_allocator = &blob_pool_allocator;\n    yoloface.opt.workspace_allocator = &workspace_pool_allocator;\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"%s.param\", modeltype);\n    sprintf(modelpath, \"%s.bin\", modeltype);\n    yoloface.load_param(mgr, parampath);\n    yoloface.load_model(mgr, modelpath);\n\n    target_size = _target_size;\n    norm_vals[0] = _norm_vals[0];\n    norm_vals[1] = _norm_vals[1];\n    norm_vals[2] = _norm_vals[2];\n\n    return 0;\n}\n\n\nint YoloFace::detect(const cv::Mat& rgb, std::vector<Object>& objects, float prob_threshold, float nms_threshold)\n{\n  \n    target_size = 640;\n    int img_w = rgb.cols;\n    int img_h = rgb.rows;\n\n    // letterbox pad to multiple of 32\n    int w = img_w;\n    int h = img_h;\n    float scale = 1.f;\n    if (w > h)\n    {\n        scale = (float)target_size / w;\n        w = target_size;\n        h = h * scale;\n    }\n    else\n    {\n        scale = (float)target_size / h;\n        h = target_size;\n        w = w * scale;\n    }\n\n    ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, img_w, img_h, w, h);\n\n    // pad to target_size rectangle\n    // yolov5/utils/datasets.py letterbox\n    int wpad = target_size - w;//(w + 31) / 32 * 32 - w;\n    int hpad = target_size - h;//(h + 31) / 32 * 32 - h;\n    ncnn::Mat in_pad;\n    ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 114.f);\n\n\n    in_pad.substract_mean_normalize(0, norm_vals);\n\n    ncnn::Extractor ex = yoloface.create_extractor();\n\n    ex.input(\"images\", in_pad);\n\n    std::vector<Object> proposals;\n\n    // anchor setting from yolov5/models/yolov5s.yaml\n\n\n    // stride 8\n    {\n        ncnn::Mat out;\n        ex.extract(\"stride_8\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 4.f;\n        anchors[1] = 5.f;\n        anchors[2] = 6.f;\n        anchors[3] = 8.f;\n        anchors[4] = 10.f;\n        anchors[5] = 12.f;\n\n        std::vector<Object> objects8;\n        generate_proposals(anchors, 8, in_pad, out, prob_threshold, objects8);\n\n        proposals.insert(proposals.end(), objects8.begin(), objects8.end());\n    }\n\n    // stride 16\n    {\n        ncnn::Mat out;\n\n        ex.extract(\"stride_16\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 15.f;\n        anchors[1] = 19.f;\n        anchors[2] = 23.f;\n        anchors[3] = 30.f;\n        anchors[4] = 39.f;\n        anchors[5] = 52.f;\n\n        std::vector<Object> objects16;\n        generate_proposals(anchors, 16, in_pad, out, prob_threshold, objects16);\n\n        proposals.insert(proposals.end(), objects16.begin(), objects16.end());\n    }\n\n    // stride 32\n    {\n        ncnn::Mat out;\n\n        ex.extract(\"stride_32\", out);\n\n        ncnn::Mat anchors(6);\n        anchors[0] = 72.f;\n        anchors[1] = 97.f;\n        anchors[2] = 123.f;\n        anchors[3] = 164.f;\n        anchors[4] = 209.f;\n        anchors[5] = 297.f;\n\n        std::vector<Object> objects32;\n        generate_proposals(anchors, 32, in_pad, out, prob_threshold, objects32);\n\n        proposals.insert(proposals.end(), objects32.begin(), objects32.end());\n    }\n\n    // sort all proposals by score from highest to lowest\n    qsort_descent_inplace(proposals);\n\n    // apply nms with nms_threshold\n    std::vector<int> picked;\n    nms_sorted_bboxes(proposals, picked, nms_threshold);\n\n    int count = picked.size();\n\n    objects.resize(count);\n    for (int i = 0; i < count; i++)\n    {\n        objects[i] = proposals[picked[i]];\n\n        // adjust offset to original unpadded\n        float x0 = (objects[i].rect.x - (wpad / 2)) / scale;\n        float y0 = (objects[i].rect.y - (hpad / 2)) / scale;\n        float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale;\n        float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale;\n\n        for (int j = 0; j < objects[i].pts.size(); j++)\n        {\n            float x = (objects[i].pts[j].x - (wpad / 2)) / scale;\n            float y = (objects[i].pts[j].y - (hpad / 2)) / scale;\n            objects[i].pts[j].x = x;\n            objects[i].pts[j].y = y;\n        }\n\n        // clip\n        x0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);\n        y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);\n        x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);\n        y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);\n\n        objects[i].rect.x = x0;\n        objects[i].rect.y = y0;\n        objects[i].rect.width = x1 - x0;\n        objects[i].rect.height = y1 - y0;\n    }\n\n\n    return 0;\n}\n\nint YoloFace::draw(cv::Mat& rgb, const std::vector<Object>& objects)\n{\n\n    static const unsigned char colors[19][3] = {\n        { 54,  67, 244},\n        { 99,  30, 233},\n        {176,  39, 156},\n        {183,  58, 103},\n        {181,  81,  63},\n        {243, 150,  33},\n        {244, 169,   3},\n        {212, 188,   0},\n        {136, 150,   0},\n        { 80, 175,  76},\n        { 74, 195, 139},\n        { 57, 220, 205},\n        { 59, 235, 255},\n        {  7, 193, 255},\n        {  0, 152, 255},\n        { 34,  87, 255},\n        { 72,  85, 121},\n        {158, 158, 158},\n        {139, 125,  96}\n    };\n\n    int color_index = 0;\n\n    for (size_t i = 0; i < objects.size(); i++)\n    {\n        const Object& obj = objects[i];\n\n        const unsigned char* color = colors[color_index % 19];\n        color_index++;\n\n        cv::Scalar cc(color[0], color[1], color[2]);\n\n        cv::rectangle(rgb,obj.rect, cc, 2);\n\n        char text[256];\n        sprintf(text, \"%.1f%%\",  obj.prob * 100);\n\n        int baseLine = 0;\n        cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n        int x = obj.rect.x;\n        int y = obj.rect.y - label_size.height - baseLine;\n        if (y < 0)\n            y = 0;\n        if (x + label_size.width > rgb.cols)\n            x = rgb.cols - label_size.width;\n\n        cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cc, -1);\n\n        cv::Scalar textcc = (color[0] + color[1] + color[2] >= 381) ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255);\n\n        cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, textcc, 1);\n        for (int j = 0; j < obj.pts.size(); j++)\n        {\n            cv::circle(rgb, cv::Point(obj.pts[j].x,obj.pts[j].y), 2, cv::Scalar(0, 255, 0), -1);\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/yoloface.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef YOLOFACE_H\n#define YOLOFACE_H\n\n#include <opencv2/core/core.hpp>\n\n#include <net.h>\nstruct Landmarks\n{\n    float x;\n    float y;\n    float score;\n};\nstruct Object\n{\n    cv::Rect_<float> rect;\n    int label;\n    float prob;\n    std::vector<Landmarks> pts;\n};\n\n\nclass YoloFace\n{\npublic:\n    YoloFace();\n\n    int load(const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);\n\n    int load(AAssetManager* mgr, const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);\n\n    int detect(const cv::Mat& rgb, std::vector<Object>& objects, float prob_threshold = 0.25f, float nms_threshold = 0.45f);\n\n    int draw(cv::Mat& rgb, const std::vector<Object>& objects);\n\nprivate:\n\n    ncnn::Net yoloface;\n\n    int target_size;\n    float mean_vals[3];\n    float norm_vals[3];\n    int image_w;\n    int image_h;\n    int in_w;\n    int in_h;\n\n    ncnn::UnlockedPoolAllocator blob_pool_allocator;\n    ncnn::PoolAllocator workspace_pool_allocator;\n};\n\n#endif // NANODET_H\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/jni/yolofacencnn.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include <android/asset_manager_jni.h>\n#include <android/native_window_jni.h>\n#include <android/native_window.h>\n\n#include <android/log.h>\n\n#include <jni.h>\n\n#include <string>\n#include <vector>\n\n#include <platform.h>\n#include <benchmark.h>\n\n#include \"yoloface.h\"\n\n#include \"ndkcamera.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#if __ARM_NEON\n#include <arm_neon.h>\n#endif // __ARM_NEON\n\nstatic int draw_unsupported(cv::Mat& rgb)\n{\n    const char text[] = \"unsupported\";\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine);\n\n    int y = (rgb.rows - label_size.height) / 2;\n    int x = (rgb.cols - label_size.width) / 2;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic int draw_fps(cv::Mat& rgb)\n{\n    // resolve moving average\n    float avg_fps = 0.f;\n    {\n        static double t0 = 0.f;\n        static float fps_history[10] = {0.f};\n\n        double t1 = ncnn::get_current_time();\n        if (t0 == 0.f)\n        {\n            t0 = t1;\n            return 0;\n        }\n\n        float fps = 1000.f / (t1 - t0);\n        t0 = t1;\n\n        for (int i = 9; i >= 1; i--)\n        {\n            fps_history[i] = fps_history[i - 1];\n        }\n        fps_history[0] = fps;\n\n        if (fps_history[9] == 0.f)\n        {\n            return 0;\n        }\n\n        for (int i = 0; i < 10; i++)\n        {\n            avg_fps += fps_history[i];\n        }\n        avg_fps /= 10.f;\n    }\n\n    char text[32];\n    sprintf(text, \"FPS=%.2f\", avg_fps);\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n    int y = 0;\n    int x = rgb.cols - label_size.width;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic YoloFace* g_yoloface = 0;\nstatic ncnn::Mutex lock;\n\nclass MyNdkCamera : public NdkCameraWindow\n{\npublic:\n    virtual void on_image_render(cv::Mat& rgb) const;\n};\n\nvoid MyNdkCamera::on_image_render(cv::Mat& rgb) const\n{\n    // nanodet\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (g_yoloface)\n        {\n            std::vector<Object> objects;\n            g_yoloface->detect(rgb, objects);\n\n            g_yoloface->draw(rgb, objects);\n        }\n        else\n        {\n            draw_unsupported(rgb);\n        }\n    }\n\n    draw_fps(rgb);\n}\n\nstatic MyNdkCamera* g_camera = 0;\n\nextern \"C\" {\n\nJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnLoad\");\n\n    g_camera = new MyNdkCamera;\n\n    return JNI_VERSION_1_4;\n}\n\nJNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnUnload\");\n\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        delete g_yoloface;\n        g_yoloface = 0;\n    }\n\n    delete g_camera;\n    g_camera = 0;\n}\n\n// public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu)\n{\n    if (modelid < 0 || modelid > 6 || cpugpu < 0 || cpugpu > 1)\n    {\n        return JNI_FALSE;\n    }\n\n    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"loadModel %p\", mgr);\n\n    const char* modeltypes[] =\n    {\n        \"yolov7-lite-e\",\n        \"yolov7-tiny\"\n    };\n\n    const int target_sizes[] =\n    {\n        640,\n        640\n    };\n\n    const float mean_vals[][3] =\n    {\n        {127.f, 127.f, 127.f},\n    };\n\n    const float norm_vals[][3] =\n    {\n        {1 / 255.f, 1 / 255.f, 1 / 255.f},\n        {1 / 255.f, 1 / 255.f, 1 / 255.f},\n    };\n\n    const char* modeltype = modeltypes[(int)modelid];\n    int target_size = target_sizes[(int)modelid];\n    bool use_gpu = (int)cpugpu == 1;\n\n    // reload\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (use_gpu && ncnn::get_gpu_count() == 0)\n        {\n            // no gpu\n            delete g_yoloface;\n            g_yoloface = 0;\n        }\n        else\n        {\n            if (!g_yoloface)\n                g_yoloface = new YoloFace;\n            g_yoloface->load(mgr, modeltype, target_size, mean_vals[(int)modelid], norm_vals[(int)modelid], use_gpu);\n        }\n    }\n\n    return JNI_TRUE;\n}\n\n// public native boolean openCamera(int facing);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_openCamera(JNIEnv* env, jobject thiz, jint facing)\n{\n    if (facing < 0 || facing > 1)\n        return JNI_FALSE;\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"openCamera %d\", facing);\n\n    g_camera->open((int)facing);\n\n    return JNI_TRUE;\n}\n\n// public native boolean closeCamera();\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_closeCamera(JNIEnv* env, jobject thiz)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"closeCamera\");\n\n    g_camera->close();\n\n    return JNI_TRUE;\n}\n\n// public native boolean setOutputWindow(Surface surface);\nJNIEXPORT jboolean JNICALL Java_com_tencent_ncnnyoloface_NcnnYoloFace_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)\n{\n    ANativeWindow* win = ANativeWindow_fromSurface(env, surface);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"setOutputWindow %p\", win);\n\n    g_camera->set_window(win);\n\n    return JNI_TRUE;\n}\n\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Button\n        android:id=\"@+id/buttonSwitchCamera\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"切换摄像头\" />\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Spinner\n        android:id=\"@+id/spinnerModel\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/model_array\" />\n\n    <Spinner\n        android:id=\"@+id/spinnerCPUGPU\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/cpugpu_array\" />\n\n    </LinearLayout>\n\n    <SurfaceView\n        android:id=\"@+id/cameraview\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "ncnn-android-yolov7_face/app/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">yolov7face_demo</string>\n    <string-array name=\"model_array\">\n        <item>yolov7-lite-e</item>\n        <item>yolov7-tiny</item>\n    </string-array>\n    <string-array name=\"cpugpu_array\">\n        <item>CPU</item>\n        <item>GPU</item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "ncnn-android-yolov7_face/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    repositories {\n        jcenter()\n        google()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        google()\n    }\n}\n"
  },
  {
    "path": "ncnn-android-yolov7_face/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sun Sep 08 23:09:42 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "ncnn-android-yolov7_face/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "ncnn-android-yolov7_face/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "ncnn-android-yolov7_face/local.properties",
    "content": "## This file must *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local configuration.\n#\n# Location of the SDK. This is only used by Gradle.\n# For customization when using a Version Control System, please read the\n# header note.\n#Mon Mar 29 09:07:23 CST 2021\nsdk.dir=D\\:\\\\Android\n"
  },
  {
    "path": "ncnn-android-yolov7_face/settings.gradle",
    "content": "include ':app'\n"
  }
]