├── .gitignore ├── .readthedocs.yaml ├── 123.py ├── LICENSE ├── README.md ├── Untitled.ipynb ├── assets ├── demo.png ├── dog.jpg ├── git_fig.png └── logo.png ├── datasets ├── README.md ├── ccpd │ ├── voctococo.py │ └── yolotovoc.py ├── plate_kp │ ├── voctococo.py │ └── yolotovoc.py └── plate_seg │ ├── 50rle.zip │ ├── voctococo.py │ └── yolotovoc.py ├── demo ├── MegEngine │ ├── cpp │ │ ├── README.md │ │ ├── build.sh │ │ └── yolox.cpp │ └── python │ │ ├── README.md │ │ ├── build.py │ │ ├── convert_weights.py │ │ ├── demo.py │ │ ├── dump.py │ │ └── models │ │ ├── __init__.py │ │ ├── darknet.py │ │ ├── network_blocks.py │ │ ├── yolo_fpn.py │ │ ├── yolo_head.py │ │ ├── yolo_pafpn.py │ │ └── yolox.py ├── ONNXRuntime │ ├── README.md │ └── onnx_inference.py ├── OpenVINO │ ├── README.md │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── yolox_openvino.cpp │ └── python │ │ ├── README.md │ │ └── openvino_inference.py ├── TensorRT │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── logging.h │ │ └── yolox.cpp │ └── python │ │ └── README.md └── ncnn │ ├── android │ ├── README.md │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ └── yolox.param │ │ │ ├── java │ │ │ └── com │ │ │ │ └── megvii │ │ │ │ └── yoloXncnn │ │ │ │ ├── MainActivity.java │ │ │ │ └── yoloXncnn.java │ │ │ ├── jni │ │ │ ├── CMakeLists.txt │ │ │ └── yoloXncnn_jni.cpp │ │ │ └── res │ │ │ ├── layout │ │ │ └── main.xml │ │ │ └── values │ │ │ └── strings.xml │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle │ └── cpp │ ├── README.md │ └── yolox.cpp ├── docs ├── .gitignore ├── Makefile ├── _static │ └── css │ │ └── custom.css ├── conf.py ├── demo │ ├── megengine_cpp_readme.md │ ├── megengine_py_readme.md │ ├── ncnn_android_readme.md │ ├── ncnn_cpp_readme.md │ ├── onnx_readme.md │ ├── openvino_cpp_readme.md │ ├── openvino_py_readme.md │ ├── trt_cpp_readme.md │ └── trt_py_readme.md ├── index.rst ├── manipulate_training_image_size.md ├── model_zoo.md ├── quick_run.md ├── requirements-doc.txt ├── train_custom_data.md └── updates_note.md ├── exps ├── default │ ├── nano.py │ ├── yolov3.py │ ├── yolox_ccpd.py │ ├── yolox_decorate.py │ ├── yolox_kp.py │ ├── yolox_l.py │ ├── yolox_m.py │ ├── yolox_masonry.py │ ├── yolox_plaster.py │ ├── yolox_s.py │ ├── yolox_seg.py │ ├── yolox_tiny.py │ └── yolox_x.py └── example │ ├── custom │ ├── nano.py │ └── yolox_s.py │ └── yolox_voc │ └── yolox_voc_s.py ├── imgs ├── kps │ ├── 5.jpg │ ├── 6.jpg │ └── 7.jpg └── segs │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ └── 5.jpg ├── my_trt.py ├── requirements.txt ├── setup.cfg ├── setup.py ├── tests ├── __init__.py └── utils │ └── test_model_utils.py ├── tools ├── __init__.py ├── demo.py ├── demo_panoptic.py ├── eval.py ├── export_onnx.py ├── export_torchscript.py ├── train.py └── trt.py ├── trt_convert.py ├── yolox ├── __init__.py ├── core │ ├── __init__.py │ ├── launch.py │ └── trainer.py ├── data │ ├── __init__.py │ ├── data_augment.py │ ├── data_prefetcher.py │ ├── dataloading.py │ ├── datasets │ │ ├── __init__.py │ │ ├── coco.py │ │ ├── coco_classes.py │ │ ├── datasets_wrapper.py │ │ ├── generate_wall_data.py │ │ ├── mosaicdetection.py │ │ ├── voc.py │ │ └── voc_classes.py │ └── samplers.py ├── evaluators │ ├── __init__.py │ ├── coco_evaluator.py │ ├── voc_eval.py │ └── voc_evaluator.py ├── exp │ ├── __init__.py │ ├── base_exp.py │ ├── build.py │ └── yolox_base.py ├── layers │ ├── __init__.py │ ├── fast_coco_eval_api.py │ └── jit_ops.py ├── models │ ├── __init__.py │ ├── coatnet.py │ ├── darknet.py │ ├── losses.py │ ├── network_blocks.py │ ├── yolo_fpn.py │ ├── yolo_head.py │ ├── yolo_head_panoptic.py │ ├── yolo_pafpn.py │ ├── yolo_pafpn_slim.py │ ├── yolov7_tiny.py │ └── yolox.py └── utils │ ├── __init__.py │ ├── allreduce_norm.py │ ├── boxes.py │ ├── checkpoint.py │ ├── compat.py │ ├── demo_utils.py │ ├── dist.py │ ├── ema.py │ ├── fuse_model.py │ ├── logger.py │ ├── lr_scheduler.py │ ├── metric.py │ ├── model_utils.py │ ├── setup_env.py │ └── visualize.py └── 注意.txt /.gitignore: -------------------------------------------------------------------------------- 1 | ### Linux ### 2 | *~ 3 | 4 | # user experiments directory 5 | YOLOX_outputs/ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### PyCharm ### 20 | # User-specific stuff 21 | .idea 22 | 23 | # CMake 24 | cmake-build-*/ 25 | 26 | # Mongo Explorer plugin 27 | .idea/**/mongoSettings.xml 28 | 29 | # File-based project format 30 | *.iws 31 | 32 | # IntelliJ 33 | out/ 34 | 35 | # mpeltonen/sbt-idea plugin 36 | .idea_modules/ 37 | 38 | # JIRA plugin 39 | atlassian-ide-plugin.xml 40 | 41 | # Cursive Clojure plugin 42 | .idea/replstate.xml 43 | 44 | # Crashlytics plugin (for Android Studio and IntelliJ) 45 | com_crashlytics_export_strings.xml 46 | crashlytics.properties 47 | crashlytics-build.properties 48 | fabric.properties 49 | 50 | # Editor-based Rest Client 51 | .idea/httpRequests 52 | 53 | # Android studio 3.1+ serialized cache file 54 | .idea/caches/build_file_checksums.ser 55 | 56 | # JetBrains templates 57 | **___jb_tmp___ 58 | 59 | ### Python ### 60 | # Byte-compiled / optimized / DLL files 61 | __pycache__/ 62 | *.py[cod] 63 | *$py.class 64 | 65 | # C extensions 66 | *.so 67 | 68 | # Distribution / packaging 69 | .Python 70 | build/ 71 | develop-eggs/ 72 | dist/ 73 | downloads/ 74 | eggs/ 75 | .eggs/ 76 | lib/ 77 | lib64/ 78 | parts/ 79 | sdist/ 80 | var/ 81 | wheels/ 82 | pip-wheel-metadata/ 83 | share/python-wheels/ 84 | *.egg-info/ 85 | .installed.cfg 86 | *.egg 87 | MANIFEST 88 | 89 | # PyInstaller 90 | # Usually these files are written by a python script from a template 91 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 92 | *.manifest 93 | *.spec 94 | 95 | # Installer logs 96 | pip-log.txt 97 | pip-delete-this-directory.txt 98 | 99 | # Unit test / coverage reports 100 | htmlcov/ 101 | .tox/ 102 | .nox/ 103 | .coverage 104 | .coverage.* 105 | .cache 106 | nosetests.xml 107 | coverage.xml 108 | *.cover 109 | .hypothesis/ 110 | .pytest_cache/ 111 | 112 | # Translations 113 | *.mo 114 | *.pot 115 | 116 | # Django stuff: 117 | *.log 118 | local_settings.py 119 | db.sqlite3 120 | 121 | # Flask stuff: 122 | instance/ 123 | .webassets-cache 124 | 125 | # Scrapy stuff: 126 | .scrapy 127 | 128 | # Sphinx documentation 129 | docs/_build/ 130 | docs/build/ 131 | 132 | # PyBuilder 133 | target/ 134 | 135 | # Jupyter Notebook 136 | .ipynb_checkpoints 137 | 138 | # IPython 139 | profile_default/ 140 | ipython_config.py 141 | 142 | # pyenv 143 | .python-version 144 | 145 | # pipenv 146 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 147 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 148 | # having no cross-platform support, pipenv may install dependencies that don’t work, or not 149 | # install all needed dependencies. 150 | #Pipfile.lock 151 | 152 | # celery beat schedule file 153 | celerybeat-schedule 154 | 155 | # SageMath parsed files 156 | *.sage.py 157 | 158 | # Environments 159 | .env 160 | .venv 161 | env/ 162 | venv/ 163 | ENV/ 164 | env.bak/ 165 | venv.bak/ 166 | 167 | # Spyder project settings 168 | .spyderproject 169 | .spyproject 170 | 171 | # Rope project settings 172 | .ropeproject 173 | 174 | # mkdocs documentation 175 | /site 176 | 177 | # mypy 178 | .mypy_cache/ 179 | .dmypy.json 180 | dmypy.json 181 | 182 | # Pyre type checker 183 | .pyre/ 184 | 185 | ### Vim ### 186 | # Swap 187 | [._]*.s[a-v][a-z] 188 | [._]*.sw[a-p] 189 | [._]s[a-rt-v][a-z] 190 | [._]ss[a-gi-z] 191 | [._]sw[a-p] 192 | 193 | # Session 194 | Session.vim 195 | 196 | # Temporary 197 | .netrwhist 198 | # Auto-generated tag files 199 | tags 200 | # Persistent undo 201 | [._]*.un~ 202 | 203 | # output 204 | docs/api 205 | .code-workspace.code-workspace 206 | *.pkl 207 | *.npy 208 | *.pth 209 | *.onnx 210 | *.engine 211 | events.out.tfevents* 212 | 213 | # vscode 214 | *.code-workspace 215 | .vscode 216 | 217 | # vim 218 | .vim 219 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Build documentation in the docs/ directory with Sphinx 9 | sphinx: 10 | configuration: docs/conf.py 11 | 12 | # Optionally build your docs in additional formats such as PDF 13 | formats: 14 | - pdf 15 | 16 | # Optionally set the version of Python and requirements required to build your docs 17 | python: 18 | version: "3.7" 19 | install: 20 | - requirements: docs/requirements-doc.txt 21 | - requirements: requirements.txt 22 | -------------------------------------------------------------------------------- /123.py: -------------------------------------------------------------------------------- 1 | import torch, time 2 | from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead, CSPDarknet, YOLOPAFPNSLIM, YOLO7TINY 3 | 4 | 5 | def count_parameters(model): 6 | return sum(p.numel() for p in model.parameters() if p.requires_grad) 7 | 8 | if __name__ == '__main__': 9 | # in_channels = [128, 256, 512, 1024] 10 | # in_features = ("dark2", "dark3", "dark4", "dark5") 11 | in_channels = [256, 512, 1024] 12 | in_features = ("dark3", "dark4", "dark5") 13 | depth = 0.33 14 | width = 0.50 15 | img_channel = 3 16 | 17 | # backbone = CSPDarknet(img_channel, depth, width, depthwise=False, act="silu", out_features=in_features) 18 | 19 | # backbone = YOLOPAFPN(img_channel, depth, width, in_channels=in_channels, in_features=in_features, 20 | # backbone_name='CSPDarknet').cuda() # CSPDarknet CoAtNet 0.01363 s 21 | 22 | # backbone = YOLOPAFPNSLIM(img_channel, depth, width, in_channels=in_channels, in_features=in_features, 23 | # backbone_name='CSPDarknet').cuda() # CSPDarknet CoAtNet 0.01215 s 24 | 25 | backbone = YOLO7TINY(img_channel=img_channel, width=width, act='lrelu').cuda() # 0.00808 s 0.00644 s 26 | 27 | ## 输入320*320 输出128,40,40 256,20,20 512,10,10 seg多一个 64,80,80 28 | 29 | head = YOLOXHead(1, width, in_channels=in_channels, keypoints=0, segcls=0, 30 | act="silu", repeat=0).cuda() # 0.01101 s 0.00827 s 31 | model = YOLOX(backbone, head).cuda() 32 | model.fuse() 33 | model.eval() 34 | img = torch.randn(10, 3, 192, 320).cuda() 35 | out, seg_out = model(img) 36 | # print(out.shape, seg_out.shape) 37 | # print('???', seg_out.shape) 38 | # 39 | # torch.onnx.export(backbone, img, 'model2.onnx', opset_version=12, 40 | # input_names=['images'], output_names=['output'], 41 | # dynamic_axes={'images': {0: 'batch_size', 2: 'h', 3: 'w'}, # , 2: 'h', 3: 'w' 42 | # 'output': {0: 'batch_size'}, 43 | # } 44 | # ) 45 | 46 | # outs = backbone(img) 47 | # print(count_parameters(backbone)) # 5990464 1891344 48 | # # features = [outs[f] for f in in_features] 49 | # for out in outs: 50 | # print(out.shape) 51 | 52 | for i in range(50): 53 | out, seg_out = model(img) 54 | # backbone(img) 55 | 56 | start_time = time.perf_counter() 57 | # backbone(img) 58 | out, seg_out = model(img) 59 | end_time = time.perf_counter() 60 | print(f'time cost: {round(end_time - start_time, 5)} s') 61 | -------------------------------------------------------------------------------- /assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcmingchang/yolox_keypoint_segment/c2e990c848c5e388c2abf6147fef77db126f88bc/assets/demo.png -------------------------------------------------------------------------------- /assets/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcmingchang/yolox_keypoint_segment/c2e990c848c5e388c2abf6147fef77db126f88bc/assets/dog.jpg -------------------------------------------------------------------------------- /assets/git_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcmingchang/yolox_keypoint_segment/c2e990c848c5e388c2abf6147fef77db126f88bc/assets/git_fig.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcmingchang/yolox_keypoint_segment/c2e990c848c5e388c2abf6147fef77db126f88bc/assets/logo.png -------------------------------------------------------------------------------- /datasets/README.md: -------------------------------------------------------------------------------- 1 | # Prepare datasets 2 | 3 | If you have a dataset directory, you could use os environment variable named `YOLOX_DATADIR`. Under this directory, YOLOX will look for datasets in the structure described below, if needed. 4 | ``` 5 | $YOLOX_DATADIR/ 6 | COCO/ 7 | ``` 8 | You can set the location for builtin datasets by 9 | ```shell 10 | export YOLOX_DATADIR=/path/to/your/datasets 11 | ``` 12 | If `YOLOX_DATADIR` is not set, the default value of dataset directory is `./datasets` relative to your current working directory. 13 | 14 | ## Expected dataset structure for [COCO detection](https://cocodataset.org/#download): 15 | 16 | ``` 17 | COCO/ 18 | annotations/ 19 | instances_{train,val}2017.json 20 | {train,val}2017/ 21 | # image files that are mentioned in the corresponding json 22 | ``` 23 | 24 | You can use the 2014 version of the dataset as well. 25 | -------------------------------------------------------------------------------- /datasets/ccpd/yolotovoc.py: -------------------------------------------------------------------------------- 1 | from xml.dom.minidom import Document 2 | from lxml.etree import Element, SubElement, tostring 3 | import pprint 4 | from xml.dom.minidom import parseString 5 | import cv2, os 6 | class XmlMaker: 7 | 8 | def __init__(self, txtpath, xmlpath): 9 | self.txtPath = txtpath 10 | self.xmlPath = xmlpath 11 | self.txtList = [] 12 | self.keypoint = True 13 | self.color = ['blue', 'green', 'yellow', 'black', 'other'] 14 | 15 | def readtxt(self): 16 | jpg = [] 17 | txtfile = open(self.txtPath, "r", encoding='gbk', errors='ignore') 18 | self.txtList = txtfile.readlines() 19 | for i in self.txtList: 20 | jpg = i.strip().split(" ")[0] 21 | if self.keypoint: 22 | try: 23 | keypoints = i.strip().split(" ")[1] 24 | xys = i.strip().split(" ")[2:] 25 | except: 26 | xys = [] 27 | else: 28 | xys = i.strip().split(" ")[1:] 29 | 30 | node_root = Element('annotation') 31 | node_folder = SubElement(node_root, 'folder') 32 | node_folder.text = 'VOC2012' 33 | node_filename = SubElement(node_root, 'filename') 34 | node_filename.text = jpg 35 | img = cv2.imread(jpg) 36 | try: 37 | shape = img.shape 38 | except: 39 | print('skip ',jpg) 40 | 41 | node_size = SubElement(node_root, 'size') 42 | node_width = SubElement(node_size, 'width') 43 | 44 | node_width.text = str(shape[1]) 45 | 46 | node_height = SubElement(node_size, 'height') 47 | node_height.text = str(shape[0]) 48 | 49 | node_depth = SubElement(node_size, 'depth') 50 | node_depth.text = '3' 51 | 52 | for xy in xys: 53 | list_xy = xy.split(",") 54 | x_min = list_xy[0] 55 | y_min = list_xy[1] 56 | x_max = list_xy[2] 57 | y_max = list_xy[3] 58 | classes = list_xy[4] 59 | node_object = SubElement(node_root, 'object') 60 | node_name = SubElement(node_object, 'name') 61 | node_name.text = self.color[int(classes)] 62 | node_difficult = SubElement(node_object, 'difficult') 63 | node_difficult.text = '0' 64 | node_bndbox = SubElement(node_object, 'bndbox') 65 | node_xmin = SubElement(node_bndbox, 'xmin') 66 | node_xmin.text = str(x_min) 67 | node_ymin = SubElement(node_bndbox, 'ymin') 68 | node_ymin.text = str(y_min) 69 | node_xmax = SubElement(node_bndbox, 'xmax') 70 | node_xmax.text = str(x_max) 71 | node_ymax = SubElement(node_bndbox, 'ymax') 72 | node_ymax.text = str(y_max) 73 | 74 | if self.keypoint: 75 | node_keypint = SubElement(node_object, 'keypoints') 76 | node_keypint.text = keypoints 77 | 78 | 79 | xml = tostring(node_root, pretty_print=True) # 格式化显示,该换行的换行 80 | xml_name = jpg.split("/")[-1][:-4]+".xml" 81 | print(xml_name) 82 | with open(self.xmlPath+"/"+xml_name, "wb") as f: 83 | f.write(xml) 84 | f.close() 85 | 86 | 87 | if __name__ == "__main__": 88 | read =XmlMaker("train.txt","images") 89 | read.readtxt() 90 | os.rename('./images', './nnotations') 91 | 92 | -------------------------------------------------------------------------------- /datasets/plate_kp/yolotovoc.py: -------------------------------------------------------------------------------- 1 | from xml.dom.minidom import Document 2 | from lxml.etree import Element, SubElement, tostring 3 | import pprint 4 | from xml.dom.minidom import parseString 5 | import cv2, os 6 | class XmlMaker: 7 | 8 | def __init__(self, txtpath, xmlpath): 9 | self.txtPath = txtpath 10 | self.xmlPath = xmlpath 11 | self.txtList = [] 12 | self.keypoint = True 13 | self.color = ['blue', 'green'] 14 | 15 | def readtxt(self): 16 | jpg = [] 17 | txtfile = open(self.txtPath, "r", encoding='gbk', errors='ignore') 18 | self.txtList = txtfile.readlines() 19 | for i in self.txtList: 20 | jpg = i.strip().split(" ")[0] 21 | if self.keypoint: 22 | try: 23 | keypoints = i.strip().split(" ")[1] 24 | xys = i.strip().split(" ")[2:] 25 | except: 26 | xys = [] 27 | else: 28 | xys = i.strip().split(" ")[1:] 29 | 30 | node_root = Element('annotation') 31 | node_folder = SubElement(node_root, 'folder') 32 | node_folder.text = 'VOC2012' 33 | node_filename = SubElement(node_root, 'filename') 34 | node_filename.text = jpg 35 | img = cv2.imread(jpg) 36 | try: 37 | shape = img.shape 38 | except: 39 | print('skip ',jpg) 40 | 41 | node_size = SubElement(node_root, 'size') 42 | node_width = SubElement(node_size, 'width') 43 | 44 | node_width.text = str(shape[1]) 45 | 46 | node_height = SubElement(node_size, 'height') 47 | node_height.text = str(shape[0]) 48 | 49 | node_depth = SubElement(node_size, 'depth') 50 | node_depth.text = '3' 51 | 52 | for xy in xys: 53 | list_xy = xy.split(",") 54 | x_min = list_xy[0] 55 | y_min = list_xy[1] 56 | x_max = list_xy[2] 57 | y_max = list_xy[3] 58 | classes = list_xy[4] 59 | node_object = SubElement(node_root, 'object') 60 | node_name = SubElement(node_object, 'name') 61 | node_name.text = self.color[int(classes)] 62 | node_difficult = SubElement(node_object, 'difficult') 63 | node_difficult.text = '0' 64 | node_bndbox = SubElement(node_object, 'bndbox') 65 | node_xmin = SubElement(node_bndbox, 'xmin') 66 | node_xmin.text = str(x_min) 67 | node_ymin = SubElement(node_bndbox, 'ymin') 68 | node_ymin.text = str(y_min) 69 | node_xmax = SubElement(node_bndbox, 'xmax') 70 | node_xmax.text = str(x_max) 71 | node_ymax = SubElement(node_bndbox, 'ymax') 72 | node_ymax.text = str(y_max) 73 | 74 | if self.keypoint: 75 | node_keypint = SubElement(node_object, 'keypoints') 76 | node_keypint.text = keypoints 77 | 78 | 79 | xml = tostring(node_root, pretty_print=True) # 格式化显示,该换行的换行 80 | xml_name = jpg.split("/")[-1][:-4]+".xml" 81 | print(xml_name) 82 | with open(self.xmlPath+"/"+xml_name, "wb") as f: 83 | f.write(xml) 84 | f.close() 85 | 86 | 87 | if __name__ == "__main__": 88 | read =XmlMaker("train.txt","images") 89 | read.readtxt() 90 | os.rename('./images', './nnotations') 91 | 92 | -------------------------------------------------------------------------------- /datasets/plate_seg/50rle.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcmingchang/yolox_keypoint_segment/c2e990c848c5e388c2abf6147fef77db126f88bc/datasets/plate_seg/50rle.zip -------------------------------------------------------------------------------- /datasets/plate_seg/yolotovoc.py: -------------------------------------------------------------------------------- 1 | from lxml.etree import Element, SubElement, tostring 2 | import cv2, os 3 | 4 | CATE_LS = [] 5 | 6 | class XmlMaker: 7 | 8 | def __init__(self,txtpath,xmlpath): 9 | self.txtPath = txtpath 10 | self.xmlPath = xmlpath 11 | self.txtList = [] 12 | self.keypoint = False 13 | self.segmentation = True 14 | 15 | def readtxt(self): 16 | txtfile = open(self.txtPath, "r", encoding='gbk', errors='ignore') 17 | self.txtList = txtfile.readlines() 18 | for i in self.txtList: 19 | jpg = i.strip().split(" ")[0] 20 | if self.keypoint: 21 | keypoints = i.strip().split(" ")[1] 22 | xys = i.strip().split(" ")[2:] 23 | elif self.segmentation: 24 | xys = i.strip().split(" ")[1:] 25 | else: 26 | xys = i.strip().split(" ")[1:] 27 | 28 | node_root = Element('annotation') 29 | node_folder = SubElement(node_root, 'folder') 30 | node_folder.text = 'VOC2012' 31 | node_filename = SubElement(node_root, 'filename') 32 | node_filename.text = jpg 33 | img = cv2.imread(f'images/{jpg}') 34 | shape = img.shape 35 | 36 | node_size = SubElement(node_root, 'size') 37 | node_width = SubElement(node_size, 'width') 38 | 39 | node_width.text = str(shape[1]) 40 | 41 | node_height = SubElement(node_size, 'height') 42 | node_height.text = str(shape[0]) 43 | 44 | node_depth = SubElement(node_size, 'depth') 45 | node_depth.text = '3' 46 | 47 | for xy in xys: 48 | if self.segmentation: 49 | xy, segmentations = xy.split("/seg/") 50 | list_xy = xy.split(",") 51 | x_min = list_xy[0] 52 | y_min = list_xy[1] 53 | x_max = list_xy[2] 54 | y_max = list_xy[3] 55 | classes = list_xy[4] 56 | else: 57 | list_xy = xy.split(",") 58 | x_min = list_xy[0] 59 | y_min = list_xy[1] 60 | x_max = list_xy[2] 61 | y_max = list_xy[3] 62 | classes = list_xy[4] 63 | CATE_LS.append(classes) 64 | node_object = SubElement(node_root, 'object') 65 | node_name = SubElement(node_object, 'name') 66 | node_name.text = classes 67 | node_difficult = SubElement(node_object, 'difficult') 68 | node_difficult.text = '0' 69 | node_bndbox = SubElement(node_object, 'bndbox') 70 | node_xmin = SubElement(node_bndbox, 'xmin') 71 | node_xmin.text = str(x_min) 72 | node_ymin = SubElement(node_bndbox, 'ymin') 73 | node_ymin.text = str(y_min) 74 | node_xmax = SubElement(node_bndbox, 'xmax') 75 | node_xmax.text = str(x_max) 76 | node_ymax = SubElement(node_bndbox, 'ymax') 77 | node_ymax.text = str(y_max) 78 | 79 | if self.keypoint: 80 | node_keypint = SubElement(node_object, 'keypoints') 81 | node_keypint.text = keypoints 82 | elif self.segmentation: 83 | node_segmentation = SubElement(node_object, 'segmentation') 84 | node_segmentation.text = segmentations 85 | 86 | 87 | xml = tostring(node_root, pretty_print=True) # 格式化显示,该换行的换行 88 | xml_name = jpg.split("/")[-1][:-4]+".xml" 89 | print(xml_name) 90 | with open(self.xmlPath+"/"+xml_name, "wb") as f: 91 | f.write(xml) 92 | f.close() 93 | 94 | if __name__ == "__main__": 95 | read =XmlMaker("train.txt","images") 96 | read.readtxt() 97 | os.rename('./images', './nnotations') 98 | print(set(CATE_LS)) 99 | 100 | -------------------------------------------------------------------------------- /demo/MegEngine/cpp/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ -z $CXX ];then 5 | echo "please export you c++ toolchain to CXX" 6 | echo "for example:" 7 | echo "build for host: export CXX=g++" 8 | echo "cross build for aarch64-android(always locate in NDK): export CXX=aarch64-linux-android21-clang++" 9 | echo "cross build for aarch64-linux: export CXX=aarch64-linux-gnu-g++" 10 | exit -1 11 | fi 12 | 13 | if [ -z $MGE_INSTALL_PATH ];then 14 | echo "please refsi ./README.md to init MGE_INSTALL_PATH env" 15 | exit -1 16 | fi 17 | 18 | if [ -z $OPENCV_INSTALL_INCLUDE_PATH ];then 19 | echo "please refs ./README.md to init OPENCV_INSTALL_INCLUDE_PATH env" 20 | exit -1 21 | fi 22 | 23 | if [ -z $OPENCV_INSTALL_LIB_PATH ];then 24 | echo "please refs ./README.md to init OPENCV_INSTALL_LIB_PATH env" 25 | exit -1 26 | fi 27 | 28 | INCLUDE_FLAG="-I$MGE_INSTALL_PATH/include -I$OPENCV_INSTALL_INCLUDE_PATH" 29 | LINK_FLAG="-L$MGE_INSTALL_PATH/lib/ -lmegengine -L$OPENCV_INSTALL_LIB_PATH -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs" 30 | BUILD_FLAG="-static-libstdc++ -O3 -pie -fPIE -g" 31 | 32 | if [[ $CXX =~ "android" ]]; then 33 | LINK_FLAG="${LINK_FLAG} -llog -lz" 34 | fi 35 | 36 | echo "CXX: $CXX" 37 | echo "MGE_INSTALL_PATH: $MGE_INSTALL_PATH" 38 | echo "INCLUDE_FLAG: $INCLUDE_FLAG" 39 | echo "LINK_FLAG: $LINK_FLAG" 40 | echo "BUILD_FLAG: $BUILD_FLAG" 41 | 42 | echo "[" > compile_commands.json 43 | echo "{" >> compile_commands.json 44 | echo "\"directory\": \"$PWD\"," >> compile_commands.json 45 | echo "\"command\": \"$CXX yolox.cpp -o yolox ${INCLUDE_FLAG} ${LINK_FLAG}\"," >> compile_commands.json 46 | echo "\"file\": \"$PWD/yolox.cpp\"," >> compile_commands.json 47 | echo "}," >> compile_commands.json 48 | echo "]" >> compile_commands.json 49 | $CXX yolox.cpp -o yolox ${INCLUDE_FLAG} ${LINK_FLAG} ${BUILD_FLAG} 50 | 51 | echo "build success, output file: yolox" 52 | if [[ $CXX =~ "android" ]]; then 53 | echo "try command to run:" 54 | echo "adb push/scp $MGE_INSTALL_PATH/lib/libmegengine.so android_phone" 55 | echo "adb push/scp $OPENCV_INSTALL_LIB_PATH/*.so android_phone" 56 | echo "adb push/scp ./yolox yolox_s.mge android_phone" 57 | echo "adb push/scp ../../../assets/dog.jpg android_phone" 58 | echo "adb/ssh to android_phone, then run: LD_LIBRARY_PATH=. ./yolox yolox_s.mge dog.jpg cpu/multithread " 59 | else 60 | echo "try command to run: LD_LIBRARY_PATH=$MGE_INSTALL_PATH/lib/:$OPENCV_INSTALL_LIB_PATH ./yolox yolox_s.mge ../../../assets/dog.jpg cuda/cpu/multithread " 61 | fi 62 | -------------------------------------------------------------------------------- /demo/MegEngine/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-Python-MegEngine 2 | 3 | Python version of YOLOX object detection base on [MegEngine](https://github.com/MegEngine/MegEngine). 4 | 5 | ## Tutorial 6 | 7 | ### Step1: install requirements 8 | 9 | ``` 10 | python3 -m pip install megengine -f https://megengine.org.cn/whl/mge.html 11 | ``` 12 | 13 | ### Step2: convert checkpoint weights from torch's path file 14 | 15 | ``` 16 | python3 convert_weights.py -w yolox_s.pth -o yolox_s_mge.pkl 17 | ``` 18 | 19 | ### Step3: run demo 20 | 21 | This part is the same as torch's python demo, but no need to specify device. 22 | 23 | ``` 24 | python3 demo.py image -n yolox-s -c yolox_s_mge.pkl --path ../../../assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result 25 | ``` 26 | 27 | ### [Optional]Step4: dump model for cpp inference 28 | 29 | > **Note**: result model is dumped with `optimize_for_inference` and `enable_fuse_conv_bias_nonlinearity`. 30 | 31 | ``` 32 | python3 dump.py -n yolox-s -c yolox_s_mge.pkl --dump_path yolox_s.mge 33 | ``` 34 | -------------------------------------------------------------------------------- /demo/MegEngine/python/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | import megengine as mge 5 | import megengine.module as M 6 | 7 | from models.yolo_fpn import YOLOFPN 8 | from models.yolo_head import YOLOXHead 9 | from models.yolo_pafpn import YOLOPAFPN 10 | from models.yolox import YOLOX 11 | 12 | 13 | def build_yolox(name="yolox-s"): 14 | num_classes = 80 15 | 16 | # value meaning: depth, width 17 | param_dict = { 18 | "yolox-nano": (0.33, 0.25), 19 | "yolox-tiny": (0.33, 0.375), 20 | "yolox-s": (0.33, 0.50), 21 | "yolox-m": (0.67, 0.75), 22 | "yolox-l": (1.0, 1.0), 23 | "yolox-x": (1.33, 1.25), 24 | } 25 | if name == "yolov3": 26 | depth = 1.0 27 | width = 1.0 28 | backbone = YOLOFPN() 29 | head = YOLOXHead(num_classes, width, in_channels=[128, 256, 512], act="lrelu") 30 | model = YOLOX(backbone, head) 31 | else: 32 | assert name in param_dict 33 | kwargs = {} 34 | depth, width = param_dict[name] 35 | if name == "yolox-nano": 36 | kwargs["depthwise"] = True 37 | in_channels = [256, 512, 1024] 38 | backbone = YOLOPAFPN(depth, width, in_channels=in_channels, **kwargs) 39 | head = YOLOXHead(num_classes, width, in_channels=in_channels, **kwargs) 40 | model = YOLOX(backbone, head) 41 | 42 | for m in model.modules(): 43 | if isinstance(m, M.BatchNorm2d): 44 | m.eps = 1e-3 45 | 46 | return model 47 | 48 | 49 | def build_and_load(weight_file, name="yolox-s"): 50 | model = build_yolox(name) 51 | model_weights = mge.load(weight_file) 52 | model.load_state_dict(model_weights, strict=False) 53 | return model 54 | -------------------------------------------------------------------------------- /demo/MegEngine/python/convert_weights.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | import argparse 4 | from collections import OrderedDict 5 | 6 | import megengine as mge 7 | import torch 8 | 9 | 10 | def make_parser(): 11 | parser = argparse.ArgumentParser() 12 | parser.add_argument("-w", "--weights", type=str, help="path of weight file") 13 | parser.add_argument( 14 | "-o", 15 | "--output", 16 | default="weight_mge.pkl", 17 | type=str, 18 | help="path of weight file", 19 | ) 20 | return parser 21 | 22 | 23 | def numpy_weights(weight_file): 24 | torch_weights = torch.load(weight_file, map_location="cpu") 25 | if "model" in torch_weights: 26 | torch_weights = torch_weights["model"] 27 | new_dict = OrderedDict() 28 | for k, v in torch_weights.items(): 29 | new_dict[k] = v.cpu().numpy() 30 | return new_dict 31 | 32 | 33 | def map_weights(weight_file, output_file): 34 | torch_weights = numpy_weights(weight_file) 35 | 36 | new_dict = OrderedDict() 37 | for k, v in torch_weights.items(): 38 | if "num_batches_tracked" in k: 39 | print("drop: {}".format(k)) 40 | continue 41 | if k.endswith("bias"): 42 | print("bias key: {}".format(k)) 43 | v = v.reshape(1, -1, 1, 1) 44 | new_dict[k] = v 45 | elif "dconv" in k and "conv.weight" in k: 46 | print("depthwise conv key: {}".format(k)) 47 | cout, cin, k1, k2 = v.shape 48 | v = v.reshape(cout, 1, cin, k1, k2) 49 | new_dict[k] = v 50 | else: 51 | new_dict[k] = v 52 | 53 | mge.save(new_dict, output_file) 54 | print("save weights to {}".format(output_file)) 55 | 56 | 57 | def main(): 58 | parser = make_parser() 59 | args = parser.parse_args() 60 | map_weights(args.weights, args.output) 61 | 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /demo/MegEngine/python/dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | # Copyright (c) Megvii, Inc. and its affiliates. 4 | 5 | import argparse 6 | 7 | import megengine as mge 8 | import numpy as np 9 | from megengine import jit 10 | 11 | from build import build_and_load 12 | 13 | 14 | def make_parser(): 15 | parser = argparse.ArgumentParser("YOLOX Demo Dump") 16 | parser.add_argument("-n", "--name", type=str, default="yolox-s", help="model name") 17 | parser.add_argument("-c", "--ckpt", default=None, type=str, help="ckpt for eval") 18 | parser.add_argument( 19 | "--dump_path", default="model.mge", help="path to save the dumped model" 20 | ) 21 | return parser 22 | 23 | 24 | def dump_static_graph(model, graph_name="model.mge"): 25 | model.eval() 26 | model.head.decode_in_inference = False 27 | 28 | data = mge.Tensor(np.random.random((1, 3, 640, 640))) 29 | 30 | @jit.trace(capture_as_const=True) 31 | def pred_func(data): 32 | outputs = model(data) 33 | return outputs 34 | 35 | pred_func(data) 36 | pred_func.dump( 37 | graph_name, 38 | arg_names=["data"], 39 | optimize_for_inference=True, 40 | enable_fuse_conv_bias_nonlinearity=True, 41 | ) 42 | 43 | 44 | def main(args): 45 | model = build_and_load(args.ckpt, name=args.name) 46 | dump_static_graph(model, args.dump_path) 47 | 48 | 49 | if __name__ == "__main__": 50 | args = make_parser().parse_args() 51 | main(args) 52 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | from .darknet import CSPDarknet, Darknet 6 | from .yolo_fpn import YOLOFPN 7 | from .yolo_head import YOLOXHead 8 | from .yolo_pafpn import YOLOPAFPN 9 | from .yolox import YOLOX 10 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/darknet.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.module as M 6 | 7 | from .network_blocks import BaseConv, CSPLayer, DWConv, Focus, ResLayer, SPPBottleneck 8 | 9 | 10 | class Darknet(M.Module): 11 | # number of blocks from dark2 to dark5. 12 | depth2blocks = {21: [1, 2, 2, 1], 53: [2, 8, 8, 4]} 13 | 14 | def __init__( 15 | self, depth, in_channels=3, stem_out_channels=32, out_features=("dark3", "dark4", "dark5"), 16 | ): 17 | """ 18 | Args: 19 | depth (int): depth of darknet used in model, usually use [21, 53] for this param. 20 | in_channels (int): number of input channels, for example, use 3 for RGB image. 21 | stem_out_channels (int): number of output channels of darknet stem. 22 | It decides channels of darknet layer2 to layer5. 23 | out_features (Tuple[str]): desired output layer name. 24 | """ 25 | super().__init__() 26 | assert out_features, "please provide output features of Darknet" 27 | self.out_features = out_features 28 | self.stem = M.Sequential( 29 | BaseConv(in_channels, stem_out_channels, ksize=3, stride=1, act="lrelu"), 30 | *self.make_group_layer(stem_out_channels, num_blocks=1, stride=2), 31 | ) 32 | in_channels = stem_out_channels * 2 # 64 33 | 34 | num_blocks = Darknet.depth2blocks[depth] 35 | # create darknet with `stem_out_channels` and `num_blocks` layers. 36 | # to make model structure more clear, we don't use `for` statement in python. 37 | self.dark2 = M.Sequential(*self.make_group_layer(in_channels, num_blocks[0], stride=2)) 38 | in_channels *= 2 # 128 39 | self.dark3 = M.Sequential(*self.make_group_layer(in_channels, num_blocks[1], stride=2)) 40 | in_channels *= 2 # 256 41 | self.dark4 = M.Sequential(*self.make_group_layer(in_channels, num_blocks[2], stride=2)) 42 | in_channels *= 2 # 512 43 | 44 | self.dark5 = M.Sequential( 45 | *self.make_group_layer(in_channels, num_blocks[3], stride=2), 46 | *self.make_spp_block([in_channels, in_channels * 2], in_channels * 2), 47 | ) 48 | 49 | def make_group_layer(self, in_channels: int, num_blocks: int, stride: int = 1): 50 | "starts with conv layer then has `num_blocks` `ResLayer`" 51 | return [ 52 | BaseConv(in_channels, in_channels * 2, ksize=3, stride=stride, act="lrelu"), 53 | *[(ResLayer(in_channels * 2)) for _ in range(num_blocks)] 54 | ] 55 | 56 | def make_spp_block(self, filters_list, in_filters): 57 | m = M.Sequential( 58 | *[ 59 | BaseConv(in_filters, filters_list[0], 1, stride=1, act="lrelu"), 60 | BaseConv(filters_list[0], filters_list[1], 3, stride=1, act="lrelu"), 61 | SPPBottleneck( 62 | in_channels=filters_list[1], 63 | out_channels=filters_list[0], 64 | activation="lrelu" 65 | ), 66 | BaseConv(filters_list[0], filters_list[1], 3, stride=1, act="lrelu"), 67 | BaseConv(filters_list[1], filters_list[0], 1, stride=1, act="lrelu"), 68 | ] 69 | ) 70 | return m 71 | 72 | def forward(self, x): 73 | outputs = {} 74 | x = self.stem(x) 75 | outputs["stem"] = x 76 | x = self.dark2(x) 77 | outputs["dark2"] = x 78 | x = self.dark3(x) 79 | outputs["dark3"] = x 80 | x = self.dark4(x) 81 | outputs["dark4"] = x 82 | x = self.dark5(x) 83 | outputs["dark5"] = x 84 | return {k: v for k, v in outputs.items() if k in self.out_features} 85 | 86 | 87 | class CSPDarknet(M.Module): 88 | 89 | def __init__( 90 | self, dep_mul, wid_mul, 91 | out_features=("dark3", "dark4", "dark5"), 92 | depthwise=False, act="silu", 93 | ): 94 | super().__init__() 95 | assert out_features, "please provide output features of Darknet" 96 | self.out_features = out_features 97 | Conv = DWConv if depthwise else BaseConv 98 | 99 | base_channels = int(wid_mul * 64) # 64 100 | base_depth = max(round(dep_mul * 3), 1) # 3 101 | 102 | # stem 103 | self.stem = Focus(3, base_channels, ksize=3, act=act) 104 | 105 | # dark2 106 | self.dark2 = M.Sequential( 107 | Conv(base_channels, base_channels * 2, 3, 2, act=act), 108 | CSPLayer( 109 | base_channels * 2, base_channels * 2, 110 | n=base_depth, depthwise=depthwise, act=act 111 | ), 112 | ) 113 | 114 | # dark3 115 | self.dark3 = M.Sequential( 116 | Conv(base_channels * 2, base_channels * 4, 3, 2, act=act), 117 | CSPLayer( 118 | base_channels * 4, base_channels * 4, 119 | n=base_depth * 3, depthwise=depthwise, act=act, 120 | ), 121 | ) 122 | 123 | # dark4 124 | self.dark4 = M.Sequential( 125 | Conv(base_channels * 4, base_channels * 8, 3, 2, act=act), 126 | CSPLayer( 127 | base_channels * 8, base_channels * 8, 128 | n=base_depth * 3, depthwise=depthwise, act=act, 129 | ), 130 | ) 131 | 132 | # dark5 133 | self.dark5 = M.Sequential( 134 | Conv(base_channels * 8, base_channels * 16, 3, 2, act=act), 135 | SPPBottleneck(base_channels * 16, base_channels * 16, activation=act), 136 | CSPLayer( 137 | base_channels * 16, base_channels * 16, n=base_depth, 138 | shortcut=False, depthwise=depthwise, act=act, 139 | ), 140 | ) 141 | 142 | def forward(self, x): 143 | outputs = {} 144 | x = self.stem(x) 145 | outputs["stem"] = x 146 | x = self.dark2(x) 147 | outputs["dark2"] = x 148 | x = self.dark3(x) 149 | outputs["dark3"] = x 150 | x = self.dark4(x) 151 | outputs["dark4"] = x 152 | x = self.dark5(x) 153 | outputs["dark5"] = x 154 | return {k: v for k, v in outputs.items() if k in self.out_features} 155 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolo_fpn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.functional as F 6 | import megengine.module as M 7 | 8 | from .darknet import Darknet 9 | from .network_blocks import BaseConv, UpSample 10 | 11 | 12 | class YOLOFPN(M.Module): 13 | """ 14 | YOLOFPN module. Darknet 53 is the default backbone of this model. 15 | """ 16 | 17 | def __init__( 18 | self, depth=53, in_features=["dark3", "dark4", "dark5"], 19 | ): 20 | super().__init__() 21 | 22 | self.backbone = Darknet(depth) 23 | self.in_features = in_features 24 | 25 | # out 1 26 | self.out1_cbl = self._make_cbl(512, 256, 1) 27 | self.out1 = self._make_embedding([256, 512], 512 + 256) 28 | 29 | # out 2 30 | self.out2_cbl = self._make_cbl(256, 128, 1) 31 | self.out2 = self._make_embedding([128, 256], 256 + 128) 32 | 33 | # upsample 34 | self.upsample = UpSample(scale_factor=2, mode="bilinear") 35 | 36 | def _make_cbl(self, _in, _out, ks): 37 | return BaseConv(_in, _out, ks, stride=1, act="lrelu") 38 | 39 | def _make_embedding(self, filters_list, in_filters): 40 | m = M.Sequential( 41 | *[ 42 | self._make_cbl(in_filters, filters_list[0], 1), 43 | self._make_cbl(filters_list[0], filters_list[1], 3), 44 | 45 | self._make_cbl(filters_list[1], filters_list[0], 1), 46 | 47 | self._make_cbl(filters_list[0], filters_list[1], 3), 48 | self._make_cbl(filters_list[1], filters_list[0], 1), 49 | ] 50 | ) 51 | return m 52 | 53 | def forward(self, inputs): 54 | """ 55 | Args: 56 | inputs (Tensor): input image. 57 | 58 | Returns: 59 | Tuple[Tensor]: FPN output features.. 60 | """ 61 | # backbone 62 | out_features = self.backbone(inputs) 63 | x2, x1, x0 = [out_features[f] for f in self.in_features] 64 | 65 | # yolo branch 1 66 | x1_in = self.out1_cbl(x0) 67 | x1_in = self.upsample(x1_in) 68 | x1_in = F.concat([x1_in, x1], 1) 69 | out_dark4 = self.out1(x1_in) 70 | 71 | # yolo branch 2 72 | x2_in = self.out2_cbl(out_dark4) 73 | x2_in = self.upsample(x2_in) 74 | x2_in = F.concat([x2_in, x2], 1) 75 | out_dark3 = self.out2(x2_in) 76 | 77 | outputs = (out_dark3, out_dark4, x0) 78 | return outputs 79 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolo_pafpn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.module as M 6 | import megengine.functional as F 7 | 8 | from .darknet import CSPDarknet 9 | from .network_blocks import BaseConv, CSPLayer, DWConv, UpSample 10 | 11 | 12 | class YOLOPAFPN(M.Module): 13 | """ 14 | YOLOv3 model. Darknet 53 is the default backbone of this model. 15 | """ 16 | 17 | def __init__( 18 | self, depth=1.0, width=1.0, in_features=("dark3", "dark4", "dark5"), 19 | in_channels=[256, 512, 1024], depthwise=False, act="silu", 20 | ): 21 | super().__init__() 22 | self.backbone = CSPDarknet(depth, width, depthwise=depthwise, act=act) 23 | self.in_features = in_features 24 | self.in_channels = in_channels 25 | Conv = DWConv if depthwise else BaseConv 26 | 27 | self.upsample = UpSample(scale_factor=2, mode="bilinear") 28 | self.lateral_conv0 = BaseConv( 29 | int(in_channels[2] * width), int(in_channels[1] * width), 1, 1, act=act 30 | ) 31 | self.C3_p4 = CSPLayer( 32 | int(2 * in_channels[1] * width), 33 | int(in_channels[1] * width), 34 | round(3 * depth), 35 | False, 36 | depthwise=depthwise, 37 | act=act, 38 | ) # cat 39 | 40 | self.reduce_conv1 = BaseConv( 41 | int(in_channels[1] * width), int(in_channels[0] * width), 1, 1, act=act 42 | ) 43 | self.C3_p3 = CSPLayer( 44 | int(2 * in_channels[0] * width), 45 | int(in_channels[0] * width), 46 | round(3 * depth), 47 | False, 48 | depthwise=depthwise, 49 | act=act, 50 | ) 51 | 52 | # bottom-up conv 53 | self.bu_conv2 = Conv( 54 | int(in_channels[0] * width), int(in_channels[0] * width), 3, 2, act=act 55 | ) 56 | self.C3_n3 = CSPLayer( 57 | int(2 * in_channels[0] * width), 58 | int(in_channels[1] * width), 59 | round(3 * depth), 60 | False, 61 | depthwise=depthwise, 62 | act=act, 63 | ) 64 | 65 | # bottom-up conv 66 | self.bu_conv1 = Conv( 67 | int(in_channels[1] * width), int(in_channels[1] * width), 3, 2, act=act 68 | ) 69 | self.C3_n4 = CSPLayer( 70 | int(2 * in_channels[1] * width), 71 | int(in_channels[2] * width), 72 | round(3 * depth), 73 | False, 74 | depthwise=depthwise, 75 | act=act, 76 | ) 77 | 78 | def forward(self, input): 79 | """ 80 | Args: 81 | inputs: input images. 82 | 83 | Returns: 84 | Tuple[Tensor]: FPN feature. 85 | """ 86 | 87 | # backbone 88 | out_features = self.backbone(input) 89 | features = [out_features[f] for f in self.in_features] 90 | [x2, x1, x0] = features 91 | 92 | fpn_out0 = self.lateral_conv0(x0) # 1024->512/32 93 | f_out0 = self.upsample(fpn_out0) # 512/16 94 | f_out0 = F.concat([f_out0, x1], 1) # 512->1024/16 95 | f_out0 = self.C3_p4(f_out0) # 1024->512/16 96 | 97 | fpn_out1 = self.reduce_conv1(f_out0) # 512->256/16 98 | f_out1 = self.upsample(fpn_out1) # 256/8 99 | f_out1 = F.concat([f_out1, x2], 1) # 256->512/8 100 | pan_out2 = self.C3_p3(f_out1) # 512->256/8 101 | 102 | p_out1 = self.bu_conv2(pan_out2) # 256->256/16 103 | p_out1 = F.concat([p_out1, fpn_out1], 1) # 256->512/16 104 | pan_out1 = self.C3_n3(p_out1) # 512->512/16 105 | 106 | p_out0 = self.bu_conv1(pan_out1) # 512->512/32 107 | p_out0 = F.concat([p_out0, fpn_out0], 1) # 512->1024/32 108 | pan_out0 = self.C3_n4(p_out0) # 1024->1024/32 109 | 110 | outputs = (pan_out2, pan_out1, pan_out0) 111 | return outputs 112 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.module as M 6 | 7 | from .yolo_head import YOLOXHead 8 | from .yolo_pafpn import YOLOPAFPN 9 | 10 | 11 | class YOLOX(M.Module): 12 | """ 13 | YOLOX model module. The module list is defined by create_yolov3_modules function. 14 | The network returns loss values from three YOLO layers during training 15 | and detection results during test. 16 | """ 17 | 18 | def __init__(self, backbone=None, head=None): 19 | super().__init__() 20 | if backbone is None: 21 | backbone = YOLOPAFPN() 22 | if head is None: 23 | head = YOLOXHead(80) 24 | 25 | self.backbone = backbone 26 | self.head = head 27 | 28 | def forward(self, x): 29 | # fpn output content features of [dark3, dark4, dark5] 30 | fpn_outs = self.backbone(x) 31 | assert not self.training 32 | outputs = self.head(fpn_outs) 33 | 34 | return outputs 35 | -------------------------------------------------------------------------------- /demo/ONNXRuntime/README.md: -------------------------------------------------------------------------------- 1 | ## YOLOX-ONNXRuntime in Python 2 | 3 | This doc introduces how to convert your pytorch model into onnx, and how to run an onnxruntime demo to verify your convertion. 4 | 5 | ### Download ONNX models. 6 | 7 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 8 | |:------| :----: | :----: | :---: | :---: | :---: | 9 | | YOLOX-Nano | 0.91M | 1.08 | 416x416 | 25.8 |[github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.onnx) | 10 | | YOLOX-Tiny | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny.onnx) | 11 | | YOLOX-S | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.onnx) | 12 | | YOLOX-M | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m.onnx) | 13 | | YOLOX-L | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l.onnx) | 14 | | YOLOX-Darknet53| 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_darknet.onnx) | 15 | | YOLOX-X | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x.onnx) | 16 | 17 | 18 | ### Convert Your Model to ONNX 19 | 20 | First, you should move to by: 21 | ```shell 22 | cd 23 | ``` 24 | Then, you can: 25 | 26 | 1. Convert a standard YOLOX model by -n: 27 | ```shell 28 | python3 tools/export_onnx.py --output-name yolox_s.onnx -n yolox-s -c yolox_s.pth 29 | ``` 30 | Notes: 31 | * -n: specify a model name. The model name must be one of the [yolox-s,m,l,x and yolox-nane, yolox-tiny, yolov3] 32 | * -c: the model you have trained 33 | * -o: opset version, default 11. **However, if you will further convert your onnx model to [OpenVINO](https://github.com/Megvii-BaseDetection/YOLOX/demo/OpenVINO/), please specify the opset version to 10.** 34 | * --no-onnxsim: disable onnxsim 35 | * To customize an input shape for onnx model, modify the following code in tools/export.py: 36 | 37 | ```python 38 | dummy_input = torch.randn(1, 3, exp.test_size[0], exp.test_size[1]) 39 | ``` 40 | 41 | 2. Convert a standard YOLOX model by -f. When using -f, the above command is equivalent to: 42 | 43 | ```shell 44 | python3 tools/export_onnx.py --output-name yolox_s.onnx -f exps/default/yolox_s.py -c yolox_s.pth 45 | ``` 46 | 47 | 3. To convert your customized model, please use -f: 48 | 49 | ```shell 50 | python3 tools/export_onnx.py --output-name your_yolox.onnx -f exps/your_dir/your_yolox.py -c your_yolox.pth 51 | ``` 52 | 53 | ### ONNXRuntime Demo 54 | 55 | Step1. 56 | ```shell 57 | cd /demo/ONNXRuntime 58 | ``` 59 | 60 | Step2. 61 | ```shell 62 | python3 onnx_inference.py -m -i -o -s 0.3 --input_shape 640,640 63 | ``` 64 | Notes: 65 | * -m: your converted onnx model 66 | * -i: input_image 67 | * -s: score threshold for visualization. 68 | * --input_shape: should be consistent with the shape you used for onnx convertion. 69 | -------------------------------------------------------------------------------- /demo/ONNXRuntime/onnx_inference.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) Megvii, Inc. and its affiliates. 4 | 5 | import argparse 6 | import os 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | import onnxruntime 12 | 13 | from yolox.data.data_augment import preproc as preprocess 14 | from yolox.data.datasets import COCO_CLASSES 15 | from yolox.utils import mkdir, multiclass_nms, demo_postprocess, vis 16 | 17 | 18 | def make_parser(): 19 | parser = argparse.ArgumentParser("onnxruntime inference sample") 20 | parser.add_argument( 21 | "-m", 22 | "--model", 23 | type=str, 24 | default="yolox.onnx", 25 | help="Input your onnx model.", 26 | ) 27 | parser.add_argument( 28 | "-i", 29 | "--image_path", 30 | type=str, 31 | default='test_image.png', 32 | help="Path to your input image.", 33 | ) 34 | parser.add_argument( 35 | "-o", 36 | "--output_dir", 37 | type=str, 38 | default='demo_output', 39 | help="Path to your output directory.", 40 | ) 41 | parser.add_argument( 42 | "-s", 43 | "--score_thr", 44 | type=float, 45 | default=0.3, 46 | help="Score threshould to filter the result.", 47 | ) 48 | parser.add_argument( 49 | "--input_shape", 50 | type=str, 51 | default="640,640", 52 | help="Specify an input shape for inference.", 53 | ) 54 | parser.add_argument( 55 | "--with_p6", 56 | action="store_true", 57 | help="Whether your model uses p6 in FPN/PAN.", 58 | ) 59 | return parser 60 | 61 | 62 | if __name__ == '__main__': 63 | args = make_parser().parse_args() 64 | 65 | input_shape = tuple(map(int, args.input_shape.split(','))) 66 | origin_img = cv2.imread(args.image_path) 67 | img, ratio = preprocess(origin_img, input_shape) 68 | 69 | session = onnxruntime.InferenceSession(args.model) 70 | 71 | ort_inputs = {session.get_inputs()[0].name: img[None, :, :, :]} 72 | output = session.run(None, ort_inputs) 73 | predictions = demo_postprocess(output[0], input_shape, p6=args.with_p6)[0] 74 | 75 | boxes = predictions[:, :4] 76 | scores = predictions[:, 4:5] * predictions[:, 5:] 77 | 78 | boxes_xyxy = np.ones_like(boxes) 79 | boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2]/2. 80 | boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3]/2. 81 | boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2]/2. 82 | boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3]/2. 83 | boxes_xyxy /= ratio 84 | dets = multiclass_nms(boxes_xyxy, scores, nms_thr=0.45, score_thr=0.1) 85 | if dets is not None: 86 | final_boxes, final_scores, final_cls_inds = dets[:, :4], dets[:, 4], dets[:, 5] 87 | origin_img = vis(origin_img, final_boxes, final_scores, final_cls_inds, 88 | conf=args.score_thr, class_names=COCO_CLASSES) 89 | 90 | mkdir(args.output_dir) 91 | output_path = os.path.join(args.output_dir, os.path.basename(args.image_path)) 92 | cv2.imwrite(output_path, origin_img) 93 | -------------------------------------------------------------------------------- /demo/OpenVINO/README.md: -------------------------------------------------------------------------------- 1 | ## YOLOX for OpenVINO 2 | 3 | * [C++ Demo](./cpp) 4 | * [Python Demo](./python) -------------------------------------------------------------------------------- /demo/OpenVINO/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | project(yolox_openvino_demo) 5 | 6 | find_package(OpenCV REQUIRED) 7 | find_package(InferenceEngine REQUIRED) 8 | find_package(ngraph REQUIRED) 9 | 10 | include_directories( 11 | ${OpenCV_INCLUDE_DIRS} 12 | ${CMAKE_CURRENT_SOURCE_DIR} 13 | ${CMAKE_CURRENT_BINARY_DIR} 14 | ) 15 | 16 | add_executable(yolox_openvino yolox_openvino.cpp) 17 | 18 | target_link_libraries( 19 | yolox_openvino 20 | ${InferenceEngine_LIBRARIES} 21 | ${NGRAPH_LIBRARIES} 22 | ${OpenCV_LIBS} 23 | ) -------------------------------------------------------------------------------- /demo/OpenVINO/cpp/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-OpenVINO in C++ 2 | 3 | This tutorial includes a C++ demo for OpenVINO, as well as some converted models. 4 | 5 | ### Download OpenVINO models. 6 | 7 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 8 | |:------| :----: | :----: | :---: | :---: | :---: | 9 | | [YOLOX-Nano](../../../exps/default/nano.py) | 0.91M | 1.08 | 416x416 | 25.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano_openvino.tar.gz) | 10 | | [YOLOX-Tiny](../../../exps/default/yolox_tiny.py) | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny_openvino.tar.gz) | 11 | | [YOLOX-S](../../../exps/default/yolox_s.py) | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s_openvino.tar.gz) | 12 | | [YOLOX-M](../../../exps/default/yolox_m.py) | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m_openvino.tar.gz) | 13 | | [YOLOX-L](../../../exps/default/yolox_l.py) | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l_openvino.tar.gz) | 14 | | [YOLOX-Darknet53](../../../exps/default/yolov3.py) | 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_dark_openvino.tar.gz) | 15 | | [YOLOX-X](../../../exps/default/yolox_x.py) | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x_openvino.tar.gz) | 16 | 17 | ## Install OpenVINO Toolkit 18 | 19 | Please visit [Openvino Homepage](https://docs.openvinotoolkit.org/latest/get_started_guides.html) for more details. 20 | 21 | ## Set up the Environment 22 | 23 | ### For Linux 24 | 25 | **Option1. Set up the environment tempororally. You need to run this command everytime you start a new shell window.** 26 | 27 | ```shell 28 | source /opt/intel/openvino_2021/bin/setupvars.sh 29 | ``` 30 | 31 | **Option2. Set up the environment permenantly.** 32 | 33 | *Step1.* For Linux: 34 | ```shell 35 | vim ~/.bashrc 36 | ``` 37 | 38 | *Step2.* Add the following line into your file: 39 | 40 | ```shell 41 | source /opt/intel/openvino_2021/bin/setupvars.sh 42 | ``` 43 | 44 | *Step3.* Save and exit the file, then run: 45 | 46 | ```shell 47 | source ~/.bashrc 48 | ``` 49 | 50 | 51 | ## Convert model 52 | 53 | 1. Export ONNX model 54 | 55 | Please refer to the [ONNX tutorial](../../ONNXRuntime). **Note that you should set --opset to 10, otherwise your next step will fail.** 56 | 57 | 2. Convert ONNX to OpenVINO 58 | 59 | ``` shell 60 | cd /openvino_2021/deployment_tools/model_optimizer 61 | ``` 62 | 63 | Install requirements for convert tool 64 | 65 | ```shell 66 | sudo ./install_prerequisites/install_prerequisites_onnx.sh 67 | ``` 68 | 69 | Then convert model. 70 | ```shell 71 | python3 mo.py --input_model --input_shape [--data_type FP16] 72 | ``` 73 | For example: 74 | ```shell 75 | python3 mo.py --input_model yolox_tiny.onnx --input_shape [1,3,416,416] --data_type FP16 76 | ``` 77 | 78 | Make sure the input shape is consistent with [those](yolox_openvino.cpp#L24-L25) in cpp file. 79 | 80 | ## Build 81 | 82 | ### Linux 83 | ```shell 84 | source /opt/intel/openvino_2021/bin/setupvars.sh 85 | mkdir build 86 | cd build 87 | cmake .. 88 | make 89 | ``` 90 | 91 | ## Demo 92 | 93 | ### c++ 94 | 95 | ```shell 96 | ./yolox_openvino 97 | ``` 98 | -------------------------------------------------------------------------------- /demo/OpenVINO/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-OpenVINO in Python 2 | 3 | This tutorial includes a Python demo for OpenVINO, as well as some converted models. 4 | 5 | ### Download OpenVINO models. 6 | 7 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 8 | |:------| :----: | :----: | :---: | :---: | :---: | 9 | | [YOLOX-Nano](../../../exps/default/nano.py) | 0.91M | 1.08 | 416x416 | 25.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano_openvino.tar.gz) | 10 | | [YOLOX-Tiny](../../../exps/default/yolox_tiny.py) | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny_openvino.tar.gz) | 11 | | [YOLOX-S](../../../exps/default/yolox_s.py) | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s_openvino.tar.gz) | 12 | | [YOLOX-M](../../../exps/default/yolox_m.py) | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m_openvino.tar.gz) | 13 | | [YOLOX-L](../../../exps/default/yolox_l.py) | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l_openvino.tar.gz) | 14 | | [YOLOX-Darknet53](../../../exps/default/yolov3.py) | 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_dark_openvino.tar.gz) | 15 | | [YOLOX-X](../../../exps/default/yolox_x.py) | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x_openvino.tar.gz) | 16 | 17 | ## Install OpenVINO Toolkit 18 | 19 | Please visit [Openvino Homepage](https://docs.openvinotoolkit.org/latest/get_started_guides.html) for more details. 20 | 21 | ## Set up the Environment 22 | 23 | ### For Linux 24 | 25 | **Option1. Set up the environment tempororally. You need to run this command everytime you start a new shell window.** 26 | 27 | ```shell 28 | source /opt/intel/openvino_2021/bin/setupvars.sh 29 | ``` 30 | 31 | **Option2. Set up the environment permenantly.** 32 | 33 | *Step1.* For Linux: 34 | ```shell 35 | vim ~/.bashrc 36 | ``` 37 | 38 | *Step2.* Add the following line into your file: 39 | 40 | ```shell 41 | source /opt/intel/openvino_2021/bin/setupvars.sh 42 | ``` 43 | 44 | *Step3.* Save and exit the file, then run: 45 | 46 | ```shell 47 | source ~/.bashrc 48 | ``` 49 | 50 | 51 | ## Convert model 52 | 53 | 1. Export ONNX model 54 | 55 | Please refer to the [ONNX tutorial](https://github.com/Megvii-BaseDetection/YOLOX/demo/ONNXRuntime). **Note that you should set --opset to 10, otherwise your next step will fail.** 56 | 57 | 2. Convert ONNX to OpenVINO 58 | 59 | ``` shell 60 | cd /openvino_2021/deployment_tools/model_optimizer 61 | ``` 62 | 63 | Install requirements for convert tool 64 | 65 | ```shell 66 | sudo ./install_prerequisites/install_prerequisites_onnx.sh 67 | ``` 68 | 69 | Then convert model. 70 | ```shell 71 | python3 mo.py --input_model --input_shape [--data_type FP16] 72 | ``` 73 | For example: 74 | ```shell 75 | python3 mo.py --input_model yolox.onnx --input_shape [1,3,640,640] --data_type FP16 --output_dir converted_output 76 | ``` 77 | 78 | ## Demo 79 | 80 | ### python 81 | 82 | ```shell 83 | python openvino_inference.py -m -i 84 | ``` 85 | or 86 | ```shell 87 | python openvino_inference.py -m -i -o -s -d 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /demo/TensorRT/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(yolox) 4 | 5 | add_definitions(-std=c++11) 6 | 7 | option(CUDA_USE_STATIC_CUDA_RUNTIME OFF) 8 | set(CMAKE_CXX_STANDARD 11) 9 | set(CMAKE_BUILD_TYPE Debug) 10 | 11 | find_package(CUDA REQUIRED) 12 | 13 | include_directories(${PROJECT_SOURCE_DIR}/include) 14 | # include and link dirs of cuda and tensorrt, you need adapt them if yours are different 15 | # cuda 16 | include_directories(/data/cuda/cuda-10.2/cuda/include) 17 | link_directories(/data/cuda/cuda-10.2/cuda/lib64) 18 | # cudnn 19 | include_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/include) 20 | link_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/lib64) 21 | # tensorrt 22 | include_directories(/data/cuda/cuda-10.2/TensorRT/v7.2.1.6/include) 23 | link_directories(/data/cuda/cuda-10.2/TensorRT/v7.2.1.6/lib) 24 | 25 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED") 26 | 27 | find_package(OpenCV) 28 | include_directories(${OpenCV_INCLUDE_DIRS}) 29 | 30 | add_executable(yolox ${PROJECT_SOURCE_DIR}/yolox.cpp) 31 | target_link_libraries(yolox nvinfer) 32 | target_link_libraries(yolox cudart) 33 | target_link_libraries(yolox ${OpenCV_LIBS}) 34 | 35 | add_definitions(-O2 -pthread) 36 | 37 | -------------------------------------------------------------------------------- /demo/TensorRT/cpp/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-TensorRT in C++ 2 | 3 | As YOLOX models are easy to convert to tensorrt using [torch2trt gitrepo](https://github.com/NVIDIA-AI-IOT/torch2trt), 4 | our C++ demo does not include the model converting or constructing like other tenorrt demos. 5 | 6 | 7 | ## Step 1: Prepare serialized engine file 8 | 9 | Follow the trt [python demo README](https://github.com/Megvii-BaseDetection/YOLOX/blob/main/demo/TensorRT/python/README.md) to convert and save the serialized engine file. 10 | 11 | Check the 'model_trt.engine' file generated from Step 1, which will be automatically saved at the current demo dir. 12 | 13 | 14 | ## Step 2: build the demo 15 | 16 | Please follow the [TensorRT Installation Guide](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html) to install TensorRT. 17 | 18 | And you should set the TensorRT path and CUDA path in CMakeLists.txt. 19 | 20 | If you train your custom dataset, you may need to modify the value of `num_class`. 21 | 22 | ```c++ 23 | const int num_class = 80; 24 | ``` 25 | 26 | Install opencv with ```sudo apt-get install libopencv-dev``` (we don't need a higher version of opencv like v3.3+). 27 | 28 | build the demo: 29 | 30 | ```shell 31 | mkdir build 32 | cd build 33 | cmake .. 34 | make 35 | ``` 36 | 37 | Then run the demo: 38 | 39 | ```shell 40 | ./yolox ../model_trt.engine -i ../../../../assets/dog.jpg 41 | ``` 42 | 43 | or 44 | 45 | ```shell 46 | ./yolox -i 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /demo/TensorRT/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-TensorRT in Python 2 | 3 | This tutorial includes a Python demo for TensorRT. 4 | 5 | ## Install TensorRT Toolkit 6 | 7 | Please follow the [TensorRT Installation Guide](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html) and [torch2trt gitrepo](https://github.com/NVIDIA-AI-IOT/torch2trt) to install TensorRT and torch2trt. 8 | 9 | ## Convert model 10 | 11 | YOLOX models can be easily conveted to TensorRT models using torch2trt 12 | 13 | If you want to convert our model, use the flag -n to specify a model name: 14 | ```shell 15 | python tools/trt.py -n -c 16 | ``` 17 | For example: 18 | ```shell 19 | python tools/trt.py -n yolox-s -c your_ckpt.pth 20 | ``` 21 | can be: yolox-nano, yolox-tiny. yolox-s, yolox-m, yolox-l, yolox-x. 22 | 23 | If you want to convert your customized model, use the flag -f to specify you exp file: 24 | ```shell 25 | python tools/trt.py -f -c 26 | ``` 27 | For example: 28 | ```shell 29 | python tools/trt.py -f /path/to/your/yolox/exps/yolox_s.py -c your_ckpt.pth 30 | ``` 31 | *yolox_s.py* can be any exp file modified by you. 32 | 33 | The converted model and the serialized engine file (for C++ demo) will be saved on your experiment output dir. 34 | 35 | ## Demo 36 | 37 | The TensorRT python demo is merged on our pytorch demo file, so you can run the pytorch demo command with ```--trt```. 38 | 39 | ```shell 40 | python tools/demo.py image -n yolox-s --trt --save_result 41 | ``` 42 | or 43 | ```shell 44 | python tools/demo.py image -f exps/default/yolox_s.py --trt --save_result 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /demo/ncnn/android/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-Android-ncnn 2 | 3 | Andoird app of YOLOX object detection base on [ncnn](https://github.com/Tencent/ncnn) 4 | 5 | 6 | ## Tutorial 7 | 8 | ### Step1 9 | 10 | Download ncnn-android-vulkan.zip from [releases of ncnn](https://github.com/Tencent/ncnn/releases). This repo uses 11 | [20210525 release](https://github.com/Tencent/ncnn/releases/download/20210525/ncnn-20210525-android-vulkan.zip) for building. 12 | 13 | ### Step2 14 | 15 | After downloading, please extract your zip file. Then, there are two ways to finish this step: 16 | * put your extracted directory into **app/src/main/jni** 17 | * change the **ncnn_DIR** path in **app/src/main/jni/CMakeLists.txt** to your extracted directory 18 | 19 | ### Step3 20 | Download example param and bin file from [onedrive](https://megvii-my.sharepoint.cn/:u:/g/personal/gezheng_megvii_com/ESXBH_GSSmFMszWJ6YG2VkQB5cWDfqVWXgk0D996jH0rpQ?e=qzEqUh) or [github](https://github.com/Megvii-BaseDetection/storage/releases/download/0.0.1/yolox_s_ncnn.tar.gz). Unzip the file to **app/src/main/assets**. 21 | 22 | ### Step4 23 | Open this project with Android Studio, build it and enjoy! 24 | 25 | ## Reference 26 | 27 | * [ncnn-android-yolov5](https://github.com/nihui/ncnn-android-yolov5) 28 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "29.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.megvii.yoloXncnn" 9 | archivesBaseName = "$applicationId" 10 | 11 | ndk { 12 | moduleName "ncnn" 13 | abiFilters "armeabi-v7a", "arm64-v8a" 14 | } 15 | minSdkVersion 24 16 | } 17 | 18 | externalNativeBuild { 19 | cmake { 20 | version "3.10.2" 21 | path file('src/main/jni/CMakeLists.txt') 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/java/com/megvii/yoloXncnn/yoloXncnn.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) Megvii, Inc. and its affiliates. All rights reserved. 2 | 3 | package com.megvii.yoloXncnn; 4 | 5 | import android.content.res.AssetManager; 6 | import android.graphics.Bitmap; 7 | 8 | public class YOLOXncnn 9 | { 10 | public native boolean Init(AssetManager mgr); 11 | 12 | public class Obj 13 | { 14 | public float x; 15 | public float y; 16 | public float w; 17 | public float h; 18 | public String label; 19 | public float prob; 20 | } 21 | 22 | public native Obj[] Detect(Bitmap bitmap, boolean use_gpu); 23 | 24 | static { 25 | System.loadLibrary("yoloXncnn"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/jni/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(yoloXncnn) 2 | 3 | cmake_minimum_required(VERSION 3.4.1) 4 | 5 | set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210525-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn) 6 | find_package(ncnn REQUIRED) 7 | 8 | add_library(yoloXncnn SHARED yoloXncnn_jni.cpp) 9 | 10 | target_link_libraries(yoloXncnn 11 | ncnn 12 | 13 | jnigraphics 14 | ) 15 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 |