diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..c2dcd6d --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.6) + +project(opencv_jni_shared) + +# dummy target to bring libc++_shared.so into packages +add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..c2dcd6d --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.6) + +project(opencv_jni_shared) + +# dummy target to bring libc++_shared.so into packages +add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/sdk/build.gradle b/sdk/build.gradle index 19af051..7784f62 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -1,93 +1,3 @@ -// This file is part of OpenCV project. -// It is subject to the license terms in the LICENSE file found in the top-level directory -// of this distribution and at http://opencv.org/license.html. - -// -// Notes about integration OpenCV into existed Android Studio application project are below (application 'app' module should exist). -// -// This file is located in /sdk directory (near 'etc', 'java', 'native' subdirectories) -// -// Add module into Android Studio application project: -// -// - Android Studio way: -// (will copy almost all OpenCV Android SDK into your project, ~200Mb) -// -// Import module: Menu -> "File" -> "New" -> "Module" -> "Import Gradle project": -// Source directory: select this "sdk" directory -// Module name: ":opencv" -// -// - or attach library module from OpenCV Android SDK -// (without copying into application project directory, allow to share the same module between projects) -// -// Edit "settings.gradle" and add these lines: -// -// def opencvsdk='' -// // You can put declaration above into gradle.properties file instead (including file in HOME directory), -// // but without 'def' and apostrophe symbols ('): opencvsdk= -// include ':opencv' -// project(':opencv').projectDir = new File(opencvsdk + '/sdk') -// -// -// -// Add dependency into application module: -// -// - Android Studio way: -// "Open Module Settings" (F4) -> "Dependencies" tab -// -// - or add "project(':opencv')" dependency into app/build.gradle: -// -// dependencies { -// implementation fileTree(dir: 'libs', include: ['*.jar']) -// ... -// implementation project(':opencv') -// } -// -// -// -// Load OpenCV native library before using: -// -// - avoid using of "OpenCVLoader.initAsync()" approach - it is deprecated -// It may load library with different version (from OpenCV Android Manager, which is installed separatelly on device) -// -// - use "System.loadLibrary("opencv_java4")" or "OpenCVLoader.initDebug()" -// TODO: Add accurate API to load OpenCV native library -// -// -// -// Native C++ support (necessary to use OpenCV in native code of application only): -// -// - Use find_package() in app/CMakeLists.txt: -// -// find_package(OpenCV 4.9 REQUIRED java) -// ... -// target_link_libraries(native-lib ${OpenCV_LIBRARIES}) -// -// - Add "OpenCV_DIR" and enable C++ exceptions/RTTI support via app/build.gradle -// Documentation about CMake options: https://developer.android.com/ndk/guides/cmake.html -// -// defaultConfig { -// ... -// externalNativeBuild { -// cmake { -// cppFlags "-std=c++11 -frtti -fexceptions" -// arguments "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni" // , "-DANDROID_ARM_NEON=TRUE" -// } -// } -// } -// -// - (optional) Limit/filter ABIs to build ('android' scope of 'app/build.gradle'): -// Useful information: https://developer.android.com/studio/build/gradle-tips.html (Configure separate APKs per ABI) -// -// splits { -// abi { -// enable true -// universalApk false -// reset() -// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a' -// } -// } -// - apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'kotlin-android' @@ -159,7 +69,7 @@ externalNativeBuild { cmake { - path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt') + path (project.projectDir.toString() + '/CMakeLists.txt') } } } diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..c2dcd6d --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.6) + +project(opencv_jni_shared) + +# dummy target to bring libc++_shared.so into packages +add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/sdk/build.gradle b/sdk/build.gradle index 19af051..7784f62 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -1,93 +1,3 @@ -// This file is part of OpenCV project. -// It is subject to the license terms in the LICENSE file found in the top-level directory -// of this distribution and at http://opencv.org/license.html. - -// -// Notes about integration OpenCV into existed Android Studio application project are below (application 'app' module should exist). -// -// This file is located in /sdk directory (near 'etc', 'java', 'native' subdirectories) -// -// Add module into Android Studio application project: -// -// - Android Studio way: -// (will copy almost all OpenCV Android SDK into your project, ~200Mb) -// -// Import module: Menu -> "File" -> "New" -> "Module" -> "Import Gradle project": -// Source directory: select this "sdk" directory -// Module name: ":opencv" -// -// - or attach library module from OpenCV Android SDK -// (without copying into application project directory, allow to share the same module between projects) -// -// Edit "settings.gradle" and add these lines: -// -// def opencvsdk='' -// // You can put declaration above into gradle.properties file instead (including file in HOME directory), -// // but without 'def' and apostrophe symbols ('): opencvsdk= -// include ':opencv' -// project(':opencv').projectDir = new File(opencvsdk + '/sdk') -// -// -// -// Add dependency into application module: -// -// - Android Studio way: -// "Open Module Settings" (F4) -> "Dependencies" tab -// -// - or add "project(':opencv')" dependency into app/build.gradle: -// -// dependencies { -// implementation fileTree(dir: 'libs', include: ['*.jar']) -// ... -// implementation project(':opencv') -// } -// -// -// -// Load OpenCV native library before using: -// -// - avoid using of "OpenCVLoader.initAsync()" approach - it is deprecated -// It may load library with different version (from OpenCV Android Manager, which is installed separatelly on device) -// -// - use "System.loadLibrary("opencv_java4")" or "OpenCVLoader.initDebug()" -// TODO: Add accurate API to load OpenCV native library -// -// -// -// Native C++ support (necessary to use OpenCV in native code of application only): -// -// - Use find_package() in app/CMakeLists.txt: -// -// find_package(OpenCV 4.9 REQUIRED java) -// ... -// target_link_libraries(native-lib ${OpenCV_LIBRARIES}) -// -// - Add "OpenCV_DIR" and enable C++ exceptions/RTTI support via app/build.gradle -// Documentation about CMake options: https://developer.android.com/ndk/guides/cmake.html -// -// defaultConfig { -// ... -// externalNativeBuild { -// cmake { -// cppFlags "-std=c++11 -frtti -fexceptions" -// arguments "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni" // , "-DANDROID_ARM_NEON=TRUE" -// } -// } -// } -// -// - (optional) Limit/filter ABIs to build ('android' scope of 'app/build.gradle'): -// Useful information: https://developer.android.com/studio/build/gradle-tips.html (Configure separate APKs per ABI) -// -// splits { -// abi { -// enable true -// universalApk false -// reset() -// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a' -// } -// } -// - apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'kotlin-android' @@ -159,7 +69,7 @@ externalNativeBuild { cmake { - path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt') + path (project.projectDir.toString() + '/CMakeLists.txt') } } } diff --git a/sdk/dummy.cpp b/sdk/dummy.cpp new file mode 100644 index 0000000..8b1a393 --- /dev/null +++ b/sdk/dummy.cpp @@ -0,0 +1 @@ +// empty diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..c2dcd6d --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.6) + +project(opencv_jni_shared) + +# dummy target to bring libc++_shared.so into packages +add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/sdk/build.gradle b/sdk/build.gradle index 19af051..7784f62 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -1,93 +1,3 @@ -// This file is part of OpenCV project. -// It is subject to the license terms in the LICENSE file found in the top-level directory -// of this distribution and at http://opencv.org/license.html. - -// -// Notes about integration OpenCV into existed Android Studio application project are below (application 'app' module should exist). -// -// This file is located in /sdk directory (near 'etc', 'java', 'native' subdirectories) -// -// Add module into Android Studio application project: -// -// - Android Studio way: -// (will copy almost all OpenCV Android SDK into your project, ~200Mb) -// -// Import module: Menu -> "File" -> "New" -> "Module" -> "Import Gradle project": -// Source directory: select this "sdk" directory -// Module name: ":opencv" -// -// - or attach library module from OpenCV Android SDK -// (without copying into application project directory, allow to share the same module between projects) -// -// Edit "settings.gradle" and add these lines: -// -// def opencvsdk='' -// // You can put declaration above into gradle.properties file instead (including file in HOME directory), -// // but without 'def' and apostrophe symbols ('): opencvsdk= -// include ':opencv' -// project(':opencv').projectDir = new File(opencvsdk + '/sdk') -// -// -// -// Add dependency into application module: -// -// - Android Studio way: -// "Open Module Settings" (F4) -> "Dependencies" tab -// -// - or add "project(':opencv')" dependency into app/build.gradle: -// -// dependencies { -// implementation fileTree(dir: 'libs', include: ['*.jar']) -// ... -// implementation project(':opencv') -// } -// -// -// -// Load OpenCV native library before using: -// -// - avoid using of "OpenCVLoader.initAsync()" approach - it is deprecated -// It may load library with different version (from OpenCV Android Manager, which is installed separatelly on device) -// -// - use "System.loadLibrary("opencv_java4")" or "OpenCVLoader.initDebug()" -// TODO: Add accurate API to load OpenCV native library -// -// -// -// Native C++ support (necessary to use OpenCV in native code of application only): -// -// - Use find_package() in app/CMakeLists.txt: -// -// find_package(OpenCV 4.9 REQUIRED java) -// ... -// target_link_libraries(native-lib ${OpenCV_LIBRARIES}) -// -// - Add "OpenCV_DIR" and enable C++ exceptions/RTTI support via app/build.gradle -// Documentation about CMake options: https://developer.android.com/ndk/guides/cmake.html -// -// defaultConfig { -// ... -// externalNativeBuild { -// cmake { -// cppFlags "-std=c++11 -frtti -fexceptions" -// arguments "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni" // , "-DANDROID_ARM_NEON=TRUE" -// } -// } -// } -// -// - (optional) Limit/filter ABIs to build ('android' scope of 'app/build.gradle'): -// Useful information: https://developer.android.com/studio/build/gradle-tips.html (Configure separate APKs per ABI) -// -// splits { -// abi { -// enable true -// universalApk false -// reset() -// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a' -// } -// } -// - apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'kotlin-android' @@ -159,7 +69,7 @@ externalNativeBuild { cmake { - path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt') + path (project.projectDir.toString() + '/CMakeLists.txt') } } } diff --git a/sdk/dummy.cpp b/sdk/dummy.cpp new file mode 100644 index 0000000..8b1a393 --- /dev/null +++ b/sdk/dummy.cpp @@ -0,0 +1 @@ +// empty diff --git a/sdk/libcxx_helper/CMakeLists.txt b/sdk/libcxx_helper/CMakeLists.txt deleted file mode 100644 index c2dcd6d..0000000 --- a/sdk/libcxx_helper/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.6) - -project(opencv_jni_shared) - -# dummy target to bring libc++_shared.so into packages -add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/app/src/main/assets/best-sim-opt-fp16.bin b/app/src/main/assets/best-sim-opt-fp16.bin new file mode 100644 index 0000000..f0c4888 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.bin Binary files differ diff --git a/app/src/main/assets/best-sim-opt-fp16.param b/app/src/main/assets/best-sim-opt-fp16.param new file mode 100644 index 0000000..9ab48c2 --- /dev/null +++ b/app/src/main/assets/best-sim-opt-fp16.param @@ -0,0 +1,211 @@ +7767517 +209 249 +Input images 0 1 images +Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=3 3=2 4=1 5=1 6=864 +Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0 +Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 3=2 4=1 5=1 6=18432 +Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0 +Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0 /model.2/cv1/conv/Conv_output_0 0=64 1=1 5=1 6=4096 +Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0 +Slice /model.2/Split 1 2 /model.2/cv1/act/Mul_output_0 /model.2/Split_output_0 /model.2/Split_output_1 -23300=2,32,-233 +Split splitncnn_0 1 3 /model.2/Split_output_1 /model.2/Split_output_1_splitncnn_0 /model.2/Split_output_1_splitncnn_1 /model.2/Split_output_1_splitncnn_2 +Convolution /model.2/m.0/cv1/conv/Conv 1 1 /model.2/Split_output_1_splitncnn_2 /model.2/m.0/cv1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv1/act/Mul 1 1 /model.2/m.0/cv1/conv/Conv_output_0 /model.2/m.0/cv1/act/Mul_output_0 +Convolution /model.2/m.0/cv2/conv/Conv 1 1 /model.2/m.0/cv1/act/Mul_output_0 /model.2/m.0/cv2/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.2/m.0/cv2/act/Mul 1 1 /model.2/m.0/cv2/conv/Conv_output_0 /model.2/m.0/cv2/act/Mul_output_0 +BinaryOp /model.2/m.0/Add 2 1 /model.2/Split_output_1_splitncnn_1 /model.2/m.0/cv2/act/Mul_output_0 /model.2/m.0/Add_output_0 +Concat /model.2/Concat 3 1 /model.2/Split_output_0 /model.2/Split_output_1_splitncnn_0 /model.2/m.0/Add_output_0 /model.2/Concat_output_0 +Convolution /model.2/cv2/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv2/conv/Conv_output_0 0=64 1=1 5=1 6=6144 +Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0 +Convolution /model.3/conv/Conv 1 1 /model.2/cv2/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=73728 +Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0 +Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0 /model.4/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=16384 +Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0 +Slice /model.4/Split 1 2 /model.4/cv1/act/Mul_output_0 /model.4/Split_output_0 /model.4/Split_output_1 -23300=2,64,-233 +Split splitncnn_1 1 3 /model.4/Split_output_1 /model.4/Split_output_1_splitncnn_0 /model.4/Split_output_1_splitncnn_1 /model.4/Split_output_1_splitncnn_2 +Convolution /model.4/m.0/cv1/conv/Conv 1 1 /model.4/Split_output_1_splitncnn_2 /model.4/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv1/act/Mul 1 1 /model.4/m.0/cv1/conv/Conv_output_0 /model.4/m.0/cv1/act/Mul_output_0 +Convolution /model.4/m.0/cv2/conv/Conv 1 1 /model.4/m.0/cv1/act/Mul_output_0 /model.4/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.0/cv2/act/Mul 1 1 /model.4/m.0/cv2/conv/Conv_output_0 /model.4/m.0/cv2/act/Mul_output_0 +BinaryOp /model.4/m.0/Add 2 1 /model.4/Split_output_1_splitncnn_1 /model.4/m.0/cv2/act/Mul_output_0 /model.4/m.0/Add_output_0 +Split splitncnn_2 1 3 /model.4/m.0/Add_output_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.0/Add_output_0_splitncnn_2 +Convolution /model.4/m.1/cv1/conv/Conv 1 1 /model.4/m.0/Add_output_0_splitncnn_2 /model.4/m.1/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv1/act/Mul 1 1 /model.4/m.1/cv1/conv/Conv_output_0 /model.4/m.1/cv1/act/Mul_output_0 +Convolution /model.4/m.1/cv2/conv/Conv 1 1 /model.4/m.1/cv1/act/Mul_output_0 /model.4/m.1/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.4/m.1/cv2/act/Mul 1 1 /model.4/m.1/cv2/conv/Conv_output_0 /model.4/m.1/cv2/act/Mul_output_0 +BinaryOp /model.4/m.1/Add 2 1 /model.4/m.0/Add_output_0_splitncnn_1 /model.4/m.1/cv2/act/Mul_output_0 /model.4/m.1/Add_output_0 +Concat /model.4/Concat 4 1 /model.4/Split_output_0 /model.4/Split_output_1_splitncnn_0 /model.4/m.0/Add_output_0_splitncnn_0 /model.4/m.1/Add_output_0 /model.4/Concat_output_0 +Convolution /model.4/cv2/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=32768 +Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0 +Split splitncnn_3 1 2 /model.4/cv2/act/Mul_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.4/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.5/conv/Conv 1 1 /model.4/cv2/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=294912 +Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0 +Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0 /model.6/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=65536 +Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0 +Slice /model.6/Split 1 2 /model.6/cv1/act/Mul_output_0 /model.6/Split_output_0 /model.6/Split_output_1 -23300=2,128,-233 +Split splitncnn_4 1 3 /model.6/Split_output_1 /model.6/Split_output_1_splitncnn_0 /model.6/Split_output_1_splitncnn_1 /model.6/Split_output_1_splitncnn_2 +Convolution /model.6/m.0/cv1/conv/Conv 1 1 /model.6/Split_output_1_splitncnn_2 /model.6/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv1/act/Mul 1 1 /model.6/m.0/cv1/conv/Conv_output_0 /model.6/m.0/cv1/act/Mul_output_0 +Convolution /model.6/m.0/cv2/conv/Conv 1 1 /model.6/m.0/cv1/act/Mul_output_0 /model.6/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.0/cv2/act/Mul 1 1 /model.6/m.0/cv2/conv/Conv_output_0 /model.6/m.0/cv2/act/Mul_output_0 +BinaryOp /model.6/m.0/Add 2 1 /model.6/Split_output_1_splitncnn_1 /model.6/m.0/cv2/act/Mul_output_0 /model.6/m.0/Add_output_0 +Split splitncnn_5 1 3 /model.6/m.0/Add_output_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.0/Add_output_0_splitncnn_2 +Convolution /model.6/m.1/cv1/conv/Conv 1 1 /model.6/m.0/Add_output_0_splitncnn_2 /model.6/m.1/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv1/act/Mul 1 1 /model.6/m.1/cv1/conv/Conv_output_0 /model.6/m.1/cv1/act/Mul_output_0 +Convolution /model.6/m.1/cv2/conv/Conv 1 1 /model.6/m.1/cv1/act/Mul_output_0 /model.6/m.1/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.6/m.1/cv2/act/Mul 1 1 /model.6/m.1/cv2/conv/Conv_output_0 /model.6/m.1/cv2/act/Mul_output_0 +BinaryOp /model.6/m.1/Add 2 1 /model.6/m.0/Add_output_0_splitncnn_1 /model.6/m.1/cv2/act/Mul_output_0 /model.6/m.1/Add_output_0 +Concat /model.6/Concat 4 1 /model.6/Split_output_0 /model.6/Split_output_1_splitncnn_0 /model.6/m.0/Add_output_0_splitncnn_0 /model.6/m.1/Add_output_0 /model.6/Concat_output_0 +Convolution /model.6/cv2/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0 +Split splitncnn_6 1 2 /model.6/cv2/act/Mul_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.6/cv2/act/Mul_output_0_splitncnn_1 +Convolution /model.7/conv/Conv 1 1 /model.6/cv2/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 3=2 4=1 5=1 6=1179648 +Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0 +Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0 /model.8/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=262144 +Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0 +Slice /model.8/Split 1 2 /model.8/cv1/act/Mul_output_0 /model.8/Split_output_0 /model.8/Split_output_1 -23300=2,256,-233 +Split splitncnn_7 1 3 /model.8/Split_output_1 /model.8/Split_output_1_splitncnn_0 /model.8/Split_output_1_splitncnn_1 /model.8/Split_output_1_splitncnn_2 +Convolution /model.8/m.0/cv1/conv/Conv 1 1 /model.8/Split_output_1_splitncnn_2 /model.8/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv1/act/Mul 1 1 /model.8/m.0/cv1/conv/Conv_output_0 /model.8/m.0/cv1/act/Mul_output_0 +Convolution /model.8/m.0/cv2/conv/Conv 1 1 /model.8/m.0/cv1/act/Mul_output_0 /model.8/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.8/m.0/cv2/act/Mul 1 1 /model.8/m.0/cv2/conv/Conv_output_0 /model.8/m.0/cv2/act/Mul_output_0 +BinaryOp /model.8/m.0/Add 2 1 /model.8/Split_output_1_splitncnn_1 /model.8/m.0/cv2/act/Mul_output_0 /model.8/m.0/Add_output_0 +Concat /model.8/Concat 3 1 /model.8/Split_output_0 /model.8/Split_output_1_splitncnn_0 /model.8/m.0/Add_output_0 /model.8/Concat_output_0 +Convolution /model.8/cv2/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0 +Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv2/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=131072 +Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0 +Split splitncnn_8 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1 +Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_9 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 1=5 3=2 5=1 +Split splitncnn_10 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1 +Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 1=5 3=2 5=1 +Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 +Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=524288 +Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0 +Split splitncnn_11 1 2 /model.9/cv2/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.9/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.10/Resize 1 1 /model.9/cv2/act/Mul_output_0_splitncnn_1 /model.10/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.11/Concat 2 1 /model.10/Resize_output_0 /model.6/cv2/act/Mul_output_0_splitncnn_0 /model.11/Concat_output_0 +Convolution /model.12/cv1/conv/Conv 1 1 /model.11/Concat_output_0 /model.12/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=196608 +Swish /model.12/cv1/act/Mul 1 1 /model.12/cv1/conv/Conv_output_0 /model.12/cv1/act/Mul_output_0 +Slice /model.12/Split 1 2 /model.12/cv1/act/Mul_output_0 /model.12/Split_output_0 /model.12/Split_output_1 -23300=2,128,-233 +Split splitncnn_12 1 2 /model.12/Split_output_1 /model.12/Split_output_1_splitncnn_0 /model.12/Split_output_1_splitncnn_1 +Convolution /model.12/m.0/cv1/conv/Conv 1 1 /model.12/Split_output_1_splitncnn_1 /model.12/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv1/act/Mul 1 1 /model.12/m.0/cv1/conv/Conv_output_0 /model.12/m.0/cv1/act/Mul_output_0 +Convolution /model.12/m.0/cv2/conv/Conv 1 1 /model.12/m.0/cv1/act/Mul_output_0 /model.12/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.12/m.0/cv2/act/Mul 1 1 /model.12/m.0/cv2/conv/Conv_output_0 /model.12/m.0/cv2/act/Mul_output_0 +Concat /model.12/Concat 3 1 /model.12/Split_output_0 /model.12/Split_output_1_splitncnn_0 /model.12/m.0/cv2/act/Mul_output_0 /model.12/Concat_output_0 +Convolution /model.12/cv2/conv/Conv 1 1 /model.12/Concat_output_0 /model.12/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.12/cv2/act/Mul 1 1 /model.12/cv2/conv/Conv_output_0 /model.12/cv2/act/Mul_output_0 +Split splitncnn_13 1 2 /model.12/cv2/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.12/cv2/act/Mul_output_0_splitncnn_1 +Interp /model.13/Resize 1 1 /model.12/cv2/act/Mul_output_0_splitncnn_1 /model.13/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 +Concat /model.14/Concat 2 1 /model.13/Resize_output_0 /model.4/cv2/act/Mul_output_0_splitncnn_0 /model.14/Concat_output_0 +Convolution /model.15/cv1/conv/Conv 1 1 /model.14/Concat_output_0 /model.15/cv1/conv/Conv_output_0 0=128 1=1 5=1 6=49152 +Swish /model.15/cv1/act/Mul 1 1 /model.15/cv1/conv/Conv_output_0 /model.15/cv1/act/Mul_output_0 +Slice /model.15/Split 1 2 /model.15/cv1/act/Mul_output_0 /model.15/Split_output_0 /model.15/Split_output_1 -23300=2,64,-233 +Split splitncnn_14 1 2 /model.15/Split_output_1 /model.15/Split_output_1_splitncnn_0 /model.15/Split_output_1_splitncnn_1 +Convolution /model.15/m.0/cv1/conv/Conv 1 1 /model.15/Split_output_1_splitncnn_1 /model.15/m.0/cv1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv1/act/Mul 1 1 /model.15/m.0/cv1/conv/Conv_output_0 /model.15/m.0/cv1/act/Mul_output_0 +Convolution /model.15/m.0/cv2/conv/Conv 1 1 /model.15/m.0/cv1/act/Mul_output_0 /model.15/m.0/cv2/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.15/m.0/cv2/act/Mul 1 1 /model.15/m.0/cv2/conv/Conv_output_0 /model.15/m.0/cv2/act/Mul_output_0 +Concat /model.15/Concat 3 1 /model.15/Split_output_0 /model.15/Split_output_1_splitncnn_0 /model.15/m.0/cv2/act/Mul_output_0 /model.15/Concat_output_0 +Convolution /model.15/cv2/conv/Conv 1 1 /model.15/Concat_output_0 /model.15/cv2/conv/Conv_output_0 0=128 1=1 5=1 6=24576 +Swish /model.15/cv2/act/Mul 1 1 /model.15/cv2/conv/Conv_output_0 /model.15/cv2/act/Mul_output_0 +Split splitncnn_15 1 5 /model.15/cv2/act/Mul_output_0 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.15/cv2/act/Mul_output_0_splitncnn_4 +Convolution /model.16/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_4 /model.16/conv/Conv_output_0 0=128 1=3 3=2 4=1 5=1 6=147456 +Swish /model.16/act/Mul 1 1 /model.16/conv/Conv_output_0 /model.16/act/Mul_output_0 +Concat /model.17/Concat 2 1 /model.16/act/Mul_output_0 /model.12/cv2/act/Mul_output_0_splitncnn_0 /model.17/Concat_output_0 +Convolution /model.18/cv1/conv/Conv 1 1 /model.17/Concat_output_0 /model.18/cv1/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv1/act/Mul 1 1 /model.18/cv1/conv/Conv_output_0 /model.18/cv1/act/Mul_output_0 +Slice /model.18/Split 1 2 /model.18/cv1/act/Mul_output_0 /model.18/Split_output_0 /model.18/Split_output_1 -23300=2,128,-233 +Split splitncnn_16 1 2 /model.18/Split_output_1 /model.18/Split_output_1_splitncnn_0 /model.18/Split_output_1_splitncnn_1 +Convolution /model.18/m.0/cv1/conv/Conv 1 1 /model.18/Split_output_1_splitncnn_1 /model.18/m.0/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv1/act/Mul 1 1 /model.18/m.0/cv1/conv/Conv_output_0 /model.18/m.0/cv1/act/Mul_output_0 +Convolution /model.18/m.0/cv2/conv/Conv 1 1 /model.18/m.0/cv1/act/Mul_output_0 /model.18/m.0/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.18/m.0/cv2/act/Mul 1 1 /model.18/m.0/cv2/conv/Conv_output_0 /model.18/m.0/cv2/act/Mul_output_0 +Concat /model.18/Concat 3 1 /model.18/Split_output_0 /model.18/Split_output_1_splitncnn_0 /model.18/m.0/cv2/act/Mul_output_0 /model.18/Concat_output_0 +Convolution /model.18/cv2/conv/Conv 1 1 /model.18/Concat_output_0 /model.18/cv2/conv/Conv_output_0 0=256 1=1 5=1 6=98304 +Swish /model.18/cv2/act/Mul 1 1 /model.18/cv2/conv/Conv_output_0 /model.18/cv2/act/Mul_output_0 +Split splitncnn_17 1 4 /model.18/cv2/act/Mul_output_0 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.18/cv2/act/Mul_output_0_splitncnn_3 +Convolution /model.19/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_3 /model.19/conv/Conv_output_0 0=256 1=3 3=2 4=1 5=1 6=589824 +Swish /model.19/act/Mul 1 1 /model.19/conv/Conv_output_0 /model.19/act/Mul_output_0 +Concat /model.20/Concat 2 1 /model.19/act/Mul_output_0 /model.9/cv2/act/Mul_output_0_splitncnn_0 /model.20/Concat_output_0 +Convolution /model.21/cv1/conv/Conv 1 1 /model.20/Concat_output_0 /model.21/cv1/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv1/act/Mul 1 1 /model.21/cv1/conv/Conv_output_0 /model.21/cv1/act/Mul_output_0 +Slice /model.21/Split 1 2 /model.21/cv1/act/Mul_output_0 /model.21/Split_output_0 /model.21/Split_output_1 -23300=2,256,-233 +Split splitncnn_18 1 2 /model.21/Split_output_1 /model.21/Split_output_1_splitncnn_0 /model.21/Split_output_1_splitncnn_1 +Convolution /model.21/m.0/cv1/conv/Conv 1 1 /model.21/Split_output_1_splitncnn_1 /model.21/m.0/cv1/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv1/act/Mul 1 1 /model.21/m.0/cv1/conv/Conv_output_0 /model.21/m.0/cv1/act/Mul_output_0 +Convolution /model.21/m.0/cv2/conv/Conv 1 1 /model.21/m.0/cv1/act/Mul_output_0 /model.21/m.0/cv2/conv/Conv_output_0 0=256 1=3 4=1 5=1 6=589824 +Swish /model.21/m.0/cv2/act/Mul 1 1 /model.21/m.0/cv2/conv/Conv_output_0 /model.21/m.0/cv2/act/Mul_output_0 +Concat /model.21/Concat 3 1 /model.21/Split_output_0 /model.21/Split_output_1_splitncnn_0 /model.21/m.0/cv2/act/Mul_output_0 /model.21/Concat_output_0 +Convolution /model.21/cv2/conv/Conv 1 1 /model.21/Concat_output_0 /model.21/cv2/conv/Conv_output_0 0=512 1=1 5=1 6=393216 +Swish /model.21/cv2/act/Mul 1 1 /model.21/cv2/conv/Conv_output_0 /model.21/cv2/act/Mul_output_0 +Split splitncnn_19 1 3 /model.21/cv2/act/Mul_output_0 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.21/cv2/act/Mul_output_0_splitncnn_2 +Convolution /model.22/proto/cv1/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_3 /model.22/proto/cv1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv1/act/Mul 1 1 /model.22/proto/cv1/conv/Conv_output_0 /model.22/proto/cv1/act/Mul_output_0 +Deconvolution /model.22/proto/upsample/ConvTranspose 1 1 /model.22/proto/cv1/act/Mul_output_0 /model.22/proto/upsample/ConvTranspose_output_0 0=128 1=2 3=2 5=1 6=65536 +Convolution /model.22/proto/cv2/conv/Conv 1 1 /model.22/proto/upsample/ConvTranspose_output_0 /model.22/proto/cv2/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/proto/cv2/act/Mul 1 1 /model.22/proto/cv2/conv/Conv_output_0 /model.22/proto/cv2/act/Mul_output_0 +Convolution /model.22/proto/cv3/conv/Conv 1 1 /model.22/proto/cv2/act/Mul_output_0 /model.22/proto/cv3/conv/Conv_output_0 0=32 1=1 5=1 6=4096 +Swish /model.22/proto/cv3/act/Mul 1 1 /model.22/proto/cv3/conv/Conv_output_0 /model.22/proto/cv3/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=36864 +Swish /model.22/cv4.0/cv4.0.0/act/Mul 1 1 /model.22/cv4.0/cv4.0.0/conv/Conv_output_0 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.1/conv/Conv 1 1 /model.22/cv4.0/cv4.0.0/act/Mul_output_0 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.0/cv4.0.1/act/Mul 1 1 /model.22/cv4.0/cv4.0.1/conv/Conv_output_0 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 +Convolution /model.22/cv4.0/cv4.0.2/Conv 1 1 /model.22/cv4.0/cv4.0.1/act/Mul_output_0 /model.22/cv4.0/cv4.0.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape 1 1 /model.22/cv4.0/cv4.0.2/Conv_output_0 /model.22/Reshape_output_0 0=-1 1=32 +Convolution /model.22/cv4.1/cv4.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=73728 +Swish /model.22/cv4.1/cv4.1.0/act/Mul 1 1 /model.22/cv4.1/cv4.1.0/conv/Conv_output_0 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.1/conv/Conv 1 1 /model.22/cv4.1/cv4.1.0/act/Mul_output_0 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.1/cv4.1.1/act/Mul 1 1 /model.22/cv4.1/cv4.1.1/conv/Conv_output_0 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 +Convolution /model.22/cv4.1/cv4.1.2/Conv 1 1 /model.22/cv4.1/cv4.1.1/act/Mul_output_0 /model.22/cv4.1/cv4.1.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_1 1 1 /model.22/cv4.1/cv4.1.2/Conv_output_0 /model.22/Reshape_1_output_0 0=-1 1=32 +Convolution /model.22/cv4.2/cv4.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_2 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=147456 +Swish /model.22/cv4.2/cv4.2.0/act/Mul 1 1 /model.22/cv4.2/cv4.2.0/conv/Conv_output_0 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.1/conv/Conv 1 1 /model.22/cv4.2/cv4.2.0/act/Mul_output_0 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 0=32 1=3 4=1 5=1 6=9216 +Swish /model.22/cv4.2/cv4.2.1/act/Mul 1 1 /model.22/cv4.2/cv4.2.1/conv/Conv_output_0 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 +Convolution /model.22/cv4.2/cv4.2.2/Conv 1 1 /model.22/cv4.2/cv4.2.1/act/Mul_output_0 /model.22/cv4.2/cv4.2.2/Conv_output_0 0=32 1=1 5=1 6=1024 +Reshape /model.22/Reshape_2 1 1 /model.22/cv4.2/cv4.2.2/Conv_output_0 /model.22/Reshape_2_output_0 0=-1 1=32 +Concat /model.22/Concat 3 1 /model.22/Reshape_output_0 /model.22/Reshape_1_output_0 /model.22/Reshape_2_output_0 /model.22/Concat_output_0 0=1 +Convolution /model.22/cv2.0/cv2.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=73728 +Swish /model.22/cv2.0/cv2.0.0/act/Mul 1 1 /model.22/cv2.0/cv2.0.0/conv/Conv_output_0 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.1/conv/Conv 1 1 /model.22/cv2.0/cv2.0.0/act/Mul_output_0 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.0/cv2.0.1/act/Mul 1 1 /model.22/cv2.0/cv2.0.1/conv/Conv_output_0 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 +Convolution /model.22/cv2.0/cv2.0.2/Conv 1 1 /model.22/cv2.0/cv2.0.1/act/Mul_output_0 /model.22/cv2.0/cv2.0.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.0/cv3.0.0/conv/Conv 1 1 /model.15/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.0/act/Mul 1 1 /model.22/cv3.0/cv3.0.0/conv/Conv_output_0 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.1/conv/Conv 1 1 /model.22/cv3.0/cv3.0.0/act/Mul_output_0 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.0/cv3.0.1/act/Mul 1 1 /model.22/cv3.0/cv3.0.1/conv/Conv_output_0 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 +Convolution /model.22/cv3.0/cv3.0.2/Conv 1 1 /model.22/cv3.0/cv3.0.1/act/Mul_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_1 2 1 /model.22/cv2.0/cv2.0.2/Conv_output_0 /model.22/cv3.0/cv3.0.2/Conv_output_0 /model.22/Concat_1_output_0 +Convolution /model.22/cv2.1/cv2.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=147456 +Swish /model.22/cv2.1/cv2.1.0/act/Mul 1 1 /model.22/cv2.1/cv2.1.0/conv/Conv_output_0 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.1/conv/Conv 1 1 /model.22/cv2.1/cv2.1.0/act/Mul_output_0 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.1/cv2.1.1/act/Mul 1 1 /model.22/cv2.1/cv2.1.1/conv/Conv_output_0 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 +Convolution /model.22/cv2.1/cv2.1.2/Conv 1 1 /model.22/cv2.1/cv2.1.1/act/Mul_output_0 /model.22/cv2.1/cv2.1.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.1/cv3.1.0/conv/Conv 1 1 /model.18/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=294912 +Swish /model.22/cv3.1/cv3.1.0/act/Mul 1 1 /model.22/cv3.1/cv3.1.0/conv/Conv_output_0 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.1/conv/Conv 1 1 /model.22/cv3.1/cv3.1.0/act/Mul_output_0 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.1/cv3.1.1/act/Mul 1 1 /model.22/cv3.1/cv3.1.1/conv/Conv_output_0 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 +Convolution /model.22/cv3.1/cv3.1.2/Conv 1 1 /model.22/cv3.1/cv3.1.1/act/Mul_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_2 2 1 /model.22/cv2.1/cv2.1.2/Conv_output_0 /model.22/cv3.1/cv3.1.2/Conv_output_0 /model.22/Concat_2_output_0 +Convolution /model.22/cv2.2/cv2.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=294912 +Swish /model.22/cv2.2/cv2.2.0/act/Mul 1 1 /model.22/cv2.2/cv2.2.0/conv/Conv_output_0 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.1/conv/Conv 1 1 /model.22/cv2.2/cv2.2.0/act/Mul_output_0 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 0=64 1=3 4=1 5=1 6=36864 +Swish /model.22/cv2.2/cv2.2.1/act/Mul 1 1 /model.22/cv2.2/cv2.2.1/conv/Conv_output_0 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 +Convolution /model.22/cv2.2/cv2.2.2/Conv 1 1 /model.22/cv2.2/cv2.2.1/act/Mul_output_0 /model.22/cv2.2/cv2.2.2/Conv_output_0 0=64 1=1 5=1 6=4096 +Convolution /model.22/cv3.2/cv3.2.0/conv/Conv 1 1 /model.21/cv2/act/Mul_output_0_splitncnn_0 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=589824 +Swish /model.22/cv3.2/cv3.2.0/act/Mul 1 1 /model.22/cv3.2/cv3.2.0/conv/Conv_output_0 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.1/conv/Conv 1 1 /model.22/cv3.2/cv3.2.0/act/Mul_output_0 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 0=128 1=3 4=1 5=1 6=147456 +Swish /model.22/cv3.2/cv3.2.1/act/Mul 1 1 /model.22/cv3.2/cv3.2.1/conv/Conv_output_0 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 +Convolution /model.22/cv3.2/cv3.2.2/Conv 1 1 /model.22/cv3.2/cv3.2.1/act/Mul_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 0=6 1=1 5=1 6=768 +Concat /model.22/Concat_3 2 1 /model.22/cv2.2/cv2.2.2/Conv_output_0 /model.22/cv3.2/cv3.2.2/Conv_output_0 /model.22/Concat_3_output_0 +Reshape /model.22/Reshape_3 1 1 /model.22/Concat_1_output_0 /model.22/Reshape_3_output_0 0=-1 1=70 +Reshape /model.22/Reshape_4 1 1 /model.22/Concat_2_output_0 /model.22/Reshape_4_output_0 0=-1 1=70 +Reshape /model.22/Reshape_5 1 1 /model.22/Concat_3_output_0 /model.22/Reshape_5_output_0 0=-1 1=70 +Concat /model.22/Concat_4 3 1 /model.22/Reshape_3_output_0 /model.22/Reshape_4_output_0 /model.22/Reshape_5_output_0 /model.22/Concat_4_output_0 0=1 +Concat /model.22/Concat_5 2 1 /model.22/Concat_4_output_0 /model.22/Concat_output_0 /model.22/Concat_5_output_0 +Permute /model.22/Transpose 1 1 /model.22/Concat_5_output_0 output 0=1 +Reshape /model.22/Reshape_6 1 1 /model.22/proto/cv3/act/Mul_output_0 seg 0=-1 1=32 diff --git a/app/src/main/assets/model.ncnn.bin b/app/src/main/assets/model.ncnn.bin new file mode 100644 index 0000000..b58a0c9 --- /dev/null +++ b/app/src/main/assets/model.ncnn.bin Binary files differ diff --git a/app/src/main/assets/model.ncnn.param b/app/src/main/assets/model.ncnn.param new file mode 100644 index 0000000..b720190 --- /dev/null +++ b/app/src/main/assets/model.ncnn.param @@ -0,0 +1,80 @@ +7767517 +78 94 +Input images 0 1 images +Convolution conv_1 1 1 images 1 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 +Swish silu_28 1 1 1 2 +Convolution conv_2 1 1 2 3 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=18432 +Swish silu_29 1 1 3 4 +Convolution conv_3 1 1 4 5 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 +Swish silu_30 1 1 5 6 +Slice split_0 1 2 6 7 8 -23300=2,32,32 1=0 +Split splitncnn_0 1 3 8 9 10 11 +Convolution conv_4 1 1 11 12 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_31 1 1 12 13 +Convolution conv_5 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=9216 +Swish silu_32 1 1 14 15 +BinaryOp add_0 2 1 10 15 16 0=0 +Concat cat_0 3 1 7 9 16 17 0=0 +Convolution conv_6 1 1 17 18 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=6144 +Swish silu_33 1 1 18 19 +Convolution conv_7 1 1 19 20 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=73728 +Swish silu_34 1 1 20 21 +Convolution conv_8 1 1 21 22 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 +Swish silu_35 1 1 22 23 +Slice split_1 1 2 23 24 25 -23300=2,64,64 1=0 +Split splitncnn_1 1 3 25 26 27 28 +Convolution conv_9 1 1 28 29 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_36 1 1 29 30 +Convolution conv_10 1 1 30 31 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_37 1 1 31 32 +BinaryOp add_1 2 1 27 32 33 0=0 +Split splitncnn_2 1 3 33 34 35 36 +Convolution conv_11 1 1 36 37 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_38 1 1 37 38 +Convolution conv_12 1 1 38 39 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=36864 +Swish silu_39 1 1 39 40 +BinaryOp add_2 2 1 35 40 41 0=0 +Concat cat_1 4 1 24 26 34 41 42 0=0 +Convolution conv_13 1 1 42 43 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 +Swish silu_40 1 1 43 44 +Convolution conv_14 1 1 44 45 0=256 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=294912 +Swish silu_41 1 1 45 46 +Convolution conv_15 1 1 46 47 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 +Swish silu_42 1 1 47 48 +Slice split_2 1 2 48 49 50 -23300=2,128,128 1=0 +Split splitncnn_3 1 3 50 51 52 53 +Convolution conv_16 1 1 53 54 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_43 1 1 54 55 +Convolution conv_17 1 1 55 56 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_44 1 1 56 57 +BinaryOp add_3 2 1 52 57 58 0=0 +Split splitncnn_4 1 3 58 59 60 61 +Convolution conv_18 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_45 1 1 62 63 +Convolution conv_19 1 1 63 64 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=147456 +Swish silu_46 1 1 64 65 +BinaryOp add_4 2 1 60 65 66 0=0 +Concat cat_2 4 1 49 51 59 66 67 0=0 +Convolution conv_20 1 1 67 68 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 +Swish silu_47 1 1 68 69 +Convolution conv_21 1 1 69 70 0=512 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=1179648 +Swish silu_48 1 1 70 71 +Convolution conv_22 1 1 71 72 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 +Swish silu_49 1 1 72 73 +Slice split_3 1 2 73 74 75 -23300=2,256,256 1=0 +Split splitncnn_5 1 3 75 76 77 78 +Convolution conv_23 1 1 78 79 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_50 1 1 79 80 +Convolution conv_24 1 1 80 81 0=256 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=589824 +Swish silu_51 1 1 81 82 +BinaryOp add_5 2 1 77 82 83 0=0 +Concat cat_3 3 1 74 76 83 84 0=0 +Convolution conv_25 1 1 84 85 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=393216 +Swish silu_52 1 1 85 86 +Convolution conv_26 1 1 86 87 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=655360 +Swish silu_53 1 1 87 88 +Pooling gap_0 1 1 88 89 0=1 4=1 +Reshape reshape_55 1 1 89 90 0=1 1=1 2=-1 +Flatten flatten_56 1 1 90 91 +InnerProduct linear_27 1 1 91 92 0=3 1=1 2=3840 +Softmax softmax_54 1 1 92 output 0=0 1=1 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 646e82f..fd0427f 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -128,10 +128,8 @@ } static void generate_proposals(std::vector grid_strides, const ncnn::Mat &pred, - float prob_threshold, std::vector &objects) { + float prob_threshold, std::vector &objects, int num_class) { const int num_points = grid_strides.size(); - //识别种类数 - const int num_class = 43; const int reg_max_1 = 16; for (int i = 0; i < num_points; i++) { @@ -203,6 +201,153 @@ } } +/***模型分割*************/ +static void matmul(const std::vector &bottom_blobs, ncnn::Mat &top_blob) { + ncnn::Option opt; + opt.num_threads = 2; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("MatMul"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 0);// axis + + op->load_param(pd); + + op->create_pipeline(opt); + std::vector top_blobs(1); + op->forward(bottom_blobs, top_blobs, opt); + top_blob = top_blobs[0]; + + op->destroy_pipeline(opt); + + delete op; +} + +static void sigmoid(ncnn::Mat &bottom) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Sigmoid"); + + op->create_pipeline(opt); + + // forward + + op->forward_inplace(bottom, opt); + op->destroy_pipeline(opt); + + delete op; +} + +static void reshape(const ncnn::Mat &in, ncnn::Mat &out, int c, int h, int w, int d) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Reshape"); + + // set param + ncnn::ParamDict pd; + + pd.set(0, w);// start + pd.set(1, h);// end + if (d > 0) + pd.set(11, d);//axes + pd.set(2, c);//axes + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void slice(const ncnn::Mat &in, ncnn::Mat &out, int start, int end, int axis) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Crop"); + + // set param + ncnn::ParamDict pd; + + ncnn::Mat axes = ncnn::Mat(1); + axes.fill(axis); + ncnn::Mat ends = ncnn::Mat(1); + ends.fill(end); + ncnn::Mat starts = ncnn::Mat(1); + starts.fill(start); + pd.set(9, starts);// start + pd.set(10, ends);// end + pd.set(11, axes);//axes + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void interp(const ncnn::Mat &in, const float &scale, const int &out_w, const int &out_h, + ncnn::Mat &out) { + ncnn::Option opt; + opt.num_threads = 4; + opt.use_fp16_storage = false; + opt.use_packing_layout = false; + + ncnn::Layer *op = ncnn::create_layer("Interp"); + + // set param + ncnn::ParamDict pd; + pd.set(0, 2);// resize_type + pd.set(1, scale);// height_scale + pd.set(2, scale);// width_scale + pd.set(3, out_h);// height + pd.set(4, out_w);// width + + op->load_param(pd); + + op->create_pipeline(opt); + + // forward + op->forward(in, out, opt); + + op->destroy_pipeline(opt); + + delete op; +} + +static void decode_mask(const ncnn::Mat &mask_feat, const int &img_w, const int &img_h, + const ncnn::Mat &mask_proto, const ncnn::Mat &in_pad, const int &wpad, + const int &hpad, ncnn::Mat &mask_pred_result) { + ncnn::Mat masks; + matmul(std::vector{mask_feat, mask_proto}, masks); + sigmoid(masks); + reshape(masks, masks, masks.h, in_pad.h / 4, in_pad.w / 4, 0); + slice(masks, mask_pred_result, (wpad / 2) / 4, (in_pad.w - wpad / 2) / 4, 2); + slice(mask_pred_result, mask_pred_result, (hpad / 2) / 4, (in_pad.h - hpad / 2) / 4, 1); + interp(mask_pred_result, 4.0, img_w, img_h, mask_pred_result); +} + +/***模型分割*************/ + Yolo::Yolo() { blob_pool_allocator.set_size_compare_ratio(0.f); workspace_pool_allocator.set_size_compare_ratio(0.f); @@ -237,8 +382,8 @@ char param_path[256]; char model_path[256]; //拼接模型名(路径) - sprintf(param_path, "yolov8%s.param", model_type); - sprintf(model_path, "yolov8%s.bin", model_type); + sprintf(param_path, "%s.param", model_type); + sprintf(model_path, "%s.bin", model_type); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "param_path %s", param_path); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "model_path %s", model_path); @@ -257,7 +402,7 @@ return 0; } -void Yolo::setNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { +void Yolo::initNativeCallback(JavaVM *vm, jobject input, jlong nativeObjAddr, jobject pJobject) { javaVM = vm; /** @@ -273,142 +418,351 @@ j_callback = env->NewGlobalRef(pJobject); } -int -Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, - float nms_threshold) { - int width = rgb.cols; - int height = rgb.rows; +int Yolo::classify(const cv::Mat &rgb) { + if (state == 0) { + static const float scale_values[3] = {0.017f, 0.017f, 0.017f}; - // pad to multiple of 32 - int w = width; - int h = height; - float scale = 1.f; - if (w > h) { - scale = (float) target_size / w; - w = target_size; - h = h * scale; - } else { - scale = (float) target_size / h; - h = target_size; - w = w * scale; - } + int width = rgb.cols; + int height = rgb.rows; - ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, - w, h); + //把opencv Mat转为 ncnn Mat + ncnn::Mat in = ncnn::Mat::from_pixels(rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height); - // pad to target_size rectangle - int w_pad = (w + 31) / 32 * 32 - w; - int h_pad = (h + 31) / 32 * 32 - h; - ncnn::Mat in_pad; - ncnn::copy_make_border(in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, w_pad - w_pad / 2, - ncnn::BORDER_CONSTANT, 0.f); + std::vector cls_scores; + { + in.substract_mean_normalize(mean_values, scale_values); + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in); - in_pad.substract_mean_normalize(0, norm_values); + ncnn::Mat out; + ex.extract("output", out); - ncnn::Extractor ex = yolo.create_extractor(); + int output_size = out.w; + float float_buffer[output_size]; + for (int j = 0; j < out.w; j++) { + float_buffer[j] = out[j]; + } - ex.input("images", in_pad); + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jmethodID j_method_id = env->GetMethodID(callback_clazz, "onClassify", "([F)V"); - std::vector proposals; + jfloatArray j_output_Data = env->NewFloatArray(output_size); + env->SetFloatArrayRegion(j_output_Data, 0, output_size, float_buffer); - ncnn::Mat out; - ex.extract("output", out); - - std::vector strides = {8, 16, 32}; // might have stride=64 - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - generate_proposals(grid_strides, out, prob_threshold, proposals); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - } - - // sort objects by area - struct { - bool operator()(const Object &a, const Object &b) const { - return a.rect.area() > b.rect.area(); + env->CallVoidMethod(j_callback, j_method_id, j_output_Data); } - } objects_area_greater; - std::sort(objects.begin(), objects.end(), objects_area_greater); - - /** - * 回调给Java/Kotlin层 - * */ - JNIEnv *env; - javaVM->AttachCurrentThread(&env, nullptr); - jclass callback_clazz = env->GetObjectClass(j_callback); - jclass output_clazz = env->GetObjectClass(j_output); - - jmethodID j_method_id = env->GetMethodID( - callback_clazz, "onDetect", "(Ljava/util/ArrayList;)V" - ); - - jclass list_clazz = env->FindClass("java/util/ArrayList"); - jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); - jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); - jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); - - for (int i = 0; i < count; i++) { - auto item = objects[i]; - - jfieldID type = env->GetFieldID(output_clazz, "type", "I"); - env->SetIntField(j_output, type, item.label); - - jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); - float array[4]; - array[0] = item.rect.x; - array[1] = item.rect.y; - array[2] = item.rect.width; - array[3] = item.rect.height; - jfloatArray rectArray = env->NewFloatArray(4); - env->SetFloatArrayRegion(rectArray, 0, 4, array); - env->SetObjectField(j_output, position, rectArray); - - jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); - env->SetFloatField(j_output, prob, item.prob); - - //add - env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); } - //回调 - env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + return 0; +} - /** - * Mat数据。 - *
-----------------------------------------------
- * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 - * */ - __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "nativeObjAddr %lld", j_mat_addr); - auto *res = (cv::Mat *) j_mat_addr; - res->create(rgb.rows, rgb.cols, rgb.type()); - memcpy(res->data, rgb.data, rgb.rows * rgb.step); +int Yolo::partition(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 1) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_BGR2RGB, width, + height, w, h); + + // pad to target_size rectangle + int wpad = (w + 31) / 32 * 32 - w; + int hpad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, + ncnn::BORDER_CONSTANT, 0.f); + + const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; + in_pad.substract_mean_normalize(0, norm_vals); + + + ncnn::Extractor ex = yolo.create_extractor(); + ex.input("images", in_pad); + + ncnn::Mat out; + ex.extract("output", out); + + ncnn::Mat mask_proto; + ex.extract("seg", mask_proto); + + std::vector strides = {8, 16, 32}; + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + + std::vector proposals; + std::vector objects8; + generate_proposals(grid_strides, out, prob_threshold, objects8, 6); + + proposals.insert(proposals.end(), objects8.begin(), objects8.end()); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); + for (int i = 0; i < count; i++) { + float *mask_feat_ptr = mask_feat.row(i); + std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), + sizeof(float) * proposals[picked[i]].mask_feat.size()); + } + + ncnn::Mat mask_pred_result; + decode_mask(mask_feat, width, height, mask_proto, in_pad, wpad, hpad, mask_pred_result); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (wpad / 2)) / scale; + float y0 = (objects[i].rect.y - (hpad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + + objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); + cv::Mat mask = cv::Mat(height, width, CV_32FC1, (float *) mask_pred_result.channel(i)); + mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); + } + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onPartition", "(Ljava/util/ArrayList;)V" + ); + + //获取ArrayList类 + jclass list_clazz = env->FindClass("java/util/ArrayList"); + jmethodID arraylist_init = env->GetMethodID(list_clazz, "", "()V"); + jmethodID arraylist_add = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + //初始化ArrayList对象 + jobject arraylist_obj = env->NewObject(list_clazz, arraylist_init); + + for (auto item: objects) { + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //add + env->CallBooleanMethod(arraylist_obj, arraylist_add, j_output); + } + //回调 + env->CallVoidMethod(j_callback, j_method_id, arraylist_obj); + + /** + * Mat数据。 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } + return 0; +} + +int Yolo::detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold, + float nms_threshold) { + if (state == 2) { + int width = rgb.cols; + int height = rgb.rows; + + // pad to multiple of 32 + int w = width; + int h = height; + float scale = 1.f; + if (w > h) { + scale = (float) target_size / w; + w = target_size; + h = h * scale; + } else { + scale = (float) target_size / h; + h = target_size; + w = w * scale; + } + + ncnn::Mat in = ncnn::Mat::from_pixels_resize( + rgb.data, ncnn::Mat::PIXEL_RGB2BGR, width, height, w, h + ); + + // pad to target_size rectangle + int w_pad = (w + 31) / 32 * 32 - w; + int h_pad = (h + 31) / 32 * 32 - h; + ncnn::Mat in_pad; + ncnn::copy_make_border( + in, in_pad, h_pad / 2, h_pad - h_pad / 2, w_pad / 2, + w_pad - w_pad / 2, + ncnn::BORDER_CONSTANT, 0.f + ); + + in_pad.substract_mean_normalize(0, norm_values); + + ncnn::Extractor ex = yolo.create_extractor(); + + ex.input("images", in_pad); + + std::vector proposals; + + ncnn::Mat out; + ex.extract("output", out); + + std::vector strides = {8, 16, 32}; // might have stride=64 + std::vector grid_strides; + generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); + generate_proposals(grid_strides, out, prob_threshold, proposals, 43); + + // sort all proposals by score from highest to lowest + qsort_descent_inplace(proposals); + + // apply nms with nms_threshold + std::vector picked; + nms_sorted_bboxes(proposals, picked, nms_threshold); + + int count = picked.size(); + + objects.resize(count); + for (int i = 0; i < count; i++) { + objects[i] = proposals[picked[i]]; + + // adjust offset to original unpadded + float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; + float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; + float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; + float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; + + // clip + x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); + y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); + x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); + y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); + + objects[i].rect.x = x0; + objects[i].rect.y = y0; + objects[i].rect.width = x1 - x0; + objects[i].rect.height = y1 - y0; + } + + // sort objects by area + struct { + bool operator()(const Object &a, const Object &b) const { + return a.rect.area() > b.rect.area(); + } + } objects_area_greater; + std::sort(objects.begin(), objects.end(), objects_area_greater); + + /** + * 回调给Java/Kotlin层 + * */ + JNIEnv *env; + javaVM->AttachCurrentThread(&env, nullptr); + jclass callback_clazz = env->GetObjectClass(j_callback); + jclass output_clazz = env->GetObjectClass(j_output); + /** + * I: 整数类型(int) + * J: 长整数类型(long) + * D: 双精度浮点数类型(double) + * F: 单精度浮点数类型(float) + * Z: 布尔类型(boolean) + * C: 字符类型(char) + * B: 字节类型(byte) + * S: 短整数类型(short) + *
-----------------------------------------------
+ * Ljava/lang/Object;: 表示 Object 类型的引用 + * Ljava/lang/String;: 表示 String 类型的引用 + * L包名/类名;: 表示特定包名和类名的引用 + *
-----------------------------------------------
+ * 例如: + * int add(int a, int b): (II)I + * + * String concat(String str1, String str2): (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + *
-----------------------------------------------
+ * [Ljava/lang/String;: 表示 String 类型的一维数组 + * */ + jmethodID j_method_id = env->GetMethodID( + callback_clazz, "onDetect", "(Lcom/casic/br/app/external/YoloResult;)V" + ); + + for (int i = 0; i < count; i++) { + auto item = objects[i]; + + jfieldID type = env->GetFieldID(output_clazz, "type", "I"); + env->SetIntField(j_output, type, item.label); + + jfieldID position = env->GetFieldID(output_clazz, "position", "[F"); + float array[4]; + array[0] = item.rect.x; + array[1] = item.rect.y; + array[2] = item.rect.width; + array[3] = item.rect.height; + jfloatArray rectArray = env->NewFloatArray(4); + env->SetFloatArrayRegion(rectArray, 0, 4, array); + env->SetObjectField(j_output, position, rectArray); + + jfieldID prob = env->GetFieldID(output_clazz, "prob", "F"); + env->SetFloatField(j_output, prob, item.prob); + + //回调 + env->CallVoidMethod(j_callback, j_method_id, j_output); + } + + /** + * Mat数据。 + *
-----------------------------------------------
+ * 通过内存地址赋值。Java层传入Mat对象内存地址,再通过C++给此地址赋值,Java即可得到内存地址的Mat矩阵数据 + * */ + auto *res = (cv::Mat *) j_mat_addr; + res->create(rgb.rows, rgb.cols, rgb.type()); + memcpy(res->data, rgb.data, rgb.rows * rgb.step); + } return 0; } @@ -456,6 +810,7 @@ for (const auto &obj: objects) { const unsigned char *color = colors[color_index % 19]; + color_index++; cv::Scalar cc(color[0], color[1], color[2]); @@ -463,11 +818,11 @@ cv::rectangle(rgb, obj.rect, cc, 2); char text[256]; - sprintf(text, "%s", class_names[obj.label]); -// sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); + sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100); int baseLine = 0; - cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, + &baseLine); int x = obj.rect.x; int y = obj.rect.y - label_size.height - baseLine; @@ -484,6 +839,7 @@ ? cv::Scalar(0, 0, 0) : cv::Scalar(255, 255, 255); + cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, diff --git a/app/src/main/cpp/yolo.h b/app/src/main/cpp/yolo.h index 785adbb..1874609 100644 --- a/app/src/main/cpp/yolo.h +++ b/app/src/main/cpp/yolo.h @@ -23,6 +23,8 @@ cv::Rect_ rect; int label; float prob; + cv::Mat mask; + std::vector mask_feat; }; struct GridAndStride { int grid0; @@ -34,6 +36,16 @@ public: Yolo(); + /** + * Yolo当前状态 + *
---------------
+ * 0 - 分类
+ * 1 - 分割
+ * 2 - 检测
+ * 3 - 绘制
+ * */ + int state = 0; + int load(const char *model_type, int target_size, const float *mean_values, @@ -47,8 +59,24 @@ const float *norm_values, bool use_gpu = false); - void setNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + void initNativeCallback(JavaVM *vm, jobject result, jlong nativeObjAddr, jobject pJobject); + /** + * 分类 + * */ + int classify(const cv::Mat &rgb); + + /** + * 分割 + * */ + int partition(const cv::Mat &rgb, + std::vector &objects, + float prob_threshold = 0.4f, + float nms_threshold = 0.5f); + + /** + * 检测 + * */ int detect(const cv::Mat &rgb, std::vector &objects, float prob_threshold = 0.4f, diff --git a/app/src/main/cpp/yolov8ncnn.cpp b/app/src/main/cpp/yolov8ncnn.cpp index 8048560..e758ef5 100644 --- a/app/src/main/cpp/yolov8ncnn.cpp +++ b/app/src/main/cpp/yolov8ncnn.cpp @@ -122,16 +122,20 @@ ncnn::MutexLockGuard g(lock); if (g_yolo) { - std::vector objects; - g_yolo->detect(rgb, objects); + //分类 + g_yolo->classify(rgb); -// g_yolo->draw(rgb, objects); + std::vector objects; + + //分割 + g_yolo->partition(rgb, objects); + + //检测 + g_yolo->detect(rgb, objects); } else { draw_unsupported(rgb); } } - -// draw_fps(rgb); } static MyNdkCamera *g_camera = nullptr; @@ -170,15 +174,20 @@ AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); - const char *model_types[] = {"s-detect-sim-opt-fp16"}; + //分割、分类、检测 + const char *model_types[] = {"best-sim-opt-fp16", "model.ncnn", "yolov8s-detect-sim-opt-fp16"}; - const int target_sizes[] = {320}; + const int target_sizes[] = {320, 320, 320}; const float mean_values[][3] = { + {103.53f, 116.28f, 123.675f}, + {103.53f, 116.28f, 123.675f}, {103.53f, 116.28f, 123.675f} }; const float norm_values[][3] = { + {1 / 255.f, 1 / 255.f, 1 / 255.f}, + {1 / 255.f, 1 / 255.f, 1 / 255.f}, {1 / 255.f, 1 / 255.f, 1 / 255.f} }; @@ -243,7 +252,19 @@ g_camera->set_window(win); - g_yolo->setNativeCallback(javaVM, input, nativeObjAddr, native_callback); + g_yolo->initNativeCallback(javaVM, input, nativeObjAddr, native_callback); return JNI_TRUE; } + +JNIEXPORT jboolean JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_updateYoloState(JNIEnv *env, jobject thiz, + jint yolo_state) { + g_yolo->state = yolo_state; + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_com_casic_br_app_external_Yolov8ncnn_getYoloCurrentState(JNIEnv *env, jobject thiz) { + return g_yolo->state; +} } diff --git a/app/src/main/java/com/casic/br/app/extensions/String.kt b/app/src/main/java/com/casic/br/app/extensions/String.kt index e2a8e13..8586aed 100644 --- a/app/src/main/java/com/casic/br/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/app/extensions/String.kt @@ -32,4 +32,21 @@ LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL ) as String return "$defaultValue/static/${this.replace("\\", "/")}" +} + +fun String.getSceneByTarget(): String { + val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { + "配电箱" + } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { + "调压站" + } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { + "建筑消防" + } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { + "有限空间作业" + } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { + "非居用户" + } else { + "未知场景" + } + return scene } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/DetectResult.java b/app/src/main/java/com/casic/br/app/external/DetectResult.java deleted file mode 100644 index 4bbf1bc..0000000 --- a/app/src/main/java/com/casic/br/app/external/DetectResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.casic.br.app.external; - -public class DetectResult { - private int type; - private float[] position; - private float prob; - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public float[] getPosition() { - return position; - } - - public void setPosition(float[] position) { - this.position = position; - } - - public float getProb() { - return prob; - } - - public void setProb(float prob) { - this.prob = prob; - } -} diff --git a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt index b43a182..c353971 100644 --- a/app/src/main/java/com/casic/br/app/external/INativeCallback.kt +++ b/app/src/main/java/com/casic/br/app/external/INativeCallback.kt @@ -1,5 +1,18 @@ package com.casic.br.app.external interface INativeCallback { - fun onDetect(output: ArrayList) + /** + * 分类 + */ + fun onClassify(possibles: FloatArray) + + /** + * 分割 + */ + fun onPartition(output: ArrayList) + + /** + * 检测 + */ + fun onDetect(output: YoloResult) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/YoloResult.java b/app/src/main/java/com/casic/br/app/external/YoloResult.java new file mode 100644 index 0000000..42ebb23 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloResult.java @@ -0,0 +1,31 @@ +package com.casic.br.app.external; + +public class YoloResult { + private int type; + private float[] position; + private float prob; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position; + } + + public float getProb() { + return prob; + } + + public void setProb(float prob) { + this.prob = prob; + } +} diff --git a/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt new file mode 100644 index 0000000..ebeaf20 --- /dev/null +++ b/app/src/main/java/com/casic/br/app/external/YoloStateConst.kt @@ -0,0 +1,19 @@ +package com.casic.br.app.external + +@Retention(AnnotationRetention.SOURCE) +annotation class YoloStateConst { + companion object { + /** + * Yolo当前状态 + *
------------------------------
+ * 0 - 分类 + * 1 - 分割 + * 2 - 检测 + * 3 - 绘制 + * */ + const val CLASSIFY = 0 + const val PARTITION = 1 + const val DETECT = 2 + const val DRAW = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt index 75320f0..87476b6 100644 --- a/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt +++ b/app/src/main/java/com/casic/br/app/external/Yolov8ncnn.kt @@ -26,6 +26,10 @@ external fun closeCamera(): Boolean external fun setOutputWindow( - surface: Surface, input: DetectResult, nativeObjAddr: Long, callBack: INativeCallback + surface: Surface, input: YoloResult, nativeObjAddr: Long, callBack: INativeCallback ): Boolean + + external fun updateYoloState(@YoloStateConst yoloState: Int): Boolean + + external fun getYoloCurrentState(): Int } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt index eb4308b..62d23b2 100644 --- a/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/app/utils/LocaleConstant.kt @@ -39,6 +39,55 @@ ) } + val CLASS_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "人", "切断阀", "危险告知牌", + "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", + "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", + "对讲机", "尖头水枪", "开关", "报警装置", "接头", + "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", + "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", + "电路图", "警戒线", "调压器", "调长器", "贴纸", + "跨电线", "路锥", "软管", "过滤器", "配电箱", + "长柄阀门", "阀门", "风管" + ) + + //配电箱 + val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( + "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" + ) + + //调压站 + val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( + "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + ) + + //建筑消防 + val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( + "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形", "灭火器" + ) + + //有限空间作业 + val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( + "安全帽", + "呼吸面罩", + "施工路牌", + "安全告知牌", + "危险告知牌", + "警戒线", + "路锥", + "三脚架", + "对讲机", + "反光衣", + "照明设备", + "气体检测仪", + "安全绳" + ) + + //非居 + val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( + "三通", "人", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头" + ) + /** * ============================================================================================= * Int diff --git a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt index fc80862..3feb7e3 100644 --- a/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/CheckResultActivity.kt @@ -1,5 +1,6 @@ package com.casic.br.app.view +import android.content.Intent import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.casic.br.app.R @@ -81,6 +82,10 @@ LoadState.Loading -> {} LoadState.Success -> { "结束巡检成功".show(this) + + //通知上一级页面关闭 + val intent = Intent() + setResult(RESULT_OK, intent) finish() } diff --git a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt index 35d0cbd..cc1f13e 100644 --- a/app/src/main/java/com/casic/br/app/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/LoginActivity.kt @@ -6,6 +6,7 @@ import com.amap.api.maps.MapsInitializer import com.casic.br.app.R import com.casic.br.app.databinding.ActivityLoginBinding +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.utils.AuthenticationHelper import com.casic.br.app.utils.LocaleConstant @@ -49,7 +50,8 @@ //协程预加载算法模型 lifecycleScope.launch(Dispatchers.IO) { - yolov8ncnn.loadModel(assets, 0, 1) + yolov8ncnn.loadModel(assets, 1, 0) + yolov8ncnn.updateYoloState(YoloStateConst.CLASSIFY) } //初始化OpenCV diff --git a/app/src/main/java/com/casic/br/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/app/view/MainActivity.kt index 17cff9d..0fb34e3 100644 --- a/app/src/main/java/com/casic/br/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/MainActivity.kt @@ -20,8 +20,8 @@ } binding.startCheckButton.setOnClickListener { - navigatePageTo() -// navigatePageTo() +// navigatePageTo() + navigatePageTo() } binding.checkHistoryButton.setOnClickListener { diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index d8f7cc2..08610a8 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -1,19 +1,25 @@ package com.casic.br.app.view +import android.app.Activity import android.content.Intent import android.graphics.PixelFormat import android.os.Bundle +import android.util.Log import android.view.SurfaceHolder +import android.view.View import android.view.WindowManager import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.casic.br.app.R import com.casic.br.app.databinding.ActivityStartCheckByYoloBinding +import com.casic.br.app.extensions.getSceneByTarget import com.casic.br.app.extensions.initImmersionBar -import com.casic.br.app.external.DetectResult import com.casic.br.app.external.INativeCallback +import com.casic.br.app.external.YoloResult +import com.casic.br.app.external.YoloStateConst import com.casic.br.app.external.Yolov8ncnn import com.casic.br.app.model.DictionaryModel import com.casic.br.app.utils.LocaleConstant @@ -27,9 +33,13 @@ import com.pengxh.kt.lite.extensions.timestampToDate import com.pengxh.kt.lite.extensions.timestampToTime import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opencv.core.Mat class StartCheckByYoloActivity : KotlinBaseActivity(), @@ -37,6 +47,11 @@ private val kTag = "StartCheckActivity" private val context = this + + /** + * 需要和训练出来的模型里面类别顺序保持一致 + * */ + private val classArray = arrayOf("电线整洁", "电线杂乱", "餐馆厨房") private val locationManager by lazy { LocationManager(this) } private val targetSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } @@ -46,6 +61,8 @@ private var inspectionAddress = "" private var inspectionId = "" private var mainDicModels: MutableList = ArrayList() + private var isShowing = false + private var detectedScene = "" override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -93,7 +110,10 @@ "巡检任务创建中,请稍后再结束任务".show(this) return@setOnClickListener } - navigatePageTo(inspectionId) + + val intent = Intent(this, CheckResultActivity::class.java) + intent.putExtra(Constant.INTENT_PARAM, inspectionId) + stopTaskLauncher.launch(intent) } binding.tipsButton.setOnClickListener { @@ -102,9 +122,9 @@ return@setOnClickListener } //根据识别出来的结果显示清单 -// navigatePageTo( -// arrayListOf(detectedScene, targetSet.toJson()) -// ) + navigatePageTo( + arrayListOf(detectedScene, targetSet.toJson()) + ) } binding.addButton.setOnClickListener { @@ -119,7 +139,7 @@ "请先选择场景或者识别出场景再试".show(this) return@setOnClickListener } -// navigatePageTo(arrayListOf(detectedScene, inspectionId)) + navigatePageTo(arrayListOf(detectedScene, inspectionId)) } } @@ -153,8 +173,7 @@ 1 -> { binding.titleView.setTitle("") -// isDetectingScene = false -// detectedScene = "" + detectedScene = "" "场景重置成功".show(context) } } @@ -171,15 +190,89 @@ val data = it.data ?: return@ActivityResultCallback val sceneName = data.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) -// detectedScene = sceneName + detectedScene = sceneName } }) - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - yolov8ncnn.setOutputWindow(holder.surface, DetectResult(), mat.nativeObjAddr, this) + private val stopTaskLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + finish() + } } - override fun onDetect(output: ArrayList) { + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + yolov8ncnn.setOutputWindow(holder.surface, YoloResult(), mat.nativeObjAddr, this) + } + + override fun onClassify(possibles: FloatArray) { + if (isShowing) { + return + } + + //找出最大值的下标 + var max = possibles[0] + var maxIndex = 0 + possibles.forEachIndexed { index, fl -> + if (fl > max) { + max = fl + maxIndex = index + } + } + + try { + Log.d(kTag, "onClassify: ${classArray[maxIndex]}") + lifecycleScope.launch(Dispatchers.Main) { + isShowing = true + if (classArray[maxIndex] == classArray[2]) { + //非居 + AlertControlDialog.Builder() + .setContext(context) + .setTitle("提示") + .setMessage("识别到${classArray[maxIndex]}场景,是否开始排查该场景的隐患?") + .setNegativeButton("稍后") + .setPositiveButton("好的").setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + //需要同时调用分割和检测模型 + + } + + override fun onCancelClick() { + isShowing = false + } + }).build().show() + } else { + if (yolov8ncnn.getYoloCurrentState() != YoloStateConst.DETECT) { + //需要调用检测模型 + loadModelFromAssets(2) + yolov8ncnn.updateYoloState(YoloStateConst.DETECT) + } + } + } + } catch (e: ArrayIndexOutOfBoundsException) { + e.printStackTrace() + } + } + + override fun onPartition(output: ArrayList) { + + } + + override fun onDetect(output: YoloResult) { + //需要根据检测结果反推属于什么场景 + val label = LocaleConstant.CLASS_NAMES_ARRAY[output.type] + + targetSet.add(label) + detectedScene = label.getSceneByTarget() + lifecycleScope.launch(Dispatchers.Main) { + binding.titleView.setTitle(detectedScene) + //显示角标 + binding.tipsTagView.visibility = View.VISIBLE + binding.tipsTagView.text = "${targetSet.size}" + } + binding.detectView.updateTargetPosition(output) // if (mat.width() > 0 && mat.height() > 0) { // val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888) @@ -208,4 +301,14 @@ super.onDestroy() locationManager.stopLocation() } + + /** + * index对应 JNI 里面定义的数组角标 + * */ + private fun loadModelFromAssets(index: Int) { + val result = yolov8ncnn.loadModel(assets, index, 0) + if (!result) { + Log.d(kTag, "reload: yolov8ncnn loadModel failed") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt index cb05187..b997dd4 100644 --- a/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt +++ b/app/src/main/java/com/casic/br/app/widgets/YoloTargetDetectView.kt @@ -8,29 +8,20 @@ import android.text.TextPaint import android.util.AttributeSet import android.view.View -import com.casic.br.app.external.DetectResult +import com.casic.br.app.external.YoloResult +import com.casic.br.app.utils.LocaleConstant import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.sp2px -class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) { +class YoloTargetDetectView constructor(context: Context, attrs: AttributeSet) : + View(context, attrs) { private val kTag = "DetectView" private val textPaint by lazy { TextPaint() } private val backgroundPaint by lazy { Paint() } private val borderPaint by lazy { Paint() } private val rect by lazy { Rect() } - private val classNames = arrayListOf( - "三脚架", "三通", "人", "切断阀", "危险告知牌", - "压力测试仪", "压力表", "反光衣", "呼吸面罩", "喉箍", - "圆头水枪", "安全告知牌", "安全帽", "安全标识", "安全绳", - "对讲机", "尖头水枪", "开关", "报警装置", "接头", - "施工路牌", "气体检测仪", "水带", "水带_矩形", "流量计", - "消火栓箱", "灭火器", "照明设备", "熄火保护", "电线暴露", - "电路图", "警戒线", "调压器", "调长器", "贴纸", - "跨电线", "路锥", "软管", "过滤器", "配电箱", - "长柄阀门", "阀门", "风管" - ) - private var results: MutableList = ArrayList() + private var result: YoloResult? = null init { textPaint.color = Color.WHITE @@ -48,40 +39,41 @@ borderPaint.isAntiAlias = true } - fun updateTargetPosition(results: MutableList) { - this.results = results + fun updateTargetPosition(result: YoloResult) { + this.result = result postInvalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - results.forEach { - val label = classNames[it.type] + result?.apply { + val prob = String.format("%.2f", this.prob * 100) + val label = "${LocaleConstant.CLASS_NAMES_ARRAY[this.type]} ${prob}%" val textLength = textPaint.measureText(label) //文字背景 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[0].dp2px(context) + textLength).toInt() + 10, - it.position[1].dp2px(context).toInt() - 55 + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[0].dp2px(context) + textLength).toInt() + 10, + this.position[1].dp2px(context).toInt() - 50 ) canvas.drawRect(rect, backgroundPaint) //画文字。数值是文字左右边距,可酌情调整 canvas.drawText( label, - it.position[0].dp2px(context) + (textLength + 10) / 2, - it.position[1].dp2px(context) - 10, + this.position[0].dp2px(context) + (textLength + 10) / 2, + this.position[1].dp2px(context) - 10, textPaint ) //画框 rect.set( - (it.position[0].dp2px(context)).toInt(), - (it.position[1].dp2px(context)).toInt(), - (it.position[2] + it.position[0]).dp2px(context).toInt(), - (it.position[3] + it.position[1]).dp2px(context).toInt() + (this.position[0].dp2px(context)).toInt(), + (this.position[1].dp2px(context)).toInt(), + (this.position[2] + this.position[0]).dp2px(context).toInt(), + (this.position[3] + this.position[1]).dp2px(context).toInt() ) canvas.drawRect(rect, borderPaint) } diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..c2dcd6d --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.6) + +project(opencv_jni_shared) + +# dummy target to bring libc++_shared.so into packages +add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/sdk/build.gradle b/sdk/build.gradle index 19af051..7784f62 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -1,93 +1,3 @@ -// This file is part of OpenCV project. -// It is subject to the license terms in the LICENSE file found in the top-level directory -// of this distribution and at http://opencv.org/license.html. - -// -// Notes about integration OpenCV into existed Android Studio application project are below (application 'app' module should exist). -// -// This file is located in /sdk directory (near 'etc', 'java', 'native' subdirectories) -// -// Add module into Android Studio application project: -// -// - Android Studio way: -// (will copy almost all OpenCV Android SDK into your project, ~200Mb) -// -// Import module: Menu -> "File" -> "New" -> "Module" -> "Import Gradle project": -// Source directory: select this "sdk" directory -// Module name: ":opencv" -// -// - or attach library module from OpenCV Android SDK -// (without copying into application project directory, allow to share the same module between projects) -// -// Edit "settings.gradle" and add these lines: -// -// def opencvsdk='' -// // You can put declaration above into gradle.properties file instead (including file in HOME directory), -// // but without 'def' and apostrophe symbols ('): opencvsdk= -// include ':opencv' -// project(':opencv').projectDir = new File(opencvsdk + '/sdk') -// -// -// -// Add dependency into application module: -// -// - Android Studio way: -// "Open Module Settings" (F4) -> "Dependencies" tab -// -// - or add "project(':opencv')" dependency into app/build.gradle: -// -// dependencies { -// implementation fileTree(dir: 'libs', include: ['*.jar']) -// ... -// implementation project(':opencv') -// } -// -// -// -// Load OpenCV native library before using: -// -// - avoid using of "OpenCVLoader.initAsync()" approach - it is deprecated -// It may load library with different version (from OpenCV Android Manager, which is installed separatelly on device) -// -// - use "System.loadLibrary("opencv_java4")" or "OpenCVLoader.initDebug()" -// TODO: Add accurate API to load OpenCV native library -// -// -// -// Native C++ support (necessary to use OpenCV in native code of application only): -// -// - Use find_package() in app/CMakeLists.txt: -// -// find_package(OpenCV 4.9 REQUIRED java) -// ... -// target_link_libraries(native-lib ${OpenCV_LIBRARIES}) -// -// - Add "OpenCV_DIR" and enable C++ exceptions/RTTI support via app/build.gradle -// Documentation about CMake options: https://developer.android.com/ndk/guides/cmake.html -// -// defaultConfig { -// ... -// externalNativeBuild { -// cmake { -// cppFlags "-std=c++11 -frtti -fexceptions" -// arguments "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni" // , "-DANDROID_ARM_NEON=TRUE" -// } -// } -// } -// -// - (optional) Limit/filter ABIs to build ('android' scope of 'app/build.gradle'): -// Useful information: https://developer.android.com/studio/build/gradle-tips.html (Configure separate APKs per ABI) -// -// splits { -// abi { -// enable true -// universalApk false -// reset() -// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a' -// } -// } -// - apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'kotlin-android' @@ -159,7 +69,7 @@ externalNativeBuild { cmake { - path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt') + path (project.projectDir.toString() + '/CMakeLists.txt') } } } diff --git a/sdk/dummy.cpp b/sdk/dummy.cpp new file mode 100644 index 0000000..8b1a393 --- /dev/null +++ b/sdk/dummy.cpp @@ -0,0 +1 @@ +// empty diff --git a/sdk/libcxx_helper/CMakeLists.txt b/sdk/libcxx_helper/CMakeLists.txt deleted file mode 100644 index c2dcd6d..0000000 --- a/sdk/libcxx_helper/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.6) - -project(opencv_jni_shared) - -# dummy target to bring libc++_shared.so into packages -add_library(opencv_jni_shared STATIC dummy.cpp) diff --git a/sdk/libcxx_helper/dummy.cpp b/sdk/libcxx_helper/dummy.cpp deleted file mode 100644 index 8b1a393..0000000 --- a/sdk/libcxx_helper/dummy.cpp +++ /dev/null @@ -1 +0,0 @@ -// empty