├── .gitignore ├── LICENSE ├── README.md ├── config ├── EfficientNet-Lite │ ├── nanodet-EfficientNet-Lite0_320.yml │ ├── nanodet-EfficientNet-Lite1_416.yml │ └── nanodet-EfficientNet-Lite2_512.yml ├── RepVGG │ └── nanodet-RepVGG-A0_416.yml ├── Transformer │ └── nanodet-t.yml ├── nanodet-g-mod.yml ├── nanodet-m-416.yml ├── nanodet-m-640-mod.yml ├── nanodet-m.yml └── nanodet_custom_xml_dataset.yml ├── demo ├── demo-inference-with-pytorch.ipynb └── demo.py ├── demo_android_ncnn ├── .gitignore ├── Android_demo.jpg ├── LICENSE ├── README.md ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── rangi │ │ │ └── nanodet │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── NanoDet.cpp │ │ │ ├── NanoDet.h │ │ │ ├── YoloV4.cpp │ │ │ ├── YoloV4.h │ │ │ ├── YoloV5.cpp │ │ │ ├── YoloV5.h │ │ │ └── jni_interface.cpp │ │ ├── java │ │ │ └── com │ │ │ │ └── rangi │ │ │ │ └── nanodet │ │ │ │ ├── AppCrashHandler.java │ │ │ │ ├── Box.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── NanoDet.java │ │ │ │ ├── NcnnApp.java │ │ │ │ ├── WelcomeActivity.java │ │ │ │ ├── YOLOv4.java │ │ │ │ └── YOLOv5.java │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable-xxhdpi │ │ │ ├── cpu.png │ │ │ ├── gpu.png │ │ │ └── ncnn_icon.png │ │ │ ├── drawable │ │ │ ├── cpu_gpu_bg.xml │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ └── activity_welcome.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── rangi │ │ └── nanodet │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── demo_libtorch ├── CMakeLists.txt ├── README.md ├── main.cpp ├── nanodet_libtorch.cpp └── nanodet_libtorch.h ├── demo_mnn ├── CMakeLists.txt ├── README.md ├── imgs │ ├── 000252.jpg │ └── 000258.jpg ├── main.cpp ├── nanodet_mnn.cpp ├── nanodet_mnn.hpp ├── python │ └── demo_mnn.py └── results │ ├── 000252.jpg │ └── 000258.jpg ├── demo_ncnn ├── CMakeLists.txt ├── README.md ├── benchmark.jpg ├── main.cpp ├── nanodet.cpp ├── nanodet.h └── python │ └── demo_ncnn.py ├── demo_openvino ├── CMakeLists.txt ├── README.md ├── main.cpp ├── nanodet_openvino.cpp └── nanodet_openvino.h ├── docs ├── config_file_detail.md └── imgs │ ├── Android_demo.jpg │ ├── Model_arch.png │ └── Title.jpg ├── nanodet ├── data │ ├── collate.py │ ├── dataset │ │ ├── __init__.py │ │ ├── base.py │ │ ├── coco.py │ │ └── xml_dataset.py │ └── transform │ │ ├── __init__.py │ │ ├── color.py │ │ ├── mosaic.py │ │ ├── pipeline.py │ │ └── warp.py ├── evaluator │ ├── __init__.py │ └── coco_detection.py ├── model │ ├── arch │ │ ├── __init__.py │ │ └── one_stage_detector.py │ ├── backbone │ │ ├── __init__.py │ │ ├── custom_csp.py │ │ ├── efficientnet_lite.py │ │ ├── ghostnet.py │ │ ├── mobilenetv2.py │ │ ├── repvgg.py │ │ ├── resnet.py │ │ └── shufflenetv2.py │ ├── fpn │ │ ├── __init__.py │ │ ├── fpn.py │ │ ├── pan.py │ │ └── tan.py │ ├── head │ │ ├── __init__.py │ │ ├── assigner │ │ │ ├── assign_result.py │ │ │ ├── atss_assigner.py │ │ │ └── base_assigner.py │ │ ├── gfl_head.py │ │ └── nanodet_head.py │ ├── loss │ │ ├── gfocal_loss.py │ │ ├── iou_loss.py │ │ └── utils.py │ └── module │ │ ├── activation.py │ │ ├── conv.py │ │ ├── init_weights.py │ │ ├── nms.py │ │ ├── norm.py │ │ ├── scale.py │ │ └── transformer.py ├── trainer │ ├── __init__.py │ ├── dist_trainer.py │ ├── task.py │ └── trainer.py └── util │ ├── __init__.py │ ├── box_transform.py │ ├── check_point.py │ ├── config.py │ ├── data_parallel.py │ ├── distributed_data_parallel.py │ ├── flops_counter.py │ ├── logger.py │ ├── misc.py │ ├── path.py │ ├── rank_filter.py │ ├── scatter_gather.py │ ├── util_mixins.py │ ├── visualization.py │ └── yacs.py ├── requirements.txt ├── setup.py └── tools ├── convert_old_checkpoint.py ├── deprecated ├── test.py └── train.py ├── export_onnx.py ├── export_torchscript.py ├── flops.py ├── inference.py ├── show_dataset.py ├── test.py └── train.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | workspace/ 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | .vscode 107 | .idea 108 | .DS_Store 109 | 110 | # custom 111 | *.pkl 112 | *.pkl.json 113 | *.log.json 114 | work_dirs/ 115 | 116 | # Pytorch 117 | *.pth 118 | *.py~ 119 | *.sh~ 120 | -------------------------------------------------------------------------------- /config/EfficientNet-Lite/nanodet-EfficientNet-Lite0_320.yml: -------------------------------------------------------------------------------- 1 | # nanodet-EfficientNet-Lite0_320 2 | # COCO mAP(0.5:0.95) = 0.247 3 | # AP_50 = 0.404 4 | # AP_75 = 0.250 5 | # AP_small = 0.079 6 | # AP_m = 0.243 7 | # AP_l = 0.406 8 | save_dir: workspace/efficient0_320 9 | model: 10 | arch: 11 | name: OneStageDetector 12 | backbone: 13 | name: EfficientNetLite 14 | model_name: efficientnet_lite0 15 | out_stages: [2,4,6] 16 | activation: ReLU6 17 | fpn: 18 | name: PAN 19 | in_channels: [40, 112, 320] 20 | out_channels: 96 21 | start_level: 0 22 | num_outs: 3 23 | head: 24 | name: NanoDetHead 25 | num_classes: 80 26 | input_channel: 96 27 | feat_channels: 96 28 | activation: ReLU6 29 | stacked_convs: 2 30 | share_cls_reg: True 31 | octave_base_scale: 5 32 | scales_per_octave: 1 33 | strides: [8, 16, 32] 34 | reg_max: 7 35 | norm_cfg: 36 | type: BN 37 | loss: 38 | loss_qfl: 39 | name: QualityFocalLoss 40 | use_sigmoid: True 41 | beta: 2.0 42 | loss_weight: 1.0 43 | loss_dfl: 44 | name: DistributionFocalLoss 45 | loss_weight: 0.25 46 | loss_bbox: 47 | name: GIoULoss 48 | loss_weight: 2.0 49 | data: 50 | train: 51 | name: coco 52 | img_path: /coco/train2017 53 | ann_path: /coco/annotations/instances_train2017.json 54 | input_size: [320,320] #[w,h] 55 | keep_ratio: True 56 | pipeline: 57 | perspective: 0.0 58 | scale: [0.6, 1.4] 59 | stretch: [[1, 1], [1, 1]] 60 | rotation: 0 61 | shear: 0 62 | translate: 0.2 63 | flip: 0.5 64 | brightness: 0.2 65 | contrast: [0.6, 1.4] 66 | saturation: [0.5, 1.2] 67 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 68 | val: 69 | name: coco 70 | img_path: /coco/val2017 71 | ann_path: /coco/annotations/instances_val2017.json 72 | input_size: [320,320] #[w,h] 73 | keep_ratio: True 74 | pipeline: 75 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 76 | device: 77 | gpu_ids: [0] 78 | workers_per_gpu: 12 79 | batchsize_per_gpu: 150 80 | schedule: 81 | # resume: 82 | # load_model: YOUR_MODEL_PATH 83 | optimizer: 84 | name: SGD 85 | lr: 0.15 86 | momentum: 0.9 87 | weight_decay: 0.0001 88 | warmup: 89 | name: linear 90 | steps: 500 91 | ratio: 0.01 92 | total_epochs: 190 93 | lr_schedule: 94 | name: MultiStepLR 95 | milestones: [140,170,180,185] 96 | gamma: 0.1 97 | val_intervals: 1 98 | evaluator: 99 | name: CocoDetectionEvaluator 100 | save_key: mAP 101 | 102 | log: 103 | interval: 10 104 | 105 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 106 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 107 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 108 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 109 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 110 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 111 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 112 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 113 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 114 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 115 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 116 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 117 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 118 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 119 | -------------------------------------------------------------------------------- /config/EfficientNet-Lite/nanodet-EfficientNet-Lite1_416.yml: -------------------------------------------------------------------------------- 1 | # nanodet-EfficientNet-Lite1_416 2 | # COCO mAP(0.5:0.95) = 0.303 3 | # AP_50 = 0.471 4 | # AP_75 = 0.313 5 | # AP_small = 0.122 6 | # AP_m = 0.321 7 | # AP_l = 0.432 8 | save_dir: workspace/efficient1_416_SGD 9 | model: 10 | arch: 11 | name: OneStageDetector 12 | backbone: 13 | name: EfficientNetLite 14 | model_name: efficientnet_lite1 15 | out_stages: [2,4,6] 16 | activation: ReLU6 17 | pretrain: True 18 | fpn: 19 | name: PAN 20 | in_channels: [40, 112, 320] 21 | out_channels: 128 22 | start_level: 0 23 | num_outs: 3 24 | head: 25 | name: NanoDetHead 26 | num_classes: 80 27 | input_channel: 128 28 | feat_channels: 128 29 | stacked_convs: 3 30 | activation: ReLU6 31 | share_cls_reg: True 32 | octave_base_scale: 8 33 | scales_per_octave: 1 34 | strides: [8, 16, 32] 35 | reg_max: 10 36 | norm_cfg: 37 | type: BN 38 | loss: 39 | loss_qfl: 40 | name: QualityFocalLoss 41 | use_sigmoid: True 42 | beta: 2.0 43 | loss_weight: 1.0 44 | loss_dfl: 45 | name: DistributionFocalLoss 46 | loss_weight: 0.25 47 | loss_bbox: 48 | name: GIoULoss 49 | loss_weight: 2.0 50 | data: 51 | train: 52 | name: coco 53 | img_path: /coco/train2017 54 | ann_path: /coco/annotations/instances_train2017.json 55 | input_size: [416,416] #[w,h] 56 | keep_ratio: True 57 | pipeline: 58 | perspective: 0.0 59 | scale: [0.5, 1.5] 60 | stretch: [[1, 1], [1, 1]] 61 | rotation: 0 62 | shear: 0 63 | translate: 0.2 64 | flip: 0.5 65 | brightness: 0.2 66 | contrast: [0.6, 1.4] 67 | saturation: [0.5, 1.2] 68 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 69 | val: 70 | name: coco 71 | img_path: /coco/val2017 72 | ann_path: /coco/annotations/instances_val2017.json 73 | input_size: [416,416] #[w,h] 74 | keep_ratio: True 75 | pipeline: 76 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 77 | device: 78 | gpu_ids: [0] 79 | workers_per_gpu: 12 80 | batchsize_per_gpu: 100 81 | schedule: 82 | # resume: 83 | # load_model: YOUR_MODEL_PATH 84 | optimizer: 85 | name: SGD 86 | lr: 0.07 87 | momentum: 0.9 88 | weight_decay: 0.0001 89 | warmup: 90 | name: linear 91 | steps: 500 92 | ratio: 0.01 93 | total_epochs: 170 94 | lr_schedule: 95 | name: MultiStepLR 96 | milestones: [130,150,160,165] 97 | gamma: 0.1 98 | val_intervals: 5 99 | evaluator: 100 | name: CocoDetectionEvaluator 101 | save_key: mAP 102 | 103 | log: 104 | interval: 10 105 | 106 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 107 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 108 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 109 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 110 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 111 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 112 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 113 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 114 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 115 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 116 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 117 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 118 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 119 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 120 | -------------------------------------------------------------------------------- /config/EfficientNet-Lite/nanodet-EfficientNet-Lite2_512.yml: -------------------------------------------------------------------------------- 1 | # nanodet-EfficientNet-Lite2_512 2 | # COCO mAP(0.5:0.95) = 0.326 3 | # AP_50 = 0.501 4 | # AP_75 = 0.344 5 | # AP_small = 0.152 6 | # AP_m = 0.342 7 | # AP_l = 0.481 8 | save_dir: workspace/efficientlite2_512 9 | model: 10 | arch: 11 | name: OneStageDetector 12 | backbone: 13 | name: EfficientNetLite 14 | model_name: efficientnet_lite2 15 | out_stages: [2,4,6] 16 | activation: ReLU6 17 | pretrain: True 18 | fpn: 19 | name: PAN 20 | in_channels: [48, 120, 352] 21 | out_channels: 128 22 | start_level: 0 23 | num_outs: 3 24 | head: 25 | name: NanoDetHead 26 | num_classes: 80 27 | input_channel: 128 28 | feat_channels: 128 29 | stacked_convs: 4 30 | activation: ReLU6 31 | share_cls_reg: True 32 | octave_base_scale: 5 33 | scales_per_octave: 1 34 | strides: [8, 16, 32] 35 | reg_max: 10 36 | norm_cfg: 37 | type: BN 38 | loss: 39 | loss_qfl: 40 | name: QualityFocalLoss 41 | use_sigmoid: True 42 | beta: 2.0 43 | loss_weight: 1.0 44 | loss_dfl: 45 | name: DistributionFocalLoss 46 | loss_weight: 0.25 47 | loss_bbox: 48 | name: GIoULoss 49 | loss_weight: 2.0 50 | data: 51 | train: 52 | name: coco 53 | img_path: /coco/train2017 54 | ann_path: /coco/annotations/instances_train2017.json 55 | input_size: [512,512] #[w,h] 56 | keep_ratio: True 57 | pipeline: 58 | perspective: 0.0 59 | scale: [0.5, 1.5] 60 | stretch: [[1, 1], [1, 1]] 61 | rotation: 0 62 | shear: 0 63 | translate: 0.2 64 | flip: 0.5 65 | brightness: 0.2 66 | contrast: [0.6, 1.4] 67 | saturation: [0.5, 1.2] 68 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 69 | val: 70 | name: coco 71 | img_path: /coco/val2017 72 | ann_path: /coco/annotations/instances_val2017.json 73 | input_size: [512,512] #[w,h] 74 | keep_ratio: True 75 | pipeline: 76 | normalize: [[127.0, 127.0, 127.0], [128.0, 128.0, 128.0]] 77 | device: 78 | gpu_ids: [0] 79 | workers_per_gpu: 12 80 | batchsize_per_gpu: 60 81 | schedule: 82 | # resume: 83 | # load_model: YOUR_MODEL_PATH 84 | optimizer: 85 | name: SGD 86 | lr: 0.06 87 | momentum: 0.9 88 | weight_decay: 0.0001 89 | warmup: 90 | name: linear 91 | steps: 300 92 | ratio: 0.1 93 | total_epochs: 135 94 | lr_schedule: 95 | name: MultiStepLR 96 | milestones: [90,110,120,130] 97 | gamma: 0.1 98 | val_intervals: 5 99 | evaluator: 100 | name: CocoDetectionEvaluator 101 | save_key: mAP 102 | 103 | log: 104 | interval: 10 105 | 106 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 107 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 108 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 109 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 110 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 111 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 112 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 113 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 114 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 115 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 116 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 117 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 118 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 119 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 120 | -------------------------------------------------------------------------------- /config/RepVGG/nanodet-RepVGG-A0_416.yml: -------------------------------------------------------------------------------- 1 | # nanodet-EfficientNet-Lite1_416 2 | save_dir: workspace/RepVGG-A0-416 3 | model: 4 | arch: 5 | name: OneStageDetector 6 | backbone: 7 | name: RepVGG 8 | arch: A0 9 | out_stages: [2,3,4] 10 | activation: ReLU 11 | last_channel: 512 12 | deploy: False 13 | fpn: 14 | name: PAN 15 | in_channels: [96, 192, 512] 16 | out_channels: 128 17 | start_level: 0 18 | num_outs: 3 19 | head: 20 | name: NanoDetHead 21 | num_classes: 80 22 | conv_type: Conv 23 | input_channel: 128 24 | feat_channels: 128 25 | stacked_convs: 2 26 | activation: ReLU 27 | share_cls_reg: True 28 | octave_base_scale: 8 29 | scales_per_octave: 1 30 | strides: [8, 16, 32] 31 | reg_max: 10 32 | norm_cfg: 33 | type: BN 34 | loss: 35 | loss_qfl: 36 | name: QualityFocalLoss 37 | use_sigmoid: True 38 | beta: 2.0 39 | loss_weight: 1.0 40 | loss_dfl: 41 | name: DistributionFocalLoss 42 | loss_weight: 0.25 43 | loss_bbox: 44 | name: GIoULoss 45 | loss_weight: 2.0 46 | data: 47 | train: 48 | name: coco 49 | img_path: /coco/train2017 50 | ann_path: /coco/annotations/instances_train2017.json 51 | input_size: [416,416] #[w,h] 52 | keep_ratio: True 53 | pipeline: 54 | perspective: 0.0 55 | scale: [0.5, 1.5] 56 | stretch: [[1, 1], [1, 1]] 57 | rotation: 0 58 | shear: 0 59 | translate: 0.2 60 | flip: 0.5 61 | brightness: 0.2 62 | contrast: [0.6, 1.4] 63 | saturation: [0.5, 1.2] 64 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 65 | val: 66 | name: coco 67 | img_path: /coco/val2017 68 | ann_path: /coco/annotations/instances_val2017.json 69 | input_size: [416,416] #[w,h] 70 | keep_ratio: True 71 | pipeline: 72 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 73 | device: 74 | gpu_ids: [0] 75 | workers_per_gpu: 1 76 | batchsize_per_gpu: 100 77 | schedule: 78 | # resume: 79 | # load_model: YOUR_MODEL_PATH 80 | optimizer: 81 | name: SGD 82 | lr: 0.07 83 | momentum: 0.9 84 | weight_decay: 0.0001 85 | warmup: 86 | name: linear 87 | steps: 500 88 | ratio: 0.01 89 | total_epochs: 170 90 | lr_schedule: 91 | name: MultiStepLR 92 | milestones: [130,150,160,165] 93 | gamma: 0.1 94 | val_intervals: 5 95 | evaluator: 96 | name: CocoDetectionEvaluator 97 | save_key: mAP 98 | 99 | log: 100 | interval: 10 101 | 102 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 103 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 104 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 105 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 106 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 107 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 108 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 109 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 110 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 111 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 112 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 113 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 114 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 115 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 116 | -------------------------------------------------------------------------------- /config/Transformer/nanodet-t.yml: -------------------------------------------------------------------------------- 1 | # NanoDet-m with transformer attention 2 | # COCO mAP(0.5:0.95) = 0.217 3 | # AP_50 = 0.363 4 | # AP_75 = 0.218 5 | # AP_small = 0.069 6 | # AP_m = 0.214 7 | # AP_l = 0.364 8 | 9 | save_dir: workspace/nanodet_t 10 | model: 11 | arch: 12 | name: OneStageDetector 13 | backbone: 14 | name: ShuffleNetV2 15 | model_size: 1.0x 16 | out_stages: [2,3,4] 17 | activation: LeakyReLU 18 | fpn: 19 | name: TAN # transformer attention network 20 | in_channels: [116, 232, 464] 21 | out_channels: 128 22 | feature_hw: [20,20] # size for position embedding 23 | num_heads: 8 24 | num_encoders: 1 25 | mlp_ratio: 4 26 | dropout_ratio: 0.1 27 | activation: LeakyReLU 28 | head: 29 | name: NanoDetHead 30 | num_classes: 80 31 | input_channel: 128 32 | feat_channels: 128 33 | stacked_convs: 2 34 | share_cls_reg: True 35 | octave_base_scale: 5 36 | scales_per_octave: 1 37 | strides: [8, 16, 32] 38 | reg_max: 7 39 | norm_cfg: 40 | type: BN 41 | loss: 42 | loss_qfl: 43 | name: QualityFocalLoss 44 | use_sigmoid: True 45 | beta: 2.0 46 | loss_weight: 1.0 47 | loss_dfl: 48 | name: DistributionFocalLoss 49 | loss_weight: 0.25 50 | loss_bbox: 51 | name: GIoULoss 52 | loss_weight: 2.0 53 | data: 54 | train: 55 | name: coco 56 | img_path: coco/train2017 57 | ann_path: coco/annotations/instances_train2017.json 58 | input_size: [320,320] #[w,h] 59 | keep_ratio: True 60 | pipeline: 61 | perspective: 0.0 62 | scale: [0.6, 1.4] 63 | stretch: [[1, 1], [1, 1]] 64 | rotation: 0 65 | shear: 0 66 | translate: 0.2 67 | flip: 0.5 68 | brightness: 0.2 69 | contrast: [0.8, 1.2] 70 | saturation: [0.8, 1.2] 71 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 72 | val: 73 | name: coco 74 | img_path: coco/val2017 75 | ann_path: coco/annotations/instances_val2017.json 76 | input_size: [320,320] #[w,h] 77 | keep_ratio: True 78 | pipeline: 79 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 80 | device: 81 | gpu_ids: [0] 82 | workers_per_gpu: 8 83 | batchsize_per_gpu: 160 84 | schedule: 85 | resume: 86 | # load_model: YOUR_MODEL_PATH 87 | optimizer: 88 | name: SGD 89 | lr: 0.14 90 | momentum: 0.9 91 | weight_decay: 0.0001 92 | warmup: 93 | name: linear 94 | steps: 500 95 | ratio: 0.01 96 | total_epochs: 190 97 | lr_schedule: 98 | name: MultiStepLR 99 | milestones: [140,170,180,185] 100 | gamma: 0.1 101 | val_intervals: 10 102 | evaluator: 103 | name: CocoDetectionEvaluator 104 | save_key: mAP 105 | 106 | log: 107 | interval: 10 108 | 109 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 110 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 111 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 112 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 113 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 114 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 115 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 116 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 117 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 118 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 119 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 120 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 121 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 122 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 123 | -------------------------------------------------------------------------------- /config/nanodet-g-mod.yml: -------------------------------------------------------------------------------- 1 | # NanoDet-g-416 is designed for edge NPU, GPU or TPU with high parallel computing power but low memory bandwidth 2 | # COCO mAP(0.5:0.95) = 22.9 3 | # Flops = 4.2B 4 | # Params = 3.8M 5 | # COCO pre-trained weight link: https://drive.google.com/file/d/10uW7oqZKw231l_tr4C1bJWkbCXgBf7av/view?usp=sharing 6 | save_dir: workspace/rmcv1 7 | model: 8 | arch: 9 | name: OneStageDetector 10 | backbone: 11 | name: CustomCspNet 12 | net_cfg: [[ 'Conv', 3, 32, 3, 2], # 1/2 13 | [ 'MaxPool', 3, 2 ], # 1/4 14 | [ 'CspBlock', 32, 1, 3, 1 ], # 1/4 15 | [ 'CspBlock', 64, 2, 3, 2 ], # 1/8 16 | [ 'CspBlock', 128, 2, 3, 2 ], # 1/16 17 | [ 'CspBlock', 256, 3, 3, 2 ]] # 1/32 18 | out_stages: [3,4,5] 19 | activation: LeakyReLU 20 | fpn: 21 | name: PAN 22 | in_channels: [128, 256, 512] 23 | out_channels: 128 24 | start_level: 0 25 | num_outs: 3 26 | head: 27 | name: NanoDetHead 28 | num_classes: 18 29 | conv_type: Conv 30 | activation: LeakyReLU 31 | input_channel: 128 32 | feat_channels: 128 33 | stacked_convs: 1 34 | share_cls_reg: True 35 | octave_base_scale: 8 36 | scales_per_octave: 1 37 | strides: [8, 16, 32] 38 | reg_max: 10 39 | norm_cfg: 40 | type: BN 41 | loss: 42 | loss_qfl: 43 | name: QualityFocalLoss 44 | use_sigmoid: True 45 | beta: 2.0 46 | loss_weight: 1.0 47 | loss_dfl: 48 | name: DistributionFocalLoss 49 | loss_weight: 0.25 50 | loss_bbox: 51 | name: GIoULoss 52 | loss_weight: 2.0 53 | data: 54 | train: 55 | name: coco 56 | img_path: ../rmcv_yolo/images 57 | ann_path: ../rmcv_yolo/annotations/train.json 58 | input_size: [416,416] #[w,h] 59 | keep_ratio: True 60 | load_mosaic: True 61 | mixup: True 62 | pipeline: 63 | perspective: 0.0002 64 | scale: [0.5, 1.5] 65 | stretch: [[1, 1], [1, 1]] 66 | rotation: 5 67 | shear: 3 68 | gamma: [0.5,1.7] 69 | translate: 0.1 70 | flip: 0.5 71 | hsv_h: 0.0138 72 | hsv_s: 0.464 73 | hsv_v: 0.464 74 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 75 | val: 76 | name: coco 77 | img_path: ../rmcv_yolo/images 78 | ann_path: ../rmcv_yolo/annotations/val.json 79 | input_size: [416,416] #[w,h] 80 | keep_ratio: True 81 | pipeline: 82 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 83 | device: 84 | gpu_ids: [0] 85 | workers_per_gpu: 4 86 | batchsize_per_gpu: 128 87 | schedule: 88 | # resume: 89 | load_model: model_0.01.ckpt 90 | optimizer: 91 | name: SGD 92 | lr: 0.003 93 | momentum: 0.843 94 | weight_decay: 0.00036 95 | warmup: 96 | name: linear 97 | steps: 500 98 | ratio: 0.01 99 | total_epochs: 50 100 | lr_schedule: 101 | name: MultiStepLR 102 | milestones: [30,45] 103 | gamma: 0.1 104 | val_intervals: 1 105 | evaluator: 106 | name: CocoDetectionEvaluator 107 | save_key: mAP 108 | 109 | log: 110 | interval: 10 111 | 112 | class_names: ['R1', 'B1', 'R2', 'B2', 'R3', 'B3', 'R4', 'B4','R5', 'B5', 'R7', 'B7', 'R10', 'B10', 'R11', 'B11', 'RE', 'BE'] 113 | 114 | -------------------------------------------------------------------------------- /config/nanodet-m-416.yml: -------------------------------------------------------------------------------- 1 | #nanodet-m-416 2 | # COCO mAP(0.5:0.95) = 0.235 3 | # AP_50 = 0.384 4 | # AP_75 = 0.242 5 | # AP_small = 0.082 6 | # AP_m = 0.240 7 | # AP_l = 0.375 8 | save_dir: workspace/nanodet_m_416 9 | model: 10 | arch: 11 | name: OneStageDetector 12 | backbone: 13 | name: ShuffleNetV2 14 | model_size: 1.0x 15 | out_stages: [2,3,4] 16 | activation: LeakyReLU 17 | fpn: 18 | name: PAN 19 | in_channels: [116, 232, 464] 20 | out_channels: 96 21 | start_level: 0 22 | num_outs: 3 23 | head: 24 | name: NanoDetHead 25 | num_classes: 80 26 | input_channel: 96 27 | feat_channels: 96 28 | stacked_convs: 2 29 | share_cls_reg: True 30 | octave_base_scale: 5 31 | scales_per_octave: 1 32 | strides: [8, 16, 32] 33 | reg_max: 7 34 | norm_cfg: 35 | type: BN 36 | loss: 37 | loss_qfl: 38 | name: QualityFocalLoss 39 | use_sigmoid: True 40 | beta: 2.0 41 | loss_weight: 1.0 42 | loss_dfl: 43 | name: DistributionFocalLoss 44 | loss_weight: 0.25 45 | loss_bbox: 46 | name: GIoULoss 47 | loss_weight: 2.0 48 | data: 49 | train: 50 | name: coco 51 | img_path: coco/train2017 52 | ann_path: coco/annotations/instances_train2017.json 53 | input_size: [416,416] #[w,h] 54 | keep_ratio: True 55 | pipeline: 56 | perspective: 0.0 57 | scale: [0.5, 1.4] 58 | stretch: [[1, 1], [1, 1]] 59 | rotation: 0 60 | shear: 0 61 | translate: 0.2 62 | flip: 0.5 63 | brightness: 0.2 64 | contrast: [0.6, 1.4] 65 | saturation: [0.5, 1.2] 66 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 67 | val: 68 | name: coco 69 | img_path: coco/val2017 70 | ann_path: coco/annotations/instances_val2017.json 71 | input_size: [416,416] #[w,h] 72 | keep_ratio: True 73 | pipeline: 74 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 75 | device: 76 | gpu_ids: [0] 77 | workers_per_gpu: 8 78 | batchsize_per_gpu: 192 79 | schedule: 80 | # resume: 81 | # load_model: YOUR_MODEL_PATH 82 | optimizer: 83 | name: SGD 84 | lr: 0.14 85 | momentum: 0.9 86 | weight_decay: 0.0001 87 | warmup: 88 | name: linear 89 | steps: 300 90 | ratio: 0.1 91 | total_epochs: 280 92 | lr_schedule: 93 | name: MultiStepLR 94 | milestones: [240,260,275] 95 | gamma: 0.1 96 | val_intervals: 10 97 | evaluator: 98 | name: CocoDetectionEvaluator 99 | save_key: mAP 100 | 101 | log: 102 | interval: 10 103 | 104 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 105 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 106 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 107 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 108 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 109 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 110 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 111 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 112 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 113 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 114 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 115 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 116 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 117 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 118 | -------------------------------------------------------------------------------- /config/nanodet-m-640-mod.yml: -------------------------------------------------------------------------------- 1 | #nanodet-m-416 2 | # COCO mAP(0.5:0.95) = 0.235 3 | # AP_50 = 0.384 4 | # AP_75 = 0.242 5 | # AP_small = 0.082 6 | # AP_m = 0.240 7 | # AP_l = 0.375 8 | save_dir: workspace/rmcv_m 9 | model: 10 | arch: 11 | name: OneStageDetector 12 | backbone: 13 | name: ShuffleNetV2 14 | model_size: 1.0x 15 | out_stages: [2,3,4] 16 | activation: LeakyReLU 17 | fpn: 18 | name: PAN 19 | in_channels: [116, 232, 464] 20 | out_channels: 96 21 | start_level: 0 22 | num_outs: 3 23 | head: 24 | name: NanoDetHead 25 | num_classes: 18 26 | input_channel: 96 27 | feat_channels: 96 28 | stacked_convs: 2 29 | share_cls_reg: True 30 | octave_base_scale: 5 31 | scales_per_octave: 1 32 | strides: [8, 16, 32] 33 | reg_max: 7 34 | norm_cfg: 35 | type: BN 36 | loss: 37 | loss_qfl: 38 | name: QualityFocalLoss 39 | use_sigmoid: True 40 | beta: 2.0 41 | loss_weight: 1.0 42 | loss_dfl: 43 | name: DistributionFocalLoss 44 | loss_weight: 0.25 45 | loss_bbox: 46 | name: GIoULoss 47 | loss_weight: 2.0 48 | data: 49 | train: 50 | name: coco 51 | img_path: ../rmcv_yolo/images 52 | ann_path: ../rmcv_yolo/annotations/train.json 53 | input_size: [640,640] #[w,h] 54 | keep_ratio: True 55 | mixup: True 56 | load_mosaic: False 57 | pipeline: 58 | perspective: 0.0002 59 | scale: [0.5, 1.4] 60 | stretch: [[1, 1], [1, 1]] 61 | rotation: 5 62 | shear: 3 63 | translate: 0.1 64 | flip: 0.5 65 | hsv_h: 0.0138 66 | hsv_s: 0.464 67 | hsv_v: 0.464 68 | val: 69 | name: coco 70 | img_path: ../rmcv_yolo/images 71 | ann_path: ../rmcv_yolo/annotations/val.json 72 | input_size: [640,640] #[w,h] 73 | keep_ratio: True 74 | pipeline: 75 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 76 | device: 77 | gpu_ids: [0] 78 | workers_per_gpu: 8 79 | batchsize_per_gpu: 32 80 | schedule: 81 | resume: 82 | # load_model: nanodet_m.ckpt 83 | optimizer: 84 | name: SGD 85 | lr: 0.01 86 | momentum: 0.9 87 | weight_decay: 0.0001 88 | warmup: 89 | name: linear 90 | steps: 300 91 | ratio: 0.01 92 | total_epochs: 100 93 | lr_schedule: 94 | name: MultiStepLR 95 | milestones: [30,60,90] 96 | gamma: 0.1 97 | val_intervals: 2 98 | evaluator: 99 | name: CocoDetectionEvaluator 100 | save_key: mAP 101 | 102 | log: 103 | interval: 10 104 | 105 | class_names: ['R1', 'B1', 'R2', 'B2', 'R3', 'B3', 'R4', 'B4','R5', 'B5', 'R7', 'B7', 'R10', 'B10', 'R11', 'B11', 'RE', 'BE'] 106 | -------------------------------------------------------------------------------- /config/nanodet-m.yml: -------------------------------------------------------------------------------- 1 | #Config File example 2 | save_dir: workspace/nanodet_m 3 | model: 4 | arch: 5 | name: OneStageDetector 6 | backbone: 7 | name: ShuffleNetV2 8 | model_size: 1.0x 9 | out_stages: [2,3,4] 10 | activation: LeakyReLU 11 | fpn: 12 | name: PAN 13 | in_channels: [116, 232, 464] 14 | out_channels: 96 15 | start_level: 0 16 | num_outs: 3 17 | head: 18 | name: NanoDetHead 19 | num_classes: 80 20 | input_channel: 96 21 | feat_channels: 96 22 | stacked_convs: 2 23 | share_cls_reg: True 24 | octave_base_scale: 5 25 | scales_per_octave: 1 26 | strides: [8, 16, 32] 27 | reg_max: 7 28 | norm_cfg: 29 | type: BN 30 | loss: 31 | loss_qfl: 32 | name: QualityFocalLoss 33 | use_sigmoid: True 34 | beta: 2.0 35 | loss_weight: 1.0 36 | loss_dfl: 37 | name: DistributionFocalLoss 38 | loss_weight: 0.25 39 | loss_bbox: 40 | name: GIoULoss 41 | loss_weight: 2.0 42 | data: 43 | train: 44 | name: coco 45 | img_path: coco/train2017 46 | ann_path: coco/annotations/instances_train2017.json 47 | input_size: [320,320] #[w,h] 48 | keep_ratio: True 49 | pipeline: 50 | perspective: 0.0 51 | scale: [0.6, 1.4] 52 | stretch: [[1, 1], [1, 1]] 53 | rotation: 0 54 | shear: 0 55 | translate: 0.2 56 | flip: 0.5 57 | brightness: 0.2 58 | contrast: [0.8, 1.2] 59 | saturation: [0.8, 1.2] 60 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 61 | val: 62 | name: coco 63 | img_path: coco/val2017 64 | ann_path: coco/annotations/instances_val2017.json 65 | input_size: [320,320] #[w,h] 66 | keep_ratio: True 67 | pipeline: 68 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 69 | device: 70 | gpu_ids: [0] 71 | workers_per_gpu: 12 72 | batchsize_per_gpu: 160 73 | schedule: 74 | # resume: 75 | # load_model: YOUR_MODEL_PATH 76 | optimizer: 77 | name: SGD 78 | lr: 0.14 79 | momentum: 0.9 80 | weight_decay: 0.0001 81 | warmup: 82 | name: linear 83 | steps: 300 84 | ratio: 0.1 85 | total_epochs: 190 86 | lr_schedule: 87 | name: MultiStepLR 88 | milestones: [130,160,175,185] 89 | gamma: 0.1 90 | val_intervals: 10 91 | evaluator: 92 | name: CocoDetectionEvaluator 93 | save_key: mAP 94 | 95 | log: 96 | interval: 10 97 | 98 | class_names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 99 | 'train', 'truck', 'boat', 'traffic_light', 'fire_hydrant', 100 | 'stop_sign', 'parking_meter', 'bench', 'bird', 'cat', 'dog', 101 | 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 102 | 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 103 | 'skis', 'snowboard', 'sports_ball', 'kite', 'baseball_bat', 104 | 'baseball_glove', 'skateboard', 'surfboard', 'tennis_racket', 105 | 'bottle', 'wine_glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 106 | 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 107 | 'hot_dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 108 | 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv', 'laptop', 109 | 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave', 110 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 111 | 'vase', 'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'] 112 | -------------------------------------------------------------------------------- /config/nanodet_custom_xml_dataset.yml: -------------------------------------------------------------------------------- 1 | #Config File example 2 | save_dir: workspace/nanodet_m 3 | model: 4 | arch: 5 | name: OneStageDetector 6 | backbone: 7 | name: ShuffleNetV2 8 | model_size: 1.0x 9 | out_stages: [2,3,4] 10 | activation: LeakyReLU 11 | fpn: 12 | name: PAN 13 | in_channels: [116, 232, 464] 14 | out_channels: 96 15 | start_level: 0 16 | num_outs: 3 17 | head: 18 | name: NanoDetHead 19 | num_classes: 80 #Please fill in the number of categories (not include background category) 20 | input_channel: 96 21 | feat_channels: 96 22 | stacked_convs: 2 23 | share_cls_reg: True 24 | octave_base_scale: 5 25 | scales_per_octave: 1 26 | strides: [8, 16, 32] 27 | reg_max: 7 28 | norm_cfg: 29 | type: BN 30 | loss: 31 | loss_qfl: 32 | name: QualityFocalLoss 33 | use_sigmoid: True 34 | beta: 2.0 35 | loss_weight: 1.0 36 | loss_dfl: 37 | name: DistributionFocalLoss 38 | loss_weight: 0.25 39 | loss_bbox: 40 | name: GIoULoss 41 | loss_weight: 2.0 42 | 43 | class_names: &class_names ['NAME1', 'NAME2', 'NAME3', 'NAME4', '...'] #Please fill in the category names (not include background category) 44 | data: 45 | train: 46 | name: xml_dataset 47 | class_names: *class_names 48 | img_path: TRAIN_IMAGE_FOLDER #Please fill in train image path 49 | ann_path: TRAIN_XML_FOLDER #Please fill in train xml path 50 | input_size: [320,320] #[w,h] 51 | keep_ratio: True 52 | pipeline: 53 | perspective: 0.0 54 | scale: [0.6, 1.4] 55 | stretch: [[1, 1], [1, 1]] 56 | rotation: 0 57 | shear: 0 58 | translate: 0.2 59 | flip: 0.5 60 | brightness: 0.2 61 | contrast: [0.8, 1.2] 62 | saturation: [0.8, 1.2] 63 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 64 | val: 65 | name: xml_dataset 66 | class_names: *class_names 67 | img_path: VAL_IMAGE_FOLDER #Please fill in val image path 68 | ann_path: VAL_XML_FOLDER #Please fill in val xml path 69 | input_size: [320,320] #[w,h] 70 | keep_ratio: True 71 | pipeline: 72 | normalize: [[103.53, 116.28, 123.675], [57.375, 57.12, 58.395]] 73 | device: 74 | gpu_ids: [0] 75 | workers_per_gpu: 12 76 | batchsize_per_gpu: 160 77 | schedule: 78 | # resume: 79 | # load_model: YOUR_MODEL_PATH 80 | optimizer: 81 | name: SGD 82 | lr: 0.14 83 | momentum: 0.9 84 | weight_decay: 0.0001 85 | warmup: 86 | name: linear 87 | steps: 300 88 | ratio: 0.1 89 | total_epochs: 190 90 | lr_schedule: 91 | name: MultiStepLR 92 | milestones: [130,160,175,185] 93 | gamma: 0.1 94 | val_intervals: 10 95 | evaluator: 96 | name: CocoDetectionEvaluator 97 | save_key: mAP 98 | 99 | log: 100 | interval: 10 101 | -------------------------------------------------------------------------------- /demo_android_ncnn/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | /.idea/caches 6 | /.idea/libraries 7 | /.idea/modules.xml 8 | /.idea/workspace.xml 9 | /.idea/navEditor.xml 10 | /.idea/assetWizardSettings.xml 11 | .DS_Store 12 | /build 13 | /captures 14 | .externalNativeBuild 15 | .cxx 16 | -------------------------------------------------------------------------------- /demo_android_ncnn/Android_demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxnaive/nanodet-TensorRT/56ef43cef8a71202cab7536798b479382742c8b9/demo_android_ncnn/Android_demo.jpg -------------------------------------------------------------------------------- /demo_android_ncnn/README.md: -------------------------------------------------------------------------------- 1 | # NanoDet NCNN Android Demo 2 | 3 | This repo is an Android object detection demo of NanoDet using 4 | [Tencent's NCNN framework](https://github.com/Tencent/ncnn). 5 | 6 | # Tutorial 7 | 8 | ## Step1. 9 | Download ncnn-android-vulkan.zip from ncnn repo or build ncnn-android from source. 10 | 11 | - [ncnn-android-vulkan.zip download link](https://github.com/Tencent/ncnn/releases) 12 | 13 | ## Step2. 14 | Unzip ncnn-android-vulkan.zip into demo_android_ncnn/app/src/main/cpp or change the ncnn_DIR path to yours in demo_android_ncnn/app/src/main/cpp/CMakeLists.txt 15 | 16 | ## Step3. 17 | Copy the NanoDet ncnn model file (nanodet_m.param and nanodet_m.bin) from models folder into demo_android_ncnn/app/src/main/assets 18 | 19 | * [NanoDet ncnn model download link](https://github.com/RangiLyu/nanodet/releases/download/v0.0.1/nanodet_ncnn_model.zip) 20 | 21 | If you want to run yolov4-tiny and yolov5s, download them and also put in demo_android_ncnn/app/src/main/assets. 22 | 23 | * [Yolov4 and v5 ncnn model download link](https://drive.google.com/file/d/1Qk_1fDvOcFmNppDnaMFW-xFpMgLDyeAs/view?usp=sharing) 24 | 25 | ## Step4. 26 | Open demo_android_ncnn folder with Android Studio and then build it. 27 | 28 | # Screenshot 29 | ![](Android_demo.jpg) 30 | 31 | 32 | # Reference 33 | 34 | * [ncnn](https://github.com/tencent/ncnn) 35 | * [YOLOv5_NCNN](https://github.com/WZTENG/YOLOv5_NCNN) 36 | 37 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.3" 6 | defaultConfig { 7 | applicationId "com.rangi.nanodet" 8 | minSdkVersion 26 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | arguments '-DANDROID_PLATFORM=android-24', '-DANDROID_STL=c++_static', '-DANDROID_STL=c++_shared' 17 | } 18 | } 19 | 20 | ndk { 21 | moduleName "NcnnJniLog" 22 | ldLibs "log", "z", "m" 23 | abiFilters "armeabi-v7a", "arm64-v8a" 24 | } 25 | 26 | multiDexEnabled true 27 | } 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | externalNativeBuild { 35 | cmake { 36 | path "src/main/cpp/CMakeLists.txt" 37 | version "3.10.2" 38 | } 39 | } 40 | sourceSets { 41 | main { 42 | jniLibs.srcDirs = ['libs'] 43 | } 44 | } 45 | 46 | repositories { 47 | flatDir { 48 | dirs 'libs' 49 | } 50 | } 51 | } 52 | 53 | dependencies { 54 | implementation fileTree(dir: 'libs', include: ['*.jar']) 55 | implementation 'androidx.appcompat:appcompat:1.1.0' 56 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 57 | testImplementation 'junit:junit:4.12' 58 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 59 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 60 | 61 | // Use the most recent version of CameraX, currently that is alpha04 62 | def camerax_version = "1.0.0-alpha05" 63 | //noinspection GradleDependency 64 | implementation "androidx.camera:camera-core:${camerax_version}" 65 | //noinspection GradleDependency 66 | implementation "androidx.camera:camera-camera2:${camerax_version}" 67 | 68 | implementation 'com.android.support:multidex:1.0.3' 69 | // crash 70 | implementation 'com.zxy.android:recovery:1.0.0' 71 | // photoview 72 | implementation 'com.github.chrisbanes:PhotoView:2.3.0' 73 | // implementation 'com.bm.photoview:library:1.4.1' 74 | 75 | } 76 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/androidTest/java/com/rangi/nanodet/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("gd.hq.yolov5", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20201218-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn) 4 | find_package(ncnn REQUIRED) 5 | 6 | add_library(yolov5 SHARED 7 | jni_interface.cpp 8 | YoloV5.cpp 9 | YoloV4.cpp 10 | NanoDet.cpp 11 | ) 12 | 13 | target_link_libraries(yolov5 ncnn jnigraphics) 14 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/NanoDet.h: -------------------------------------------------------------------------------- 1 | // 2 | // Create by RangiLyu 3 | // 2020 / 10 / 2 4 | // 5 | 6 | #ifndef NANODET_H 7 | #define NANODET_H 8 | 9 | #include "net.h" 10 | #include "YoloV5.h" 11 | 12 | typedef struct HeadInfo 13 | { 14 | std::string cls_layer; 15 | std::string dis_layer; 16 | int stride; 17 | } HeadInfo; 18 | 19 | 20 | class NanoDet{ 21 | public: 22 | NanoDet(AAssetManager *mgr, const char *param, const char *bin, bool useGPU); 23 | 24 | ~NanoDet(); 25 | 26 | std::vector detect(JNIEnv *env, jobject image, float score_threshold, float nms_threshold); 27 | std::vector labels{"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", 28 | "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", 29 | "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", 30 | "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", 31 | "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", 32 | "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", 33 | "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", 34 | "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", 35 | "hair drier", "toothbrush"}; 36 | private: 37 | void preprocess(JNIEnv *env, jobject image, ncnn::Mat& in); 38 | void decode_infer(ncnn::Mat& cls_pred, ncnn::Mat& dis_pred, int stride, float threshold, std::vector>& results, float width_ratio, float height_ratio); 39 | BoxInfo disPred2Bbox(const float*& dfl_det, int label, float score, int x, int y, int stride, float width_ratio, float height_ratio); 40 | 41 | static void nms(std::vector& result, float nms_threshold); 42 | 43 | ncnn::Net *Net; 44 | int input_size = 320; 45 | int num_class = 80; 46 | int reg_max = 7; 47 | std::vector heads_info{ 48 | // cls_pred|dis_pred|stride 49 | {"cls_pred_stride_8", "dis_pred_stride_8", 8}, 50 | {"cls_pred_stride_16", "dis_pred_stride_16", 16}, 51 | {"cls_pred_stride_32", "dis_pred_stride_32", 32}, 52 | }; 53 | 54 | public: 55 | static NanoDet *detector; 56 | static bool hasGPU; 57 | }; 58 | 59 | 60 | #endif //NANODET_H 61 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/YoloV4.cpp: -------------------------------------------------------------------------------- 1 | #include "YoloV4.h" 2 | 3 | bool YoloV4::hasGPU = true; 4 | YoloV4 *YoloV4::detector = nullptr; 5 | 6 | YoloV4::YoloV4(AAssetManager *mgr, const char *param, const char *bin, bool useGPU) { 7 | Net = new ncnn::Net(); 8 | // opt 需要在加载前设置 9 | hasGPU = ncnn::get_gpu_count() > 0; 10 | Net->opt.use_vulkan_compute = hasGPU && useGPU; // gpu 11 | Net->opt.use_fp16_arithmetic = true; // fp16运算加速 12 | Net->load_param(mgr, param); 13 | Net->load_model(mgr, bin); 14 | } 15 | 16 | YoloV4::~YoloV4() { 17 | delete Net; 18 | } 19 | 20 | std::vector YoloV4::detect(JNIEnv *env, jobject image, float threshold, float nms_threshold) { 21 | AndroidBitmapInfo img_size; 22 | AndroidBitmap_getInfo(env, image, &img_size); 23 | ncnn::Mat in_net = ncnn::Mat::from_android_bitmap_resize(env, image, ncnn::Mat::PIXEL_RGBA2RGB, input_size, 24 | input_size); 25 | float norm[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; 26 | float mean[3] = {0, 0, 0}; 27 | in_net.substract_mean_normalize(mean, norm); 28 | auto ex = Net->create_extractor(); 29 | ex.set_light_mode(true); 30 | ex.set_num_threads(4); 31 | hasGPU = ncnn::get_gpu_count() > 0; 32 | ex.set_vulkan_compute(hasGPU); 33 | ex.input(0, in_net); 34 | std::vector result; 35 | ncnn::Mat blob; 36 | ex.extract("output", blob); 37 | auto boxes = decode_infer(blob, {(int) img_size.width, (int) img_size.height}, input_size, num_class, threshold); 38 | result.insert(result.begin(), boxes.begin(), boxes.end()); 39 | // nms(result,nms_threshold); 40 | return result; 41 | } 42 | 43 | inline float fast_exp(float x) { 44 | union { 45 | uint32_t i; 46 | float f; 47 | } v{}; 48 | v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f); 49 | return v.f; 50 | } 51 | 52 | inline float sigmoid(float x) { 53 | return 1.0f / (1.0f + fast_exp(-x)); 54 | } 55 | 56 | std::vector 57 | YoloV4::decode_infer(ncnn::Mat &data, const yolocv::YoloSize &frame_size, int net_size, int num_classes, float threshold) { 58 | std::vector result; 59 | for (int i = 0; i < data.h; i++) { 60 | BoxInfo box; 61 | const float *values = data.row(i); 62 | box.label = values[0] - 1; 63 | box.score = values[1]; 64 | box.x1 = values[2] * (float) frame_size.width; 65 | box.y1 = values[3] * (float) frame_size.height; 66 | box.x2 = values[4] * (float) frame_size.width; 67 | box.y2 = values[5] * (float) frame_size.height; 68 | result.push_back(box); 69 | } 70 | return result; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/YoloV4.h: -------------------------------------------------------------------------------- 1 | #ifndef YOLOV4_H 2 | #define YOLOV4_H 3 | 4 | #include "net.h" 5 | #include "YoloV5.h" 6 | 7 | 8 | class YoloV4 { 9 | public: 10 | YoloV4(AAssetManager *mgr, const char *param, const char *bin, bool useGPU); 11 | 12 | ~YoloV4(); 13 | 14 | std::vector detect(JNIEnv *env, jobject image, float threshold, float nms_threshold); 15 | std::vector labels{"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", 16 | "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", 17 | "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", 18 | "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", 19 | "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", 20 | "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", 21 | "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", 22 | "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", 23 | "hair drier", "toothbrush"}; 24 | private: 25 | static std::vector 26 | decode_infer(ncnn::Mat &data, const yolocv::YoloSize &frame_size, int net_size, int num_classes, float threshold); 27 | 28 | // static void nms(std::vector& result,float nms_threshold); 29 | ncnn::Net *Net; 30 | int input_size = 640 / 2; 31 | int num_class = 80; 32 | public: 33 | static YoloV4 *detector; 34 | static bool hasGPU; 35 | }; 36 | 37 | 38 | #endif //YOLOV4_H 39 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/YoloV5.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 邓昊晴 on 14/6/2020. 3 | // 4 | 5 | #ifndef YOLOV5_H 6 | #define YOLOV5_H 7 | 8 | #include "net.h" 9 | 10 | namespace yolocv { 11 | typedef struct { 12 | int width; 13 | int height; 14 | } YoloSize; 15 | } 16 | 17 | typedef struct { 18 | std::string name; 19 | int stride; 20 | std::vector anchors; 21 | } YoloLayerData; 22 | 23 | typedef struct BoxInfo { 24 | float x1; 25 | float y1; 26 | float x2; 27 | float y2; 28 | float score; 29 | int label; 30 | } BoxInfo; 31 | 32 | class YoloV5 { 33 | public: 34 | YoloV5(AAssetManager *mgr, const char *param, const char *bin, bool useGPU); 35 | 36 | ~YoloV5(); 37 | 38 | std::vector detect(JNIEnv *env, jobject image, float threshold, float nms_threshold); 39 | std::vector labels{"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", 40 | "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", 41 | "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", 42 | "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", 43 | "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", 44 | "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", 45 | "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", 46 | "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", 47 | "hair drier", "toothbrush"}; 48 | private: 49 | static std::vector 50 | decode_infer(ncnn::Mat &data, int stride, const yolocv::YoloSize &frame_size, int net_size, int num_classes, 51 | const std::vector &anchors, float threshold); 52 | 53 | static void nms(std::vector &result, float nms_threshold); 54 | 55 | ncnn::Net *Net; 56 | int input_size = 640; 57 | int num_class = 80; 58 | std::vector layers{ 59 | {"394", 32, {{116, 90}, {156, 198}, {373, 326}}}, 60 | {"375", 16, {{30, 61}, {62, 45}, {59, 119}}}, 61 | {"output", 8, {{10, 13}, {16, 30}, {33, 23}}}, 62 | }; 63 | 64 | public: 65 | static YoloV5 *detector; 66 | static bool hasGPU; 67 | }; 68 | 69 | 70 | #endif //YOLOV5_H 71 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/cpp/jni_interface.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "YoloV5.h" 7 | #include "YoloV4.h" 8 | #include "NanoDet.h" 9 | 10 | 11 | JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { 12 | ncnn::create_gpu_instance(); 13 | if (ncnn::get_gpu_count() > 0) { 14 | YoloV5::hasGPU = true; 15 | YoloV4::hasGPU = true; 16 | NanoDet::hasGPU = true; 17 | } 18 | return JNI_VERSION_1_6; 19 | } 20 | 21 | JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) { 22 | ncnn::destroy_gpu_instance(); 23 | } 24 | 25 | 26 | /********************************************************************************************* 27 | NanoDet 28 | ********************************************************************************************/ 29 | 30 | extern "C" JNIEXPORT void JNICALL 31 | Java_com_rangi_nanodet_NanoDet_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { 32 | if (NanoDet::detector == nullptr) { 33 | AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); 34 | NanoDet::detector = new NanoDet(mgr, "nanodet_m.param", "nanodet_m.bin", useGPU); 35 | } 36 | } 37 | 38 | extern "C" JNIEXPORT jobjectArray JNICALL 39 | Java_com_rangi_nanodet_NanoDet_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { 40 | auto result = NanoDet::detector->detect(env, image, threshold, nms_threshold); 41 | 42 | auto box_cls = env->FindClass("com/rangi/nanodet/Box"); 43 | auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); 44 | jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); 45 | int i = 0; 46 | for (auto &box:result) { 47 | env->PushLocalFrame(1); 48 | jobject obj = env->NewObject(box_cls, cid, box.x1, box.y1, box.x2, box.y2, box.label, box.score); 49 | obj = env->PopLocalFrame(obj); 50 | env->SetObjectArrayElement(ret, i++, obj); 51 | } 52 | return ret; 53 | } 54 | 55 | /********************************************************************************************* 56 | Yolov5 57 | ********************************************************************************************/ 58 | extern "C" JNIEXPORT void JNICALL 59 | Java_com_rangi_nanodet_YOLOv5_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { 60 | if (YoloV5::detector == nullptr) { 61 | AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); 62 | YoloV5::detector = new YoloV5(mgr, "yolov5.param", "yolov5.bin", useGPU); 63 | } 64 | } 65 | 66 | extern "C" JNIEXPORT jobjectArray JNICALL 67 | Java_com_rangi_nanodet_YOLOv5_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { 68 | auto result = YoloV5::detector->detect(env, image, threshold, nms_threshold); 69 | 70 | auto box_cls = env->FindClass("com/rangi/nanodet/Box"); 71 | auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); 72 | jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); 73 | int i = 0; 74 | for (auto &box:result) { 75 | env->PushLocalFrame(1); 76 | jobject obj = env->NewObject(box_cls, cid, box.x1, box.y1, box.x2, box.y2, box.label, box.score); 77 | obj = env->PopLocalFrame(obj); 78 | env->SetObjectArrayElement(ret, i++, obj); 79 | } 80 | return ret; 81 | } 82 | 83 | /********************************************************************************************* 84 | YOLOv4-tiny 85 | ********************************************************************************************/ 86 | extern "C" JNIEXPORT void JNICALL 87 | Java_com_rangi_nanodet_YOLOv4_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { 88 | if (YoloV4::detector == nullptr) { 89 | AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); 90 | YoloV4::detector = new YoloV4(mgr, "yolov4-tiny-opt.param", "yolov4-tiny-opt.bin", useGPU); 91 | } 92 | } 93 | 94 | extern "C" JNIEXPORT jobjectArray JNICALL 95 | Java_com_rangi_nanodet_YOLOv4_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { 96 | auto result = YoloV4::detector->detect(env, image, threshold, nms_threshold); 97 | 98 | auto box_cls = env->FindClass("com/rangi/nanodet/Box"); 99 | auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); 100 | jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); 101 | int i = 0; 102 | for (auto &box:result) { 103 | env->PushLocalFrame(1); 104 | jobject obj = env->NewObject(box_cls, cid, box.x1, box.y1, box.x2, box.y2, box.label, box.score); 105 | obj = env->PopLocalFrame(obj); 106 | env->SetObjectArrayElement(ret, i++, obj); 107 | } 108 | return ret; 109 | } 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/AppCrashHandler.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | class AppCrashHandler implements Thread.UncaughtExceptionHandler { 6 | 7 | private Thread.UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 8 | 9 | @Override 10 | public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { 11 | uncaughtExceptionHandler.uncaughtException(t, e); 12 | } 13 | 14 | public static void register() { 15 | Thread.setDefaultUncaughtExceptionHandler(new AppCrashHandler()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/Box.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.RectF; 5 | 6 | import java.util.Random; 7 | 8 | public class Box { 9 | public float x0,y0,x1,y1; 10 | private int label; 11 | private float score; 12 | private static String[] labels={"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", 13 | "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", 14 | "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", 15 | "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", 16 | "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", 17 | "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", 18 | "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", 19 | "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", 20 | "hair drier", "toothbrush"}; 21 | public Box(float x0,float y0, float x1, float y1, int label, float score){ 22 | this.x0 = x0; 23 | this.y0 = y0; 24 | this.x1 = x1; 25 | this.y1 = y1; 26 | this.label = label; 27 | this.score = score; 28 | } 29 | 30 | public RectF getRect(){ 31 | return new RectF(x0,y0,x1,y1); 32 | } 33 | 34 | public String getLabel(){ 35 | return labels[label]; 36 | } 37 | 38 | public float getScore(){ 39 | return score; 40 | } 41 | 42 | public int getColor(){ 43 | Random random = new Random(label); 44 | return Color.argb(255,random.nextInt(256),random.nextInt(256),random.nextInt(256)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/NanoDet.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.content.res.AssetManager; 4 | import android.graphics.Bitmap; 5 | 6 | public class NanoDet { 7 | static { 8 | System.loadLibrary("yolov5"); 9 | } 10 | 11 | public static native void init(AssetManager manager, boolean useGPU); 12 | public static native Box[] detect(Bitmap bitmap, double threshold, double nms_threshold); 13 | } 14 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/NcnnApp.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.util.Log; 6 | 7 | import androidx.multidex.MultiDex; 8 | 9 | import com.zxy.recovery.callback.RecoveryCallback; 10 | import com.zxy.recovery.core.Recovery; 11 | 12 | 13 | public class NcnnApp extends Application { 14 | 15 | @Override 16 | public void onCreate() { 17 | super.onCreate(); 18 | 19 | //崩溃界面 20 | initRecovery(); 21 | } 22 | 23 | @Override 24 | protected void attachBaseContext(Context base) { 25 | super.attachBaseContext(base); 26 | MultiDex.install(base); 27 | } 28 | 29 | private void initRecovery() { 30 | Recovery.getInstance() 31 | .debug(BuildConfig.DEBUG) 32 | .recoverInBackground(true) 33 | .recoverStack(true) 34 | .mainPage(MainActivity.class) 35 | .recoverEnabled(true) 36 | .callback(new MyCrashCallback()) 37 | .silent(false, Recovery.SilentMode.RECOVER_ACTIVITY_STACK) 38 | // .skip(TestActivity.class) 39 | .init(this); 40 | AppCrashHandler.register(); 41 | } 42 | 43 | static final class MyCrashCallback implements RecoveryCallback { 44 | @Override 45 | public void stackTrace(String exceptionMessage) { 46 | Log.e("wzt", "exceptionMessage:" + exceptionMessage); 47 | } 48 | 49 | @Override 50 | public void cause(String cause) { 51 | Log.e("wzt", "cause:" + cause); 52 | } 53 | 54 | @Override 55 | public void exception(String exceptionType, String throwClassName, String throwMethodName, int throwLineNumber) { 56 | Log.e("wzt", "exceptionClassName:" + exceptionType); 57 | Log.e("wzt", "throwClassName:" + throwClassName); 58 | Log.e("wzt", "throwMethodName:" + throwMethodName); 59 | Log.e("wzt", "throwLineNumber:" + throwLineNumber); 60 | } 61 | 62 | @Override 63 | public void throwable(Throwable throwable) { 64 | 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import androidx.appcompat.app.AlertDialog; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.view.View; 9 | import android.widget.Button; 10 | import android.widget.CompoundButton; 11 | import android.widget.ToggleButton; 12 | 13 | 14 | public class WelcomeActivity extends AppCompatActivity { 15 | 16 | private ToggleButton tbUseGpu; 17 | private Button nanodet; 18 | private Button yolov5s; 19 | private Button yolov4tiny; 20 | 21 | private boolean useGPU = false; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_welcome); 27 | 28 | tbUseGpu = findViewById(R.id.tb_use_gpu); 29 | tbUseGpu.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 30 | @Override 31 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 32 | useGPU = isChecked; 33 | MainActivity.USE_GPU = useGPU; 34 | if (useGPU) { 35 | AlertDialog.Builder builder = new AlertDialog.Builder(WelcomeActivity.this); 36 | builder.setTitle("Warning"); 37 | builder.setMessage("It may not work well in GPU mode, or errors may occur."); 38 | builder.setCancelable(true); 39 | builder.setPositiveButton("OK", null); 40 | AlertDialog dialog = builder.create(); 41 | dialog.show(); 42 | } 43 | } 44 | }); 45 | 46 | nanodet = findViewById(R.id.btn_start_detect0); 47 | nanodet.setOnClickListener(new View.OnClickListener() { 48 | @Override 49 | public void onClick(View v) { 50 | MainActivity.USE_MODEL = MainActivity.NANODET; 51 | Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); 52 | WelcomeActivity.this.startActivity(intent); 53 | } 54 | }); 55 | 56 | yolov5s = findViewById(R.id.btn_start_detect1); 57 | yolov5s.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | MainActivity.USE_MODEL = MainActivity.YOLOV5S; 61 | Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); 62 | WelcomeActivity.this.startActivity(intent); 63 | } 64 | }); 65 | 66 | yolov4tiny = findViewById(R.id.btn_start_detect2); 67 | yolov4tiny.setOnClickListener(new View.OnClickListener() { 68 | @Override 69 | public void onClick(View v) { 70 | MainActivity.USE_MODEL = MainActivity.YOLOV4_TINY; 71 | Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); 72 | WelcomeActivity.this.startActivity(intent); 73 | } 74 | }); 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/YOLOv4.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.content.res.AssetManager; 4 | import android.graphics.Bitmap; 5 | 6 | public class YOLOv4 { 7 | static { 8 | System.loadLibrary("yolov5"); // 存放在yolov5.so中 9 | } 10 | 11 | public static native void init(AssetManager manager, boolean useGPU); 12 | public static native Box[] detect(Bitmap bitmap, double threshold, double nms_threshold); 13 | } 14 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/java/com/rangi/nanodet/YOLOv5.java: -------------------------------------------------------------------------------- 1 | package com.rangi.nanodet; 2 | 3 | import android.content.res.AssetManager; 4 | import android.graphics.Bitmap; 5 | 6 | public class YOLOv5 { 7 | static { 8 | System.loadLibrary("yolov5"); 9 | } 10 | 11 | public static native void init(AssetManager manager, boolean useGPU); 12 | public static native Box[] detect(Bitmap bitmap, double threshold, double nms_threshold); 13 | } 14 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/drawable-xxhdpi/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxnaive/nanodet-TensorRT/56ef43cef8a71202cab7536798b479382742c8b9/demo_android_ncnn/app/src/main/res/drawable-xxhdpi/cpu.png -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/drawable-xxhdpi/gpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxnaive/nanodet-TensorRT/56ef43cef8a71202cab7536798b479382742c8b9/demo_android_ncnn/app/src/main/res/drawable-xxhdpi/gpu.png -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/drawable-xxhdpi/ncnn_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxnaive/nanodet-TensorRT/56ef43cef8a71202cab7536798b479382742c8b9/demo_android_ncnn/app/src/main/res/drawable-xxhdpi/ncnn_icon.png -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/drawable/cpu_gpu_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo_android_ncnn/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |