├── .github └── workflows │ └── release.yml ├── CMakeLists.txt ├── README.md ├── assets ├── background.jpg ├── erdnet.bin └── erdnet.param ├── erdnet.cpp ├── erdnet.h ├── erdnetncnn.cpp ├── index.html └── wasmFeatureDetect.js /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: build-and-deploy 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | env: 8 | EMSCRIPTEN_VERSION: 3.1.28 9 | 10 | jobs: 11 | build-and-deploy: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: emsdk 16 | run: | 17 | git clone https://github.com/emscripten-core/emsdk.git 18 | cd emsdk 19 | ./emsdk install $EMSCRIPTEN_VERSION 20 | ./emsdk activate $EMSCRIPTEN_VERSION 21 | 22 | - name: ncnn 23 | run: | 24 | wget -q https://github.com/Tencent/ncnn/releases/download/20230223/ncnn-20230223-webassembly.zip 25 | unzip -q ncnn-20230223-webassembly.zip 26 | 27 | - name: build 28 | run: | 29 | source emsdk/emsdk_env.sh 30 | mkdir build && cd build 31 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=basic .. 32 | make -j4 33 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=simd .. 34 | make -j4 35 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=threads .. 36 | make -j4 37 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=simd-threads .. 38 | make -j4 39 | 40 | - name: collect-deploy-files 41 | run: | 42 | mkdir deploy && cd deploy 43 | cp ../build/*.data . 44 | cp ../build/*.js . 45 | cp ../build/*.wasm . 46 | cp ../*.html . 47 | cp ../*.js . 48 | 49 | - name: deploy 50 | uses: JamesIves/github-pages-deploy-action@4.1.1 51 | with: 52 | branch: gh-pages 53 | folder: deploy 54 | single-commit: true 55 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(ncnn-webassembly-erdnet) 2 | 3 | cmake_minimum_required(VERSION 3.10) 4 | 5 | set(CMAKE_BUILD_TYPE release) 6 | 7 | if(NOT WASM_FEATURE) 8 | message(FATAL_ERROR "You must pass cmake option -DWASM_FEATURE and possible values are basic, simd, threads and simd-threads") 9 | endif() 10 | 11 | set(ncnn_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ncnn-20230223-webassembly/${WASM_FEATURE}/lib/cmake/ncnn") 12 | find_package(ncnn REQUIRED) 13 | 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s FORCE_FILESYSTEM=1 -s INITIAL_MEMORY=256MB -s EXIT_RUNTIME=1") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s FORCE_FILESYSTEM=1 -s INITIAL_MEMORY=256MB -s EXIT_RUNTIME=1") 16 | set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} -s FORCE_FILESYSTEM=1 -s INITIAL_MEMORY=256MB -s EXIT_RUNTIME=1") 17 | 18 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -sEXPORTED_FUNCTIONS=['_erdnet_ncnn','_malloc','_free'] --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@.") 19 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sEXPORTED_FUNCTIONS=['_erdnet_ncnn','_malloc','_free'] --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@.") 20 | set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} -sEXPORTED_FUNCTIONS=['_erdnet_ncnn','_malloc','_free'] --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@.") 21 | 22 | if(${WASM_FEATURE} MATCHES "threads") 23 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -pthread -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4") 24 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -pthread -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4") 25 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fopenmp -pthread -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4") 26 | endif() 27 | 28 | add_executable(erdnet-${WASM_FEATURE} erdnet.cpp erdnetncnn.cpp) 29 | target_link_libraries(erdnet-${WASM_FEATURE} ncnn) 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ncnn-webassembly-portrait-segmentation 2 | 3 | open https://nihui.github.io/ncnn-webassembly-portrait-segmentation and enjoy 4 | 5 | 6 | # build and deploy 7 | 8 | 1. Install emscripten 9 | ```shell 10 | git clone https://github.com/emscripten-core/emsdk.git 11 | cd emsdk 12 | ./emsdk install 3.1.28 13 | ./emsdk activate 3.1.28 14 | 15 | source emsdk/emsdk_env.sh 16 | ``` 17 | 18 | 2. Download and extract ncnn webassembly package 19 | ```shell 20 | wget https://github.com/Tencent/ncnn/releases/download/20230223/ncnn-20230223-webassembly.zip 21 | unzip ncnn-20230223-webassembly.zip 22 | ``` 23 | 24 | 3. Build four WASM feature variants 25 | ```shell 26 | mkdir build 27 | cd build 28 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=basic .. 29 | make -j4 30 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=simd .. 31 | make -j4 32 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=threads .. 33 | make -j4 34 | cmake -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DWASM_FEATURE=simd-threads .. 35 | make -j4 36 | ``` 37 | 38 | 4. Deploy the *.data *.js *.wasm and *.html files to your web server 39 | -------------------------------------------------------------------------------- /assets/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nihui/ncnn-webassembly-portrait-segmentation/6ce48dc1c4090723e4e3d1bc38d46c846aba2d73/assets/background.jpg -------------------------------------------------------------------------------- /assets/erdnet.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nihui/ncnn-webassembly-portrait-segmentation/6ce48dc1c4090723e4e3d1bc38d46c846aba2d73/assets/erdnet.bin -------------------------------------------------------------------------------- /assets/erdnet.param: -------------------------------------------------------------------------------- 1 | 7767517 2 | 194 249 3 | Input input1 0 1 input_blob1 -23330=4,3,256,256,3 0=256 1=256 2=3 4 | Split splitncnn_0 1 6 input_blob1 input_blob1_splitncnn_0 input_blob1_splitncnn_1 input_blob1_splitncnn_2 input_blob1_splitncnn_3 input_blob1_splitncnn_4 input_blob1_splitncnn_5 -23330=24,3,256,256,3,3,256,256,3,3,256,256,3,3,256,256,3,3,256,256,3,3,256,256,3 5 | Pooling ave_pool1 1 1 input_blob1_splitncnn_5 ave_pool_blob1 -23330=4,3,128,128,3 0=1 1=3 2=2 3=1 5=1 6 | Split splitncnn_1 1 2 ave_pool_blob1 ave_pool_blob1_splitncnn_0 ave_pool_blob1_splitncnn_1 -23330=8,3,128,128,3,3,128,128,3 7 | Pooling ave_pool2 1 1 ave_pool_blob1_splitncnn_1 ave_pool_blob2 -23330=4,3,64,64,3 0=1 1=3 2=2 3=1 5=1 8 | Split splitncnn_2 1 2 ave_pool_blob2 ave_pool_blob2_splitncnn_0 ave_pool_blob2_splitncnn_1 -23330=8,3,64,64,3,3,64,64,3 9 | Pooling ave_pool3 1 1 ave_pool_blob2_splitncnn_1 ave_pool_blob3 -23330=4,3,32,32,3 0=1 1=3 2=2 3=1 5=1 10 | Split splitncnn_3 1 2 ave_pool_blob3 ave_pool_blob3_splitncnn_0 ave_pool_blob3_splitncnn_1 -23330=8,3,32,32,3,3,32,32,3 11 | Pooling ave_pool4 1 1 ave_pool_blob3_splitncnn_1 ave_pool_blob4 -23330=4,3,16,16,3 0=1 1=3 2=2 3=1 5=1 12 | Convolution conv1 1 1 input_blob1_splitncnn_4 conv_blob1 -23330=4,3,128,128,12 0=12 1=3 3=2 4=1 5=1 6=324 13 | PReLU prelu1 1 1 conv_blob1 prelu_blob1 -23330=4,3,128,128,12 0=12 14 | Split splitncnn_4 1 2 prelu_blob1 prelu_blob1_splitncnn_0 prelu_blob1_splitncnn_1 -23330=8,3,128,128,12,3,128,128,12 15 | Convolution conv2 1 1 prelu_blob1_splitncnn_1 conv_blob2 -23330=4,3,128,128,4 0=4 1=1 6=48 16 | Split splitncnn_5 1 2 conv_blob2 conv_blob2_splitncnn_0 conv_blob2_splitncnn_1 -23330=8,3,128,128,4,3,128,128,4 17 | Convolution conv3 1 1 conv_blob2_splitncnn_1 relu_blob1 -23330=4,3,128,128,4 0=4 1=3 4=1 5=1 6=144 9=1 18 | Concat cat1 2 1 conv_blob2_splitncnn_0 relu_blob1 cat_blob1 -23330=4,3,128,128,8 19 | Split splitncnn_6 1 2 cat_blob1 cat_blob1_splitncnn_0 cat_blob1_splitncnn_1 -23330=8,3,128,128,8,3,128,128,8 20 | Convolution conv4 1 1 cat_blob1_splitncnn_1 relu_blob2 -23330=4,3,128,128,4 0=4 1=3 4=1 5=1 6=288 9=1 21 | Concat cat2 2 1 cat_blob1_splitncnn_0 relu_blob2 cat_blob2 -23330=4,3,128,128,12 22 | Eltwise add1 2 1 prelu_blob1_splitncnn_0 cat_blob2 add_blob1 -23330=4,3,128,128,12 0=1 23 | BatchNorm batch_norm1 1 1 add_blob1 batch_norm_blob1_bn_scale1 -23330=4,3,128,128,12 0=12 24 | PReLU prelu2 1 1 batch_norm_blob1_bn_scale1 prelu_blob2 -23330=4,3,128,128,12 0=12 25 | Split splitncnn_7 1 2 prelu_blob2 prelu_blob2_splitncnn_0 prelu_blob2_splitncnn_1 -23330=8,3,128,128,12,3,128,128,12 26 | Concat cat3 2 1 ave_pool_blob1_splitncnn_0 prelu_blob2_splitncnn_1 cat_blob3 -23330=4,3,128,128,15 27 | BatchNorm batch_norm2 1 1 cat_blob3 batch_norm_blob2_bn_scale2 -23330=4,3,128,128,15 0=15 28 | PReLU prelu3 1 1 batch_norm_blob2_bn_scale2 prelu_blob3 -23330=4,3,128,128,15 0=15 29 | Convolution conv5 1 1 prelu_blob3 conv_blob5 -23330=4,3,64,64,24 0=24 1=3 3=2 4=1 5=1 6=3240 30 | PReLU prelu4 1 1 conv_blob5 prelu_blob4 -23330=4,3,64,64,24 0=24 31 | Split splitncnn_8 1 3 prelu_blob4 prelu_blob4_splitncnn_0 prelu_blob4_splitncnn_1 prelu_blob4_splitncnn_2 -23330=12,3,64,64,24,3,64,64,24,3,64,64,24 32 | Convolution conv6 1 1 prelu_blob4_splitncnn_2 conv_blob6 -23330=4,3,64,64,8 0=8 1=1 6=192 33 | Split splitncnn_9 1 2 conv_blob6 conv_blob6_splitncnn_0 conv_blob6_splitncnn_1 -23330=8,3,64,64,8,3,64,64,8 34 | Convolution conv7 1 1 conv_blob6_splitncnn_1 relu_blob3 -23330=4,3,64,64,8 0=8 1=3 4=1 5=1 6=576 9=1 35 | Concat cat4 2 1 conv_blob6_splitncnn_0 relu_blob3 cat_blob4 -23330=4,3,64,64,16 36 | Split splitncnn_10 1 2 cat_blob4 cat_blob4_splitncnn_0 cat_blob4_splitncnn_1 -23330=8,3,64,64,16,3,64,64,16 37 | Convolution conv8 1 1 cat_blob4_splitncnn_1 relu_blob4 -23330=4,3,64,64,8 0=8 1=3 4=1 5=1 6=1152 9=1 38 | Concat cat5 2 1 cat_blob4_splitncnn_0 relu_blob4 cat_blob5 -23330=4,3,64,64,24 39 | Eltwise add2 2 1 prelu_blob4_splitncnn_1 cat_blob5 add_blob2 -23330=4,3,64,64,24 0=1 40 | BatchNorm batch_norm3 1 1 add_blob2 batch_norm_blob3_bn_scale3 -23330=4,3,64,64,24 0=24 41 | PReLU prelu5 1 1 batch_norm_blob3_bn_scale3 prelu_blob5 -23330=4,3,64,64,24 0=24 42 | Split splitncnn_11 1 2 prelu_blob5 prelu_blob5_splitncnn_0 prelu_blob5_splitncnn_1 -23330=8,3,64,64,24,3,64,64,24 43 | Concat cat6 3 1 ave_pool_blob2_splitncnn_0 prelu_blob4_splitncnn_0 prelu_blob5_splitncnn_1 cat_blob6 -23330=4,3,64,64,51 44 | BatchNorm batch_norm4 1 1 cat_blob6 batch_norm_blob4_bn_scale4 -23330=4,3,64,64,51 0=51 45 | PReLU prelu6 1 1 batch_norm_blob4_bn_scale4 prelu_blob6 -23330=4,3,64,64,51 0=51 46 | Convolution conv9 1 1 prelu_blob6 conv_blob9 -23330=4,3,32,32,48 0=48 1=3 3=2 4=1 5=1 6=22032 47 | PReLU prelu7 1 1 conv_blob9 prelu_blob7 -23330=4,3,32,32,48 0=48 48 | Split splitncnn_12 1 3 prelu_blob7 prelu_blob7_splitncnn_0 prelu_blob7_splitncnn_1 prelu_blob7_splitncnn_2 -23330=12,3,32,32,48,3,32,32,48,3,32,32,48 49 | Convolution conv10 1 1 prelu_blob7_splitncnn_2 conv_blob10 -23330=4,3,32,32,16 0=16 1=1 6=768 50 | Split splitncnn_13 1 2 conv_blob10 conv_blob10_splitncnn_0 conv_blob10_splitncnn_1 -23330=8,3,32,32,16,3,32,32,16 51 | Convolution conv11 1 1 conv_blob10_splitncnn_1 relu_blob5 -23330=4,3,32,32,16 0=16 1=3 4=1 5=1 6=2304 9=1 52 | Concat cat7 2 1 conv_blob10_splitncnn_0 relu_blob5 cat_blob7 -23330=4,3,32,32,32 53 | Split splitncnn_14 1 2 cat_blob7 cat_blob7_splitncnn_0 cat_blob7_splitncnn_1 -23330=8,3,32,32,32,3,32,32,32 54 | Convolution conv12 1 1 cat_blob7_splitncnn_1 relu_blob6 -23330=4,3,32,32,16 0=16 1=3 4=1 5=1 6=4608 9=1 55 | Concat cat8 2 1 cat_blob7_splitncnn_0 relu_blob6 cat_blob8 -23330=4,3,32,32,48 56 | Eltwise add3 2 1 prelu_blob7_splitncnn_1 cat_blob8 add_blob3 -23330=4,3,32,32,48 0=1 57 | BatchNorm batch_norm5 1 1 add_blob3 batch_norm_blob5_bn_scale5 -23330=4,3,32,32,48 0=48 58 | PReLU prelu8 1 1 batch_norm_blob5_bn_scale5 prelu_blob8 -23330=4,3,32,32,48 0=48 59 | Split splitncnn_15 1 2 prelu_blob8 prelu_blob8_splitncnn_0 prelu_blob8_splitncnn_1 -23330=8,3,32,32,48,3,32,32,48 60 | Concat cat9 3 1 ave_pool_blob3_splitncnn_0 prelu_blob7_splitncnn_0 prelu_blob8_splitncnn_1 cat_blob9 -23330=4,3,32,32,99 61 | BatchNorm batch_norm6 1 1 cat_blob9 batch_norm_blob6_bn_scale6 -23330=4,3,32,32,99 0=99 62 | PReLU prelu9 1 1 batch_norm_blob6_bn_scale6 prelu_blob9 -23330=4,3,32,32,99 0=99 63 | Convolution conv13 1 1 prelu_blob9 conv_blob13 -23330=4,3,16,16,96 0=96 1=3 3=2 4=1 5=1 6=85536 64 | PReLU prelu10 1 1 conv_blob13 prelu_blob10 -23330=4,3,16,16,96 0=96 65 | Split splitncnn_16 1 3 prelu_blob10 prelu_blob10_splitncnn_0 prelu_blob10_splitncnn_1 prelu_blob10_splitncnn_2 -23330=12,3,16,16,96,3,16,16,96,3,16,16,96 66 | Convolution conv14 1 1 prelu_blob10_splitncnn_2 conv_blob14 -23330=4,3,16,16,16 0=16 1=1 6=1536 67 | Split splitncnn_17 1 2 conv_blob14 conv_blob14_splitncnn_0 conv_blob14_splitncnn_1 -23330=8,3,16,16,16,3,16,16,16 68 | Convolution conv15 1 1 conv_blob14_splitncnn_1 relu_blob7 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=2304 9=1 69 | Concat cat10 2 1 conv_blob14_splitncnn_0 relu_blob7 cat_blob10 -23330=4,3,16,16,32 70 | Split splitncnn_18 1 2 cat_blob10 cat_blob10_splitncnn_0 cat_blob10_splitncnn_1 -23330=8,3,16,16,32,3,16,16,32 71 | Convolution conv16 1 1 cat_blob10_splitncnn_1 relu_blob8 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=4608 9=1 72 | Concat cat11 2 1 cat_blob10_splitncnn_0 relu_blob8 cat_blob11 -23330=4,3,16,16,48 73 | Split splitncnn_19 1 2 cat_blob11 cat_blob11_splitncnn_0 cat_blob11_splitncnn_1 -23330=8,3,16,16,48,3,16,16,48 74 | Convolution conv17 1 1 cat_blob11_splitncnn_1 relu_blob9 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=6912 9=1 75 | Concat cat12 2 1 cat_blob11_splitncnn_0 relu_blob9 cat_blob12 -23330=4,3,16,16,64 76 | Split splitncnn_20 1 2 cat_blob12 cat_blob12_splitncnn_0 cat_blob12_splitncnn_1 -23330=8,3,16,16,64,3,16,16,64 77 | Convolution conv18 1 1 cat_blob12_splitncnn_1 relu_blob10 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=9216 9=1 78 | Concat cat13 2 1 cat_blob12_splitncnn_0 relu_blob10 cat_blob13 -23330=4,3,16,16,80 79 | Split splitncnn_21 1 2 cat_blob13 cat_blob13_splitncnn_0 cat_blob13_splitncnn_1 -23330=8,3,16,16,80,3,16,16,80 80 | Convolution conv19 1 1 cat_blob13_splitncnn_1 relu_blob11 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=11520 9=1 81 | Concat cat14 2 1 cat_blob13_splitncnn_0 relu_blob11 cat_blob14 -23330=4,3,16,16,96 82 | Eltwise add4 2 1 prelu_blob10_splitncnn_1 cat_blob14 add_blob4 -23330=4,3,16,16,96 0=1 83 | BatchNorm batch_norm7 1 1 add_blob4 batch_norm_blob7_bn_scale7 -23330=4,3,16,16,96 0=96 84 | PReLU prelu11 1 1 batch_norm_blob7_bn_scale7 prelu_blob11 -23330=4,3,16,16,96 0=96 85 | Split splitncnn_22 1 2 prelu_blob11 prelu_blob11_splitncnn_0 prelu_blob11_splitncnn_1 -23330=8,3,16,16,96,3,16,16,96 86 | Convolution conv20 1 1 prelu_blob11_splitncnn_1 conv_blob20 -23330=4,3,16,16,16 0=16 1=1 6=1536 87 | Split splitncnn_23 1 2 conv_blob20 conv_blob20_splitncnn_0 conv_blob20_splitncnn_1 -23330=8,3,16,16,16,3,16,16,16 88 | Convolution conv21 1 1 conv_blob20_splitncnn_1 relu_blob12 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=2304 9=1 89 | Concat cat15 2 1 conv_blob20_splitncnn_0 relu_blob12 cat_blob15 -23330=4,3,16,16,32 90 | Split splitncnn_24 1 2 cat_blob15 cat_blob15_splitncnn_0 cat_blob15_splitncnn_1 -23330=8,3,16,16,32,3,16,16,32 91 | Convolution conv22 1 1 cat_blob15_splitncnn_1 relu_blob13 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=4608 9=1 92 | Concat cat16 2 1 cat_blob15_splitncnn_0 relu_blob13 cat_blob16 -23330=4,3,16,16,48 93 | Split splitncnn_25 1 2 cat_blob16 cat_blob16_splitncnn_0 cat_blob16_splitncnn_1 -23330=8,3,16,16,48,3,16,16,48 94 | Convolution conv23 1 1 cat_blob16_splitncnn_1 relu_blob14 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=6912 9=1 95 | Concat cat17 2 1 cat_blob16_splitncnn_0 relu_blob14 cat_blob17 -23330=4,3,16,16,64 96 | Split splitncnn_26 1 2 cat_blob17 cat_blob17_splitncnn_0 cat_blob17_splitncnn_1 -23330=8,3,16,16,64,3,16,16,64 97 | Convolution conv24 1 1 cat_blob17_splitncnn_1 relu_blob15 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=9216 9=1 98 | Concat cat18 2 1 cat_blob17_splitncnn_0 relu_blob15 cat_blob18 -23330=4,3,16,16,80 99 | Split splitncnn_27 1 2 cat_blob18 cat_blob18_splitncnn_0 cat_blob18_splitncnn_1 -23330=8,3,16,16,80,3,16,16,80 100 | Convolution conv25 1 1 cat_blob18_splitncnn_1 relu_blob16 -23330=4,3,16,16,16 0=16 1=3 4=1 5=1 6=11520 9=1 101 | Concat cat19 2 1 cat_blob18_splitncnn_0 relu_blob16 cat_blob19 -23330=4,3,16,16,96 102 | Eltwise add5 2 1 prelu_blob11_splitncnn_0 cat_blob19 add_blob5 -23330=4,3,16,16,96 0=1 103 | BatchNorm batch_norm8 1 1 add_blob5 batch_norm_blob8_bn_scale8 -23330=4,3,16,16,96 0=96 104 | PReLU prelu12 1 1 batch_norm_blob8_bn_scale8 prelu_blob12 -23330=4,3,16,16,96 0=96 105 | Split splitncnn_28 1 2 prelu_blob12 prelu_blob12_splitncnn_0 prelu_blob12_splitncnn_1 -23330=8,3,16,16,96,3,16,16,96 106 | Concat cat20 3 1 ave_pool_blob4 prelu_blob10_splitncnn_0 prelu_blob12_splitncnn_1 cat_blob20 -23330=4,3,16,16,195 107 | BatchNorm batch_norm9 1 1 cat_blob20 batch_norm_blob9_bn_scale9 -23330=4,3,16,16,195 0=195 108 | PReLU prelu13 1 1 batch_norm_blob9_bn_scale9 prelu_blob13 -23330=4,3,16,16,195 0=195 109 | Convolution conv26 1 1 prelu_blob13 conv_blob26 -23330=4,3,8,8,192 0=192 1=3 3=2 4=1 5=1 6=336960 110 | PReLU prelu14 1 1 conv_blob26 prelu_blob14 -23330=4,3,8,8,192 0=192 111 | Split splitncnn_29 1 2 prelu_blob14 prelu_blob14_splitncnn_0 prelu_blob14_splitncnn_1 -23330=8,3,8,8,192,3,8,8,192 112 | Convolution conv27 1 1 prelu_blob14_splitncnn_1 conv_blob27 -23330=4,3,8,8,32 0=32 1=1 6=6144 113 | Split splitncnn_30 1 2 conv_blob27 conv_blob27_splitncnn_0 conv_blob27_splitncnn_1 -23330=8,3,8,8,32,3,8,8,32 114 | Convolution conv28 1 1 conv_blob27_splitncnn_1 relu_blob17 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=9216 9=1 115 | Concat cat21 2 1 conv_blob27_splitncnn_0 relu_blob17 cat_blob21 -23330=4,3,8,8,64 116 | Split splitncnn_31 1 2 cat_blob21 cat_blob21_splitncnn_0 cat_blob21_splitncnn_1 -23330=8,3,8,8,64,3,8,8,64 117 | Convolution conv29 1 1 cat_blob21_splitncnn_1 relu_blob18 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=18432 9=1 118 | Concat cat22 2 1 cat_blob21_splitncnn_0 relu_blob18 cat_blob22 -23330=4,3,8,8,96 119 | Split splitncnn_32 1 2 cat_blob22 cat_blob22_splitncnn_0 cat_blob22_splitncnn_1 -23330=8,3,8,8,96,3,8,8,96 120 | Convolution conv30 1 1 cat_blob22_splitncnn_1 relu_blob19 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=27648 9=1 121 | Concat cat23 2 1 cat_blob22_splitncnn_0 relu_blob19 cat_blob23 -23330=4,3,8,8,128 122 | Split splitncnn_33 1 2 cat_blob23 cat_blob23_splitncnn_0 cat_blob23_splitncnn_1 -23330=8,3,8,8,128,3,8,8,128 123 | Convolution conv31 1 1 cat_blob23_splitncnn_1 relu_blob20 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=36864 9=1 124 | Concat cat24 2 1 cat_blob23_splitncnn_0 relu_blob20 cat_blob24 -23330=4,3,8,8,160 125 | Split splitncnn_34 1 2 cat_blob24 cat_blob24_splitncnn_0 cat_blob24_splitncnn_1 -23330=8,3,8,8,160,3,8,8,160 126 | Convolution conv32 1 1 cat_blob24_splitncnn_1 relu_blob21 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=46080 9=1 127 | Concat cat25 2 1 cat_blob24_splitncnn_0 relu_blob21 cat_blob25 -23330=4,3,8,8,192 128 | Eltwise add6 2 1 prelu_blob14_splitncnn_0 cat_blob25 add_blob6 -23330=4,3,8,8,192 0=1 129 | BatchNorm batch_norm10 1 1 add_blob6 batch_norm_blob10_bn_scale10 -23330=4,3,8,8,192 0=192 130 | PReLU prelu15 1 1 batch_norm_blob10_bn_scale10 prelu_blob15 -23330=4,3,8,8,192 0=192 131 | Split splitncnn_35 1 2 prelu_blob15 prelu_blob15_splitncnn_0 prelu_blob15_splitncnn_1 -23330=8,3,8,8,192,3,8,8,192 132 | Convolution conv33 1 1 prelu_blob15_splitncnn_1 conv_blob33 -23330=4,3,8,8,32 0=32 1=1 6=6144 133 | Split splitncnn_36 1 2 conv_blob33 conv_blob33_splitncnn_0 conv_blob33_splitncnn_1 -23330=8,3,8,8,32,3,8,8,32 134 | Convolution conv34 1 1 conv_blob33_splitncnn_1 relu_blob22 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=9216 9=1 135 | Concat cat26 2 1 conv_blob33_splitncnn_0 relu_blob22 cat_blob26 -23330=4,3,8,8,64 136 | Split splitncnn_37 1 2 cat_blob26 cat_blob26_splitncnn_0 cat_blob26_splitncnn_1 -23330=8,3,8,8,64,3,8,8,64 137 | Convolution conv35 1 1 cat_blob26_splitncnn_1 relu_blob23 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=18432 9=1 138 | Concat cat27 2 1 cat_blob26_splitncnn_0 relu_blob23 cat_blob27 -23330=4,3,8,8,96 139 | Split splitncnn_38 1 2 cat_blob27 cat_blob27_splitncnn_0 cat_blob27_splitncnn_1 -23330=8,3,8,8,96,3,8,8,96 140 | Convolution conv36 1 1 cat_blob27_splitncnn_1 relu_blob24 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=27648 9=1 141 | Concat cat28 2 1 cat_blob27_splitncnn_0 relu_blob24 cat_blob28 -23330=4,3,8,8,128 142 | Split splitncnn_39 1 2 cat_blob28 cat_blob28_splitncnn_0 cat_blob28_splitncnn_1 -23330=8,3,8,8,128,3,8,8,128 143 | Convolution conv37 1 1 cat_blob28_splitncnn_1 relu_blob25 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=36864 9=1 144 | Concat cat29 2 1 cat_blob28_splitncnn_0 relu_blob25 cat_blob29 -23330=4,3,8,8,160 145 | Split splitncnn_40 1 2 cat_blob29 cat_blob29_splitncnn_0 cat_blob29_splitncnn_1 -23330=8,3,8,8,160,3,8,8,160 146 | Convolution conv38 1 1 cat_blob29_splitncnn_1 relu_blob26 -23330=4,3,8,8,32 0=32 1=3 4=1 5=1 6=46080 9=1 147 | Concat cat30 2 1 cat_blob29_splitncnn_0 relu_blob26 cat_blob30 -23330=4,3,8,8,192 148 | Eltwise add7 2 1 prelu_blob15_splitncnn_0 cat_blob30 add_blob7 -23330=4,3,8,8,192 0=1 149 | BatchNorm batch_norm11 1 1 add_blob7 batch_norm_blob11_bn_scale11 -23330=4,3,8,8,192 0=192 150 | PReLU prelu16 1 1 batch_norm_blob11_bn_scale11 prelu_blob16 -23330=4,3,8,8,192 0=192 151 | Convolution conv39 1 1 prelu_blob16 conv_blob39 -23330=4,3,8,8,2 0=2 1=1 6=384 152 | Interp interp1 1 1 conv_blob39 interp_blob1 -23330=4,3,16,16,2 0=2 1=2.000000e+00 2=2.000000e+00 153 | Convolution conv40 1 1 prelu_blob12_splitncnn_0 conv_blob40 -23330=4,3,16,16,2 0=2 1=3 4=1 5=1 6=1728 154 | PReLU prelu17 1 1 conv_blob40 prelu_blob17 -23330=4,3,16,16,2 0=2 155 | BatchNorm batch_norm12 1 1 prelu_blob17 batch_norm_blob12_bn_scale12 -23330=4,3,16,16,2 0=2 156 | PReLU prelu18 1 1 batch_norm_blob12_bn_scale12 prelu_blob18 -23330=4,3,16,16,2 0=2 157 | Eltwise add8 2 1 interp_blob1 prelu_blob18 add_blob8 -23330=4,3,16,16,2 0=1 158 | Convolution conv41 1 1 add_blob8 conv_blob41 -23330=4,3,16,16,2 0=2 1=3 4=1 6=36 159 | Interp interp2 1 1 conv_blob41 interp_blob2 -23330=4,3,32,32,2 0=2 1=2.000000e+00 2=2.000000e+00 160 | Convolution conv42 1 1 prelu_blob8_splitncnn_0 conv_blob42 -23330=4,3,32,32,2 0=2 1=3 4=1 5=1 6=864 161 | PReLU prelu19 1 1 conv_blob42 prelu_blob19 -23330=4,3,32,32,2 0=2 162 | BatchNorm batch_norm13 1 1 prelu_blob19 batch_norm_blob13_bn_scale13 -23330=4,3,32,32,2 0=2 163 | PReLU prelu20 1 1 batch_norm_blob13_bn_scale13 prelu_blob20 -23330=4,3,32,32,2 0=2 164 | Eltwise add9 2 1 interp_blob2 prelu_blob20 add_blob9 -23330=4,3,32,32,2 0=1 165 | Convolution conv43 1 1 add_blob9 conv_blob43 -23330=4,3,32,32,2 0=2 1=3 4=1 6=36 166 | Interp interp3 1 1 conv_blob43 interp_blob3 -23330=4,3,64,64,2 0=2 1=2.000000e+00 2=2.000000e+00 167 | Convolution conv44 1 1 prelu_blob5_splitncnn_0 conv_blob44 -23330=4,3,64,64,2 0=2 1=3 4=1 5=1 6=432 168 | PReLU prelu21 1 1 conv_blob44 prelu_blob21 -23330=4,3,64,64,2 0=2 169 | BatchNorm batch_norm14 1 1 prelu_blob21 batch_norm_blob14_bn_scale14 -23330=4,3,64,64,2 0=2 170 | PReLU prelu22 1 1 batch_norm_blob14_bn_scale14 prelu_blob22 -23330=4,3,64,64,2 0=2 171 | Eltwise add10 2 1 interp_blob3 prelu_blob22 add_blob10 -23330=4,3,64,64,2 0=1 172 | Convolution conv45 1 1 add_blob10 conv_blob45 -23330=4,3,64,64,2 0=2 1=3 4=1 6=36 173 | Interp interp4 1 1 conv_blob45 interp_blob4 -23330=4,3,128,128,2 0=2 1=2.000000e+00 2=2.000000e+00 174 | Convolution conv46 1 1 prelu_blob2_splitncnn_0 conv_blob46 -23330=4,3,128,128,2 0=2 1=3 4=1 5=1 6=216 175 | PReLU prelu23 1 1 conv_blob46 prelu_blob23 -23330=4,3,128,128,2 0=2 176 | BatchNorm batch_norm15 1 1 prelu_blob23 batch_norm_blob15_bn_scale15 -23330=4,3,128,128,2 0=2 177 | PReLU prelu24 1 1 batch_norm_blob15_bn_scale15 prelu_blob24 -23330=4,3,128,128,2 0=2 178 | Eltwise add11 2 1 interp_blob4 prelu_blob24 add_blob11 -23330=4,3,128,128,2 0=1 179 | Convolution conv47 1 1 add_blob11 conv_blob47 -23330=4,3,128,128,2 0=2 1=3 4=1 6=36 180 | Interp interp5 1 1 conv_blob47 interp_blob5 -23330=4,3,256,256,2 0=2 1=2.000000e+00 2=2.000000e+00 181 | Softmax softmax1 1 1 interp_blob5 softmax_blob1 -23330=4,3,256,256,2 182 | Split splitncnn_41 1 2 softmax_blob1 softmax_blob1_splitncnn_0 softmax_blob1_splitncnn_1 -23330=8,3,256,256,2,3,256,256,2 183 | Slice slice1 1 2 softmax_blob1_splitncnn_1 slice_blob1 slice_blob2 -23330=8,3,256,256,1,3,256,256,1 -23300=2,1,-233 184 | Split splitncnn_42 1 4 slice_blob2 slice_blob2_splitncnn_0 slice_blob2_splitncnn_1 slice_blob2_splitncnn_2 slice_blob2_splitncnn_3 -23330=16,3,256,256,1,3,256,256,1,3,256,256,1,3,256,256,1 185 | Eltwise mul1 2 1 input_blob1_splitncnn_3 input_blob1_splitncnn_2 mul_blob1 -23330=4,3,256,256,3 186 | Concat cat31 3 1 slice_blob2_splitncnn_3 slice_blob2_splitncnn_2 slice_blob2_splitncnn_1 cat_blob31 -23330=4,3,256,256,3 187 | Eltwise mul2 2 1 input_blob1_splitncnn_1 cat_blob31 mul_blob2 -23330=4,3,256,256,3 188 | Concat cat32 4 1 input_blob1_splitncnn_0 softmax_blob1_splitncnn_0 mul_blob1 mul_blob2 cat_blob32 -23330=4,3,256,256,11 189 | Convolution conv48 1 1 cat_blob32 relu_blob27 -23330=4,3,256,256,8 0=8 1=3 4=1 5=1 6=792 9=1 190 | Convolution conv49 1 1 relu_blob27 conv_blob49 -23330=4,3,256,256,3 0=3 1=3 4=1 5=1 6=216 191 | Slice slice2 1 3 conv_blob49 slice_blob3 slice_blob4 slice_blob5 -23330=12,3,256,256,1,3,256,256,1,3,256,256,1 -23300=3,1,1,1 192 | Eltwise mul3 2 1 slice_blob3 slice_blob2_splitncnn_0 mul_blob3 -23330=4,3,256,256,1 193 | Eltwise mul4 2 1 slice_blob4 slice_blob1 mul_blob4 -23330=4,3,256,256,1 194 | Eltwise add12 2 1 mul_blob3 mul_blob4 add_blob12 -23330=4,3,256,256,1 0=1 195 | Eltwise add13 2 1 add_blob12 slice_blob5 add_blob13 -23330=4,3,256,256,1 0=1 196 | Sigmoid sigmoid1 1 1 add_blob13 sigmoid_blob1 -23330=4,3,256,256,1 197 | -------------------------------------------------------------------------------- /erdnet.cpp: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making ncnn available. 2 | // 3 | // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | // 5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // https://opensource.org/licenses/BSD-3-Clause 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #include "erdnet.h" 16 | 17 | #include 18 | #include 19 | 20 | int ERDNet::load(bool use_gpu) 21 | { 22 | erdnet.clear(); 23 | 24 | ncnn::set_cpu_powersave(2); 25 | ncnn::set_omp_num_threads(ncnn::get_big_cpu_count()); 26 | 27 | erdnet.opt = ncnn::Option(); 28 | 29 | #if NCNN_VULKAN 30 | erdnet.opt.use_vulkan_compute = use_gpu; 31 | #endif 32 | 33 | erdnet.opt.num_threads = ncnn::get_big_cpu_count(); 34 | 35 | erdnet.load_param("erdnet.param"); 36 | erdnet.load_model("erdnet.bin"); 37 | 38 | return 0; 39 | } 40 | 41 | int ERDNet::detect(const cv::Mat& rgba, cv::Mat& mask_g) 42 | { 43 | const int w = rgba.cols; 44 | const int h = rgba.rows; 45 | const int input_size = 256; 46 | 47 | ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgba.data, ncnn::Mat::PIXEL_RGBA2BGR, w, h, input_size, input_size); 48 | 49 | const float mean_vals[3] = {104.f, 112.f, 121.f}; 50 | const float norm_vals[3] = {1.f/255.f, 1.f/255.f, 1.f/255.f}; 51 | in.substract_mean_normalize(mean_vals, norm_vals); 52 | 53 | ncnn::Extractor ex = erdnet.create_extractor(); 54 | 55 | ex.input("input_blob1", in); 56 | 57 | ncnn::Mat out; 58 | ex.extract("sigmoid_blob1", out); 59 | 60 | const float denorm_vals[3] = {255.f, 255.f, 255.f}; 61 | out.substract_mean_normalize(0, denorm_vals); 62 | 63 | mask_g.create(h, w, CV_8UC1); 64 | out.to_pixels_resize(mask_g.data, ncnn::Mat::PIXEL_GRAY, w, h); 65 | 66 | return 0; 67 | } 68 | 69 | int ERDNet::draw(cv::Mat& rgba, const cv::Mat& bg_bgr, const cv::Mat& mask_g) 70 | { 71 | const int w = rgba.cols; 72 | const int h = rgba.rows; 73 | 74 | for (int y = 0; y < h; y++) 75 | { 76 | uchar* rgbaptr = rgba.ptr(y); 77 | const uchar* bgptr = bg_bgr.ptr(y); 78 | const uchar* mptr = mask_g.ptr(y); 79 | 80 | for (int x = 0; x < w; x++) 81 | { 82 | const uchar alpha = mptr[0]; 83 | 84 | rgbaptr[0] = cv::saturate_cast((rgbaptr[0] * alpha + bgptr[2] * (255 - alpha)) / 255); 85 | rgbaptr[1] = cv::saturate_cast((rgbaptr[1] * alpha + bgptr[1] * (255 - alpha)) / 255); 86 | rgbaptr[2] = cv::saturate_cast((rgbaptr[2] * alpha + bgptr[0] * (255 - alpha)) / 255); 87 | 88 | rgbaptr += 4; 89 | bgptr += 3; 90 | mptr += 1; 91 | } 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /erdnet.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making ncnn available. 2 | // 3 | // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | // 5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // https://opensource.org/licenses/BSD-3-Clause 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef ERDNET_H 16 | #define ERDNET_H 17 | 18 | #include 19 | #include 20 | 21 | class ERDNet 22 | { 23 | public: 24 | int load(bool use_gpu = false); 25 | 26 | int detect(const cv::Mat& rgba, cv::Mat& mask_g); 27 | 28 | int draw(cv::Mat& rgba, const cv::Mat& bg_bgr, const cv::Mat& mask_g); 29 | 30 | private: 31 | ncnn::Net erdnet; 32 | }; 33 | 34 | #endif // ERDNET_H 35 | -------------------------------------------------------------------------------- /erdnetncnn.cpp: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making ncnn available. 2 | // 3 | // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | // 5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // https://opensource.org/licenses/BSD-3-Clause 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #include 16 | #include 17 | #include "erdnet.h" 18 | 19 | static int draw_fps(cv::Mat& rgba) 20 | { 21 | // resolve moving average 22 | float avg_fps = 0.f; 23 | { 24 | static double t0 = 0.f; 25 | static float fps_history[10] = {0.f}; 26 | 27 | double t1 = ncnn::get_current_time(); 28 | if (t0 == 0.f) 29 | { 30 | t0 = t1; 31 | return 0; 32 | } 33 | 34 | float fps = 1000.f / (t1 - t0); 35 | t0 = t1; 36 | 37 | for (int i = 9; i >= 1; i--) 38 | { 39 | fps_history[i] = fps_history[i - 1]; 40 | } 41 | fps_history[0] = fps; 42 | 43 | if (fps_history[9] == 0.f) 44 | { 45 | return 0; 46 | } 47 | 48 | for (int i = 0; i < 10; i++) 49 | { 50 | avg_fps += fps_history[i]; 51 | } 52 | avg_fps /= 10.f; 53 | } 54 | 55 | char text[32]; 56 | sprintf(text, "FPS=%.2f", avg_fps); 57 | 58 | int baseLine = 0; 59 | cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); 60 | 61 | int y = 0; 62 | int x = rgba.cols - label_size.width; 63 | 64 | cv::rectangle(rgba, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), 65 | cv::Scalar(255, 255, 255, 255), -1); 66 | 67 | cv::putText(rgba, text, cv::Point(x, y + label_size.height), 68 | cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 255)); 69 | 70 | return 0; 71 | } 72 | 73 | static ERDNet* g_erdnet = 0; 74 | static cv::Mat bg_bgr; 75 | 76 | static void on_image_render(cv::Mat& rgba) 77 | { 78 | if (!g_erdnet) 79 | { 80 | g_erdnet = new ERDNet; 81 | 82 | g_erdnet->load(); 83 | 84 | bg_bgr = cv::imread("background.jpg", 1); 85 | cv::resize(bg_bgr, bg_bgr, cv::Size(rgba.cols, rgba.rows)); 86 | } 87 | 88 | cv::Mat mask_g; 89 | g_erdnet->detect(rgba, mask_g); 90 | 91 | g_erdnet->draw(rgba, bg_bgr, mask_g); 92 | 93 | draw_fps(rgba); 94 | } 95 | 96 | #ifdef __EMSCRIPTEN_PTHREADS__ 97 | 98 | static const unsigned char* rgba_data = 0; 99 | static int w = 0; 100 | static int h = 0; 101 | 102 | static ncnn::Mutex lock; 103 | static ncnn::ConditionVariable condition; 104 | 105 | static ncnn::Mutex finish_lock; 106 | static ncnn::ConditionVariable finish_condition; 107 | 108 | static void worker() 109 | { 110 | while (1) 111 | { 112 | lock.lock(); 113 | while (rgba_data == 0) 114 | { 115 | condition.wait(lock); 116 | } 117 | 118 | cv::Mat rgba(h, w, CV_8UC4, (void*)rgba_data); 119 | 120 | on_image_render(rgba); 121 | 122 | rgba_data = 0; 123 | 124 | lock.unlock(); 125 | 126 | finish_lock.lock(); 127 | finish_condition.signal(); 128 | finish_lock.unlock(); 129 | } 130 | } 131 | 132 | #include 133 | static std::thread t(worker); 134 | 135 | extern "C" { 136 | 137 | void erdnet_ncnn(unsigned char* _rgba_data, int _w, int _h) 138 | { 139 | lock.lock(); 140 | while (rgba_data != 0) 141 | { 142 | condition.wait(lock); 143 | } 144 | 145 | rgba_data = _rgba_data; 146 | w = _w; 147 | h = _h; 148 | 149 | lock.unlock(); 150 | 151 | condition.signal(); 152 | 153 | // wait for finished 154 | finish_lock.lock(); 155 | while (rgba_data != 0) 156 | { 157 | finish_condition.wait(finish_lock); 158 | } 159 | finish_lock.unlock(); 160 | } 161 | 162 | } 163 | 164 | #else // __EMSCRIPTEN_PTHREADS__ 165 | 166 | extern "C" { 167 | 168 | void erdnet_ncnn(unsigned char* rgba_data, int w, int h) 169 | { 170 | cv::Mat rgba(h, w, CV_8UC4, (void*)rgba_data); 171 | 172 | on_image_render(rgba); 173 | } 174 | 175 | } 176 | 177 | #endif // __EMSCRIPTEN_PTHREADS__ 178 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ncnn webassembly erdnet 7 | 16 | 17 | 18 | 19 | 20 |
21 |

ncnn webassembly erdnet

22 |
23 | 24 |
25 |
26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 218 | 219 | 220 | 221 | 222 | -------------------------------------------------------------------------------- /wasmFeatureDetect.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).wasmFeatureDetect=n()}(this,function(){"use strict";return{bigInt:()=>(async e=>{try{return(await WebAssembly.instantiate(e)).instance.exports.b(BigInt(0))===BigInt(0)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,126,1,126,3,2,1,0,7,5,1,1,98,0,0,10,6,1,4,0,32,0,11])),bulkMemory:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,3,1,0,1,10,14,1,12,0,65,0,65,0,65,0,252,10,0,0,11])),exceptions:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,6,64,25,11,11])),multiValue:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,0,2,127,127,3,2,1,0,10,8,1,6,0,65,0,65,0,11])),mutableGlobals:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,2,8,1,1,97,1,98,3,127,1,6,6,1,127,1,65,0,11,7,5,1,1,97,3,1])),referenceTypes:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,7,1,5,0,208,112,26,11])),saturatedFloatToInt:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,12,1,10,0,67,0,0,0,0,252,0,26,11])),signExtensions:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,65,0,192,26,11])),simd:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11])),tailCall:async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,6,1,4,0,18,0,11])),threads:()=>(async e=>{try{return"undefined"!=typeof MessageChannel&&(new MessageChannel).port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(e)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]))}}); 2 | --------------------------------------------------------------------------------