├── LICENSE ├── README.md ├── README_EN.md ├── assets ├── bit.png ├── coco.jpg └── visdrone.jpg ├── cpp ├── ascend │ ├── CMakeLists.txt │ ├── README.md │ ├── bin │ │ └── ascend_det │ ├── include │ │ ├── argparser.h │ │ ├── cpp-py │ │ │ └── str.h │ │ ├── detect │ │ │ ├── common.h │ │ │ └── mdc │ │ │ │ ├── blob.h │ │ │ │ ├── davinci_net.h │ │ │ │ ├── dvpp_handler.h │ │ │ │ ├── image_data.h │ │ │ │ └── yolo.h │ │ └── print_utils.h │ ├── scripts │ │ └── find_packages.py │ └── src │ │ ├── davinci_net.cpp │ │ ├── dvpp_handler.cpp │ │ └── main.cpp ├── mnn │ ├── CMakeLists.txt │ ├── README.md │ ├── config │ │ ├── mnn_detection_coco.yaml │ │ └── mnn_detection_visdrone.yaml │ ├── include │ │ ├── argparse │ │ │ └── argparser.h │ │ ├── image_utils │ │ │ ├── detect_process.h │ │ │ └── mnn.h │ │ └── print_utils.h │ ├── models │ │ └── README.txt │ ├── setup.bash │ └── src │ │ └── demo.cpp ├── rknn │ ├── CMakeLists.txt │ ├── README.md │ ├── include │ │ ├── 3rdparty │ │ │ └── rga │ │ │ │ └── RK3588 │ │ │ │ ├── include │ │ │ │ ├── GrallocOps.h │ │ │ │ ├── RgaApi.h │ │ │ │ ├── RgaMutex.h │ │ │ │ ├── RgaSingleton.h │ │ │ │ ├── RgaUtils.h │ │ │ │ ├── RockchipRga.h │ │ │ │ ├── drmrga.h │ │ │ │ ├── im2d.h │ │ │ │ ├── im2d.hpp │ │ │ │ ├── im2d_buffer.h │ │ │ │ ├── im2d_common.h │ │ │ │ ├── im2d_expand.h │ │ │ │ ├── im2d_mpi.h │ │ │ │ ├── im2d_single.h │ │ │ │ ├── im2d_task.h │ │ │ │ ├── im2d_type.h │ │ │ │ ├── im2d_version.h │ │ │ │ └── rga.h │ │ │ │ └── lib │ │ │ │ └── Linux │ │ │ │ └── aarch64 │ │ │ │ └── librga.so │ │ ├── argparse │ │ │ └── argparser.h │ │ ├── drm_func.h │ │ ├── image_utils │ │ │ ├── detect_process.h │ │ │ ├── mnn.h │ │ │ └── rknn.h │ │ ├── libmk_api.so │ │ ├── librga.so │ │ ├── librknnrt.so │ │ ├── print_utils.h │ │ ├── rga_func.h │ │ ├── rknn_api.h │ │ └── rknn_matmul_api.h │ ├── model │ │ └── readme.txt │ ├── scripts │ │ └── onnx2rknn.py │ ├── setup_rk3588.sh │ ├── src │ │ └── demo.cpp │ └── toolkit_install │ │ ├── requirements36.txt │ │ ├── requirements38-310.txt │ │ └── rknn_toolkit_install └── tensorrt │ ├── CMakeLists.txt │ ├── README.md │ ├── include │ ├── argparse │ │ └── argparser.h │ ├── image_utils │ │ ├── detect_process.h │ │ ├── logging.h │ │ └── trt.h │ └── print_utils.h │ └── src │ ├── trt.cpp │ └── yolo.cpp ├── demo ├── amct_onnx2om.py ├── batch_detect.py ├── check_params.py ├── conv2repconv.py ├── dota_detect.py ├── eval_from_json.py ├── export_onnx2trt.py ├── export_pth2onnx.py └── load_dataset.py ├── deployment ├── CMakeLists.txt ├── README.md ├── detect.py ├── detect_for_mdc300f.py ├── models │ ├── ascend.yaml │ ├── coco.bin │ ├── coco.engine │ ├── coco.mnn │ ├── coco.om │ ├── coco.rknn │ ├── horizon.yaml │ ├── mnn.yaml │ ├── rknn.yaml │ └── trt.yaml ├── server.py ├── src │ ├── argparser.h │ ├── demo.cpp │ ├── demo_image.cpp │ ├── demo_no_show.cpp │ └── demo_one_image.cpp └── yolo │ ├── CMakeLists.txt │ ├── __init__.py │ ├── capture │ ├── __init__.py │ └── capture.py │ ├── common.hpp │ ├── datetime.h │ ├── detect.cpp │ ├── detect.hpp │ ├── lib │ ├── horizon │ │ ├── hbmedia │ │ │ ├── libmultimedia.so │ │ │ ├── libmultimedia.so.1 │ │ │ └── libmultimedia.so.1.2.3 │ │ ├── libalog.so │ │ ├── libalog.so.1 │ │ ├── libalog.so.1.0.1 │ │ ├── libcnn_intf.so │ │ ├── libcnn_intf.so.1 │ │ ├── libcnn_intf.so.1.3.5 │ │ ├── libdnn.so │ │ ├── libhb_api_isp.so │ │ ├── libhb_api_isp.so.1 │ │ ├── libhb_api_isp.so.1.0.3 │ │ ├── libhbaudio.so │ │ ├── libhbaudio.so.1 │ │ ├── libhbaudio.so.1.0.0 │ │ ├── libhbcgroup.so │ │ ├── libhbcgroup.so.1 │ │ ├── libhbcgroup.so.1.0.0 │ │ ├── libhbdds.so │ │ ├── libhbdds.so.1 │ │ ├── libhbdds.so.1.0.0 │ │ ├── libhbkm.so │ │ ├── libhbkm.so.1 │ │ ├── libhbkm.so.1.0.0 │ │ ├── libhbmem.so │ │ ├── libhbmem.so.0 │ │ ├── libhbmem.so.0.2.0 │ │ ├── libhbpcie.so │ │ ├── libhbpcie.so.1 │ │ ├── libhbpcie.so.1.0.0 │ │ ├── libhbplayer.so │ │ ├── libhbplayer.so.1 │ │ ├── libhbplayer.so.1.0.1 │ │ ├── libhbrt_bayes_aarch64.so │ │ ├── libhbrt_bernoulli_aarch64.so │ │ ├── libhbspihal.so │ │ ├── libhbspihal.so.1 │ │ ├── libhbspihal.so.1.0.2 │ │ ├── libion.so │ │ ├── libion.so.1 │ │ └── libion.so.1.0.0 │ └── librknnrt.so │ ├── libbase.py │ ├── logger.h │ ├── os.h │ ├── platform │ ├── ascend │ │ ├── CMakeLists.txt │ │ ├── acl │ │ │ ├── acl.h │ │ │ ├── acl_base.h │ │ │ ├── acl_mdl.h │ │ │ ├── acl_op.h │ │ │ ├── acl_prof.h │ │ │ ├── acl_rt.h │ │ │ ├── error_codes │ │ │ │ ├── ge_error_codes.h │ │ │ │ └── rt_error_codes.h │ │ │ └── ops │ │ │ │ ├── acl_cblas.h │ │ │ │ ├── acl_dvpp.h │ │ │ │ └── acl_fv.h │ │ ├── ascend.cpp │ │ ├── blob.h │ │ ├── davinci_net.cpp │ │ └── davinci_net.h │ ├── common.hpp │ ├── horizon │ │ ├── CMakeLists.txt │ │ ├── dnn │ │ │ ├── hb_dnn.h │ │ │ ├── hb_dnn_ext.h │ │ │ ├── hb_dnn_status.h │ │ │ ├── hb_sys.h │ │ │ └── plugin │ │ │ │ ├── hb_dnn_dtype.h │ │ │ │ ├── hb_dnn_layer.h │ │ │ │ ├── hb_dnn_ndarray.h │ │ │ │ ├── hb_dnn_plugin.h │ │ │ │ └── hb_dnn_tuple.h │ │ └── horizon.cpp │ ├── mnn │ │ └── mnn.cpp │ ├── rockchip │ │ ├── rknn.cpp │ │ └── rknn_api.h │ └── tensorrt │ │ ├── tensorrt.cpp │ │ └── trt_logging.h │ ├── str.h │ ├── visualize.py │ ├── yolo.hpp │ └── yolo.py ├── detect.py ├── docker_export.py ├── edgeyolo ├── __init__.py ├── data │ ├── __init__.py │ ├── coco_classes.py │ ├── data_augment.py │ ├── data_prefetcher.py │ ├── dataloading.py │ ├── datasets │ │ ├── __init__.py │ │ ├── coco.py │ │ ├── coco_classes.py │ │ ├── datasets_wrapper.py │ │ ├── dota.py │ │ ├── enhanced_mosaicdetection.py │ │ ├── get_dataset.py │ │ ├── mask_coding.py │ │ ├── mask_dataloader.py │ │ ├── mosaicdetection.py │ │ ├── mosaicdetection_ori.py │ │ ├── samlabel.py │ │ ├── visdrone.py │ │ ├── voc.py │ │ ├── voc_classes.py │ │ └── yolo.py │ ├── preprocess.py │ └── samplers.py ├── detect │ ├── __init__.py │ ├── detector.py │ ├── dotaDetector.py │ └── export_detector.py ├── export │ ├── __init__.py │ ├── calib.py │ ├── pth2trt.py │ └── rknn.py ├── models │ ├── __init__.py │ ├── common.py │ ├── experimental.py │ └── yolo.py ├── train │ ├── __init__.py │ ├── default.yaml │ ├── launch_train.py │ ├── loss.py │ ├── optimizer.py │ ├── trainer.py │ └── val │ │ ├── __init__.py │ │ ├── coco_evaluator.py │ │ └── dota_evaluator.py ├── utils │ ├── __init__.py │ ├── allreduce_norm.py │ ├── boxes.py │ ├── cfg_loading.py │ ├── checkpoint.py │ ├── demo_utils.py │ ├── dist.py │ ├── ema.py │ ├── logger.py │ ├── lr_scheduler.py │ ├── metric.py │ ├── model_utils.py │ ├── plot_fig.py │ └── setup_env.py └── utils2 │ ├── __init__.py │ ├── activations.py │ ├── add_nms.py │ ├── autoanchor.py │ ├── datasets.py │ ├── general.py │ ├── google_utils.py │ ├── loss.py │ ├── metrics.py │ ├── plots.py │ └── torch_utils.py ├── evaluate.py ├── export.py ├── params ├── dataset │ ├── bdd100k.yaml │ ├── coco.yaml │ ├── dota.yaml │ ├── samlabel.yaml │ ├── visdrone.yaml │ ├── visdrone_coco.yaml │ ├── voc.yaml │ └── yolo.yaml ├── model │ ├── edgeyolo.yaml │ ├── edgeyolo_m.yaml │ ├── edgeyolo_s.yaml │ ├── edgeyolo_tiny.yaml │ └── edgeyolo_tiny_lrelu.yaml └── train │ ├── train_coco.yaml │ ├── train_dota.yaml │ └── train_visdrone.yaml ├── plot.py ├── requirements.txt └── train.py /assets/bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/assets/bit.png -------------------------------------------------------------------------------- /assets/coco.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/assets/coco.jpg -------------------------------------------------------------------------------- /assets/visdrone.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/assets/visdrone.jpg -------------------------------------------------------------------------------- /cpp/ascend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") 4 | set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") 5 | 6 | project(ascend) 7 | 8 | 9 | set(CMAKE_CXX_FLAGS "-std=c++14 -O3 -fPIC -w ${CMAKE_CXX_FLAGS}") 10 | set(CMAKE_BUILD_TYPE "Release") 11 | 12 | 13 | set(ASCEND_ACLLIB_PATH "/usr/local/Ascend/ascend-toolkit/5.0.mdc300/acllib") 14 | set(ASCEND_DRIVER_PATH "/usr/local/Ascend/ascend-toolkit/5.0.mdc300/x86_64-linux/mdc_driver_sdk") 15 | set(THIRD_PARTY_PATH "/root/MDC/thrid_party") 16 | set(CROSS_COMPILE_PATH "/usr/local/ubuntu_crossbuild_devkit/sysroot/usr") 17 | 18 | 19 | include_directories( 20 | ${ASCEND_ACLLIB_PATH}/include 21 | ${ASCEND_DRIVER_PATH}/driver/include 22 | ${CROSS_COMPILE_PATH}/local/include 23 | ${CROSS_COMPILE_PATH}/include 24 | ${PROJECT_SOURCE_DIR}/include 25 | ${PROJECT_SOURCE_DIR} 26 | ) 27 | 28 | link_directories( 29 | ${ASCEND_DRIVER_PATH}/driver/lib64 30 | ${ASCEND_ACLLIB_PATH}/lib64/stub 31 | ${CROSS_COMPILE_PATH}/local/lib 32 | /usr/local/ubuntu_crossbuild_devkit/sysroot/lib 33 | /usr/local/ubuntu_crossbuild_devkit/sysroot/lib/aarch64-linux-gnu 34 | ${CROSS_COMPILE_PATH}/lib 35 | ${CROSS_COMPILE_PATH}/lib/aarch64-linux-gnu 36 | ) 37 | 38 | 39 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 40 | 41 | 42 | add_executable(${PROJECT_NAME}_det 43 | src/main.cpp 44 | src/dvpp_handler.cpp 45 | src/davinci_net.cpp 46 | ) 47 | 48 | target_link_libraries(${PROJECT_NAME}_det 49 | yaml-cpp 50 | opencv_calib3d opencv_core opencv_dnn opencv_features2d opencv_flann opencv_highgui opencv_imgcodecs opencv_imgproc opencv_ml opencv_objdetect opencv_photo opencv_stitching opencv_video opencv_videoio opencv_shape opencv_superres opencv_videostab opencv_viz 51 | Dvpp_api Dvpp_vpc 52 | OMX_hisi_video_decoder OMX_hisi_video_encoder 53 | Dvpp_png_decoder Dvpp_jpeg_decoder Dvpp_jpeg_encoder 54 | acl_dvpp ascendcl 55 | slog 56 | c_sec 57 | pthread 58 | ) 59 | 60 | -------------------------------------------------------------------------------- /cpp/ascend/README.md: -------------------------------------------------------------------------------- 1 | # EdgeYOLO deployment for Huawei Ascent devices 2 | 3 | ## requirements 4 | 5 | - 1. Ascend-cann-toolkit_X.X.X_linux-xxxxx.run from Huawei Official Website. 6 | - 2. Ascend-cann-amct_X.X.X_linux-xxxxx.zip from Huawei Official Website. 7 | - 3. other common requiements 8 | 9 | ## model convertion 10 | ```bash 11 | # firstly use export.py/docker_export.py to export your onnx 12 | # then use convertion tools, need requirements 2 13 | python demo/amct_onnx2om.py -i /path/to/your/onnx/file.onnx \ 14 | -b 16 \ 15 | --dataset cfg/dataset/coco.yaml \ # select calib images from val set of this dataset 16 | --om \ # convert to om file, need requirements 1 17 | --fusion 18 | ``` 19 | 20 | ## run 21 | 22 | ### compile 23 | 24 | ```bash 25 | mkdir build && cd build 26 | cmake .. 27 | make -j4 28 | ``` 29 | 30 | ### prepare 31 | 32 | - generate yaml file like this 33 | ```yaml 34 | # cfg/model.yaml 35 | model_path: /absolute/path/to/your/model.om 36 | names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 37 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 38 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 39 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 40 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 41 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 42 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 43 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 44 | 'hair drier', 'toothbrush'] 45 | ``` 46 | 47 | - finally, run this demo 48 | ```bash 49 | ./ascend_det --cfg cfg/model.yaml --source /path/to/your/video.mp4 50 | ``` 51 | -------------------------------------------------------------------------------- /cpp/ascend/bin/ascend_det: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/cpp/ascend/bin/ascend_det -------------------------------------------------------------------------------- /cpp/ascend/include/cpp-py/str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * str.h 3 | * 4 | * Created on: Mar 6, 2024 5 | * Author: LSH9832 6 | */ 7 | #ifndef CPP_PY_STR_H 8 | #define CPP_PY_STR_H 9 | 10 | 11 | namespace pyStr { 12 | 13 | bool startswith(const std::string& str, const std::string& prefix) { 14 | size_t str_len = str.length(); 15 | size_t prefix_len = prefix.length(); 16 | if (prefix_len > str_len) return false; 17 | return str.find(prefix) == 0; 18 | } 19 | 20 | bool endswith(const std::string& str, const std::string& suffix) { 21 | size_t str_len = str.length(); 22 | size_t suffix_len = suffix.length(); 23 | if (suffix_len > str_len) return false; 24 | return (str.find(suffix, str_len - suffix_len) == (str_len - suffix_len)); 25 | } 26 | 27 | bool isdigit(const std::string& str) { 28 | for (char c : str) if (!std::isdigit(c)) return false; 29 | return true; 30 | } 31 | 32 | std::string replace(std::string str, std::string old_substr, std::string new_substr) { 33 | size_t pos = 0; 34 | while ((pos = str.find(old_substr, pos)) != std::string::npos) { 35 | str.replace(pos, old_substr.length(), new_substr); 36 | pos += new_substr.length(); // 更新位置以继续搜索 37 | } 38 | return str; 39 | } 40 | 41 | std::vector split(const std::string &s, const std::string &delimiter) { 42 | std::vector tokens; 43 | size_t pos = 0; 44 | std::string::size_type prev_pos = 0; 45 | while ((pos = s.find(delimiter, prev_pos)) != std::string::npos) { 46 | tokens.push_back(s.substr(prev_pos, pos - prev_pos)); 47 | prev_pos = pos + delimiter.length(); 48 | } 49 | if (prev_pos < s.length()) tokens.push_back(s.substr(prev_pos)); 50 | return tokens; 51 | } 52 | 53 | std::vector split(const std::string &s) { 54 | std::vector tokens; 55 | size_t pos = 0; 56 | int prev_pos = -1; 57 | 58 | for (size_t i=0; i=length) return str; 82 | for (int i=0;i=length) return str; 89 | for (int i=0;i=length) return str; 96 | for (int i=0;i=length) return ret; 103 | int ori_len = ret.length(); 104 | for (int i=0;i 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | class BlobDesc { 17 | public: 18 | BlobDesc(): size_(0) 19 | { 20 | shape_.assign(0, 0); 21 | } 22 | 23 | virtual ~BlobDesc() 24 | { 25 | shape_.clear(); 26 | size_ = 0; 27 | } 28 | 29 | inline uint32_t Size() const 30 | { 31 | return size_; 32 | } 33 | 34 | inline uint32_t Dim(const int i) const 35 | { 36 | return shape_[i]; 37 | } 38 | 39 | inline std::string Shape() const 40 | { 41 | std::string shapeStr = ""; 42 | for (int i = 0; i < shape_.size(); i++) { 43 | shapeStr += std::to_string(shape_[i]) + " "; 44 | } 45 | return shapeStr; 46 | } 47 | 48 | inline uint32_t Offset(const std::vector dim) const 49 | { 50 | uint32_t offset = 0; 51 | for (int i = 0; i < shape_.size(); i++) { 52 | offset *= shape_[i]; 53 | if (dim.size() > i) { 54 | offset += dim[i]; 55 | } 56 | } 57 | 58 | return offset; 59 | } 60 | 61 | virtual int Reshape(const std::vector &dim) = 0; 62 | 63 | virtual int ReshapeLike(const BlobDesc &blobDesc) = 0; 64 | 65 | uint32_t size_; 66 | std::vector shape_; 67 | }; 68 | 69 | template 70 | class Blob : public BlobDesc { 71 | public: 72 | Blob() : data_(nullptr) {} 73 | 74 | ~Blob() 75 | { 76 | if (data_ != nullptr) { 77 | (void)acldvppFree(data_); 78 | } 79 | data_ = nullptr; 80 | } 81 | 82 | T *Data() 83 | { 84 | return data_; 85 | } 86 | 87 | virtual int Reshape(const std::vector &dim) 88 | { 89 | shape_.clear(); 90 | size_ = sizeof(T); 91 | for (int i = 0; i < dim.size(); i++) { 92 | shape_.push_back(dim[i]); 93 | size_ *= dim[i]; 94 | } 95 | 96 | if (Alloc(size_) != 0) { 97 | ACL_APP_LOG(ACL_ERROR, "Alloc blob data failed!"); 98 | return 1; 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | virtual int ReshapeLike(const BlobDesc &blob) 105 | { 106 | return Reshape(blob.shape_); 107 | } 108 | 109 | int Alloc(const uint32_t size) 110 | { 111 | size_ = size; 112 | if (data_ != nullptr) { 113 | (void)acldvppFree(data_); 114 | data_ = nullptr; 115 | ACL_APP_LOG(ACL_WARNING, "blob has been initialized, reinit!"); 116 | } 117 | 118 | aclError ret = acldvppMalloc((void **)&data_, size); 119 | if (ret != ACL_ERROR_NONE || data_ == nullptr) { 120 | ACL_APP_LOG(ACL_ERROR, "aclMalloc fail, size is %zu!", size); 121 | return 1; 122 | } 123 | 124 | return 0; 125 | } 126 | 127 | private: 128 | T *data_; 129 | }; 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /cpp/ascend/include/detect/mdc/davinci_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved. 3 | * Description: header for davinci net 4 | */ 5 | 6 | #ifndef DAVINCI_NET_H 7 | #define DAVINCI_NET_H 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class DavinciNet { 16 | private: 17 | uint32_t modelId_; 18 | void *modelMemPtr_; 19 | void *modelWeightPtr_; 20 | aclmdlDesc *modelDesc_; 21 | aclmdlDataset *input_; 22 | aclmdlDataset *output_; 23 | 24 | std::map>> blobMap; 25 | 26 | int32_t deviceId_; 27 | aclrtContext context_; 28 | aclrtStream stream_; 29 | 30 | bool isLoaded_; 31 | 32 | public: 33 | 34 | std::vector input_names, output_names; 35 | std::vector> inputs_dims, outputs_dims; 36 | 37 | DavinciNet(); 38 | 39 | ~DavinciNet(); 40 | 41 | int Init(const std::string &modelPath, const int32_t deviceId = 0); 42 | 43 | int CreateContextAndStream(); 44 | 45 | int LoadModelFromFile(const std::string &modelPath); 46 | int CreateDesc(); 47 | int CreateInputTensor(); 48 | int CreateOutputTensor(); 49 | 50 | void DestroyDesc(); 51 | void DestroyInputTensor(); 52 | void DestroyOutputTensor(); 53 | void UnloadModel(); 54 | void DestroyContextAndStream(); 55 | void DisplayTensorInfo(const aclmdlIODims &dims, const aclDataType dtype, const bool input); 56 | 57 | int Inference(); 58 | std::shared_ptr GetBlob(const std::string &blobName); 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /cpp/ascend/include/detect/mdc/dvpp_handler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved. 3 | * Description: header for dvpp handler 4 | */ 5 | 6 | #ifndef DVPP_HANDLER_H 7 | #define DVPP_HANDLER_H 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | class DVPPHandler { 20 | private: 21 | int ReadImage(const std::string &fileName, Blob &inBuf); 22 | 23 | int DvppProcess(const int32_t cmd); 24 | 25 | int ConfigStride(const ImageData &imgData); 26 | 27 | inline int CheckOdd(const int num) 28 | { 29 | return num % 2 != 0 ? num : num - 1; 30 | } 31 | 32 | inline int CheckEven(const int num) 33 | { 34 | return num % 2 == 0 ? num : num - 1; 35 | } 36 | 37 | VpcUserImageConfigure image_config; 38 | VpcUserRoiConfigure roi_config; 39 | VpcUserRoiInputConfigure *input_config; 40 | VpcUserRoiOutputConfigure *output_config; 41 | 42 | dvppapi_ctl_msg dvppApiCtlMsg; 43 | IDVPPAPI *pidvppapi = nullptr; 44 | 45 | public: 46 | DVPPHandler(); 47 | 48 | ~DVPPHandler(); 49 | 50 | int DecodePNG(const std::string &infile_name, ImageData &imgdata); 51 | 52 | int DecodeJPEG(const std::string &infile_name, ImageData &imgdata); 53 | 54 | // Roi: {x1, y1, x2, y2} 55 | int Resize(ImageData &srcImg, const std::vector &cropArea, 56 | ImageData &dstImg, const std::vector &outputArea); 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /cpp/ascend/include/detect/mdc/image_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved. 3 | * Description: header for class image data 4 | */ 5 | 6 | #ifndef IMAGE_DATA_H 7 | #define IMAGE_DATA_H 8 | 9 | #include 10 | #include 11 | 12 | enum PngColorSpace { 13 | DVPP_PNG_DECODE_OUT_RGB = 6, 14 | DVPP_PNG_DECODE_OUT_RGBA = 7 15 | }; 16 | 17 | class ImageData { 18 | public: 19 | ImageData(const uint32_t h = 0, const uint32_t w = 0, const uint32_t fmt = -1) 20 | : height(h), width(w), format(fmt) 21 | { 22 | rawData = std::make_shared>(); 23 | } 24 | 25 | ImageData(const uint32_t h, const uint32_t w, std::shared_ptr> &data) 26 | : height(h), width(w), rawData(data) {} 27 | 28 | public: 29 | uint32_t height; 30 | uint32_t width; 31 | int format; 32 | std::shared_ptr> rawData; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /cpp/ascend/include/print_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * print_utils.h 3 | * 4 | * Created on: Mar 6, 2024 5 | * Author: LSH9832 6 | */ 7 | #ifndef PRINT_UTILS_H 8 | #define PRINT_UTILS_H 9 | 10 | #define YELLOW "\033[33m" /* Yellow */ 11 | #define GREEN "\033[32m" /* Green */ 12 | #define RED "\033[31m" /* Red */ 13 | #define END "\033[0m" 14 | #define ENDL "\033[0m" << std::endl 15 | 16 | #define WARN (std::cout << YELLOW) 17 | #define INFO (std::cout << GREEN) 18 | #define ERROR (std::cout << RED) 19 | 20 | #include 21 | 22 | static timeval get_now_time() { 23 | timeval _t; 24 | gettimeofday(&_t, NULL); 25 | return _t; 26 | } 27 | 28 | static int get_time_interval(timeval _t1, timeval _t2) { 29 | return (int)((_t2.tv_sec - _t1.tv_sec) * 1000 + (_t2.tv_usec - _t1.tv_usec) / 1000); 30 | } 31 | 32 | static float get_time_interval_f(timeval _t1, timeval _t2) { 33 | return ((float)(_t2.tv_sec - _t1.tv_sec) * 1000. + (float)(_t2.tv_usec - _t1.tv_usec) / 1000.); 34 | } 35 | 36 | class TimeCount { 37 | std::vector tics; 38 | std::vector tocs; 39 | 40 | public: 41 | size_t length() { 42 | return tics.size(); 43 | } 44 | 45 | void tic(int idx) { 46 | timeval now_time = get_now_time(); 47 | while (idx >= this->length()) { 48 | tics.push_back(now_time); 49 | tocs.push_back(now_time); 50 | } 51 | tics[idx] = now_time; 52 | tocs[idx] = now_time; 53 | } 54 | 55 | int get_timeval(int idx) { 56 | idx = MIN(idx, this->length()-1); 57 | return get_time_interval(tics[idx], tocs[idx]); 58 | } 59 | 60 | float get_timeval_f(int idx) { 61 | idx = MIN(idx, this->length()-1); 62 | return get_time_interval_f(tics[idx], tocs[idx]); 63 | } 64 | 65 | int toc(int idx) { 66 | idx = MIN(idx, this->length()-1); 67 | tocs[idx] = get_now_time(); 68 | return this->get_timeval(idx); 69 | } 70 | 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /cpp/ascend/scripts/find_packages.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | 4 | def get_args(): 5 | parser = argparse.ArgumentParser() 6 | parser.add_argument("-f", "--file", type=str) 7 | 8 | parser.add_argument("-ip", "--host", type=str) 9 | parser.add_argument("-u", "--user", type=str) 10 | parser.add_argument("-p", "--port", type=int, default=22) 11 | 12 | parser.add_argument("-l", "--location", type=str) 13 | 14 | return parser.parse_args() 15 | 16 | 17 | 18 | if __name__ == "__main__": 19 | args = get_args() 20 | filename = os.path.abspath(args.file) 21 | command = f"ldd {filename}" 22 | 23 | files=[] 24 | for line in os.popen(command).read().split("\n"): 25 | if "not found" in line: 26 | lib_name = line.split()[0] 27 | files.append(lib_name) 28 | 29 | command = "scp " 30 | for f in files: 31 | command += f"{f} " 32 | command += f"{args.user}@{args.host}:{args.location}" + ("" if args.port == 22 else f" -p {args.port}") 33 | 34 | print(command) 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /cpp/mnn/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(mnn_det) 3 | 4 | 5 | include_directories( 6 | include 7 | ) 8 | 9 | find_package(OpenCV 4 REQUIRED) 10 | include_directories(${OpenCV_INCLUDE_DIRS}) 11 | 12 | include_directories(/usr/include/eigen3) 13 | 14 | # --------------modify your own mnn path--------------- 15 | include_directories(/home/lsh/code/mnn_dev/MNN/include) 16 | link_directories(/home/lsh/code/mnn_dev/MNN/build) 17 | # --------------modify your own mnn path--------------- 18 | 19 | 20 | add_executable(mnn_det 21 | src/demo.cpp 22 | ) 23 | 24 | target_link_libraries(mnn_det ${OpenCV_LIBRARIES}) 25 | target_link_libraries(mnn_det MNN) 26 | target_link_libraries(mnn_det yaml-cpp) -------------------------------------------------------------------------------- /cpp/mnn/README.md: -------------------------------------------------------------------------------- 1 | # MNN Deployment demo for EdgeYOLO 2 | 3 | ## 1. install MNN Framework 4 | before using this framework, please install mnn SDK 5 | 6 | ```bash 7 | git clone https://github.com/alibaba/MNN 8 | cd MNN 9 | ./schema/generate.sh 10 | mkdir build && cd build 11 | 12 | # cpu only 13 | cmake .. -DMNN_OPENCL=ON -DMNN_BUILD_CONVERTER=ON -DMNN_BUILD_TOOL=ON -DMNN_BUILD_QUANTOOLS=ON -DMNN_BUILD_OPENCV=ON 14 | 15 | # cuda 16 | cmake .. -DCMAKE_BUILD_TYPE=Release \ 17 | -DMNN_BUILD_QUANTOOLS=ON \ 18 | -DMNN_BUILD_CONVERTER=ON \ 19 | -DMNN_OPENGL=ON \ 20 | -DMNN_VULKAN=ON \ 21 | -DMNN_CUDA=ON \ 22 | -DMNN_TENSORRT=OFF \ 23 | -DMNN_BUILD_DEMO=ON \ 24 | -DMNN_BUILD_BENCHMARK=ON 25 | 26 | # if -DMNN_OPENGL=ON and openglv3 is not installed in your device, then you can run the following command 27 | # sudo ln -s /usr/lib/x86_64-linux-gnu/libGLESv2.so /usr/lib/x86_64-linux-gnu/libGLESv3.so # x86_64 28 | # sudo ln -s /usr/lib/aarch64-linux-gnu/libGLESv2.so /usr/lib/aarch64-linux-gnu/libGLESv3.so # arm64 29 | 30 | make -j8 31 | ``` 32 | 33 | or just [**download here**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.1/mnn_dev.zip) to make sure you are using the same version with mine. 34 | ```bash 35 | unzip mnn_dev.zip 36 | cd mnn_dev 37 | 38 | # if you use cpu only 39 | chmod +x ./setup.bash && ./setup.bash 40 | 41 | # if you want to use cuda opencl opengl 42 | chmod +x ./setup_cuda.bash && ./setup_cuda.bash 43 | ``` 44 | 45 | ## 2. setup & model preparation 46 | 47 | - first, modify link_directories and include_directories of MNN in CMakeLists.txt 48 | - compile this demo 49 | 50 | ```bash 51 | chmod +x setup.bash && ./setup.bash 52 | ``` 53 | - convert your own mnn models and put it in "./models" 54 | 55 | ```bash 56 | cd /path_to_your_MNN/build 57 | ./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel xxx.mnn --fp16 58 | ``` 59 | or you can download converted [**coco model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.1/edgeyolo_coco.mnn) and [**visdrone model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.1/edgeyolo_visdrone.mnn) (tiny-lrelu) and put them in dir "./models" 60 | 61 | then modify **config/mnn_detection_xxx.yaml**: 62 | 63 | ```yaml 64 | model: "/path_to_this_project/models/edgeyolo_coco.mnn" 65 | names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 66 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 67 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 68 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 69 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 70 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 71 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 72 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 73 | 'hair drier', 'toothbrush'] 74 | num_threads: 3 # number of threads while doing inference 75 | conf_thres: 0.25 76 | nms_thres: 0.45 77 | ``` 78 | 79 | 80 | ## 3. run edgeyolo with MNN 81 | 82 | ```bash 83 | # example 84 | ./build/mnn_det --cfg config/mnn_detection_coco.yaml \ # model config 85 | --video \ # or --device --picture 86 | --source /path_to_video_file.mp4 \ # or 0 for camera, or /path/to/image.jpg for picture 87 | --no-label \ # do not draw label 88 | --loop \ # display in loop 89 | --cpu # use cpu, or --gpu, default is auto choose 90 | ``` 91 | 92 | -------------------------------------------------------------------------------- /cpp/mnn/config/mnn_detection_coco.yaml: -------------------------------------------------------------------------------- 1 | model: "models/edgeyolo_coco.mnn" 2 | names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 3 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 4 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 5 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 6 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 7 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 8 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 9 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 10 | 'hair drier', 'toothbrush'] 11 | num_threads: 3 12 | conf_thres: 0.25 13 | nms_thres: 0.45 14 | -------------------------------------------------------------------------------- /cpp/mnn/config/mnn_detection_visdrone.yaml: -------------------------------------------------------------------------------- 1 | model: "models/edgeyolo_visdrone.mnn" 2 | names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor'] 3 | num_threads: 4 4 | conf_thres: 0.25 5 | nms_thres: 0.45 6 | -------------------------------------------------------------------------------- /cpp/mnn/include/print_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef PRINT_UTILS_H 2 | #define PRINT_UTILS_H 3 | 4 | #define YELLOW "\033[33m" /* Yellow */ 5 | #define GREEN "\033[32m" /* Green */ 6 | #define RED "\033[31m" /* Red */ 7 | #define ENDL "\033[0m" << std::endl 8 | 9 | #define WARN (std::cout << YELLOW) 10 | #define INFO (std::cout << GREEN) 11 | #define ERROR (std::cout << RED) 12 | 13 | timeval get_now_time() { 14 | timeval _t; 15 | gettimeofday(&_t, NULL); 16 | return _t; 17 | } 18 | 19 | int get_time_interval(timeval _t1, timeval _t2) { 20 | return (int)((_t2.tv_sec - _t1.tv_sec) * 1000 + (_t2.tv_usec - _t1.tv_usec) / 1000); 21 | } 22 | 23 | #endif -------------------------------------------------------------------------------- /cpp/mnn/models/README.txt: -------------------------------------------------------------------------------- 1 | just put your mnn model here 2 | -------------------------------------------------------------------------------- /cpp/mnn/setup.bash: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | sudo apt install -y libyaml-cpp0.6 3 | mkdir build 4 | cd build 5 | cmake .. 6 | make -j8 7 | cd .. 8 | echo "\n" 9 | ./build/mnn_det -? 10 | -------------------------------------------------------------------------------- /cpp/rknn/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | project(rknn_edgeyolo_demo) 4 | 5 | set(CMAKE_CXX_STANDARD 14) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | # set(CMAKE_CXX_FLAGS "-pthread") 8 | 9 | # skip 3rd-party lib dependencies 10 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined") 11 | 12 | # install target and libraries 13 | set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/rknn_edgeyolo_demo_${CMAKE_SYSTEM_NAME}) 14 | 15 | set(CMAKE_SKIP_INSTALL_RPATH FALSE) 16 | set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 17 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 18 | 19 | # rknn api 20 | # set(RKNN_API_PATH ${CMAKE_SOURCE_DIR}/../../runtime/RK3588/${CMAKE_SYSTEM_NAME}/librknn_api) 21 | set(LIB_ARCH aarch64) 22 | set(RKNN_RT_LIB ${CMAKE_SOURCE_DIR}/include/librknnrt.so) 23 | 24 | #rga 25 | set(RGA_PATH ${CMAKE_SOURCE_DIR}/include/3rdparty/rga/RK3588) 26 | set(RGA_LIB ${RGA_PATH}/lib/Linux//${LIB_ARCH}/librga.so) 27 | 28 | 29 | # include_directories(${RKNN_API_PATH}/include) 30 | include_directories(${CMAKE_SOURCE_DIR}/include/3rdparty) 31 | include_directories(${RGA_PATH}/include) 32 | 33 | # opencv 34 | find_package(OpenCV REQUIRED) 35 | 36 | set(CMAKE_INSTALL_RPATH "lib") 37 | 38 | 39 | # rknn_det 40 | include_directories( ${CMAKE_SOURCE_DIR}/include) 41 | 42 | add_executable(rknn_det 43 | src/demo.cpp 44 | ) 45 | 46 | target_link_libraries(rknn_det 47 | ${RKNN_RT_LIB} 48 | ${OpenCV_LIBS} 49 | ${RGA_LIB} 50 | yaml-cpp 51 | ) 52 | 53 | # install target and libraries 54 | set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/rknn_edgeyolo_demo_${CMAKE_SYSTEM_NAME}) 55 | install(TARGETS rknn_det DESTINATION ./) 56 | install(PROGRAMS ${RKNN_RT_LIB} DESTINATION lib) 57 | install(PROGRAMS ${RGA_LIB} DESTINATION lib) 58 | install(DIRECTORY model DESTINATION ./) -------------------------------------------------------------------------------- /cpp/rknn/README.md: -------------------------------------------------------------------------------- 1 | # EdgeYOLO RKNN deployment tool 2 | 3 | ## note: this rknn code can only run in linux and only for rk3588. 4 | 5 | | Model | Size | FPSRK3588, 3 cores
int8 batch=1
include all process | Download | 6 | |:------|:---------:|:-----------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| 7 | |**Tiny-LRELU**| 384×640 | 65 | [**coco model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_lrelu_coco.rknn), [**coco config**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_lrelu_coco.yaml)
[**visdrone model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_lrelu_visdrone.rknn), [**visdrone config**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_lrelu_visdrone.yaml) | 8 | |**Tiny** | 384×640 | 24
(too many SiLU activate layers) | [**coco model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_coco.rknn), [**coco config**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_coco.yaml)
[**visdrone model**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_visdrone.rknn), [**visdrone config**](https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/edgeyolo_tiny_visdrone.yaml) | 9 | 10 | ## 1. Model convert 11 | ### 1.1 Setup RKNN Toolkit2 on your PC(x86_64) with edgeyolo requirements 12 | 13 | - this toolkit only supports python3.6, python3.8 and python3.10 14 | 15 | ```bash 16 | cd toolkit_install 17 | ./rknn_toolkit_install 38 # or 36, or 310 18 | ``` 19 | 20 | ### 1.2 convert your model 21 | 22 | - or just use the rknn models given in the above table. 23 | 24 | ```bash 25 | cd /path_to_edgeyolo_project_root_path 26 | 27 | python export.py --weights edgeyolo_tiny_lrelu_coco.pth \ # your pth weights 28 | --input-size 384 640 \ # for 16:9, if 4:3, use 480 640 29 | --rknn \ # export rknn model 30 | --dataset cfg/dataset/coco.yaml \ # calib dataset 31 | --num-img 100 \ # number of calib img 32 | 33 | # optional but not commend 34 | --rknn-platform rk3588 \ # rk3566 and so on, you can convert model, but our code only support rk3588(and rk3588s) 35 | ``` 36 | 37 | then it generates 4 files as follows 38 | ``` 39 | output/export/edgeyolo_tiny_lrelu_coco/384x640_batch1.rknn # rknn model 40 | output/export/edgeyolo_tiny_lrelu_coco/384x640_batch1_for_rknn.onnx # different from onnx file for tensorrt 41 | output/export/edgeyolo_tiny_lrelu_coco/384x640_batch1.json # json file, not used currently 42 | output/export/edgeyolo_tiny_lrelu_coco/384x640_batch1.yaml # config file to use 43 | ``` 44 | 45 | ## 2. Run rknn model in your rk3588 device(arm64) 46 | 47 | if you want to use the newest rknn library, see [official website](https://github.com/airockchip/rknn-toolkit2) 48 | 49 | - copy dir '**cpp/rknn**' to your rk3588 device. 50 | - cd rknn 51 | - copy converted ".yaml" and ".rknn" file to ./model. if rename, rename both file with the same name. 52 | - then 53 | ```bash 54 | chmod +x ./setup_rk3588.sh 55 | ./setup_rk3588.sh 56 | 57 | cd install/rknn_edgeyolo_demo_Linux 58 | 59 | ./rknn_det -? # parser helper 60 | 61 | ./rknn_det --model model/384x640_batch1.rknn \ 62 | --video \ # use video source(include rtsp/rtmp), or --device for camera id, or --picture for single image. 63 | --source /path_to_your_video.mp4 \ # or 0, or /path_to_your_image.jpg 64 | --no-label \ # draw bounding box without label 65 | --loop # play in loop, press esc to quit 66 | ``` 67 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/GrallocOps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rk_graphic_buffer_h_ 20 | #define _rk_graphic_buffer_h_ 21 | 22 | #ifdef ANDROID 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include "drmrga.h" 49 | #include "rga.h" 50 | 51 | // ------------------------------------------------------------------------------- 52 | int RkRgaGetHandleFd(buffer_handle_t handle, int *fd); 53 | int RkRgaGetHandleAttributes(buffer_handle_t handle, 54 | std::vector *attrs); 55 | int RkRgaGetHandleMapAddress(buffer_handle_t handle, 56 | void **buf); 57 | #endif //Android 58 | 59 | #endif //_rk_graphic_buffer_h_ 60 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/RgaApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _rockchip_rga_c_h_ 19 | #define _rockchip_rga_c_h_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include "drmrga.h" 34 | #include "rga.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C"{ 38 | #endif 39 | 40 | /* 41 | * Compatible with the old version of C interface.The new 42 | * version of the C interface no longer requires users to 43 | * initialize rga, so RgaInit and RgaDeInit are just for 44 | * compatibility with the old C interface, so please do 45 | * not use ctx, because it is usually a NULL. 46 | */ 47 | #define RgaInit(ctx) ({ \ 48 | int ret = 0; \ 49 | ret = c_RkRgaInit(); \ 50 | c_RkRgaGetContext(ctx); \ 51 | ret;\ 52 | }) 53 | #define RgaDeInit(ctx) { \ 54 | (void)ctx; /* unused */ \ 55 | c_RkRgaDeInit(); \ 56 | } 57 | #define RgaBlit(...) c_RkRgaBlit(__VA_ARGS__) 58 | #define RgaCollorFill(...) c_RkRgaColorFill(__VA_ARGS__) 59 | #define RgaFlush() c_RkRgaFlush() 60 | 61 | int c_RkRgaInit(); 62 | void c_RkRgaDeInit(); 63 | void c_RkRgaGetContext(void **ctx); 64 | int c_RkRgaBlit(rga_info_t *src, rga_info_t *dst, rga_info_t *src1); 65 | int c_RkRgaColorFill(rga_info_t *dst); 66 | int c_RkRgaFlush(); 67 | 68 | #ifndef ANDROID /* linux */ 69 | int c_RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); 70 | int c_RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); 71 | int c_RkRgaGetMmap(bo_t *bo_info); 72 | int c_RkRgaUnmap(bo_t *bo_info); 73 | int c_RkRgaFree(bo_t *bo_info); 74 | int c_RkRgaGetBufferFd(bo_t *bo_info, int *fd); 75 | #endif /* #ifndef ANDROID */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* #ifndef _rockchip_rga_c_h_ */ 82 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/RgaSingleton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _LIBS_RGA_SINGLETON_H 20 | #define _LIBS_RGA_SINGLETON_H 21 | 22 | #ifndef ANDROID 23 | #include "RgaMutex.h" 24 | 25 | #if defined(__clang__) 26 | #pragma clang diagnostic push 27 | #pragma clang diagnostic ignored "-Wundefined-var-template" 28 | #endif 29 | 30 | template 31 | class Singleton { 32 | public: 33 | static TYPE& getInstance() { 34 | Mutex::Autolock _l(sLock); 35 | TYPE* instance = sInstance; 36 | if (instance == nullptr) { 37 | instance = new TYPE(); 38 | sInstance = instance; 39 | } 40 | return *instance; 41 | } 42 | 43 | static bool hasInstance() { 44 | Mutex::Autolock _l(sLock); 45 | return sInstance != nullptr; 46 | } 47 | 48 | protected: 49 | ~Singleton() { } 50 | Singleton() { } 51 | 52 | private: 53 | Singleton(const Singleton&); 54 | Singleton& operator = (const Singleton&); 55 | static Mutex sLock; 56 | static TYPE* sInstance; 57 | }; 58 | 59 | #if defined(__clang__) 60 | #pragma clang diagnostic pop 61 | #endif 62 | 63 | #define RGA_SINGLETON_STATIC_INSTANCE(TYPE) \ 64 | template<> ::Mutex \ 65 | (::Singleton< TYPE >::sLock)(::Mutex::PRIVATE); \ 66 | template<> TYPE* ::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \ 67 | template class ::Singleton< TYPE >; 68 | 69 | #endif //ANDROID 70 | #endif //_LIBS_RGA_SINGLETON_H 71 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/RgaUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rga_utils_h_ 20 | #define _rga_utils_h_ 21 | 22 | // ------------------------------------------------------------------------------- 23 | float get_bpp_from_format(int format); 24 | int get_perPixel_stride_from_format(int format); 25 | int get_buf_from_file(void *buf, int f, int sw, int sh, int index); 26 | int output_buf_data_to_file(void *buf, int f, int sw, int sh, int index); 27 | const char *translate_format_str(int format); 28 | int get_buf_from_file_FBC(void *buf, int f, int sw, int sh, int index); 29 | int output_buf_data_to_file_FBC(void *buf, int f, int sw, int sh, int index); 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/RockchipRga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rockchip_rga_h_ 20 | #define _rockchip_rga_h_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "drmrga.h" 34 | #include "GrallocOps.h" 35 | #include "RgaUtils.h" 36 | #include "rga.h" 37 | 38 | ////////////////////////////////////////////////////////////////////////////////// 39 | #ifndef ANDROID 40 | #include "RgaSingleton.h" 41 | #endif 42 | 43 | #ifdef ANDROID 44 | #include 45 | #include 46 | #include 47 | 48 | namespace android { 49 | #endif 50 | 51 | class RockchipRga :public Singleton { 52 | public: 53 | 54 | static inline RockchipRga& get() { 55 | return getInstance(); 56 | } 57 | 58 | int RkRgaInit(); 59 | void RkRgaDeInit(); 60 | void RkRgaGetContext(void **ctx); 61 | #ifndef ANDROID /* LINUX */ 62 | int RkRgaAllocBuffer(int drm_fd /* input */, bo_t *bo_info, 63 | int width, int height, int bpp, int flags); 64 | int RkRgaFreeBuffer(int drm_fd /* input */, bo_t *bo_info); 65 | int RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); 66 | int RkRgaGetAllocBufferExt(bo_t *bo_info, int width, int height, int bpp, int flags); 67 | int RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); 68 | int RkRgaGetMmap(bo_t *bo_info); 69 | int RkRgaUnmap(bo_t *bo_info); 70 | int RkRgaFree(bo_t *bo_info); 71 | int RkRgaGetBufferFd(bo_t *bo_info, int *fd); 72 | #else 73 | int RkRgaGetBufferFd(buffer_handle_t handle, int *fd); 74 | int RkRgaGetHandleMapCpuAddress(buffer_handle_t handle, void **buf); 75 | #endif 76 | int RkRgaBlit(rga_info *src, rga_info *dst, rga_info *src1); 77 | int RkRgaCollorFill(rga_info *dst); 78 | int RkRgaCollorPalette(rga_info *src, rga_info *dst, rga_info *lut); 79 | int RkRgaFlush(); 80 | 81 | 82 | void RkRgaSetLogOnceFlag(int log) { 83 | mLogOnce = log; 84 | } 85 | void RkRgaSetAlwaysLogFlag(bool log) { 86 | mLogAlways = log; 87 | } 88 | void RkRgaLogOutRgaReq(struct rga_req rgaReg); 89 | int RkRgaLogOutUserPara(rga_info *rgaInfo); 90 | inline bool RkRgaIsReady() { 91 | return mSupportRga; 92 | } 93 | 94 | RockchipRga(); 95 | ~RockchipRga(); 96 | private: 97 | bool mSupportRga; 98 | int mLogOnce; 99 | int mLogAlways; 100 | void * mContext; 101 | 102 | friend class Singleton; 103 | }; 104 | 105 | #ifdef ANDROID 106 | }; // namespace android 107 | #endif 108 | 109 | #endif 110 | 111 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/im2d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * PutinLee 5 | * Cerf Yu 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #ifndef _im2d_h_ 21 | #define _im2d_h_ 22 | 23 | #include "im2d_version.h" 24 | #include "im2d_type.h" 25 | 26 | #include "im2d_common.h" 27 | #include "im2d_buffer.h" 28 | #include "im2d_single.h" 29 | #include "im2d_task.h" 30 | #include "im2d_mpi.h" 31 | 32 | #endif /* #ifndef _im2d_h_ */ 33 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/im2d.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * PutinLee 5 | * Cerf Yu 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _im2d_hpp_ 20 | #define _im2d_hpp_ 21 | 22 | #include "im2d.h" 23 | #include "im2d_expand.h" 24 | 25 | #endif /* #ifndef _im2d_hpp_ */ 26 | 27 | 28 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/im2d_expand.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_expand_h_ 19 | #define _im2d_expand_h_ 20 | 21 | #ifdef __cplusplus 22 | 23 | #include "im2d_type.h" 24 | 25 | // #if ANDROID 26 | 27 | // #include 28 | 29 | // using namespace android; 30 | 31 | // IM_API rga_buffer_handle_t importbuffer_GraphicBuffer_handle(buffer_handle_t hnd); 32 | // IM_API rga_buffer_handle_t importbuffer_GraphicBuffer(sp buf); 33 | 34 | // IM_API rga_buffer_t wrapbuffer_handle(buffer_handle_t hnd); 35 | // IM_API rga_buffer_t wrapbuffer_GraphicBuffer(sp buf); 36 | 37 | // #if USE_AHARDWAREBUFFER 38 | // #include 39 | // IM_API rga_buffer_handle_t importbuffer_AHardwareBuffer(AHardwareBuffer *buf); 40 | // IM_API rga_buffer_t wrapbuffer_AHardwareBuffer(AHardwareBuffer *buf); 41 | 42 | // #endif /* #if USE_AHARDWAREBUFFER */ 43 | // #endif /* #if ANDROID */ 44 | 45 | #endif /* #ifdef __cplusplus */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/im2d_mpi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_mpi_hpp_ 19 | #define _im2d_mpi_hpp_ 20 | 21 | #include "im2d_type.h" 22 | 23 | /** 24 | * Create and config an rga ctx for rockit-ko 25 | * 26 | * @param flags 27 | * Some configuration flags for this job 28 | * 29 | * @returns job id. 30 | */ 31 | IM_EXPORT_API im_ctx_id_t imbegin(uint32_t flags); 32 | 33 | /** 34 | * Cancel and delete an rga ctx for rockit-ko 35 | * 36 | * @param flags 37 | * Some configuration flags for this job 38 | * 39 | * @returns success or else negative error code. 40 | */ 41 | IM_EXPORT_API IM_STATUS imcancel(im_ctx_id_t id); 42 | 43 | /** 44 | * process for rockit-ko 45 | * 46 | * @param src 47 | * The input source image and is also the foreground image in blend. 48 | * @param dst 49 | * The output destination image and is also the foreground image in blend. 50 | * @param pat 51 | * The foreground image, or a LUT table. 52 | * @param srect 53 | * The rectangle on the src channel image that needs to be processed. 54 | * @param drect 55 | * The rectangle on the dst channel image that needs to be processed. 56 | * @param prect 57 | * The rectangle on the pat channel image that needs to be processed. 58 | * @param acquire_fence_fd 59 | * @param release_fence_fd 60 | * @param opt 61 | * The image processing options configuration. 62 | * @param usage 63 | * The image processing usage. 64 | * @param ctx_id 65 | * ctx id 66 | * 67 | * @returns success or else negative error code. 68 | */ 69 | #ifdef __cplusplus 70 | IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, 71 | im_rect srect, im_rect drect, im_rect prect, 72 | int acquire_fence_fd, int *release_fence_fd, 73 | im_opt_t *opt, int usage, im_ctx_id_t ctx_id); 74 | #endif 75 | IM_EXPORT_API IM_STATUS improcess_ctx(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, 76 | im_rect srect, im_rect drect, im_rect prect, 77 | int acquire_fence_fd, int *release_fence_fd, 78 | im_opt_t *opt, int usage, im_ctx_id_t ctx_id); 79 | 80 | #endif /* #ifndef _im2d_mpi_hpp_ */ -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/include/im2d_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _RGA_IM2D_VERSION_H_ 20 | #define _RGA_IM2D_VERSION_H_ 21 | 22 | #define RGA_VERSION_STR_HELPER(x) #x 23 | #define RGA_VERSION_STR(x) RGA_VERSION_STR_HELPER(x) 24 | 25 | /* RGA im2d api verison */ 26 | #define RGA_API_MAJOR_VERSION 1 27 | #define RGA_API_MINOR_VERSION 9 28 | #define RGA_API_REVISION_VERSION 1 29 | #define RGA_API_BUILD_VERSION 4 30 | 31 | #define RGA_API_VERSION \ 32 | RGA_VERSION_STR(RGA_API_MAJOR_VERSION) "." \ 33 | RGA_VERSION_STR(RGA_API_MINOR_VERSION) "." \ 34 | RGA_VERSION_STR(RGA_API_REVISION_VERSION) "_[" \ 35 | RGA_VERSION_STR(RGA_API_BUILD_VERSION) "]" 36 | #define RGA_API_FULL_VERSION "rga_api version " RGA_API_VERSION 37 | 38 | /* For header file version verification */ 39 | #define RGA_CURRENT_API_VERSION (\ 40 | (RGA_API_MAJOR_VERSION & 0xff) << 24 | \ 41 | (RGA_API_MINOR_VERSION & 0xff) << 16 | \ 42 | (RGA_API_REVISION_VERSION & 0xff) << 8 | \ 43 | (RGA_API_BUILD_VERSION & 0xff)\ 44 | ) 45 | #define RGA_CURRENT_API_HEADER_VERSION RGA_CURRENT_API_VERSION 46 | 47 | #endif /* _RGA_IM2D_VERSION_H_ */ 48 | -------------------------------------------------------------------------------- /cpp/rknn/include/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/cpp/rknn/include/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so -------------------------------------------------------------------------------- /cpp/rknn/include/drm_func.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRM_FUNC_H__ 2 | #define __DRM_FUNC_H__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include // open function 8 | #include // close function 9 | #include 10 | #include 11 | 12 | 13 | #include 14 | #include "libdrm/drm_fourcc.h" 15 | #include "xf86drm.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | typedef int (* FUNC_DRM_IOCTL)(int fd, unsigned long request, void *arg); 22 | 23 | typedef struct _drm_context{ 24 | void *drm_handle; 25 | FUNC_DRM_IOCTL io_func; 26 | } drm_context; 27 | 28 | /* memory type definitions. */ 29 | enum drm_rockchip_gem_mem_type 30 | { 31 | /* Physically Continuous memory and used as default. */ 32 | ROCKCHIP_BO_CONTIG = 1 << 0, 33 | /* cachable mapping. */ 34 | ROCKCHIP_BO_CACHABLE = 1 << 1, 35 | /* write-combine mapping. */ 36 | ROCKCHIP_BO_WC = 1 << 2, 37 | ROCKCHIP_BO_SECURE = 1 << 3, 38 | ROCKCHIP_BO_MASK = ROCKCHIP_BO_CONTIG | ROCKCHIP_BO_CACHABLE | 39 | ROCKCHIP_BO_WC | ROCKCHIP_BO_SECURE 40 | }; 41 | 42 | int drm_init(drm_context *drm_ctx); 43 | 44 | void* drm_buf_alloc(drm_context *drm_ctx,int drm_fd, int TexWidth, int TexHeight,int bpp,int *fd,unsigned int *handle,size_t *actual_size); 45 | 46 | int drm_buf_destroy(drm_context *drm_ctx,int drm_fd,int buf_fd, int handle,void *drm_buf,size_t size); 47 | 48 | void drm_deinit(drm_context *drm_ctx, int drm_fd); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif /*__DRM_FUNC_H__*/ -------------------------------------------------------------------------------- /cpp/rknn/include/libmk_api.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/cpp/rknn/include/libmk_api.so -------------------------------------------------------------------------------- /cpp/rknn/include/librga.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/cpp/rknn/include/librga.so -------------------------------------------------------------------------------- /cpp/rknn/include/librknnrt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/cpp/rknn/include/librknnrt.so -------------------------------------------------------------------------------- /cpp/rknn/include/print_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef PRINT_UTILS_H 2 | #define PRINT_UTILS_H 3 | 4 | #define YELLOW "\033[33m" /* Yellow */ 5 | #define GREEN "\033[32m" /* Green */ 6 | #define RED "\033[31m" /* Red */ 7 | #define ENDL "\033[0m" << std::endl 8 | 9 | #define WARN (std::cout << YELLOW) 10 | #define INFO (std::cout << GREEN) 11 | #define ERROR (std::cout << RED) 12 | 13 | timeval get_now_time() { 14 | timeval _t; 15 | gettimeofday(&_t, NULL); 16 | return _t; 17 | } 18 | 19 | int get_time_interval(timeval _t1, timeval _t2) { 20 | return (int)((_t2.tv_sec - _t1.tv_sec) * 1000 + (_t2.tv_usec - _t1.tv_usec) / 1000); 21 | } 22 | 23 | #endif -------------------------------------------------------------------------------- /cpp/rknn/include/rga_func.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGA_FUNC_H__ 2 | #define __RGA_FUNC_H__ 3 | 4 | #include 5 | #include "RgaApi.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef int(* FUNC_RGA_INIT)(); 12 | typedef void(* FUNC_RGA_DEINIT)(); 13 | typedef int(* FUNC_RGA_BLIT)(rga_info_t *, rga_info_t *, rga_info_t *); 14 | 15 | typedef struct _rga_context{ 16 | void *rga_handle; 17 | FUNC_RGA_INIT init_func; 18 | FUNC_RGA_DEINIT deinit_func; 19 | FUNC_RGA_BLIT blit_func; 20 | } rga_context; 21 | 22 | int RGA_init(rga_context* rga_ctx); 23 | 24 | void img_resize_fast(rga_context *rga_ctx, int src_fd, int src_w, int src_h, uint64_t dst_phys, int dst_w, int dst_h); 25 | 26 | void img_resize_slow(rga_context *rga_ctx, void *src_virt, int src_w, int src_h, void *dst_virt, int dst_w, int dst_h); 27 | 28 | int RGA_deinit(rga_context* rga_ctx); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif/*__RGA_FUNC_H__*/ 34 | -------------------------------------------------------------------------------- /cpp/rknn/model/readme.txt: -------------------------------------------------------------------------------- 1 | put your rknn models and yaml config in this dir 2 | -------------------------------------------------------------------------------- /cpp/rknn/scripts/onnx2rknn.py: -------------------------------------------------------------------------------- 1 | from rknn.api import RKNN 2 | import argparse 3 | import os.path as osp 4 | from glob import glob 5 | import yaml 6 | import random 7 | 8 | 9 | PLATFORM = "rk3588" 10 | 11 | 12 | def get_args(): 13 | parser = argparse.ArgumentParser("EdgeYOLO RKNN model converter parser") 14 | 15 | parser.add_argument("-o", "--onnx", type=str, default="edgeyolo_tiny_lrelu_coco.onnx", help="onnx model") 16 | parser.add_argument("-r", "--rknn", type=str, default="edgeyolo_tiny_lrelu_coco.rknn", help="rknn model") 17 | 18 | parser.add_argument("-p", "--platform", type=str, default=PLATFORM) 19 | 20 | # quantize 21 | parser.add_argument("--no-quantize", action="store_true", help="do not quantize") 22 | parser.add_argument("-d", "--dataset", type=str, default=None, help="dataset img path") 23 | parser.add_argument("--suffix", type=str, default="jpg", help="dataset image suffix") 24 | parser.add_argument("--num", type=int, default=512, help="number of calib files") 25 | 26 | return parser.parse_args() 27 | 28 | 29 | if __name__ == '__main__': 30 | 31 | args = get_args() 32 | 33 | # Create RKNN object 34 | rknn = RKNN(verbose=True) 35 | # pre-process config 36 | print('--> Config model') 37 | rknn.config(target_platform=args.platform) 38 | print('done') 39 | 40 | # Load ONNX model 41 | print('--> Loading model') 42 | ret = rknn.load_onnx(model=args.onnx) 43 | if ret != 0: 44 | print('Load model failed!') 45 | exit(ret) 46 | print('done') 47 | 48 | # Build model 49 | print('--> Building model') 50 | 51 | if args.dataset is not None: 52 | temp_file = "temp_calib.txt" 53 | with open(args.dataset) as yamlf: 54 | dataset_cfg: dict = yaml.load(yamlf, yaml.Loader) 55 | 56 | img_files = glob(osp.join(args.dataset, f"*.{args.suffix}")) 57 | random.shuffle(img_files) 58 | 59 | img_files = img_files[:args.num] 60 | 61 | temp_file_str = "" 62 | for img_file in img_files: 63 | temp_file_str += f"{img_file}\n" 64 | 65 | temp_file_str = temp_file_str[:-1] 66 | 67 | with open(temp_file, "w") as f: 68 | f.write(temp_file_str) 69 | 70 | ret = rknn.build(do_quantization=not args.no_quantize, dataset=None if args.no_quantize else args.dataset) 71 | if ret != 0: 72 | print('Build model failed!') 73 | exit(ret) 74 | print('done') 75 | 76 | # Export RKNN model 77 | print('--> Export rknn model') 78 | ret = rknn.export_rknn(args.rknn) 79 | if ret != 0: 80 | print('Export rknn model failed!') 81 | exit(ret) 82 | print('done') -------------------------------------------------------------------------------- /cpp/rknn/setup_rk3588.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | # TARGET_SOC="rk3588" 4 | GCC_COMPILER=aarch64-linux-gnu 5 | 6 | export LD_LIBRARY_PATH=${TOOL_CHAIN}/lib64:$LD_LIBRARY_PATH 7 | export CC=${GCC_COMPILER}-gcc 8 | export CXX=${GCC_COMPILER}-g++ 9 | 10 | ROOT_PWD=$( cd "$( dirname $0 )" && cd -P "$( dirname "$SOURCE" )" && pwd ) 11 | 12 | # build 13 | BUILD_DIR=${ROOT_PWD}/build/build_linux_aarch64 14 | 15 | if [ ! -d "${BUILD_DIR}" ]; then 16 | mkdir -p ${BUILD_DIR} 17 | fi 18 | 19 | cd ${BUILD_DIR} 20 | cmake ../.. -DCMAKE_SYSTEM_NAME=Linux 21 | make -j8 22 | make install 23 | cd - 24 | 25 | -------------------------------------------------------------------------------- /cpp/rknn/toolkit_install/requirements36.txt: -------------------------------------------------------------------------------- 1 | # python3.6 2 | numpy 3 | protobuf 4 | flatbuffers==1.12 5 | requests==2.27.1 6 | psutil==5.9.0 7 | ruamel.yaml==0.17.4 8 | scipy 9 | tqdm 10 | opencv-python 11 | fast-histogram==0.11 12 | 13 | # base 14 | onnx==1.10.0 15 | onnxoptimizer==0.2.7 16 | onnxruntime==1.10.0 -------------------------------------------------------------------------------- /cpp/rknn/toolkit_install/requirements38-310.txt: -------------------------------------------------------------------------------- 1 | # python3.8 or python3.10 2 | numpy 3 | protobuf 4 | flatbuffers==2.0 5 | requests==2.28.1 6 | psutil==5.9.0 7 | ruamel.yaml==0.17.21 8 | scipy 9 | tqdm 10 | opencv-python 11 | fast-histogram==0.11 12 | 13 | # base 14 | onnx==1.14.0 15 | onnxoptimizer==0.3.8 16 | onnxruntime==1.14.1 17 | -------------------------------------------------------------------------------- /cpp/rknn/toolkit_install/rknn_toolkit_install: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | if [ $# == 1 ]; then 4 | 5 | if [ "$1" == '36' ]; then 6 | 7 | wget https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/rknn_toolkit2-1.5.2+b642f30c-cp36-cp36m-linux_x86_64.whl 8 | pip3 install -r requirements36.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 9 | pip3 install rknn_toolkit2-1.5.2+b642f30c-cp36-cp36m-linux_x86_64.whl --no-dependencies 10 | 11 | elif [ "$1" == '38' ]; then 12 | 13 | wget https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/rknn_toolkit2-1.5.2+b642f30c-cp38-cp38-linux_x86_64.whl 14 | pip3 install -r requirements38-310.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 15 | pip3 install rknn_toolkit2-1.5.2+b642f30c-cp38-cp38-linux_x86_64.whl --no-dependencies 16 | 17 | elif [ "$1" == '310' ]; then 18 | 19 | wget https://github.com/LSH9832/edgeyolo/releases/download/v1.0.2/rknn_toolkit2-1.5.2+b642f30c-cp310-cp310-linux_x86_64.whl 20 | pip3 install -r requirements38-310.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 21 | pip3 install rknn_toolkit2-1.5.2+b642f30c-cp310-cp310-linux_x86_64.whl --no-dependencies 22 | 23 | else 24 | 25 | echo "only support version 36 38 310" 26 | exit 27 | 28 | fi 29 | 30 | 31 | 32 | 33 | else 34 | echo "usage: $0 . example: $0 36" 35 | 36 | fi 37 | 38 | 39 | -------------------------------------------------------------------------------- /cpp/tensorrt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(trt_det LANGUAGES CXX) 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 Release) 10 | 11 | include_directories( 12 | include 13 | ) 14 | 15 | find_package(OpenCV REQUIRED) 16 | include_directories(${OpenCV_INCLUDE_DIRS}) 17 | 18 | # cuda # cudnn # tensorrt 19 | find_package(CUDA REQUIRED) 20 | include_directories(/usr/local/cuda/include) 21 | link_directories(/usr/local/cuda/lib64) 22 | include_directories(/usr/local/TensorRT-8.6.1.6/include) 23 | 24 | add_executable(trt_det 25 | src/yolo.cpp 26 | src/trt.cpp 27 | ) 28 | 29 | target_link_libraries(trt_det nvinfer) 30 | target_link_libraries(trt_det cudart) 31 | target_link_libraries(trt_det yaml-cpp) 32 | target_link_libraries(trt_det ${OpenCV_LIBS}) 33 | -------------------------------------------------------------------------------- /cpp/tensorrt/README.md: -------------------------------------------------------------------------------- 1 | # EdgeYOLO TensorRT deployment demo 2 | 3 | ## note 4 | 5 | Currently, this demo only supports models with batch = 1. 6 | 7 | ## requirements 8 | 9 | - libopencv-dev 10 | - libyaml-cpp0.6 11 | 12 | ## build 13 | modify CMakeLists.txt and then 14 | ```shell 15 | mkdir build && cd build 16 | cmake .. 17 | make 18 | ``` 19 | ## usage 20 | 21 | copy your engine file and yaml file to a same path, then 22 | 23 | ```shell 24 | # name of yaml and engine file should be the same. 25 | ./trt_det /path/to/your/model.engine /path/to/your/videos --conf 0.25 --nms 0.5 --loop --no-label 26 | ``` 27 | -------------------------------------------------------------------------------- /cpp/tensorrt/include/image_utils/trt.h: -------------------------------------------------------------------------------- 1 | #ifndef TRT_H 2 | #define TRT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "image_utils/logging.h" 15 | #include "image_utils/detect_process.h" 16 | #include "yaml-cpp/yaml.h" 17 | 18 | using namespace nvinfer1; 19 | 20 | 21 | struct CFG_MSG { 22 | std::string INPUT_NAME; // input_0 23 | std::string OUTPUT_NAME; // output_0 24 | cv::Size INPUT_SIZE; // = cv::Size(384, 672); 25 | std::vector NAMES; 26 | bool NORMALIZE; // 0 27 | bool loaded = false; 28 | }; 29 | 30 | class yoloNet { 31 | 32 | int num_classes=0; 33 | int output_num_array=0; 34 | 35 | double conf_thres = 0.25; 36 | double nms_thres = 0.45; 37 | long long output_size = 1; 38 | cv::Size image_size = cv::Size(640, 640); 39 | size_t size{0}; 40 | 41 | int num_names = 0; 42 | 43 | IRuntime* runtime; 44 | IExecutionContext* context; 45 | ICudaEngine* engine; 46 | 47 | int inputIndex; 48 | int outputIndex; 49 | int batch=1; 50 | 51 | bool first=true; 52 | bool cuda_occupyed=false; 53 | bool normalize=false; 54 | 55 | std::string input_name = "input_0"; 56 | std::string output_name = "output_0"; 57 | cudaStream_t stream; 58 | void* buffers[2]; 59 | float* prob; 60 | 61 | public: 62 | yoloNet(); 63 | CFG_MSG cfg; 64 | 65 | bool load_engine(std::string cfg_file); 66 | bool engine_loaded=false; 67 | 68 | void set_conf_threshold(float thres); 69 | void set_nms_threshold(float thres); 70 | void set_input_name(std::string name); 71 | void set_output_name(std::string name); 72 | void release(); 73 | 74 | std::vector infer(cv::Mat image); 75 | 76 | }; 77 | 78 | #endif 79 | #define TRT_H 80 | -------------------------------------------------------------------------------- /cpp/tensorrt/include/print_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef PRINT_UTILS_H 2 | #define PRINT_UTILS_H 3 | 4 | #define YELLOW "\033[33m" /* Yellow */ 5 | #define GREEN "\033[32m" /* Green */ 6 | #define RED "\033[31m" /* Red */ 7 | #define END "\033[0m" 8 | #define ENDL "\033[0m" << std::endl 9 | 10 | #define WARN (std::cout << YELLOW) 11 | #define INFO (std::cout << GREEN) 12 | #define ERROR (std::cout << RED) 13 | 14 | #include 15 | 16 | timeval get_now_time() { 17 | timeval _t; 18 | gettimeofday(&_t, NULL); 19 | return _t; 20 | } 21 | 22 | 23 | int get_time_interval(timeval _t1, timeval _t2) { 24 | return (int)((_t2.tv_sec - _t1.tv_sec) * 1000 + (_t2.tv_usec - _t1.tv_usec) / 1000); 25 | } 26 | 27 | #endif -------------------------------------------------------------------------------- /demo/check_params.py: -------------------------------------------------------------------------------- 1 | from edgeyolo import get_model_info, EdgeYOLO 2 | 3 | 4 | model = EdgeYOLO("../params/model/edgeyolo_coco_repconv_tiny.yaml").model 5 | # model = EdgeYOLO("../params/model/edgeyolo_coco_repconv_s.yaml").model 6 | print(get_model_info(model, (640, 640))) 7 | model.reparameterize() 8 | print(get_model_info(model, (640, 640))) 9 | -------------------------------------------------------------------------------- /demo/conv2repconv.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from edgeyolo import EdgeYOLO, get_model_info, NoPrint 4 | import tqdm 5 | 6 | 7 | def conv2repconv(model: EdgeYOLO, repmodel: EdgeYOLO): 8 | ori_model = model.model 9 | dist_model = repmodel.model 10 | 11 | params = {} 12 | ori_params = ori_model.state_dict() 13 | for k, v in dist_model.state_dict().items(): 14 | if k in ori_params: 15 | v_ = ori_params[k] 16 | 17 | elif "rbr_dense" in k: 18 | ori_k = k.replace("rbr_dense.0", "conv").replace("rbr_dense.1", "bn") 19 | if ori_k in ori_params: 20 | v_ = ori_params[ori_k] 21 | else: 22 | print(f"no relative params for repconv params:{k}") 23 | v_ = v 24 | else: 25 | print(f"new layer {k}") 26 | v_ = v 27 | 28 | if v.shape == v_.shape: 29 | params[k] = v_ 30 | else: 31 | print(f"size not match! shape is {v.shape} while input shape is {v_.shape}") 32 | 33 | repmodel.model.load_state_dict(params, strict=False) 34 | repmodel.now_epoch = -1 35 | repmodel.class_names = model.class_names 36 | return repmodel 37 | 38 | 39 | if __name__ == '__main__': 40 | import torch 41 | 42 | # model = conv2repconv( 43 | # EdgeYOLO(weights="./edgeyolo_coco.pth"), 44 | # EdgeYOLO(cfg_file="./params/model/edgeyolo_coco_repconv.yaml") 45 | # ) 46 | # 47 | # model.save("edgeyolo_rep_coco.pth") 48 | 49 | for i in tqdm.tqdm(range(100), ncols=200): 50 | time.sleep(0.2) 51 | 52 | # print(get_model_info(my_model.model, (640, 640))) 53 | # with NoPrint(): 54 | # my_model.model.fuse() 55 | # print(get_model_info(my_model.model, (640, 640))) 56 | 57 | 58 | 59 | # model.84.conv.weight 60 | # model.84.bn.weight 61 | # model.84.bn.bias -------------------------------------------------------------------------------- /demo/dota_detect.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | 3 | from edgeyolo.detect.dotaDetector import DOTADetector 4 | 5 | from edgeyolo import EdgeYOLO 6 | from edgeyolo.detect import draw 7 | 8 | from glob import glob 9 | import cv2 10 | from tqdm import tqdm 11 | 12 | from edgeyolo.data.datasets import get_dataset 13 | 14 | 15 | if __name__ == '__main__': 16 | # model = EdgeYOLO(weights="../weights/edgeyolo_visdrone.pth") 17 | model = EdgeYOLO(weights="../edgeyolo_tiny_dota.pth") 18 | model.model.fuse() 19 | print(model.ckpt["ap50_95"]) 20 | nc = len(model.class_names) 21 | 22 | detector = DOTADetector( 23 | model=model.model, 24 | nc=nc, 25 | conf=0.001, 26 | nms=0.65, 27 | img_size=1280, 28 | normal=True, 29 | twice_nms=False 30 | ) 31 | 32 | dataset = get_dataset("../params/dataset/dota.yaml", mode="val") 33 | 34 | # print(dataset.class_ids) 35 | 36 | show = False 37 | 38 | coco_result = [] 39 | 40 | 41 | img_list = glob("/dataset/DOTA/val/images/*.png") 42 | for i in tqdm(range(len(dataset)), ncols=100): 43 | 44 | img = dataset.load_image(i) 45 | _, _, _, img_id, _ = dataset.pull_item(i) 46 | img_id = int(img_id) 47 | 48 | result = detector(img) 49 | 50 | if result is not None: 51 | draw(img, [result], model.class_names, 2, True) if show else None 52 | coco_result.extend(detector.result2coco_json(result, img_id)) 53 | 54 | 55 | # print(f"{i+1}/{len(img_list)}, image_id: {img_id}") 56 | 57 | if show: 58 | cv2.imshow("test", img) 59 | if cv2.waitKey(0) == 27: 60 | cv2.destroyAllWindows() 61 | break 62 | 63 | 64 | if len(coco_result) > 0: 65 | from pycocotools.cocoeval import COCOeval 66 | import contextlib 67 | import io 68 | 69 | cocoGt = dataset.coco 70 | 71 | cocoDt = cocoGt.loadRes(coco_result) 72 | 73 | cocoEval = COCOeval(cocoGt, cocoDt, "bbox") 74 | cocoEval.evaluate() 75 | cocoEval.accumulate() 76 | redirect_string = io.StringIO() 77 | with contextlib.redirect_stdout(redirect_string): 78 | cocoEval.summarize() 79 | info = redirect_string.getvalue() 80 | 81 | print(cocoEval.stats[0], cocoEval.stats[1], f"\n{info}") 82 | -------------------------------------------------------------------------------- /demo/eval_from_json.py: -------------------------------------------------------------------------------- 1 | # for deploy model (rknn, hbdnn, ascend, mnn, tensorrt) 2 | """ 3 | json format: 4 | 5 | { 6 | "XXXXXX.jpg": {"category_id": int, "bbox": List[float](x1,y1,w,h), "score": float, "segmentation": []}, 7 | ...... 8 | } 9 | 10 | """ 11 | import os 12 | import os.path 13 | import os.path as osp 14 | import argparse 15 | from loguru import logger 16 | 17 | import sys 18 | sys.path.append("./") 19 | 20 | from edgeyolo.data import get_dataset, COCODataset 21 | 22 | 23 | def get_args(): 24 | parser = argparse.ArgumentParser("EdgeYOLO evaluate parser") 25 | parser.add_argument("-c", "--config", type=str, default="eval_results.json", help="weights") 26 | parser.add_argument("--dataset", type=str, default="params/dataset/coco.yaml", help="dataset config") 27 | return parser.parse_args() 28 | 29 | 30 | def generate_params(**kwargs): 31 | PARAMS = { 32 | "dataset_cfg": "params/dataset/coco.yaml", 33 | "config": "eval_results.json", 34 | } 35 | for k, v in kwargs.items(): 36 | PARAMS[k] = v 37 | return PARAMS 38 | 39 | 40 | def load_dataset(params): 41 | # import torch.utils.data 42 | from edgeyolo import NoPrint 43 | 44 | 45 | logger.info("loading dataset...") 46 | dataset_cfg = params.get("dataset_cfg") 47 | with NoPrint(): 48 | valdataset = get_dataset( 49 | cfg=dataset_cfg, 50 | img_size=(640, 640), 51 | preproc=None, 52 | mode="val", 53 | ) 54 | return valdataset 55 | 56 | 57 | def eval(params=None): 58 | import json 59 | dataset = load_dataset(params) 60 | eval_result: dict = json.load(open(params["config"], "r")) 61 | 62 | cocoFormatResult = [] 63 | 64 | for i in range(len(dataset)): 65 | if isinstance(dataset, COCODataset): 66 | cur_id = dataset.ids[i] 67 | _, _, _, file_name, _ = dataset.annotations[i] 68 | else: 69 | cur_id = i 70 | file_name = dataset.annotation_list[i]["image"] 71 | 72 | 73 | for obj in eval_result.get(osp.basename(file_name), []): 74 | # if obj["score"] > 0.25: 75 | # print(obj) 76 | obj["image_id"] = cur_id 77 | obj["category_id"] = dataset.class_ids[int(obj["category_id"])] 78 | cocoFormatResult.append(obj) 79 | 80 | print("num dets:", len(cocoFormatResult)) 81 | cocoGt = dataset.coco 82 | cocoDt = cocoGt.loadRes(cocoFormatResult) 83 | 84 | annType = ["segm", "bbox", "keypoints"] 85 | 86 | from pycocotools.cocoeval import COCOeval 87 | import io 88 | import contextlib 89 | 90 | cocoEval = COCOeval(cocoGt, cocoDt, annType[1]) 91 | 92 | cocoEval.evaluate() 93 | cocoEval.accumulate() 94 | redirect_string = io.StringIO() 95 | with contextlib.redirect_stdout(redirect_string): 96 | cocoEval.summarize() 97 | info = redirect_string.getvalue() 98 | # print(cocoEval.stats) 99 | print(info) 100 | 101 | 102 | if __name__ == '__main__': 103 | args = get_args() 104 | eval(generate_params( 105 | dataset_cfg=args.dataset, 106 | config=args.config 107 | )) 108 | -------------------------------------------------------------------------------- /demo/load_dataset.py: -------------------------------------------------------------------------------- 1 | from edgeyolo.data import MosaicDetection, TrainTransform, get_dataset 2 | from edgeyolo.detect import get_color 3 | import cv2 4 | import numpy as np 5 | 6 | 7 | def load(): 8 | img_size = (1280, 1280) 9 | 10 | import time 11 | 12 | t0 = time.time() 13 | 14 | dataset = get_dataset( 15 | cfg="../params/dataset/coco.yaml", 16 | img_size=img_size, 17 | preproc=TrainTransform( 18 | max_labels=500, 19 | flip_prob=0.5, 20 | hsv_prob=1, 21 | hsv_gain=[0.0138, 0.664, 0.464] 22 | ), 23 | mode="train" 24 | ) 25 | 26 | print(F"TOTAL TIME COST ON LOADING DATASET: {time.time() - t0}s") 27 | 28 | dataset = MosaicDetection( 29 | dataset, 30 | mosaic=True, 31 | img_size=img_size, 32 | preproc=dataset.preproc, 33 | degrees=float(10), 34 | translate=0.1, 35 | mosaic_scale=(0.1, 2), 36 | mixup_scale=(0.5, 1.5), 37 | shear=2.0, 38 | enable_mixup=True, 39 | mosaic_prob=0, 40 | mixup_prob=0, 41 | rank=0, 42 | train_mask=False 43 | ) 44 | 45 | print(len(dataset)) 46 | for i in range(len(dataset)): 47 | 48 | # i=979 49 | mix_img, padded_labels, *_ = dataset[i] 50 | # print(padded_labels) 51 | 52 | mix_img = np.ascontiguousarray(mix_img.transpose((1, 2, 0)), dtype="uint8") 53 | # print(dataset._dataset.annotation_list[i]["image"], mix_img.shape) 54 | 55 | for cls, *xywh in padded_labels: 56 | if not sum(xywh) == 0: 57 | cx, cy, w, h = xywh 58 | cv2.rectangle(mix_img, 59 | (int(cx - w / 2), int(cy - h / 2)), 60 | (int(cx + w / 2), int(cy + h / 2)), 61 | get_color(cls, bgr=True), 1, cv2.LINE_AA) 62 | print(f"{i+1}/{len(dataset)}") 63 | cv2.imshow("dataset", mix_img) 64 | if cv2.waitKey(0) == 27: 65 | cv2.destroyAllWindows() 66 | break 67 | 68 | 69 | 70 | if __name__ == '__main__': 71 | load() 72 | -------------------------------------------------------------------------------- /deployment/detect_for_mdc300f.py: -------------------------------------------------------------------------------- 1 | # bin/detect_one_image --config models/ascend.yaml --source 000000000785.jpg 2 | 3 | import os 4 | import requests 5 | import json 6 | import os.path as osp 7 | 8 | 9 | class RemoteCapture: 10 | def __init__(self, ip, port, path): 11 | self.ip = ip 12 | self.port = port 13 | self.path = path 14 | self.length = 0 15 | self.__request_url = f"http://{ip}:{port}/getImage" 16 | 17 | resp = requests.post( 18 | f"http://{ip}:{port}/getImageList", 19 | json={ 20 | "path": path 21 | } 22 | ) 23 | 24 | result = json.loads(resp.content) 25 | if result.get("success", False): 26 | self.imgs: list = result.get("value") 27 | self.length = len(self.imgs) 28 | 29 | self.currentFile = None 30 | 31 | def isOpened(self): 32 | return bool(len(self.imgs)) 33 | 34 | 35 | def read(self): 36 | self.currentFile = self.imgs[0] 37 | resp = requests.post( 38 | self.__request_url, 39 | json={ 40 | "path": osp.join(self.path, self.currentFile) 41 | } 42 | ) 43 | try: 44 | open(self.currentFile, "wb").write(resp.content) 45 | self.imgs = self.imgs[1:] 46 | return True, self.currentFile 47 | except: 48 | return False, None 49 | 50 | if __name__ == "__main__": 51 | import argparse 52 | import time 53 | import yaml 54 | parser = argparse.ArgumentParser() 55 | parser.add_argument("--ip", type=str, default="127.0.0.1") 56 | parser.add_argument("--port", type=int, default=12345) 57 | parser.add_argument("--path", type=str, required=True) 58 | 59 | args = parser.parse_args() 60 | 61 | cap = RemoteCapture(args.ip, args.port, args.path) 62 | if cap.isOpened(): 63 | yaml.dump( 64 | {"imgs": cap.imgs}, 65 | open("path.yaml", "w"), 66 | yaml.Dumper 67 | ) 68 | 69 | json2save = {} 70 | 71 | total_num = cap.length 72 | 73 | count = 0 74 | while cap.isOpened(): 75 | success, real_name = cap.read() 76 | if not osp.isfile(real_name): 77 | print("failed to read image!") 78 | break 79 | 80 | jsonfilename = real_name.split(".")[0] + ".json" 81 | while not osp.isfile(jsonfilename): 82 | pass 83 | while True: 84 | try: 85 | result = eval(open(jsonfilename).read()) 86 | break 87 | except: 88 | print("retry read tmp.json") 89 | pass 90 | os.remove(jsonfilename) 91 | os.remove(real_name) 92 | 93 | if osp.isfile(jsonfilename): 94 | print("failed to delete tmp.json!") 95 | 96 | json2save[real_name] = result 97 | 98 | count += 1 99 | print("eval:", f"{count}/{total_num}") 100 | 101 | print() 102 | print("saving json files ...") 103 | with open("eval_results.json", "w") as f: 104 | json.dump(json2save, f) 105 | print("done") 106 | # result = eval(os.popen(f"bin/detect_one_image --config models/ascend.yaml --source 000000000785.jpg").read().split("\n")[-2]) 107 | # print(result, type(result), type(result[0])) 108 | -------------------------------------------------------------------------------- /deployment/models/ascend.yaml: -------------------------------------------------------------------------------- 1 | model_path: ./coco.om 2 | batch_size: 1 3 | dtype: uint8 4 | img_size: 5 | - 384 6 | - 640 7 | input_name: input_0 8 | output_names: 9 | - reg0 10 | - reg1 11 | - reg2 12 | - obj_conf0 13 | - obj_conf1 14 | - obj_conf2 15 | - cls_conf0 16 | - cls_conf1 17 | - cls_conf2 18 | names: 19 | - person 20 | - bicycle 21 | - car 22 | - motorcycle 23 | - airplane 24 | - bus 25 | - train 26 | - truck 27 | - boat 28 | - traffic light 29 | - fire hydrant 30 | - stop sign 31 | - parking meter 32 | - bench 33 | - bird 34 | - cat 35 | - dog 36 | - horse 37 | - sheep 38 | - cow 39 | - elephant 40 | - bear 41 | - zebra 42 | - giraffe 43 | - backpack 44 | - umbrella 45 | - handbag 46 | - tie 47 | - suitcase 48 | - frisbee 49 | - skis 50 | - snowboard 51 | - sports ball 52 | - kite 53 | - baseball bat 54 | - baseball glove 55 | - skateboard 56 | - surfboard 57 | - tennis racket 58 | - bottle 59 | - wine glass 60 | - cup 61 | - fork 62 | - knife 63 | - spoon 64 | - bowl 65 | - banana 66 | - apple 67 | - sandwich 68 | - orange 69 | - broccoli 70 | - carrot 71 | - hot dog 72 | - pizza 73 | - donut 74 | - cake 75 | - chair 76 | - couch 77 | - potted plant 78 | - bed 79 | - dining table 80 | - toilet 81 | - tv 82 | - laptop 83 | - mouse 84 | - remote 85 | - keyboard 86 | - cell phone 87 | - microwave 88 | - oven 89 | - toaster 90 | - sink 91 | - refrigerator 92 | - book 93 | - clock 94 | - vase 95 | - scissors 96 | - teddy bear 97 | - hair drier 98 | - toothbrush 99 | obj_conf_enabled: true 100 | normalize: false 101 | 102 | kwargs: 103 | rc_mode: true 104 | version: edgeyolo 105 | conf_threshold: 0.25 106 | nms_threshold: 0.5 107 | rerank: [1, 4, 7, 2, 5, 8, 0, 3, 6] -------------------------------------------------------------------------------- /deployment/models/coco.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/models/coco.bin -------------------------------------------------------------------------------- /deployment/models/coco.engine: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/models/coco.engine -------------------------------------------------------------------------------- /deployment/models/coco.mnn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/models/coco.mnn -------------------------------------------------------------------------------- /deployment/models/coco.om: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/models/coco.om -------------------------------------------------------------------------------- /deployment/models/coco.rknn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/models/coco.rknn -------------------------------------------------------------------------------- /deployment/models/horizon.yaml: -------------------------------------------------------------------------------- 1 | model_path: ./coco.bin 2 | batch_size: 1 3 | dtype: uint8 4 | img_size: 5 | - 384 6 | - 640 7 | input_name: input_0 8 | output_names: 9 | - reg0 10 | - reg1 11 | - reg2 12 | - obj_conf0 13 | - obj_conf1 14 | - obj_conf2 15 | - cls_conf0 16 | - cls_conf1 17 | - cls_conf2 18 | names: 19 | - person 20 | - bicycle 21 | - car 22 | - motorcycle 23 | - airplane 24 | - bus 25 | - train 26 | - truck 27 | - boat 28 | - traffic light 29 | - fire hydrant 30 | - stop sign 31 | - parking meter 32 | - bench 33 | - bird 34 | - cat 35 | - dog 36 | - horse 37 | - sheep 38 | - cow 39 | - elephant 40 | - bear 41 | - zebra 42 | - giraffe 43 | - backpack 44 | - umbrella 45 | - handbag 46 | - tie 47 | - suitcase 48 | - frisbee 49 | - skis 50 | - snowboard 51 | - sports ball 52 | - kite 53 | - baseball bat 54 | - baseball glove 55 | - skateboard 56 | - surfboard 57 | - tennis racket 58 | - bottle 59 | - wine glass 60 | - cup 61 | - fork 62 | - knife 63 | - spoon 64 | - bowl 65 | - banana 66 | - apple 67 | - sandwich 68 | - orange 69 | - broccoli 70 | - carrot 71 | - hot dog 72 | - pizza 73 | - donut 74 | - cake 75 | - chair 76 | - couch 77 | - potted plant 78 | - bed 79 | - dining table 80 | - toilet 81 | - tv 82 | - laptop 83 | - mouse 84 | - remote 85 | - keyboard 86 | - cell phone 87 | - microwave 88 | - oven 89 | - toaster 90 | - sink 91 | - refrigerator 92 | - book 93 | - clock 94 | - vase 95 | - scissors 96 | - teddy bear 97 | - hair drier 98 | - toothbrush 99 | obj_conf_enabled: true 100 | normalize: false 101 | 102 | kwargs: 103 | conf_threshold: 0.25 104 | nms_threshold: 0.5 105 | input: nhwc 106 | version: edgeyolo 107 | show_info: true 108 | -------------------------------------------------------------------------------- /deployment/models/mnn.yaml: -------------------------------------------------------------------------------- 1 | model_path: ./coco.mnn 2 | batch_size: 1 3 | dtype: float 4 | img_size: 5 | - 384 6 | - 640 7 | input_name: input_0 8 | output_names: 9 | - output_0 10 | names: 11 | - person 12 | - bicycle 13 | - car 14 | - motorcycle 15 | - airplane 16 | - bus 17 | - train 18 | - truck 19 | - boat 20 | - traffic light 21 | - fire hydrant 22 | - stop sign 23 | - parking meter 24 | - bench 25 | - bird 26 | - cat 27 | - dog 28 | - horse 29 | - sheep 30 | - cow 31 | - elephant 32 | - bear 33 | - zebra 34 | - giraffe 35 | - backpack 36 | - umbrella 37 | - handbag 38 | - tie 39 | - suitcase 40 | - frisbee 41 | - skis 42 | - snowboard 43 | - sports ball 44 | - kite 45 | - baseball bat 46 | - baseball glove 47 | - skateboard 48 | - surfboard 49 | - tennis racket 50 | - bottle 51 | - wine glass 52 | - cup 53 | - fork 54 | - knife 55 | - spoon 56 | - bowl 57 | - banana 58 | - apple 59 | - sandwich 60 | - orange 61 | - broccoli 62 | - carrot 63 | - hot dog 64 | - pizza 65 | - donut 66 | - cake 67 | - chair 68 | - couch 69 | - potted plant 70 | - bed 71 | - dining table 72 | - toilet 73 | - tv 74 | - laptop 75 | - mouse 76 | - remote 77 | - keyboard 78 | - cell phone 79 | - microwave 80 | - oven 81 | - toaster 82 | - sink 83 | - refrigerator 84 | - book 85 | - clock 86 | - vase 87 | - scissors 88 | - teddy bear 89 | - hair drier 90 | - toothbrush 91 | obj_conf_enabled: true 92 | normalize: false 93 | 94 | kwargs: 95 | threads: 4 96 | type: "cuda" # cpu vulkan opencl opengl 97 | conf_threshold: 0.25 98 | nms_threshold: 0.5 99 | -------------------------------------------------------------------------------- /deployment/models/rknn.yaml: -------------------------------------------------------------------------------- 1 | model_path: ./coco.rknn 2 | batch_size: 1 3 | dtype: uint8 4 | img_size: 5 | - 384 6 | - 640 7 | input_name: input_0 8 | output_names: 9 | - reg0 10 | - reg1 11 | - reg2 12 | - obj_conf0 13 | - obj_conf1 14 | - obj_conf2 15 | - cls_conf0 16 | - cls_conf1 17 | - cls_conf2 18 | names: 19 | - person 20 | - bicycle 21 | - car 22 | - motorcycle 23 | - airplane 24 | - bus 25 | - train 26 | - truck 27 | - boat 28 | - traffic light 29 | - fire hydrant 30 | - stop sign 31 | - parking meter 32 | - bench 33 | - bird 34 | - cat 35 | - dog 36 | - horse 37 | - sheep 38 | - cow 39 | - elephant 40 | - bear 41 | - zebra 42 | - giraffe 43 | - backpack 44 | - umbrella 45 | - handbag 46 | - tie 47 | - suitcase 48 | - frisbee 49 | - skis 50 | - snowboard 51 | - sports ball 52 | - kite 53 | - baseball bat 54 | - baseball glove 55 | - skateboard 56 | - surfboard 57 | - tennis racket 58 | - bottle 59 | - wine glass 60 | - cup 61 | - fork 62 | - knife 63 | - spoon 64 | - bowl 65 | - banana 66 | - apple 67 | - sandwich 68 | - orange 69 | - broccoli 70 | - carrot 71 | - hot dog 72 | - pizza 73 | - donut 74 | - cake 75 | - chair 76 | - couch 77 | - potted plant 78 | - bed 79 | - dining table 80 | - toilet 81 | - tv 82 | - laptop 83 | - mouse 84 | - remote 85 | - keyboard 86 | - cell phone 87 | - microwave 88 | - oven 89 | - toaster 90 | - sink 91 | - refrigerator 92 | - book 93 | - clock 94 | - vase 95 | - scissors 96 | - teddy bear 97 | - hair drier 98 | - toothbrush 99 | obj_conf_enabled: true 100 | normalize: false 101 | 102 | kwargs: 103 | conf_threshold: 0.25 104 | nms_threshold: 0.5 105 | core: all 106 | version: edgeyolo 107 | show_info: true 108 | -------------------------------------------------------------------------------- /deployment/models/trt.yaml: -------------------------------------------------------------------------------- 1 | model_path: ./coco.engine 2 | batch_size: 1 3 | dtype: float 4 | img_size: 5 | - 384 6 | - 640 7 | input_name: input_0 8 | output_names: 9 | - output_0 10 | names: 11 | - person 12 | - bicycle 13 | - car 14 | - motorcycle 15 | - airplane 16 | - bus 17 | - train 18 | - truck 19 | - boat 20 | - traffic light 21 | - fire hydrant 22 | - stop sign 23 | - parking meter 24 | - bench 25 | - bird 26 | - cat 27 | - dog 28 | - horse 29 | - sheep 30 | - cow 31 | - elephant 32 | - bear 33 | - zebra 34 | - giraffe 35 | - backpack 36 | - umbrella 37 | - handbag 38 | - tie 39 | - suitcase 40 | - frisbee 41 | - skis 42 | - snowboard 43 | - sports ball 44 | - kite 45 | - baseball bat 46 | - baseball glove 47 | - skateboard 48 | - surfboard 49 | - tennis racket 50 | - bottle 51 | - wine glass 52 | - cup 53 | - fork 54 | - knife 55 | - spoon 56 | - bowl 57 | - banana 58 | - apple 59 | - sandwich 60 | - orange 61 | - broccoli 62 | - carrot 63 | - hot dog 64 | - pizza 65 | - donut 66 | - cake 67 | - chair 68 | - couch 69 | - potted plant 70 | - bed 71 | - dining table 72 | - toilet 73 | - tv 74 | - laptop 75 | - mouse 76 | - remote 77 | - keyboard 78 | - cell phone 79 | - microwave 80 | - oven 81 | - toaster 82 | - sink 83 | - refrigerator 84 | - book 85 | - clock 86 | - vase 87 | - scissors 88 | - teddy bear 89 | - hair drier 90 | - toothbrush 91 | obj_conf_enabled: true 92 | normalize: false 93 | 94 | kwargs: 95 | conf_threshold: 0.25 96 | nms_threshold: 0.5 97 | -------------------------------------------------------------------------------- /deployment/server.py: -------------------------------------------------------------------------------- 1 | from flask import * 2 | import os.path as osp 3 | from glob import iglob 4 | import argparse 5 | 6 | 7 | def get_args(): 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument("-p", "--port", type=int, default=12345) 10 | parser.add_argument("--debug", action="store_true") 11 | return parser.parse_args() 12 | 13 | 14 | app = Flask(__name__) 15 | 16 | 17 | @app.route("/getImageList", methods=["POST"]) 18 | def getImageList(): 19 | cfg = request.json 20 | 21 | ret = { 22 | "success": False, 23 | "value": [] 24 | } 25 | ret["success"] = osp.isdir(cfg.get("path", "")) 26 | if ret["success"]: 27 | img_dir_path = cfg.get("path") 28 | image_list = [] 29 | for suffix in ["jpg", "png", "jpeg", "bmp", "webp"]: 30 | for iname in iglob(osp.join(img_dir_path, f"*.{suffix}")): 31 | image_list.append(osp.basename(iname)) 32 | image_list.sort() 33 | ret["value"] = image_list 34 | 35 | 36 | # print(cfg) 37 | 38 | return ret 39 | 40 | 41 | @app.route("/getImage", methods=["POST"]) 42 | def getImage(): 43 | cfg = request.json 44 | 45 | ret = { 46 | "success": False, 47 | "value": None 48 | } 49 | ret["success"] = osp.isfile(cfg.get("path", "")) 50 | if ret["success"]: 51 | return send_file(cfg["path"]) 52 | 53 | return ret 54 | 55 | 56 | 57 | if __name__ == "__main__": 58 | args = get_args() 59 | app.run("0.0.0.0", args.port, args.debug) 60 | 61 | -------------------------------------------------------------------------------- /deployment/src/demo.cpp: -------------------------------------------------------------------------------- 1 | #ifndef YOLO_DEMO_CPP 2 | #define YOLO_DEMO_CPP 3 | 4 | #include "../yolo/detect.hpp" 5 | #include "../yolo/os.h" 6 | #include "../yolo/datetime.h" 7 | #include "./argparser.h" 8 | 9 | 10 | argparser::ArgumentParser parseArgs(int argc, char** argv) 11 | { 12 | argparser::ArgumentParser parser("yolo demo parser", argc, argv); 13 | 14 | parser.add_option("-c", "--config", "config file path", ""); 15 | parser.add_option("-s", "--source", "video source", ""); 16 | parser.add_option("-p", "--pause", "stop at start", false); 17 | parser.add_help_option(); 18 | 19 | return parser.parse(); 20 | } 21 | 22 | 23 | int main(int argc, char** argv) 24 | { 25 | auto args = parseArgs(argc, argv); 26 | 27 | pystring configPath = args.get_option_string("--config"); 28 | pystring sourcePath = args.get_option_string("--source"); 29 | 30 | 31 | if (!configPath.lower().endswith(".yaml") && !configPath.lower().endswith("yml")) 32 | { 33 | std::cerr << "[E] only support yaml config file, got " << configPath.lower() << std::endl; 34 | return -1; 35 | } 36 | if (!os::path::isfile(configPath)) 37 | { 38 | std::cerr << "[E] config file not exist!" << std::endl; 39 | return -1; 40 | } 41 | 42 | std::cout << "----------------start init detector-----------------" << std::endl; 43 | 44 | 45 | Detector det; 46 | if(!det.init(configPath.str())) 47 | { 48 | std::cerr << "[E] failed to init detector!" << std::endl; 49 | return -1; 50 | } 51 | 52 | std::cout << "\033[32m\033[1m[INFO] acceleration platform: " 53 | << det.platform() << "\033[0m" << std::endl; 54 | 55 | 56 | 57 | std::cout << "--------------------start detect--------------------" << std::endl; 58 | 59 | 60 | cv::VideoCapture cap(sourcePath.str()); 61 | int delay = args.get_option_bool("--pause")?0:1; 62 | cv::Mat frame; 63 | std::vector> result; 64 | 65 | 66 | while (cap.isOpened()) 67 | { 68 | cap.read(frame); 69 | if (frame.empty()) 70 | { 71 | std::cerr << "\nvideo is empty, exit."; 72 | cap.release(); 73 | break; 74 | } 75 | 76 | result.clear(); 77 | 78 | float ratio=1.0; 79 | cv::Mat resizedImage; 80 | 81 | double t0 = pytime::time(); 82 | // ----------- detect ----------- 83 | det.detect(frame, result); 84 | 85 | 86 | // det.preProcess(frame, resizedImage, ratio); 87 | 88 | // double t1 = pytime::time(); 89 | 90 | // det.infer(resizedImage, ratio, result); 91 | 92 | double t2 = pytime::time(); 93 | 94 | // ------------------------------ 95 | // std::cerr << "\rdelay: " << std::fixed << std::setprecision(3) << 1000 * (t2 - t0) << "ms, " 96 | // << " preprocess:" << 1000 * (t1 - t0) << "ms, infer:" << 1000 * (t2 - t1) << " ms. "; 97 | 98 | std::cerr << "\rdelay: " << std::fixed << std::setprecision(3) << 1000 * (t2 - t0) << "ms "; 99 | 100 | cv::Mat frame_show; 101 | if (result.size()) 102 | { 103 | frame_show = det.draw(frame, result); 104 | // cv::imwrite("test.jpg", frame); 105 | } 106 | 107 | cv::imshow("demo", frame_show); 108 | int k = cv::waitKey(delay); 109 | if (k == ' ') 110 | { 111 | delay = 1 - delay; 112 | } 113 | else if (k == 27) 114 | { 115 | cap.release(); 116 | break; 117 | } 118 | } 119 | std::cout << std::endl; 120 | 121 | cv::destroyAllWindows(); 122 | return 0; 123 | } 124 | 125 | #endif -------------------------------------------------------------------------------- /deployment/src/demo_image.cpp: -------------------------------------------------------------------------------- 1 | #ifndef YOLO_DEMO_IMAGE_CPP 2 | #define YOLO_DEMO_IMAGE_CPP 3 | 4 | #include "../yolo/detect.hpp" 5 | #include "../yolo/os.h" 6 | #include "../yolo/datetime.h" 7 | #include "../yolo/str.h" 8 | #include "./argparser.h" 9 | #include "yaml-cpp/yaml.h" 10 | 11 | 12 | argparser::ArgumentParser parseArgs(int argc, char** argv) 13 | { 14 | argparser::ArgumentParser parser("yolo demo parser", argc, argv); 15 | 16 | parser.add_option("-c", "--config", "config file path", ""); 17 | parser.add_option("-s", "--source", "images source, yaml", ""); 18 | parser.add_option("-t", "--times", "infer times", 1); 19 | parser.add_help_option(); 20 | 21 | return parser.parse(); 22 | } 23 | 24 | 25 | int main(int argc, char** argv) 26 | { 27 | auto args = parseArgs(argc, argv); 28 | 29 | pystring configPath = args.get_option_string("--config"); 30 | pystring sourcePath = args.get_option_string("--source"); 31 | int times = args.get_option_int("--times"); 32 | 33 | if (!configPath.lower().endswith(".yaml") && !configPath.lower().endswith("yml")) 34 | { 35 | std::cerr << "[E] only support yaml config file, got " << configPath.lower() << std::endl; 36 | return -1; 37 | } 38 | if (!os::path::isfile(configPath)) 39 | { 40 | std::cerr << "[E] config file not exist!" << std::endl; 41 | return -1; 42 | } 43 | 44 | std::cout << "----------------start init detector-----------------" << std::endl; 45 | 46 | 47 | Detector det; 48 | if(!det.init(configPath.str())) 49 | { 50 | std::cerr << "[E] failed to init detector!" << std::endl; 51 | return -1; 52 | } 53 | 54 | std::cout << "\033[32m\033[1m[INFO] acceleration platform: " 55 | << det.platform() << "\033[0m" << std::endl; 56 | 57 | 58 | std::cout << "--------------------load image path list--------------------" << std::endl; 59 | auto cfg = YAML::LoadFile(sourcePath.str()); 60 | 61 | auto dirPath = os::path::dirname(sourcePath); 62 | auto filenames = cfg["frames"].as>(); 63 | 64 | std::vector> result; 65 | 66 | os::makedirs("./result"); 67 | 68 | std::cout << "--------------------start detect--------------------" << std::endl; 69 | 70 | 71 | cv::Mat frame; 72 | for(auto filename:filenames) 73 | { 74 | std::string fp = os::path::join({dirPath, filename}); 75 | frame = cv::imread(fp); 76 | if (frame.empty()) continue; 77 | 78 | double t0 = pytime::time(); 79 | // ----------- detect ----------- 80 | 81 | // std::cout << "detect once" << std::endl; 82 | result.clear(); 83 | det.detect(frame, result); 84 | 85 | 86 | // std::cout << "detect once end" << std::endl; 87 | // det.preProcess(frame, resizedImage, ratio); 88 | 89 | // double t1 = pytime::time(); 90 | 91 | // det.infer(resizedImage, ratio, result); 92 | 93 | double t2 = pytime::time(); 94 | 95 | // ------------------------------ 96 | // std::cerr << "\rdelay: " << std::fixed << std::setprecision(3) << 1000 * (t2 - t0) << "ms, " 97 | // << " preprocess:" << 1000 * (t1 - t0) << "ms, infer:" << 1000 * (t2 - t1) << " ms. "; 98 | 99 | std::cerr << "\rdelay: " << std::fixed << std::setprecision(3) << 1000 * (t2 - t0) << "ms "; 100 | 101 | cv::Mat frame_show; 102 | if (result.size()) 103 | { 104 | frame = det.draw(frame, result); 105 | } 106 | cv::imwrite("result/" + filename, frame); 107 | 108 | } 109 | 110 | std::cout << std::endl; 111 | return 0; 112 | } 113 | 114 | #endif -------------------------------------------------------------------------------- /deployment/yolo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | 3 | project(yoloInfer LANGUAGES CXX) 4 | 5 | add_definitions(-std=c++14) 6 | 7 | 8 | set(CMAKE_CXX_STANDARD 14) 9 | set(CMAKE_CXX_FLAGS "-std=c++14 -O3 -fPIC -w ${CMAKE_CXX_FLAGS}") 10 | set(CMAKE_CXX_FLAGS -pthread) 11 | set(CMAKE_BUILD_TYPE Release) 12 | 13 | 14 | message("CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") 15 | 16 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib/") 17 | 18 | if (TENSORRT) 19 | option(CUDA_USE_STATIC_CUDA_RUNTIME OFF) 20 | find_package(CUDA REQUIRED) 21 | 22 | include_directories(~/envs/TensorRT-8.6.1.6/include) 23 | include_directories(~/envs/cudnn/include) 24 | include_directories(/usr/local/cuda/include) 25 | 26 | link_directories(~/envs/TensorRT-8.6.1.6/lib) 27 | link_directories(~/envs/cudnn/lib) 28 | link_directories(/usr/local/cuda/lib64) 29 | 30 | 31 | add_library(yoloInferTensorRT SHARED 32 | ${CMAKE_CURRENT_SOURCE_DIR}/platform/tensorrt/tensorrt.cpp 33 | ) 34 | 35 | target_link_libraries(yoloInferTensorRT PUBLIC 36 | nvinfer 37 | cudart 38 | ) 39 | endif() 40 | 41 | if (MNN) 42 | include_directories(~/envs/MNN/install/include) 43 | link_directories(~/envs/MNN/install/lib) 44 | 45 | add_library(yoloInferMNN SHARED 46 | ${CMAKE_CURRENT_SOURCE_DIR}/platform/mnn/mnn.cpp 47 | ) 48 | target_link_libraries(yoloInferMNN PUBLIC 49 | MNN 50 | ) 51 | endif() 52 | 53 | if(ROCKCHIP) 54 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 55 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined") 56 | link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib) 57 | 58 | add_library(yoloInferRKNN SHARED 59 | ${CMAKE_CURRENT_SOURCE_DIR}/platform/rockchip/rknn.cpp 60 | ) 61 | 62 | target_link_libraries(yoloInferRKNN PUBLIC 63 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/librknnrt.so 64 | ) 65 | 66 | endif() 67 | 68 | if (ASCEND) 69 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/platform/ascend) 70 | endif() 71 | 72 | 73 | if (HORIZON) 74 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/platform/horizon) 75 | endif() 76 | -------------------------------------------------------------------------------- /deployment/yolo/__init__.py: -------------------------------------------------------------------------------- 1 | from .yolo import YOLO -------------------------------------------------------------------------------- /deployment/yolo/capture/__init__.py: -------------------------------------------------------------------------------- 1 | from .capture import setup_source -------------------------------------------------------------------------------- /deployment/yolo/datetime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef PYLIKE_DATETIME_H 3 | #define PYLIKE_DATETIME_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "./str.h" 11 | #include 12 | #include 13 | 14 | 15 | namespace pytime { 16 | 17 | static double time() { 18 | timeval _t; 19 | gettimeofday(&_t, NULL); 20 | double ret = (double)_t.tv_sec + (double)_t.tv_usec / 1000000.0; 21 | return ret; 22 | } 23 | 24 | static void sleep(double sec) { 25 | double t0 = pytime::time(); 26 | while (1) { 27 | if (pytime::time()-t0 > sec) break; 28 | } 29 | } 30 | 31 | } 32 | 33 | 34 | class TimeCount { 35 | std::vector tics; 36 | std::vector tocs; 37 | 38 | public: 39 | size_t length() { 40 | return tics.size(); 41 | } 42 | 43 | void tic(int idx) { 44 | double now_time = pytime::time(); 45 | while (idx >= this->length()) { 46 | tics.push_back(now_time); 47 | tocs.push_back(now_time); 48 | } 49 | tics[idx] = now_time; 50 | tocs[idx] = now_time; 51 | } 52 | 53 | int get_timeval(int idx) { 54 | idx = MIN(idx, this->length()-1); 55 | return 1000 * (tocs[idx] - tics[idx]); 56 | } 57 | 58 | double get_timeval_f(int idx) { 59 | idx = MIN(idx, this->length()-1); 60 | return 1000.0 * (tocs[idx] - tics[idx]); 61 | } 62 | 63 | int toc(int idx) { 64 | idx = MIN(idx, this->length()-1); 65 | tocs[idx] = pytime::time(); 66 | return this->get_timeval(idx); 67 | } 68 | 69 | }; 70 | 71 | 72 | namespace datetime { 73 | 74 | class Datetime { 75 | public: 76 | // 构造函数,默认当前时间 77 | Datetime() { 78 | now(); 79 | } 80 | 81 | Datetime now() { 82 | tp_ = std::chrono::system_clock::now(); 83 | std::time_t now_c = std::chrono::system_clock::to_time_t(tp_); 84 | tm_ = *std::localtime(&now_c); 85 | return *this; 86 | } 87 | 88 | pystring strftime(pystring format="") { 89 | if (!format.length() || format.empty()) { 90 | format = "%Y-%m-%d %H:%M:%S.%ms"; 91 | } 92 | std::ostringstream oss, oss_ms; 93 | auto duration = tp_.time_since_epoch(); 94 | auto millis = std::chrono::duration_cast(duration).count(); 95 | oss_ms << std::setfill('0') << std::setw(3) << millis % 1000; 96 | format = format.replace("%ms", oss_ms.str()); 97 | oss << std::put_time(&tm_, format.c_str()); 98 | return pystring(oss.str()); 99 | } 100 | 101 | int year() const { 102 | return tm_.tm_year + 1900; 103 | } 104 | 105 | int month() const { 106 | return tm_.tm_mon + 1; 107 | } 108 | 109 | int day() const { 110 | return tm_.tm_mday; 111 | } 112 | 113 | int hour() const { 114 | return tm_.tm_hour; 115 | } 116 | 117 | int minute() const { 118 | return tm_.tm_min; 119 | } 120 | 121 | int second() const { 122 | return tm_.tm_sec; 123 | } 124 | 125 | private: 126 | std::tm tm_; 127 | std::chrono::system_clock::time_point tp_; 128 | }; 129 | 130 | 131 | namespace datetime { 132 | 133 | static Datetime now() { 134 | return Datetime(); 135 | } 136 | } 137 | 138 | } 139 | 140 | 141 | #endif -------------------------------------------------------------------------------- /deployment/yolo/detect.hpp: -------------------------------------------------------------------------------- 1 | #ifndef YOLO_DETECT_HPP 2 | #define YOLO_DETECT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | class Detector 11 | { 12 | public: 13 | 14 | Detector() {} 15 | 16 | ~Detector(); 17 | 18 | bool init(std::string configFile); 19 | 20 | std::string platform(); 21 | 22 | void preProcess(const cv::Mat& image, cv::Mat& resized, float& ratio); 23 | 24 | void infer(cv::Mat& image, float ratio, std::vector>& prediction); 25 | 26 | void detect(const cv::Mat& image, std::vector>& prediction, cv::Size* oriSz=nullptr); 27 | 28 | void set(std::string key, std::string value); 29 | 30 | std::vector getNames(); 31 | 32 | cv::Mat draw(cv::Mat& src, std::vector>& prediction, bool draw_label=true, int thickness=20); 33 | 34 | struct Impl; 35 | private: 36 | Impl* impl_=nullptr; 37 | }; 38 | 39 | 40 | #endif -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/hbmedia/libmultimedia.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/hbmedia/libmultimedia.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/hbmedia/libmultimedia.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/hbmedia/libmultimedia.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/hbmedia/libmultimedia.so.1.2.3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/hbmedia/libmultimedia.so.1.2.3 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libalog.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libalog.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libalog.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libalog.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libalog.so.1.0.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libalog.so.1.0.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libcnn_intf.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libcnn_intf.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libcnn_intf.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libcnn_intf.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libcnn_intf.so.1.3.5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libcnn_intf.so.1.3.5 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libdnn.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libdnn.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhb_api_isp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhb_api_isp.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhb_api_isp.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhb_api_isp.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhb_api_isp.so.1.0.3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhb_api_isp.so.1.0.3 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbaudio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbaudio.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbaudio.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbaudio.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbaudio.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbaudio.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbcgroup.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbcgroup.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbcgroup.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbcgroup.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbcgroup.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbcgroup.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbdds.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbdds.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbdds.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbdds.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbdds.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbdds.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbkm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbkm.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbkm.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbkm.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbkm.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbkm.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbmem.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbmem.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbmem.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbmem.so.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbmem.so.0.2.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbmem.so.0.2.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbpcie.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbpcie.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbpcie.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbpcie.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbpcie.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbpcie.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbplayer.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbplayer.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbplayer.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbplayer.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbplayer.so.1.0.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbplayer.so.1.0.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbrt_bayes_aarch64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbrt_bayes_aarch64.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbrt_bernoulli_aarch64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbrt_bernoulli_aarch64.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbspihal.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbspihal.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbspihal.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbspihal.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libhbspihal.so.1.0.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libhbspihal.so.1.0.2 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libion.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libion.so -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libion.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libion.so.1 -------------------------------------------------------------------------------- /deployment/yolo/lib/horizon/libion.so.1.0.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/horizon/libion.so.1.0.0 -------------------------------------------------------------------------------- /deployment/yolo/lib/librknnrt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LSH9832/edgeyolo/0ba2ee513bd42363de79e918efdca7d4de66a38a/deployment/yolo/lib/librknnrt.so -------------------------------------------------------------------------------- /deployment/yolo/libbase.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | from numpy.ctypeslib import ndpointer 3 | import numpy as np 4 | import os.path as osp 5 | from glob import glob 6 | import sys 7 | import os 8 | 9 | suffix_map = { 10 | "engine": "TensorRT", 11 | "trt": "TensorRT", 12 | "rknn": "RKNN", 13 | "mnn": "MNN", 14 | "om": "Ascend", 15 | "bin": "Horizon" 16 | } 17 | 18 | swap_map = { 19 | "tensorrt": (2, 0, 1), 20 | "mnn": (2, 0, 1), 21 | "rknn": None, 22 | "ascend": (2, 0, 1), 23 | "horizon": None 24 | } 25 | 26 | dtype_map = { 27 | "tensorrt": np.float32, 28 | "mnn": np.float32, 29 | "rknn": np.uint8, 30 | "ascend": np.float32, 31 | "horizon": np.uint8, 32 | } 33 | 34 | def list_strings(strings): 35 | # 将Python字符串列表转换为C的char**类型 36 | strings_array = (c_char_p * len(strings))() 37 | for i, string in enumerate(strings): 38 | strings_array[i] = c_char_p(string.encode('utf-8')) 39 | 40 | return cast(strings_array, POINTER(c_char_p)) 41 | 42 | class NoPrint: 43 | 44 | def __init__(self, flag=True): 45 | self.flag = flag 46 | 47 | def __enter__(self): 48 | if self.flag: 49 | self._original_stdout = sys.stdout 50 | sys.stdout = open(os.devnull, 'w') 51 | 52 | def __exit__(self, exc_type, exc_val, exc_tb): 53 | if self.flag: 54 | sys.stdout.close() 55 | sys.stdout = self._original_stdout 56 | 57 | 58 | class LibBase: 59 | 60 | def __init__(self, model_path: str): 61 | self.suffix = None 62 | self._set(model_path) 63 | 64 | # print(self.dtype) 65 | 66 | def platform(self) -> str: 67 | plat_str = b" " 68 | self.yoloPlatform(plat_str) 69 | return plat_str.decode().split()[0] 70 | 71 | def _set(self, model_path: str): 72 | self.suffix = model_path.split(".")[-1].lower() 73 | if self.suffix not in suffix_map: 74 | print(f"[E] do not support model type: {self.suffix}") 75 | exit(-1) 76 | 77 | libPath = osp.join( 78 | osp.dirname(__file__), "lib", 79 | f"libyoloInfer{suffix_map[self.suffix]}.so" 80 | ) 81 | if osp.isfile(libPath): 82 | lib = CDLL(libPath) 83 | else: 84 | raise IOError(f"can not open {libPath}") 85 | 86 | self.setupYOLO = lib.setupYOLO 87 | self.setupYOLO.argtypes = [ 88 | c_char_p, 89 | c_char_p, 90 | POINTER(c_char_p), # char** 91 | c_int, 92 | c_int, 93 | c_int, 94 | ndpointer(dtype=np.int32), 95 | c_int, 96 | c_int 97 | ] 98 | self.setupYOLO.restype = c_void_p 99 | 100 | 101 | self.initYOLO = lib.initYOLO 102 | self.initYOLO.argtypes = [c_void_p] 103 | self.initYOLO.restype = c_bool 104 | 105 | self.isInit = lib.isInit 106 | self.isInit.argtypes = [c_void_p] 107 | self.isInit.restype = c_bool 108 | 109 | self.getNumClasses = lib.getNumClasses 110 | self.getNumClasses.argtypes = [c_void_p] 111 | self.getNumClasses.restype = c_int 112 | 113 | self.getNumArrays = lib.getNumArrays 114 | self.getNumArrays.argtypes = [c_void_p] 115 | self.getNumArrays.restype = c_int 116 | 117 | self.yoloSet = lib.set 118 | self.yoloSet.argtypes = [ 119 | c_void_p, 120 | c_char_p, 121 | c_char_p 122 | ] 123 | 124 | self.yoloPlatform = lib.platform 125 | self.yoloPlatform.argtypes = [c_char_p] 126 | 127 | self.swap = swap_map[self.platform().lower()] 128 | self.dtype = dtype_map[self.platform().lower()] 129 | 130 | self.inference = lib.inference 131 | self.inference.argtypes = [ 132 | c_void_p, 133 | ndpointer(dtype=self.dtype), 134 | ndpointer(dtype=np.float32), 135 | c_float 136 | ] 137 | 138 | self.releaseYOLO = lib.releaseYOLO 139 | self.releaseYOLO.argtypes = [c_void_p] 140 | -------------------------------------------------------------------------------- /deployment/yolo/platform/ascend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | 3 | project(yoloInferAscend) 4 | 5 | if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) 6 | set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") 7 | set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") 8 | endif() 9 | 10 | set(CMAKE_CXX_FLAGS "-std=c++14 -O3 -fPIC -w ${CMAKE_CXX_FLAGS}") 11 | set(CMAKE_CXX_FLAGS -pthread) 12 | set(CMAKE_BUILD_TYPE "Release") 13 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined") 14 | 15 | 16 | set(CROSS_COMPILE_PATH "/usr/local/ubuntu_crossbuild_devkit/sysroot") 17 | set(ASCEND_TOOLKIT_PATH "/usr/local/Ascend/ascend-toolkit/5.0.mdc300") 18 | 19 | # set(CROSS_COMPILE_PATH "/home/lsh/code/CrossCompile/ascend/ubuntu_crossbuild_devkit/sysroot") 20 | # set(ASCEND_TOOLKIT_PATH "/home/lsh/code/CrossCompile/ascend/Ascend/ascend-toolkit/5.0.mdc300") 21 | 22 | set(ASCEND_ACLLIB_PATH ${ASCEND_TOOLKIT_PATH}/arm64-linux/acllib) 23 | set(ASCEND_ATCLIB_PATH ${ASCEND_TOOLKIT_PATH}/x86_64-linux/atc) 24 | set(ASCEND_DRIVER_PATH ${ASCEND_TOOLKIT_PATH}/x86_64-linux/mdc_driver_sdk) 25 | 26 | 27 | include_directories( 28 | ${ASCEND_ACLLIB_PATH}/include 29 | ${ASCEND_DRIVER_PATH}/driver/include 30 | ${CROSS_COMPILE_PATH}/usr/local/include 31 | ${CROSS_COMPILE_PATH}/usr/include 32 | ${CROSS_COMPILE_PATH}/usr/include/aarch64-linux-gnu 33 | ) 34 | 35 | link_directories( 36 | ${ASCEND_DRIVER_PATH}/driver/lib64 37 | ${ASCEND_ATCLIB_PATH}/lib64 38 | # ${ASCEND_ACLLIB_PATH}/lib64 39 | ${ASCEND_ACLLIB_PATH}/lib64/stub 40 | ${CROSS_COMPILE_PATH}/usr/local/lib 41 | ${CROSS_COMPILE_PATH}/lib 42 | ${CROSS_COMPILE_PATH}/lib/aarch64-linux-gnu 43 | ${CROSS_COMPILE_PATH}/usr/lib 44 | ${CROSS_COMPILE_PATH}/usr/lib/aarch64-linux-gnu 45 | ) 46 | 47 | 48 | add_library(yoloInferAscend SHARED 49 | ${CMAKE_CURRENT_SOURCE_DIR}/ascend.cpp 50 | ${CMAKE_CURRENT_SOURCE_DIR}/davinci_net.cpp 51 | ) 52 | 53 | target_link_libraries(yoloInferAscend PUBLIC 54 | # OMX_hisi_video_decoder OMX_hisi_video_encoder 55 | # Dvpp_png_decoder Dvpp_jpeg_decoder Dvpp_jpeg_encoder 56 | acl_dvpp 57 | ascendcl 58 | slog 59 | c_sec 60 | pthread 61 | ) -------------------------------------------------------------------------------- /deployment/yolo/platform/ascend/acl/acl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file acl.h 3 | * 4 | * Copyright (C) Huawei Technologies Co., Ltd. 2019-2020. All Rights Reserved. 5 | * 6 | * This program is distributed in the hope that it will be useful, 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9 | */ 10 | 11 | #ifndef INC_EXTERNAL_ACL_ACL_H_ 12 | #define INC_EXTERNAL_ACL_ACL_H_ 13 | 14 | #include "./acl_rt.h" 15 | #include "./acl_op.h" 16 | #include "./acl_mdl.h" 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | // Current version is 1.0.0 23 | #define ACL_MAJOR_VERSION 1 24 | #define ACL_MINOR_VERSION 0 25 | #define ACL_PATCH_VERSION 0 26 | 27 | /** 28 | * @ingroup AscendCL 29 | * @brief acl initialize 30 | * 31 | * @par Restriction 32 | * The aclInit interface can be called only once in a process 33 | * @param configPath [IN] the config path,it can be NULL 34 | * @retval ACL_SUCCESS The function is successfully executed. 35 | * @retval OtherValues Failure 36 | */ 37 | ACL_FUNC_VISIBILITY aclError aclInit(const char *configPath); 38 | 39 | /** 40 | * @ingroup AscendCL 41 | * @brief acl finalize 42 | * 43 | * @par Restriction 44 | * Need to call aclFinalize before the process exits. 45 | * After calling aclFinalize,the services cannot continue to be used normally. 46 | * @retval ACL_SUCCESS The function is successfully executed. 47 | * @retval OtherValues Failure 48 | */ 49 | ACL_FUNC_VISIBILITY aclError aclFinalize(); 50 | 51 | /** 52 | * @ingroup AscendCL 53 | * @brief query ACL interface version 54 | * 55 | * @param majorVersion[OUT] ACL interface major version 56 | * @param minorVersion[OUT] ACL interface minor version 57 | * @param patchVersion[OUT] ACL interface patch version 58 | * @retval ACL_SUCCESS The function is successfully executed. 59 | * @retval OtherValues Failure 60 | */ 61 | ACL_FUNC_VISIBILITY aclError aclrtGetVersion(int32_t *majorVersion, int32_t *minorVersion, int32_t *patchVersion); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif // INC_EXTERNAL_ACL_ACL_H_ 68 | -------------------------------------------------------------------------------- /deployment/yolo/platform/ascend/acl/error_codes/ge_error_codes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019-2020 Huawei Technologies Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef INC_EXTERNAL_GE_GE_ERROR_CODES_H_ 18 | #define INC_EXTERNAL_GE_GE_ERROR_CODES_H_ 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | static const uint32_t ACL_ERROR_GE_PARAM_INVALID = 145000; 26 | static const uint32_t ACL_ERROR_GE_EXEC_NOT_INIT = 145001; 27 | static const uint32_t ACL_ERROR_GE_EXEC_MODEL_PATH_INVALID = 145002; 28 | static const uint32_t ACL_ERROR_GE_EXEC_MODEL_ID_INVALID = 145003; 29 | static const uint32_t ACL_ERROR_GE_EXEC_MODEL_DATA_SIZE_INVALID = 145006; 30 | static const uint32_t ACL_ERROR_GE_EXEC_MODEL_ADDR_INVALID = 145007; 31 | static const uint32_t ACL_ERROR_GE_EXEC_MODEL_QUEUE_ID_INVALID = 145008; 32 | static const uint32_t ACL_ERROR_GE_EXEC_LOAD_MODEL_REPEATED = 145009; 33 | static const uint32_t ACL_ERROR_GE_DYNAMIC_INPUT_ADDR_INVALID = 145011; 34 | static const uint32_t ACL_ERROR_GE_DYNAMIC_INPUT_LENGTH_INVALID = 145012; 35 | static const uint32_t ACL_ERROR_GE_DYNAMIC_BATCH_SIZE_INVALID = 145013; 36 | static const uint32_t ACL_ERROR_GE_AIPP_BATCH_EMPTY = 145014; 37 | static const uint32_t ACL_ERROR_GE_AIPP_NOT_EXIST = 145015; 38 | static const uint32_t ACL_ERROR_GE_AIPP_MODE_INVALID = 145016; 39 | static const uint32_t ACL_ERROR_GE_OP_TASK_TYPE_INVALID = 145017; 40 | static const uint32_t ACL_ERROR_GE_OP_KERNEL_TYPE_INVALID = 145018; 41 | static const uint32_t ACL_ERROR_GE_MEMORY_ALLOCATION = 245000; 42 | static const uint32_t ACL_ERROR_GE_INTERNAL_ERROR = 545000; 43 | static const uint32_t ACL_ERROR_GE_LOAD_MODEL = 545001; 44 | static const uint32_t ACL_ERROR_GE_EXEC_LOAD_MODEL_PARTITION_FAILED = 545002; 45 | static const uint32_t ACL_ERROR_GE_EXEC_LOAD_WEIGHT_PARTITION_FAILED = 545003; 46 | static const uint32_t ACL_ERROR_GE_EXEC_LOAD_TASK_PARTITION_FAILED = 545004; 47 | static const uint32_t ACL_ERROR_GE_EXEC_LOAD_KERNEL_PARTITION_FAILED = 545005; 48 | static const uint32_t ACL_ERROR_GE_EXEC_RELEASE_MODEL_DATA = 545006; 49 | static const uint32_t ACL_ERROR_GE_COMMAND_HANDLE = 545007; 50 | static const uint32_t ACL_ERROR_GE_GET_TENSOR_INFO = 545008; 51 | static const uint32_t ACL_ERROR_GE_UNLOAD_MODEL = 545009; 52 | #ifdef __cplusplus 53 | } // namespace ge 54 | #endif 55 | #endif // INC_EXTERNAL_GE_GE_ERROR_CODES_H_ 56 | -------------------------------------------------------------------------------- /deployment/yolo/platform/ascend/davinci_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved. 3 | * Description: header for davinci net 4 | */ 5 | 6 | #ifndef DAVINCI_NET_H 7 | #define DAVINCI_NET_H 8 | 9 | #include "./blob.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | class DavinciNet { 17 | private: 18 | uint32_t modelId_; 19 | void *modelMemPtr_; 20 | void *modelWeightPtr_; 21 | aclmdlDesc *modelDesc_; 22 | aclmdlDataset *input_; 23 | aclmdlDataset *output_; 24 | 25 | std::map>> blobMap; 26 | 27 | int32_t deviceId_; 28 | aclrtContext context_; 29 | aclrtStream stream_; 30 | 31 | bool isLoaded_; 32 | 33 | public: 34 | 35 | std::vector input_names, output_names; 36 | std::vector> inputs_dims, outputs_dims; 37 | 38 | DavinciNet(); 39 | 40 | ~DavinciNet(); 41 | 42 | int Init(const std::string &modelPath, const int32_t deviceId = 0); 43 | 44 | int CreateContextAndStream(); 45 | 46 | int LoadModelFromFile(const std::string &modelPath); 47 | int CreateDesc(); 48 | int CreateInputTensor(); 49 | int CreateOutputTensor(); 50 | 51 | void DestroyDesc(); 52 | void DestroyInputTensor(); 53 | void DestroyOutputTensor(); 54 | void UnloadModel(); 55 | void DestroyContextAndStream(); 56 | void DisplayTensorInfo(const aclmdlIODims &dims, const aclDataType dtype, const bool input); 57 | 58 | int Inference(); 59 | std::shared_ptr GetBlob(const std::string &blobName); 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /deployment/yolo/platform/horizon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | 3 | project(yoloInferHorizon) 4 | 5 | if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) 6 | set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") 7 | set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") 8 | endif() 9 | 10 | set(CMAKE_CXX_FLAGS "-std=c++14 -O3 -fPIC -w ${CMAKE_CXX_FLAGS}") 11 | set(CMAKE_CXX_FLAGS -pthread) 12 | set(CMAKE_BUILD_TYPE "Release") 13 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined") 14 | 15 | 16 | include_directories( 17 | ${CMAKE_CURRENT_SOURCE_DIR} 18 | ) 19 | 20 | link_directories( 21 | ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/horizon 22 | ) 23 | 24 | 25 | add_library(yoloInferHorizon SHARED 26 | ${CMAKE_CURRENT_SOURCE_DIR}/horizon.cpp 27 | ) 28 | 29 | 30 | target_link_libraries(yoloInferHorizon PUBLIC 31 | dnn 32 | pthread 33 | ) -------------------------------------------------------------------------------- /deployment/yolo/platform/horizon/dnn/hb_dnn_status.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Horizon Robotics.All Rights Reserved. 2 | // 3 | // The material in this file is confidential and contains trade secrets 4 | // of Horizon Robotics Inc. This is proprietary information owned by 5 | // Horizon Robotics Inc. No part of this work may be disclosed, 6 | // reproduced, copied, transmitted, or used in any way for any purpose, 7 | // without the express written permission of Horizon Robotics Inc. 8 | 9 | #ifndef DNN_HB_DNN_STATUS_H_ 10 | #define DNN_HB_DNN_STATUS_H_ 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif // __cplusplus 17 | 18 | typedef enum { 19 | HB_DNN_SUCCESS = 0, 20 | HB_DNN_INVALID_ARGUMENT = -6000001, 21 | HB_DNN_INVALID_MODEL = -6000002, 22 | HB_DNN_MODEL_NUMBER_EXCEED_LIMIT = -6000003, 23 | HB_DNN_INVALID_PACKED_DNN_HANDLE = -6000004, 24 | HB_DNN_INVALID_DNN_HANDLE = -6000005, 25 | HB_DNN_CAN_NOT_OPEN_FILE = -6000006, 26 | HB_DNN_OUT_OF_MEMORY = -6000007, 27 | HB_DNN_TIMEOUT = -6000008, 28 | HB_DNN_TASK_NUM_EXCEED_LIMIT = -6000009, 29 | HB_DNN_TASK_BATCH_SIZE_EXCEED_LIMIT = -6000010, 30 | HB_DNN_INVALID_TASK_HANDLE = -6000011, 31 | HB_DNN_RUN_TASK_FAILED = -6000012, 32 | HB_DNN_MODEL_IS_RUNNING = -6000013, 33 | HB_DNN_INCOMPATIBLE_MODEL = -6000014, 34 | HB_DNN_API_USE_ERROR = -6000015, 35 | HB_DNN_MULTI_PROGRESS_USE_ERROR = -6000016 36 | } hbDNNStatus; 37 | 38 | /** 39 | * Get DNN error code description 40 | * @param[in] errorCode, dnn error code 41 | * @return DNN error code description in nature language 42 | */ 43 | char const *hbDNNGetErrorDesc(int32_t errorCode); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif // __cplusplus 48 | 49 | #endif // DNN_HB_DNN_STATUS_H_ 50 | -------------------------------------------------------------------------------- /deployment/yolo/platform/horizon/dnn/hb_sys.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Horizon Robotics.All Rights Reserved. 2 | // 3 | // The material in this file is confidential and contains trade secrets 4 | // of Horizon Robotics Inc. This is proprietary information owned by 5 | // Horizon Robotics Inc. No part of this work may be disclosed, 6 | // reproduced, copied, transmitted, or used in any way for any purpose, 7 | // without the express written permission of Horizon Robotics Inc. 8 | 9 | #ifndef DNN_HB_SYS_H_ 10 | #define DNN_HB_SYS_H_ 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif // __cplusplus 17 | 18 | typedef enum { 19 | HB_BPU_CORE_ANY = 0, 20 | HB_BPU_CORE_0 = (1 << 0), 21 | HB_BPU_CORE_1 = (1 << 1) 22 | } hbBPUCore; 23 | 24 | typedef enum { 25 | HB_DSP_CORE_ANY = 0, 26 | HB_DSP_CORE_0 = (1 << 0), 27 | HB_DSP_CORE_1 = (1 << 1) 28 | } hbDSPCore; 29 | 30 | typedef struct { 31 | uint64_t phyAddr; 32 | void *virAddr; 33 | uint32_t memSize; 34 | } hbSysMem; 35 | 36 | typedef enum { 37 | HB_SYS_MEM_CACHE_INVALIDATE = 1, 38 | HB_SYS_MEM_CACHE_CLEAN = 2 39 | } hbSysMemFlushFlag; 40 | 41 | typedef enum { 42 | HB_SYS_SUCCESS = 0, 43 | HB_SYS_INVALID_ARGUMENT = -6000129, 44 | HB_SYS_OUT_OF_MEMORY = -6000130, 45 | HB_SYS_REGISTER_MEM_FAILED = -6000131, 46 | } hbSysStatus; 47 | 48 | /** 49 | * Allocate system memory 50 | * @param[out] mem 51 | * @param[in] size 52 | * @return 0 if success, return defined error code otherwise 53 | */ 54 | int32_t hbSysAllocMem(hbSysMem *mem, uint32_t size); 55 | 56 | /** 57 | * Allocate cachable system memory 58 | * @param[out] mem 59 | * @param[in] size 60 | * @return 0 if success, return defined error code otherwise 61 | */ 62 | int32_t hbSysAllocCachedMem(hbSysMem *mem, uint32_t size); 63 | 64 | /** 65 | * Flush cachable system memory 66 | * @param[in] mem 67 | * @return 0 if success, return defined error code otherwise 68 | */ 69 | int32_t hbSysFlushMem(hbSysMem *mem, int32_t flag); 70 | 71 | /** 72 | * Write mem 73 | * @param[out] mem 74 | * @param[in] mem 75 | * @param[in] size 76 | * @return 0 if success, return defined error code otherwise 77 | */ 78 | int32_t hbSysWriteMem(hbSysMem *dest, char *src, uint32_t size); 79 | 80 | /** 81 | * Read mem 82 | * @param[out] mem 83 | * @param[in] mem 84 | * @param[in] size 85 | * @return 0 if success, return defined error code otherwise 86 | */ 87 | int32_t hbSysReadMem(char *dest, hbSysMem *src, uint32_t size); 88 | 89 | /** 90 | * Free mem 91 | * @param[in] mem 92 | * @return 0 if success, return defined error code otherwise 93 | */ 94 | int32_t hbSysFreeMem(hbSysMem *mem); 95 | 96 | /** 97 | * Register mem (vio etc) so that it can be used by BPU 98 | * @deprecated kept for compatibility purpose 99 | * @param[in] mem 100 | * @return 0 if success, return defined error code otherwise 101 | */ 102 | int32_t hbSysRegisterMem(hbSysMem *mem); 103 | 104 | /** 105 | * Unregister mem (already registered vio mem etc) 106 | * @deprecated kept for compatibility purpose 107 | * @param[in] mem 108 | * @return 0 if success, return defined error code otherwise 109 | */ 110 | int32_t hbSysUnregisterMem(hbSysMem *mem); 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif // __cplusplus 115 | 116 | #endif // DNN_HB_SYS_H_ 117 | -------------------------------------------------------------------------------- /deployment/yolo/platform/horizon/dnn/plugin/hb_dnn_dtype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Horizon Robotics.All Rights Reserved. 2 | // 3 | // The material in this file is confidential and contains trade secrets 4 | // of Horizon Robotics Inc. This is proprietary information owned by 5 | // Horizon Robotics Inc. No part of this work may be disclosed, 6 | // reproduced, copied, transmitted, or used in any way for any purpose, 7 | // without the express written permission of Horizon Robotics Inc. 8 | 9 | #ifndef DNN_PLUGIN_HB_DNN_DTYPE_H_ 10 | #define DNN_PLUGIN_HB_DNN_DTYPE_H_ 11 | 12 | #include 13 | #include 14 | 15 | #define HB_DNN_SIZEOF_TYPE(type) \ 16 | (hobot::dnn::TypeSize[static_cast(type)]) 17 | 18 | namespace hobot { 19 | namespace dnn { 20 | 21 | enum class TypeFlag : uint32_t { 22 | kBool = 0U, 23 | kUInt8 = 1U, 24 | kInt8 = 2U, 25 | kUInt16 = 3U, 26 | kInt16 = 4U, 27 | kUInt32 = 5U, 28 | kInt32 = 6U, 29 | kUInt64 = 7U, 30 | kInt64 = 8U, 31 | kFloat16 = 9U, 32 | kFloat32 = 10U, 33 | kFloat64 = 11U, 34 | kUnused 35 | }; // enum TypeFlag 36 | 37 | extern size_t TypeSize[static_cast(TypeFlag::kUnused) + 1]; 38 | 39 | template 40 | struct DataType { 41 | static inline TypeFlag kFlag() { return TypeFlag::kUnused; } 42 | }; 43 | 44 | template <> 45 | struct DataType { 46 | static inline TypeFlag kFlag() { return TypeFlag::kBool; } 47 | }; 48 | 49 | template <> 50 | struct DataType { 51 | static inline TypeFlag kFlag() { return TypeFlag::kUInt8; } 52 | }; 53 | 54 | template <> 55 | struct DataType { 56 | static inline TypeFlag kFlag() { return TypeFlag::kInt8; } 57 | }; 58 | 59 | template <> 60 | struct DataType { 61 | static inline TypeFlag kFlag() { return TypeFlag::kUInt16; } 62 | }; 63 | 64 | template <> 65 | struct DataType { 66 | static inline TypeFlag kFlag() { return TypeFlag::kInt16; } 67 | }; 68 | 69 | template <> 70 | struct DataType { 71 | static inline TypeFlag kFlag() { return TypeFlag::kUInt32; } 72 | }; 73 | 74 | template <> 75 | struct DataType { 76 | static inline TypeFlag kFlag() { return TypeFlag::kInt32; } 77 | }; 78 | 79 | template <> 80 | struct DataType { 81 | static inline TypeFlag kFlag() { return TypeFlag::kInt64; } 82 | }; 83 | 84 | template <> 85 | struct DataType { 86 | static inline TypeFlag kFlag() { return TypeFlag::kUInt64; } 87 | }; 88 | 89 | template <> 90 | struct DataType { 91 | static inline TypeFlag kFlag() { return TypeFlag::kFloat32; } 92 | }; 93 | 94 | template <> 95 | struct DataType { 96 | static inline TypeFlag kFlag() { return TypeFlag::kFloat64; } 97 | }; 98 | 99 | } // namespace dnn 100 | } // namespace hobot 101 | #endif // DNN_PLUGIN_HB_DNN_DTYPE_H_ 102 | -------------------------------------------------------------------------------- /deployment/yolo/platform/horizon/dnn/plugin/hb_dnn_plugin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Horizon Robotics.All Rights Reserved. 2 | // 3 | // The material in this file is confidential and contains trade secrets 4 | // of Horizon Robotics Inc. This is proprietary information owned by 5 | // Horizon Robotics Inc. No part of this work may be disclosed, 6 | // reproduced, copied, transmitted, or used in any way for any purpose, 7 | // without the express written permission of Horizon Robotics Inc. 8 | 9 | #ifndef DNN_PLUGIN_HB_DNN_PLUGIN_H_ 10 | #define DNN_PLUGIN_HB_DNN_PLUGIN_H_ 11 | 12 | #include 13 | 14 | #include "./hb_dnn_layer.h" 15 | 16 | typedef hobot::dnn::Layer *(*hbDNNLayerCreator)(); 17 | 18 | /** 19 | * Register layer creator function 20 | * @param[in] layerName: layer type 21 | * @param[in] layerCreator: layer creator function 22 | * @return 0 if success, return defined error code otherwise 23 | */ 24 | int32_t hbDNNRegisterLayerCreator(char const *layerType, 25 | hbDNNLayerCreator layerCreator); 26 | 27 | /** 28 | * Unregister layer creator function 29 | * @param[in] layerName: layer type 30 | * @return 0 if success, return defined error code otherwise 31 | */ 32 | int32_t hbDNNUnregisterLayerCreator(char const *layerType); 33 | 34 | #endif // DNN_PLUGIN_HB_DNN_PLUGIN_H_ 35 | -------------------------------------------------------------------------------- /deployment/yolo/visualize.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | class __Colors: 6 | def __init__(self): 7 | hex = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB', 8 | '2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7') 9 | self.palette = [self.hex2rgb('#' + c) for c in hex] 10 | self.n = len(self.palette) 11 | 12 | def __call__(self, i, bgr=False): 13 | c = self.palette[int(i) % self.n] 14 | return (c[2], c[1], c[0]) if bgr else c 15 | 16 | @staticmethod 17 | def hex2rgb(h): 18 | return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4)) 19 | 20 | 21 | get_color = __Colors() 22 | 23 | 24 | def draw(imgs, results, class_names, line_thickness=3, draw_label=True): 25 | single = False 26 | if isinstance(imgs, np.ndarray): 27 | imgs = [imgs] 28 | single = True 29 | out_imgs = [] 30 | tf = max(line_thickness - 1, 1) 31 | for img, result in zip(imgs, results): 32 | # print(img.shape) 33 | if result is not None: 34 | # print(result.shape) 35 | if result.shape[1] == 6: 36 | for *xywh, cls, conf in result: 37 | c1 = (int(xywh[0]), int(xywh[1])) 38 | c2 = (int(xywh[2]), int(xywh[3])) 39 | color = get_color(int(cls), True) 40 | cv2.rectangle(img, c1, c2, color, line_thickness, cv2.LINE_AA) 41 | if draw_label: 42 | label = f'{conf:.2f} {class_names[int(cls)]}' 43 | t_size = cv2.getTextSize(label, 0, fontScale=line_thickness / 3, thickness=tf)[0] 44 | c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 45 | cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled 46 | cv2.putText(img, label, (c1[0], c1[1] - 2), 0, line_thickness / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) 47 | elif result.shape[1] == 7: 48 | for *xywh, obj, conf, cls in result: 49 | c1 = (int(xywh[0]), int(xywh[1])) 50 | c2 = (int(xywh[2]), int(xywh[3])) 51 | color = get_color(int(cls), True) 52 | cv2.rectangle(img, c1, c2, color, line_thickness, cv2.LINE_AA) 53 | if draw_label: 54 | label = f'{class_names[int(cls)]} {obj * conf:.2f}' 55 | t_size = cv2.getTextSize(label, 0, fontScale=line_thickness / 3, thickness=tf)[0] 56 | c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 57 | cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled 58 | cv2.putText(img, label, (c1[0], c1[1] - 2), 0, line_thickness / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) 59 | # print(img.shape) 60 | out_imgs.append(img) 61 | return out_imgs[0] if single else out_imgs -------------------------------------------------------------------------------- /deployment/yolo/yolo.hpp: -------------------------------------------------------------------------------- 1 | #ifndef YOLO_HPP 2 | #define YOLO_HPP 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | class YOLO 11 | { 12 | public: 13 | 14 | YOLO() {} 15 | 16 | YOLO(std::string modelFile, std::string inputName, std::vector outputNames, 17 | int imgW, int imgH, std::vector strides, int device=0); 18 | 19 | bool init(); 20 | 21 | void inference(void* data, void* preds, float scales=1.0); 22 | 23 | bool isInit(); 24 | 25 | void set(std::string key, std::string value); 26 | 27 | bool inputDataReachable(); 28 | 29 | void* getInputData(); 30 | 31 | int getNumClasses(); 32 | 33 | int getNumArrays(); 34 | 35 | ~YOLO(); 36 | 37 | struct Impl; 38 | private: 39 | 40 | std::string modelFile_, inputName_; 41 | std::vector outputNames_; 42 | int imgW_, imgH_; 43 | std::vector strides_ = {8, 16, 32}; 44 | 45 | Impl* impl_ = nullptr; 46 | 47 | }; 48 | 49 | extern "C" 50 | { 51 | YOLO* setupYOLO( 52 | const char* modelFile, const char* inputName, 53 | char** outputNames, int lengthOutputs, 54 | int imgW, int imgH, 55 | const int* strides, int length_strides, int device 56 | ) 57 | { 58 | std::vector _outputNames; 59 | for(int i=0;i _strides; 66 | for (int i=0;iset(key, value); 78 | } 79 | 80 | 81 | bool initYOLO(YOLO* yolo) 82 | { 83 | return yolo->init(); 84 | } 85 | 86 | bool isInit(YOLO* yolo) 87 | { 88 | return yolo->isInit(); 89 | } 90 | 91 | int getNumClasses(YOLO* yolo) 92 | { 93 | return yolo->getNumClasses(); 94 | } 95 | 96 | int getNumArrays(YOLO* yolo) 97 | { 98 | return yolo->getNumArrays(); 99 | } 100 | 101 | void inference(YOLO* yolo, void* data, void* preds, float scale=1.0) 102 | { 103 | yolo->inference(data, preds, scale); 104 | } 105 | 106 | bool isInputReachable(YOLO* yolo) 107 | { 108 | return yolo->inputDataReachable(); 109 | } 110 | 111 | void* getInputData(YOLO* yolo) 112 | { 113 | return yolo->getInputData(); 114 | } 115 | 116 | void releaseYOLO(YOLO* yolo) 117 | { 118 | delete yolo; 119 | yolo=nullptr; 120 | } 121 | 122 | void platform(char* p); 123 | } 124 | 125 | 126 | 127 | #endif -------------------------------------------------------------------------------- /edgeyolo/__init__.py: -------------------------------------------------------------------------------- 1 | from .train import * 2 | from .models import * 3 | from .utils import * 4 | from .utils2 import * 5 | -------------------------------------------------------------------------------- /edgeyolo/data/__init__.py: -------------------------------------------------------------------------------- 1 | from .coco_classes import COCO_CLASSES 2 | from .preprocess import * 3 | from .data_augment import TrainTransform, ValTransform 4 | from .data_prefetcher import * 5 | from .dataloading import DataLoader, worker_init_reset_seed 6 | from .datasets import * 7 | from .samplers import InfiniteSampler, YoloBatchSampler 8 | 9 | -------------------------------------------------------------------------------- /edgeyolo/data/coco_classes.py: -------------------------------------------------------------------------------- 1 | COCO_CLASSES = ( 2 | "person", 3 | "bicycle", 4 | "car", 5 | "motorcycle", 6 | "airplane", 7 | "bus", 8 | "train", 9 | "truck", 10 | "boat", 11 | "traffic light", 12 | "fire hydrant", 13 | "stop sign", 14 | "parking meter", 15 | "bench", 16 | "bird", 17 | "cat", 18 | "dog", 19 | "horse", 20 | "sheep", 21 | "cow", 22 | "elephant", 23 | "bear", 24 | "zebra", 25 | "giraffe", 26 | "backpack", 27 | "umbrella", 28 | "handbag", 29 | "tie", 30 | "suitcase", 31 | "frisbee", 32 | "skis", 33 | "snowboard", 34 | "sports ball", 35 | "kite", 36 | "baseball bat", 37 | "baseball glove", 38 | "skateboard", 39 | "surfboard", 40 | "tennis racket", 41 | "bottle", 42 | "wine glass", 43 | "cup", 44 | "fork", 45 | "knife", 46 | "spoon", 47 | "bowl", 48 | "banana", 49 | "apple", 50 | "sandwich", 51 | "orange", 52 | "broccoli", 53 | "carrot", 54 | "hot dog", 55 | "pizza", 56 | "donut", 57 | "cake", 58 | "chair", 59 | "couch", 60 | "potted plant", 61 | "bed", 62 | "dining table", 63 | "toilet", 64 | "tv", 65 | "laptop", 66 | "mouse", 67 | "remote", 68 | "keyboard", 69 | "cell phone", 70 | "microwave", 71 | "oven", 72 | "toaster", 73 | "sink", 74 | "refrigerator", 75 | "book", 76 | "clock", 77 | "vase", 78 | "scissors", 79 | "teddy bear", 80 | "hair drier", 81 | "toothbrush", 82 | ) -------------------------------------------------------------------------------- /edgeyolo/data/data_prefetcher.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from .samplers import InfiniteSampler, YoloBatchSampler 3 | from .dataloading import worker_init_reset_seed, DataLoader 4 | # import cv2 5 | # 6 | # cv2.setNumThreads(params.num_threads) 7 | 8 | 9 | class MaskDataLoader: 10 | 11 | def __init__( 12 | self, 13 | dataset, 14 | batch_size: int, 15 | rank=0, 16 | world_size=1, 17 | num_workers=4, 18 | train_mask=True 19 | ): 20 | self.dataset = dataset 21 | self.train_mask = train_mask 22 | sampler = InfiniteSampler( 23 | len(self.dataset), 24 | seed=0, 25 | rank=rank, 26 | world_size=world_size 27 | ) 28 | 29 | batch_sampler = YoloBatchSampler( 30 | sampler=sampler, 31 | batch_size=batch_size, 32 | drop_last=True, # DROP LAST BATCH IF ITS BATCH SIZE IS SMALLER 33 | mosaic=True, 34 | ) 35 | 36 | dataloader_kwargs = { 37 | "num_workers": num_workers, 38 | "pin_memory": True, 39 | "batch_sampler": batch_sampler, 40 | "worker_init_fn": worker_init_reset_seed 41 | } 42 | self.train_loader = DataLoader(self.dataset, **dataloader_kwargs) 43 | self.prefetcher = DataPrefetcher(self.train_loader, train_mask) 44 | 45 | def next(self): 46 | return self.prefetcher.next() 47 | 48 | def close_mosaic(self): 49 | self.train_loader.close_mosaic() 50 | 51 | def __len__(self): 52 | return len(self.train_loader) 53 | 54 | 55 | class DataPrefetcher: 56 | """ 57 | DataPrefetcher is inspired by code of following file: 58 | https://github.com/NVIDIA/apex/blob/master/examples/imagenet/main_amp.py 59 | It could speedup your pytorch dataloader. For more information, please check 60 | https://github.com/NVIDIA/apex/issues/304#issuecomment-493562789. 61 | """ 62 | 63 | def __init__(self, loader, train_mask=True): 64 | self.loader = iter(loader) 65 | self.stream = torch.cuda.Stream() 66 | self.input_cuda = self._input_cuda_for_image 67 | self.record_stream = DataPrefetcher._record_stream_for_image 68 | 69 | self.next_input = None 70 | self.next_target = None 71 | self.next_segms = None 72 | self.train_mask = train_mask 73 | 74 | self.preload() 75 | 76 | def preload(self): 77 | try: 78 | if self.train_mask: 79 | self.next_input, self.next_target, _, _, self.next_segms = next(self.loader) 80 | else: 81 | self.next_input, self.next_target, _, _ = next(self.loader) 82 | except StopIteration: 83 | self.next_input = None 84 | self.next_target = None 85 | if self.train_mask: 86 | self.next_segms = None 87 | return 88 | 89 | with torch.cuda.stream(self.stream): 90 | self.input_cuda() 91 | self.next_target = self.next_target.cuda(non_blocking=True) 92 | if self.train_mask: 93 | self.next_segms = self.next_segms.cuda(non_blocking=True) 94 | 95 | def next(self): 96 | torch.cuda.current_stream().wait_stream(self.stream) 97 | input = self.next_input 98 | target = self.next_target 99 | if self.train_mask: 100 | segms = self.next_segms 101 | if input is not None: 102 | self.record_stream(input) 103 | if target is not None: 104 | target.record_stream(torch.cuda.current_stream()) 105 | if self.train_mask: 106 | if segms is not None: 107 | segms.record_stream(torch.cuda.current_stream()) 108 | self.preload() 109 | if self.train_mask: 110 | return input, target, segms 111 | else: 112 | return input, target 113 | 114 | def _input_cuda_for_image(self): 115 | self.next_input = self.next_input.cuda(non_blocking=True) 116 | 117 | @staticmethod 118 | def _record_stream_for_image(input): 119 | input.record_stream(torch.cuda.current_stream()) 120 | -------------------------------------------------------------------------------- /edgeyolo/data/dataloading.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import uuid 4 | 5 | import numpy as np 6 | 7 | import torch 8 | from torch.utils.data.dataloader import DataLoader as torchDataLoader 9 | from torch.utils.data.dataloader import default_collate 10 | 11 | from .samplers import YoloBatchSampler 12 | 13 | 14 | class DataLoader(torchDataLoader): 15 | """ 16 | Lightnet dataloader that enables on the fly resizing of the images. 17 | See :class:`torch.utils.data.DataLoader` for more information on the arguments. 18 | Check more on the following website: 19 | https://gitlab.com/EAVISE/lightnet/-/blob/master/lightnet/data/_dataloading.py 20 | """ 21 | 22 | def __init__(self, *args, **kwargs): 23 | super().__init__(*args, **kwargs) 24 | self.__initialized = False 25 | shuffle = False 26 | batch_sampler = None 27 | if len(args) > 5: 28 | shuffle = args[2] 29 | sampler = args[3] 30 | batch_sampler = args[4] 31 | elif len(args) > 4: 32 | shuffle = args[2] 33 | sampler = args[3] 34 | if "batch_sampler" in kwargs: 35 | batch_sampler = kwargs["batch_sampler"] 36 | elif len(args) > 3: 37 | shuffle = args[2] 38 | if "sampler" in kwargs: 39 | sampler = kwargs["sampler"] 40 | if "batch_sampler" in kwargs: 41 | batch_sampler = kwargs["batch_sampler"] 42 | else: 43 | if "shuffle" in kwargs: 44 | shuffle = kwargs["shuffle"] 45 | if "sampler" in kwargs: 46 | sampler = kwargs["sampler"] 47 | if "batch_sampler" in kwargs: 48 | batch_sampler = kwargs["batch_sampler"] 49 | 50 | # Use custom BatchSampler 51 | if batch_sampler is None: 52 | if sampler is None: 53 | if shuffle: 54 | sampler = torch.utils.data.sampler.RandomSampler(self.dataset) 55 | # sampler = torch.utils.data.DistributedSampler(self.dataset) 56 | else: 57 | sampler = torch.utils.data.sampler.SequentialSampler(self.dataset) 58 | batch_sampler = YoloBatchSampler( 59 | sampler, 60 | self.batch_size, 61 | self.drop_last, 62 | input_dimension=self.dataset.input_dim, 63 | ) 64 | # batch_sampler = IterationBasedBatchSampler(batch_sampler, num_iterations = 65 | 66 | self.batch_sampler = batch_sampler 67 | 68 | self.__initialized = True 69 | 70 | def close_mosaic(self): 71 | self.batch_sampler.mosaic = False 72 | 73 | 74 | def list_collate(batch): 75 | """ 76 | Function that collates lists or tuples together into one list (of lists/tuples). 77 | Use this as the collate function in a Dataloader, if you want to have a list of 78 | items as an output, as opposed to tensors (eg. Brambox.boxes). 79 | """ 80 | items = list(zip(*batch)) 81 | 82 | for i in range(len(items)): 83 | if isinstance(items[i][0], (list, tuple)): 84 | items[i] = list(items[i]) 85 | else: 86 | items[i] = default_collate(items[i]) 87 | 88 | return items 89 | 90 | 91 | def worker_init_reset_seed(worker_id): 92 | seed = uuid.uuid4().int % 2**32 93 | random.seed(seed) 94 | torch.set_rng_state(torch.manual_seed(seed).get_state()) 95 | np.random.seed(seed) 96 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | from .coco import COCODataset 2 | from .dota import DotaDataset 3 | # from .coco_classes import COCO_CLASSES 4 | from .datasets_wrapper import ConcatDataset, Dataset, MixConcatDataset 5 | from .mosaicdetection_ori import MosaicDetection 6 | from .enhanced_mosaicdetection import MosaicDetection as EnhancedMosaicDetection 7 | from .mask_dataloader import * 8 | from .mask_coding import * 9 | from .get_dataset import get_dataset 10 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/coco_classes.py: -------------------------------------------------------------------------------- 1 | COCO_CLASSES = ( 2 | "person", 3 | "bicycle", 4 | "car", 5 | "motorcycle", 6 | "airplane", 7 | "bus", 8 | "train", 9 | "truck", 10 | "boat", 11 | "traffic light", 12 | "fire hydrant", 13 | "stop sign", 14 | "parking meter", 15 | "bench", 16 | "bird", 17 | "cat", 18 | "dog", 19 | "horse", 20 | "sheep", 21 | "cow", 22 | "elephant", 23 | "bear", 24 | "zebra", 25 | "giraffe", 26 | "backpack", 27 | "umbrella", 28 | "handbag", 29 | "tie", 30 | "suitcase", 31 | "frisbee", 32 | "skis", 33 | "snowboard", 34 | "sports ball", 35 | "kite", 36 | "baseball bat", 37 | "baseball glove", 38 | "skateboard", 39 | "surfboard", 40 | "tennis racket", 41 | "bottle", 42 | "wine glass", 43 | "cup", 44 | "fork", 45 | "knife", 46 | "spoon", 47 | "bowl", 48 | "banana", 49 | "apple", 50 | "sandwich", 51 | "orange", 52 | "broccoli", 53 | "carrot", 54 | "hot dog", 55 | "pizza", 56 | "donut", 57 | "cake", 58 | "chair", 59 | "couch", 60 | "potted plant", 61 | "bed", 62 | "dining table", 63 | "toilet", 64 | "tv", 65 | "laptop", 66 | "mouse", 67 | "remote", 68 | "keyboard", 69 | "cell phone", 70 | "microwave", 71 | "oven", 72 | "toaster", 73 | "sink", 74 | "refrigerator", 75 | "book", 76 | "clock", 77 | "vase", 78 | "scissors", 79 | "teddy bear", 80 | "hair drier", 81 | "toothbrush", 82 | ) 83 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/datasets_wrapper.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | from functools import wraps 3 | 4 | from torch.utils.data.dataset import ConcatDataset as torchConcatDataset 5 | from torch.utils.data.dataset import Dataset as torchDataset 6 | 7 | 8 | class ConcatDataset(torchConcatDataset): 9 | def __init__(self, datasets): 10 | super(ConcatDataset, self).__init__(datasets) 11 | if hasattr(self.datasets[0], "input_dim"): 12 | self._input_dim = self.datasets[0].input_dim 13 | self.input_dim = self.datasets[0].input_dim 14 | 15 | def pull_item(self, idx): 16 | if idx < 0: 17 | if -idx > len(self): 18 | raise ValueError( 19 | "absolute value of index should not exceed dataset length" 20 | ) 21 | idx = len(self) + idx 22 | dataset_idx = bisect.bisect_right(self.cumulative_sizes, idx) 23 | if dataset_idx == 0: 24 | sample_idx = idx 25 | else: 26 | sample_idx = idx - self.cumulative_sizes[dataset_idx - 1] 27 | return self.datasets[dataset_idx].pull_item(sample_idx) 28 | 29 | 30 | class MixConcatDataset(torchConcatDataset): 31 | def __init__(self, datasets): 32 | super(MixConcatDataset, self).__init__(datasets) 33 | if hasattr(self.datasets[0], "input_dim"): 34 | self._input_dim = self.datasets[0].input_dim 35 | self.input_dim = self.datasets[0].input_dim 36 | 37 | def __getitem__(self, index): 38 | 39 | if not isinstance(index, int): 40 | idx = index[1] 41 | if idx < 0: 42 | if -idx > len(self): 43 | raise ValueError( 44 | "absolute value of index should not exceed dataset length" 45 | ) 46 | idx = len(self) + idx 47 | dataset_idx = bisect.bisect_right(self.cumulative_sizes, idx) 48 | if dataset_idx == 0: 49 | sample_idx = idx 50 | else: 51 | sample_idx = idx - self.cumulative_sizes[dataset_idx - 1] 52 | if not isinstance(index, int): 53 | index = (index[0], sample_idx, index[2]) 54 | 55 | return self.datasets[dataset_idx][index] 56 | 57 | 58 | class Dataset(torchDataset): 59 | """ This class is a subclass of the base :class:`torch.utils.data.Dataset`, 60 | that enables on the fly resizing of the ``input_dim``. 61 | 62 | Args: 63 | input_dimension (tuple): (width,height) tuple with default dimensions of the network 64 | """ 65 | 66 | def __init__(self, input_dimension, mosaic=True): 67 | super().__init__() 68 | self.__input_dim = input_dimension[:2] 69 | self.enable_mosaic = mosaic 70 | 71 | @property 72 | def input_dim(self): 73 | """ 74 | Dimension that can be used by transforms to set the correct image size, etc. 75 | This allows transforms to have a single source of truth 76 | for the input dimension of the network. 77 | 78 | Return: 79 | list: Tuple containing the current width,height 80 | """ 81 | if hasattr(self, "_input_dim"): 82 | return self._input_dim 83 | return self.__input_dim 84 | 85 | @staticmethod 86 | def mosaic_getitem(getitem_fn): 87 | """ 88 | Decorator method that needs to be used around the ``__getitem__`` method. |br| 89 | This decorator enables the closing mosaic 90 | 91 | Example: 92 | >>> class CustomSet(ln.data.Dataset): 93 | ... def __len__(self): 94 | ... return 10 95 | ... @ln.data.Dataset.mosaic_getitem 96 | ... def __getitem__(self, index): 97 | ... return self.enable_mosaic 98 | """ 99 | 100 | @wraps(getitem_fn) 101 | def wrapper(self, index): 102 | if not isinstance(index, int): 103 | self.enable_mosaic = index[0] 104 | index = index[1] 105 | 106 | ret_val = getitem_fn(self, index) 107 | 108 | return ret_val 109 | 110 | return wrapper 111 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/get_dataset.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | from .voc import VOCDataset 3 | from .coco import COCODataset 4 | from .dota import DotaDataset 5 | from .visdrone import VisDroneDataset 6 | from .yolo import YOLODataset 7 | from .samlabel import SAMLabelDataset 8 | import os.path as osp 9 | 10 | 11 | datasets = { 12 | "voc": VOCDataset, 13 | "coco": COCODataset, 14 | "dota": DotaDataset, 15 | "visdrone": VisDroneDataset, 16 | "yolo": YOLODataset, 17 | "samlabel": SAMLabelDataset 18 | } 19 | 20 | 21 | def get_dataset(cfg, img_size=(640, 640), preproc=None, mode="train", get_type=False, save_cache=True): 22 | 23 | modes = { 24 | "train": {"is_train": True, "test": False}, 25 | "val": {"is_train": False, "test": False}, 26 | "test": {"is_train": False, "test": True} 27 | } 28 | if mode not in modes: 29 | mode = "train" 30 | 31 | if isinstance(cfg, str): 32 | if osp.isfile(cfg): 33 | with open(cfg, "r") as f: 34 | cfg = yaml.load(f, yaml.SafeLoader) 35 | 36 | assert isinstance(cfg, dict) 37 | 38 | dataset = datasets.get(cfg.get("type").lower() or "coco") or COCODataset 39 | dataset = dataset( 40 | cfg=cfg, 41 | img_size=img_size, 42 | preproc=preproc, 43 | **modes.get(mode), 44 | **cfg["kwargs"] 45 | ) 46 | if save_cache: 47 | dataset.save_cache() 48 | if get_type: 49 | return dataset, cfg.get("type").lower() 50 | else: 51 | return dataset 52 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/mask_coding.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | 4 | 5 | def encode_mask(segments: list, max_obj_num=120, max_edge_num=5, max_point_num=1000): 6 | pad_mask = - np.ones([max_obj_num, max_edge_num, max_point_num, 2]) 7 | for i, obj in enumerate(segments): 8 | for j, edge in enumerate(obj): 9 | for k, point in enumerate(edge): 10 | if i < max_obj_num and j < max_edge_num and k < max_point_num: 11 | pad_mask[i, j, k] = point 12 | return pad_mask 13 | 14 | 15 | def decode_mask(segments: np.ndarray or torch.Tensor, data_type=float): 16 | segms = [] 17 | for obj in segments: 18 | objs = [] 19 | for edge in obj: 20 | if isinstance(edge, torch.Tensor): 21 | edge = edge.cpu().numpy() 22 | elif not isinstance(edge, np.ndarray): 23 | edge = np.array(edge) 24 | 25 | reserve_mask = (edge[..., 0] + edge[..., 1]) >= 0 26 | if len(reserve_mask): 27 | real_edge = edge[reserve_mask] 28 | if len(real_edge): 29 | objs.append(real_edge.astype(data_type)) 30 | # objs.append(np.vstack([edge[reserve_mask].astype(data_type), edge[reserve_mask][0:1].astype(data_type)])) 31 | if len(objs): 32 | segms.append(objs) 33 | return segms 34 | 35 | 36 | if __name__ == '__main__': 37 | a = np.array([[[[0.0, 0.0],[0.1, 0.2],[0.3, 0.4], [0.5, 0.6], [-1, -1], [0.7, 0.8]], 38 | [[-1, -1], [-1, -1], [0.3, 0.4], [0.8, 0.9]]]]) 39 | print(decode_mask(a)) 40 | -------------------------------------------------------------------------------- /edgeyolo/data/datasets/voc_classes.py: -------------------------------------------------------------------------------- 1 | VOC_CLASSES = ( 2 | "aeroplane", 3 | "bicycle", 4 | "bird", 5 | "boat", 6 | "bottle", 7 | "bus", 8 | "car", 9 | "cat", 10 | "chair", 11 | "cow", 12 | "diningtable", 13 | "dog", 14 | "horse", 15 | "motorbike", 16 | "person", 17 | "pottedplant", 18 | "sheep", 19 | "sofa", 20 | "train", 21 | "tvmonitor", 22 | ) 23 | -------------------------------------------------------------------------------- /edgeyolo/data/preprocess.py: -------------------------------------------------------------------------------- 1 | # import numpy as np 2 | # import cv2 3 | import torch.nn as nn 4 | 5 | 6 | def preprocess(inputs, targets, input_size): 7 | _, _, h, w = inputs.shape 8 | scale_y = input_size[0] / h 9 | scale_x = input_size[1] / w 10 | if scale_x != 1 or scale_y != 1: 11 | inputs = nn.functional.interpolate( 12 | inputs, size=input_size, mode="bilinear", align_corners=False 13 | ) 14 | targets[..., 1::2] = targets[..., 1::2] * scale_x 15 | targets[..., 2::2] = targets[..., 2::2] * scale_y 16 | return inputs, targets 17 | -------------------------------------------------------------------------------- /edgeyolo/data/samplers.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | from typing import Optional 3 | 4 | import torch 5 | import torch.distributed as dist 6 | from torch.utils.data.sampler import BatchSampler as torchBatchSampler 7 | from torch.utils.data.sampler import Sampler 8 | 9 | 10 | class YoloBatchSampler(torchBatchSampler): 11 | """ 12 | This batch sampler will generate mini-batches of (mosaic, index) tuples from another sampler. 13 | It works just like the :class:`torch.utils.data.sampler.BatchSampler`, 14 | but it will turn on/off the mosaic aug. 15 | """ 16 | 17 | def __init__(self, *args, mosaic=True, **kwargs): 18 | super().__init__(*args, **kwargs) 19 | self.mosaic = mosaic 20 | 21 | def __iter__(self): 22 | for batch in super().__iter__(): 23 | yield [(self.mosaic, idx) for idx in batch] 24 | 25 | 26 | class InfiniteSampler(Sampler): 27 | """ 28 | In training, we only care about the "infinite stream" of training data. 29 | So this sampler produces an infinite stream of indices and 30 | all workers cooperate to correctly shuffle the indices and sample different indices. 31 | The samplers in each worker effectively produces `indices[worker_id::num_workers]` 32 | where `indices` is an infinite stream of indices consisting of 33 | `shuffle(range(size)) + shuffle(range(size)) + ...` (if shuffle is True) 34 | or `range(size) + range(size) + ...` (if shuffle is False) 35 | """ 36 | 37 | def __init__( 38 | self, 39 | size: int, 40 | shuffle: bool = True, 41 | seed: Optional[int] = 0, 42 | rank=0, 43 | world_size=1, 44 | ): 45 | """ 46 | Args: 47 | size (int): the total number of data of the underlying dataset to sample from 48 | shuffle (bool): whether to shuffle the indices or not 49 | seed (int): the initial seed of the shuffle. Must be the same 50 | across all workers. If None, will use a random seed shared 51 | among workers (require synchronization among all workers). 52 | """ 53 | self._size = size 54 | assert size > 0 55 | self._shuffle = shuffle 56 | self._seed = int(seed) 57 | 58 | self._rank = rank 59 | self._world_size = world_size 60 | 61 | def __iter__(self): 62 | start = self._rank 63 | yield from itertools.islice( 64 | self._infinite_indices(), start, None, self._world_size 65 | ) 66 | 67 | def _infinite_indices(self): 68 | g = torch.Generator() 69 | g.manual_seed(self._seed) 70 | while True: 71 | if self._shuffle: 72 | yield from torch.randperm(self._size, generator=g) 73 | else: 74 | yield from torch.arange(self._size) 75 | 76 | def __len__(self): 77 | return self._size // self._world_size 78 | -------------------------------------------------------------------------------- /edgeyolo/detect/__init__.py: -------------------------------------------------------------------------------- 1 | from .detector import Detector 2 | from .export_detector import TRTDetector 3 | from ..utils import get_color 4 | import cv2 5 | import numpy as np 6 | 7 | 8 | def draw(imgs, results, class_names, line_thickness=3, draw_label=True): 9 | single = False 10 | if isinstance(imgs, np.ndarray): 11 | imgs = [imgs] 12 | single = True 13 | out_imgs = [] 14 | tf = max(line_thickness - 1, 1) 15 | for img, result in zip(imgs, results): 16 | # print(img.shape) 17 | if result is not None: 18 | # print(result.shape) 19 | for *xywh, obj, conf, cls in result: 20 | c1 = (int(xywh[0]), int(xywh[1])) 21 | c2 = (int(xywh[2]), int(xywh[3])) 22 | color = get_color(int(cls), True) 23 | cv2.rectangle(img, c1, c2, color, line_thickness, cv2.LINE_AA) 24 | if draw_label: 25 | label = f'{class_names[int(cls)]} {obj * conf:.2f}' 26 | t_size = cv2.getTextSize(label, 0, fontScale=line_thickness / 3, thickness=tf)[0] 27 | c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 28 | cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled 29 | cv2.putText(img, label, (c1[0], c1[1] - 2), 0, line_thickness / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) 30 | # print(img.shape) 31 | out_imgs.append(img) 32 | return out_imgs[0] if single else out_imgs 33 | -------------------------------------------------------------------------------- /edgeyolo/detect/detector.py: -------------------------------------------------------------------------------- 1 | from ..models import EdgeYOLO 2 | from ..data.data_augment import preproc 3 | from ..utils import postprocess, get_model_info 4 | import torch 5 | import numpy as np 6 | from time import time 7 | 8 | 9 | class Detector(EdgeYOLO): 10 | 11 | conf_thres = 0.25 12 | nms_thres = 0.5 13 | fuse = True 14 | cpu = False 15 | fp16 = False 16 | use_decoder = False 17 | 18 | def __init__(self, weight_file, **kwargs): 19 | super(Detector, self).__init__(None, weight_file) 20 | 21 | for k, v in kwargs.items(): 22 | if hasattr(self, k): 23 | self.__setattr__(k, v) 24 | else: 25 | print(f"no keyword named {k}") 26 | 27 | print(get_model_info(self.model, self.input_size)) 28 | 29 | if self.fuse: 30 | with torch.no_grad(): 31 | self.model.fuse() 32 | print("After re-parameterization:", get_model_info(self.model, self.input_size)) 33 | 34 | if not self.cpu: 35 | self.model.cuda(0) 36 | if self.fp16: 37 | self.model.half() 38 | self.model.eval() 39 | 40 | def __preprocess(self, imgs): 41 | pad_ims = [] 42 | rs = [] 43 | for img in imgs: 44 | pad_im, r = preproc(img, self.input_size) 45 | pad_ims.append(torch.from_numpy(pad_im).unsqueeze(0)) 46 | rs.append(r) 47 | self.t0 = time() 48 | 49 | ret_ims = pad_ims[0] if len(pad_ims) == 1 else torch.cat(pad_ims) 50 | 51 | return ret_ims, rs 52 | 53 | def __postprocess(self, results, rs): 54 | # print(results, results.shape) 55 | 56 | outs = postprocess(results, len(self.class_names), self.conf_thres, self.nms_thres, True) 57 | for i, r in enumerate(rs): 58 | if outs[i] is not None: 59 | outs[i] = outs[i].cpu() 60 | outs[i][..., :4] /= r 61 | return outs 62 | 63 | def decode_outputs(self, outputs): 64 | dtype = outputs.type() 65 | grids = [] 66 | strides = [] 67 | for (hsize, wsize), stride in zip(self.input_size, self.strides): 68 | yv, xv = torch.meshgrid([torch.arange(hsize), torch.arange(wsize)]) 69 | grid = torch.stack((xv, yv), 2).view(1, -1, 2) 70 | grids.append(grid) 71 | shape = grid.shape[:2] 72 | strides.append(torch.full((*shape, 1), stride, dtype=torch.long)) 73 | 74 | grids = torch.cat(grids, dim=1).type(dtype) 75 | strides = torch.cat(strides, dim=1).type(dtype) 76 | 77 | outputs[..., :2] = (outputs[..., :2] + grids) * strides 78 | outputs[..., 2:4] = torch.exp(outputs[..., 2:4]) * strides 79 | return outputs 80 | 81 | def __call__(self, imgs, legacy=False): 82 | if isinstance(imgs, np.ndarray): 83 | imgs = [imgs] 84 | 85 | with torch.no_grad(): 86 | inputs, ratios = self.__preprocess(imgs) 87 | if not self.cpu: 88 | inputs = inputs.cuda() 89 | if legacy: 90 | inputs /= 255 91 | if self.fp16: 92 | inputs = inputs.half() 93 | try: 94 | net_outputs = self.model(inputs) 95 | except: 96 | print(inputs.shape) 97 | raise 98 | if self.use_decoder: 99 | net_outputs = self.decode_outputs(net_outputs) 100 | outputs = self.__postprocess(net_outputs, ratios) 101 | self.dt = time() - self.t0 102 | 103 | return outputs 104 | 105 | -------------------------------------------------------------------------------- /edgeyolo/export/__init__.py: -------------------------------------------------------------------------------- 1 | from .calib import CalibDataset 2 | from .pth2trt import torch2onnx2trt 3 | -------------------------------------------------------------------------------- /edgeyolo/export/calib.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from torch2trt import Dataset 3 | 4 | import os 5 | import cv2 6 | import random 7 | import numpy as np 8 | from glob import glob 9 | from loguru import logger 10 | 11 | from ..data.data_augment import preproc 12 | 13 | 14 | class CalibDataset(Dataset): 15 | 16 | path_list = [] 17 | _max_num = 5120 # it doesn't make sense to use too many images for calibration 18 | 19 | def __init__(self, 20 | dataset_path, 21 | num_image=500, 22 | input_size=(640, 640), 23 | pixel_range=255, 24 | suffix="jpg", 25 | batch=1): 26 | self.num_img = num_image 27 | self.input_size = input_size 28 | self.path_list = [] 29 | self.batch = batch 30 | if isinstance(dataset_path, str): 31 | dataset_path = [dataset_path] 32 | for this_path in dataset_path: 33 | if os.path.isdir(this_path): 34 | self.path_list.extend(glob(os.path.join(this_path, f"*.{suffix}"))) 35 | random.shuffle(self.path_list) 36 | if self.num_img > 0: 37 | self.path_list = self.path_list[:self.num_img] 38 | if len(self.path_list) > self._max_num: 39 | logger.info(f"To many images, cut down to {self._max_num} images for calibration.") 40 | self.path_list = self.path_list[:self._max_num] 41 | batch_num = len(self.path_list) // batch 42 | self.path_list = self.path_list[:batch_num * batch] 43 | logger.info(f"used images: {len(self.path_list)}") 44 | 45 | self.norm = pixel_range == 1 46 | # print(self.norm) 47 | 48 | def __getitem__(self, item): 49 | ret = [] 50 | for file in self.path_list[item:item + self.batch]: 51 | im, _ = preproc(cv2.imread(file), self.input_size) 52 | if self.norm: 53 | im /= 255.0 54 | # im = np.ascontiguousarray(im, dtype=np.float16) 55 | ret.append(torch.from_numpy(im).unsqueeze(0).cuda()) 56 | return [torch.cat(ret)] 57 | 58 | def __len__(self): 59 | return len(self.path_list) // self.batch 60 | 61 | def insert(self, item): 62 | self.path_list.append(item) 63 | -------------------------------------------------------------------------------- /edgeyolo/train/__init__.py: -------------------------------------------------------------------------------- 1 | from .loss import conf_loss, iou_loss, cls_loss 2 | from .launch_train import launch 3 | -------------------------------------------------------------------------------- /edgeyolo/train/launch_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | import os.path as osp 3 | import cv2 4 | import yaml 5 | from datetime import timedelta 6 | from loguru import logger 7 | from platform import system 8 | 9 | import torch 10 | import torch.multiprocessing as mp 11 | from torch import distributed as dist 12 | import torch.backends.cudnn as cudnn 13 | 14 | from .trainer import Trainer 15 | from ..utils import init_logger 16 | 17 | with open(os.path.join(os.path.dirname(__file__), "default.yaml")) as dpf: 18 | DEFAULT_PARAMS: dict = yaml.load(dpf, yaml.Loader) 19 | 20 | 21 | def load_train_settings(train_setting_file: str): 22 | if train_setting_file.lower() == "default": 23 | return DEFAULT_PARAMS 24 | 25 | if osp.isfile(train_setting_file): 26 | with open(train_setting_file) as f: 27 | params = yaml.load(f, yaml.Loader) 28 | for k, v in DEFAULT_PARAMS.items(): 29 | if k not in params: 30 | params[k] = v 31 | logger.info(f"param '{k}' not list in settings file, use default value: {k}={v}") 32 | else: 33 | logger.info(f"train settings file {train_setting_file} not found, use default settings.") 34 | params = DEFAULT_PARAMS 35 | return params 36 | 37 | 38 | def train_single( 39 | rank=0, 40 | params: dict = None, 41 | dist_url="tcp://127.0.0.1:12345" 42 | ): 43 | assert params is not None, "lack of params!" 44 | torch.set_num_threads(params["num_threads"]) 45 | cv2.setNumThreads(params["num_threads"]) 46 | 47 | init_logger(os.path.join(params["output_dir"], params["log_file"])) 48 | params["device"] = params["device"] if isinstance(params["device"], list) else [params["device"]] 49 | device = params["device"][rank] 50 | torch.cuda.set_device(device) 51 | 52 | world_size = len(params["device"]) 53 | if world_size > 1: 54 | try: 55 | dist.init_process_group( 56 | backend="gloo" if system() == "Linux" else "gloo", 57 | init_method=dist_url, 58 | world_size=world_size, 59 | rank=rank, 60 | timeout=timedelta(minutes=30), 61 | ) 62 | except Exception: 63 | logger.error("Process group URL: {}".format(dist_url)) 64 | raise 65 | 66 | dist.barrier() 67 | cudnn.benchmark = params["cudnn_benchmark"] 68 | 69 | trainer = Trainer(params, rank) 70 | if params["eval_only"]: 71 | trainer.evaluate_only() 72 | else: 73 | trainer.train() 74 | 75 | 76 | def launch(train_settings_file): 77 | assert os.path.isfile(train_settings_file), f"settings file {train_settings_file} does not exist!" 78 | assert torch.cuda.is_available(), "cuda not available, please double check your device status!" 79 | 80 | params = load_train_settings(train_settings_file) 81 | init_logger() 82 | if isinstance(params["device"], int): 83 | params["device"] = [params["device"]] 84 | params["device"] = [*set(params["device"])] 85 | world_size = len(params["device"]) 86 | is_distributed = world_size > 1 87 | 88 | if is_distributed: 89 | 90 | def find_free_port(): 91 | import socket 92 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 93 | sock.bind(("", 0)) 94 | port = sock.getsockname()[1] 95 | sock.close() 96 | return port 97 | 98 | dist_url = f"tcp://127.0.0.1:{find_free_port()}" 99 | start_method = "spawn" 100 | 101 | mp.start_processes( 102 | train_single, 103 | nprocs=world_size, 104 | args=( 105 | params, 106 | dist_url 107 | ), 108 | daemon=False, 109 | start_method=start_method, 110 | ) 111 | else: 112 | train_single(params=params) 113 | -------------------------------------------------------------------------------- /edgeyolo/train/val/__init__.py: -------------------------------------------------------------------------------- 1 | from .coco_evaluator import COCOEvaluator as Evaluator 2 | from .dota_evaluator import DOTAEvaluator 3 | 4 | 5 | evaluators = { 6 | "voc": Evaluator, 7 | "coco": Evaluator, 8 | "visdrone": Evaluator, 9 | "yolo": Evaluator, 10 | "dota": DOTAEvaluator, 11 | "samlabel": Evaluator 12 | } 13 | -------------------------------------------------------------------------------- /edgeyolo/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .allreduce_norm import * 2 | from .boxes import * 3 | from .checkpoint import load_ckpt, save_checkpoint 4 | from .demo_utils import * 5 | from .dist import * 6 | from .ema import * 7 | from .logger import * 8 | from .lr_scheduler import LRScheduler 9 | from .metric import * 10 | from .model_utils import * 11 | from .setup_env import * 12 | from .cfg_loading import dictConfig 13 | -------------------------------------------------------------------------------- /edgeyolo/utils/allreduce_norm.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | from collections import OrderedDict 3 | 4 | import torch 5 | from torch import distributed as dist 6 | from torch import nn 7 | 8 | # from .dist import _get_global_gloo_group, get_world_size 9 | 10 | ASYNC_NORM = ( 11 | nn.BatchNorm1d, 12 | nn.BatchNorm2d, 13 | nn.BatchNorm3d, 14 | nn.InstanceNorm1d, 15 | nn.InstanceNorm2d, 16 | nn.InstanceNorm3d, 17 | ) 18 | 19 | __all__ = [ 20 | "get_async_norm_states", 21 | "pyobj2tensor", 22 | "tensor2pyobj", 23 | "all_reduce", 24 | "all_reduce_norm", 25 | ] 26 | 27 | 28 | def get_async_norm_states(module): 29 | async_norm_states = OrderedDict() 30 | for name, child in module.named_modules(): 31 | if isinstance(child, ASYNC_NORM): 32 | for k, v in child.state_dict().items(): 33 | async_norm_states[".".join([name, k])] = v 34 | return async_norm_states 35 | 36 | 37 | def pyobj2tensor(pyobj, device="cuda"): 38 | """serialize picklable python object to tensor""" 39 | storage = torch.ByteStorage.from_buffer(pickle.dumps(pyobj)) 40 | return torch.ByteTensor(storage).to(device=device) 41 | 42 | 43 | def tensor2pyobj(tensor): 44 | """deserialize tensor to picklable python object""" 45 | return pickle.loads(tensor.cpu().numpy().tobytes()) 46 | 47 | 48 | def _get_reduce_op(op_name): 49 | return { 50 | "sum": dist.ReduceOp.SUM, 51 | "mean": dist.ReduceOp.SUM, 52 | }[op_name.lower()] 53 | 54 | 55 | def all_reduce(py_dict, op="sum", world_size=1): 56 | 57 | if world_size == 1: 58 | return py_dict 59 | 60 | # all reduce logic across different devices. 61 | py_key = list(py_dict.keys()) 62 | py_key_tensor = pyobj2tensor(py_key) 63 | dist.broadcast(py_key_tensor, src=0) 64 | py_key = tensor2pyobj(py_key_tensor) 65 | 66 | tensor_shapes = [py_dict[k].shape for k in py_key] 67 | tensor_numels = [py_dict[k].numel() for k in py_key] 68 | 69 | flatten_tensor = torch.cat([py_dict[k].flatten() for k in py_key]) 70 | dist.all_reduce(flatten_tensor, op=_get_reduce_op(op)) 71 | if op == "mean": 72 | flatten_tensor /= world_size 73 | 74 | split_tensors = [ 75 | x.reshape(shape) 76 | for x, shape in zip(torch.split(flatten_tensor, tensor_numels), tensor_shapes) 77 | ] 78 | return OrderedDict({k: v for k, v in zip(py_key, split_tensors)}) 79 | 80 | 81 | def all_reduce_norm(module, world_size=1): 82 | """ 83 | All reduce norm statistics in different devices. 84 | """ 85 | states = get_async_norm_states(module) 86 | states = all_reduce(states, op="mean", world_size=world_size) 87 | module.load_state_dict(states, strict=False) 88 | -------------------------------------------------------------------------------- /edgeyolo/utils/cfg_loading.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import tabulate 3 | import os 4 | 5 | 6 | class dictConfig: 7 | __data_dict: dict = {} 8 | 9 | def __init__(self, src=None): 10 | if src is None: 11 | return 12 | if isinstance(src, str): 13 | if os.path.isfile(src): 14 | src = yaml.load(open(src), yaml.Loader) 15 | else: 16 | raise FileNotFoundError(f"No such file named '{src}'.") 17 | elif isinstance(src, dict): 18 | pass 19 | elif hasattr(src, "keys"): 20 | pass 21 | else: 22 | raise TypeError(f"Get wrong type of src({type(src)}), src type should be str or dict!") 23 | 24 | for k in src.keys(): 25 | self.__data_dict[k] = src[k] 26 | 27 | def __getattr__(self, item): 28 | if item in self.__data_dict.keys(): 29 | return self.__data_dict[item] 30 | else: 31 | # print(self.__data_dict) 32 | raise AttributeError(f"No attribute named '{item}'.") 33 | 34 | def __getitem__(self, item): 35 | return getattr(self, item) 36 | 37 | def __repr__(self): 38 | return tabulate.tabulate( 39 | [[k, getattr(self, k)] for k in self.__data_dict.keys()], 40 | ["Keywords", "Values"], 41 | "fancy_grid" 42 | ) 43 | 44 | def __setattr__(self, key, value): 45 | self.__data_dict[key] = value 46 | # print(self.__data_dict) 47 | 48 | def keys(self): 49 | return self.__data_dict.keys() 50 | 51 | 52 | if __name__ == '__main__': 53 | a = dictConfig() 54 | a.test = 1 55 | print(a.keys()) 56 | -------------------------------------------------------------------------------- /edgeyolo/utils/checkpoint.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | from loguru import logger 4 | 5 | import torch 6 | 7 | 8 | def load_ckpt(model, ckpt): 9 | model_state_dict = model.state_dict() 10 | load_dict = {} 11 | for key_model, v in model_state_dict.items(): 12 | if key_model not in ckpt: 13 | logger.warning( 14 | "{} is not in the ckpt. Please double check and see if this is desired.".format( 15 | key_model 16 | ) 17 | ) 18 | continue 19 | v_ckpt = ckpt[key_model] 20 | if v.shape != v_ckpt.shape: 21 | logger.warning( 22 | "Shape of {} in checkpoint is {}, while shape of {} in models is {}.".format( 23 | key_model, v_ckpt.shape, key_model, v.shape 24 | ) 25 | ) 26 | continue 27 | load_dict[key_model] = v_ckpt 28 | 29 | model.load_state_dict(load_dict, strict=False) 30 | return model 31 | 32 | 33 | def save_checkpoint(state, is_best, save_dir, model_name="", epoch: int or None = None): 34 | if epoch is not None and isinstance(epoch, int): 35 | last_model_name = '%s_%04d.pth' % (model_name, epoch) 36 | else: 37 | last_model_name = '%s_last.pth' % model_name 38 | if not os.path.exists(save_dir): 39 | os.makedirs(save_dir) 40 | filename = os.path.join(save_dir, last_model_name) 41 | torch.save(state, filename) 42 | if is_best: 43 | best_filename = os.path.join(save_dir, model_name + "_best.pth") 44 | shutil.copyfile(filename, best_filename) 45 | -------------------------------------------------------------------------------- /edgeyolo/utils/ema.py: -------------------------------------------------------------------------------- 1 | import math 2 | from copy import deepcopy 3 | 4 | import torch 5 | import torch.nn as nn 6 | 7 | __all__ = ["ModelEMA", "is_parallel"] 8 | 9 | 10 | def is_parallel(model): 11 | """check if models is in parallel mode.""" 12 | parallel_type = ( 13 | nn.parallel.DataParallel, 14 | nn.parallel.DistributedDataParallel, 15 | ) 16 | return isinstance(model, parallel_type) 17 | 18 | 19 | class ModelEMA: 20 | """ 21 | Model Exponential Moving Average from https://github.com/rwightman/pytorch-image-models 22 | Keep a moving average of everything in the models state_dict (parameters and buffers). 23 | This is intended to allow functionality like 24 | https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage 25 | A smoothed version of the weights is necessary for some training schemes to perform well. 26 | This class is sensitive where it is initialized in the sequence of models init, 27 | GPU assignment and distributed training wrappers. 28 | """ 29 | 30 | def __init__(self, model, decay=0.9999, updates=0): 31 | """ 32 | Args: 33 | model (nn.Module): models to apply EMA. 34 | decay (float): ema decay reate. 35 | updates (int): counter of EMA updates. 36 | """ 37 | # Create EMA(FP32) 38 | self.ema = deepcopy(model.module if is_parallel(model) else model).eval() 39 | self.updates = updates 40 | # decay exponential ramp (to help early epochs) 41 | self.decay = lambda x: decay * (1 - math.exp(-x / 2000)) 42 | for p in self.ema.parameters(): 43 | p.requires_grad_(False) 44 | 45 | def update(self, model): 46 | # Update EMA parameters 47 | with torch.no_grad(): 48 | self.updates += 1 49 | d = self.decay(self.updates) 50 | 51 | msd = ( 52 | model.module.state_dict() if is_parallel(model) else model.state_dict() 53 | ) # models state_dict 54 | for k, v in self.ema.state_dict().items(): 55 | if v.dtype.is_floating_point: 56 | v *= d 57 | v += (1.0 - d) * msd[k].detach() 58 | -------------------------------------------------------------------------------- /edgeyolo/utils/logger.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from loguru import logger 4 | 5 | 6 | def init_logger(file_name=None): 7 | 8 | show_format = "{time:YYYYMMDD_HHmmss} " \ 9 | "{name}:{line} - {message}" 10 | 11 | logger.remove() 12 | logger.add(sys.stdout, colorize=True, format=show_format) 13 | if file_name is not None: 14 | assert isinstance(file_name, str) 15 | save_format = "{time:YYYY-MM-DD HH:mm:ss} | {level: <8}| " \ 16 | "{name}:{function}:{line} - {message}" 17 | logger.add(file_name, format=save_format) 18 | f = file_name[:-len(file_name.split(".")[-1])] 19 | logger.add(f + "_warn.txt", level="WARNING") 20 | logger.add(f + "_err.txt", level="ERROR") 21 | 22 | 23 | class NoPrint: 24 | 25 | def __init__(self, flag=True): 26 | self.flag = flag 27 | 28 | def __enter__(self): 29 | if self.flag: 30 | self._original_stdout = sys.stdout 31 | sys.stdout = open(os.devnull, 'w') 32 | 33 | def __exit__(self, exc_type, exc_val, exc_tb): 34 | if self.flag: 35 | sys.stdout.close() 36 | sys.stdout = self._original_stdout 37 | -------------------------------------------------------------------------------- /edgeyolo/utils/metric.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import os 3 | import time 4 | from collections import defaultdict, deque 5 | 6 | import numpy as np 7 | 8 | import torch 9 | 10 | __all__ = [ 11 | "AverageMeter", 12 | "MeterBuffer", 13 | "get_total_and_free_memory_in_Mb", 14 | "occupy_mem", 15 | "gpu_mem_usage", 16 | ] 17 | 18 | 19 | def get_total_and_free_memory_in_Mb(cuda_device): 20 | devices_info_str = os.popen( 21 | "nvidia-smi --query-gpu=memory.total,memory.used --format=csv,nounits,noheader" 22 | ) 23 | devices_info = devices_info_str.read().strip().split("\n") 24 | total, used = devices_info[int(cuda_device)].split(",") 25 | return int(total), int(used) 26 | 27 | 28 | def occupy_mem(cuda_device, mem_ratio=0.9): 29 | """ 30 | pre-allocate gpu memory for training to avoid memory Fragmentation. 31 | """ 32 | total, used = get_total_and_free_memory_in_Mb(cuda_device) 33 | max_mem = int(total * mem_ratio) 34 | block_mem = max_mem - used 35 | x = torch.cuda.FloatTensor(256, 1024, block_mem) 36 | del x 37 | time.sleep(5) 38 | 39 | 40 | def gpu_mem_usage(): 41 | """ 42 | Compute the GPU memory usage for the current device (MB). 43 | """ 44 | mem_usage_bytes = torch.cuda.max_memory_allocated() 45 | return mem_usage_bytes / (1024 * 1024) 46 | 47 | 48 | class AverageMeter: 49 | """Track a series of values and provide access to smoothed values over a 50 | window or the global series average. 51 | """ 52 | 53 | def __init__(self, window_size=50): 54 | self._deque = deque(maxlen=window_size) 55 | self._total = 0.0 56 | self._count = 0 57 | 58 | def update(self, value): 59 | self._deque.append(value) 60 | self._count += 1 61 | self._total += value 62 | 63 | @property 64 | def median(self): 65 | d = np.array(list(self._deque)) 66 | return np.median(d) 67 | 68 | @property 69 | def avg(self): 70 | # if deque is empty, nan will be returned. 71 | d = np.array(list(self._deque)) 72 | return d.mean() 73 | 74 | @property 75 | def global_avg(self): 76 | return self._total / max(self._count, 1e-5) 77 | 78 | @property 79 | def latest(self): 80 | return self._deque[-1] if len(self._deque) > 0 else None 81 | 82 | @property 83 | def total(self): 84 | return self._total 85 | 86 | def reset(self): 87 | self._deque.clear() 88 | self._total = 0.0 89 | self._count = 0 90 | 91 | def clear(self): 92 | self._deque.clear() 93 | 94 | 95 | class MeterBuffer(defaultdict): 96 | """Computes and stores the average and current value""" 97 | 98 | def __init__(self, window_size=20): 99 | factory = functools.partial(AverageMeter, window_size=window_size) 100 | super().__init__(factory) 101 | 102 | def reset(self): 103 | for v in self.values(): 104 | v.reset() 105 | 106 | def get_filtered_meter(self, filter_key="time"): 107 | return {k: v for k, v in self.items() if filter_key in k} 108 | 109 | def update(self, values=None, **kwargs): 110 | if values is None: 111 | values = {} 112 | values.update(kwargs) 113 | for k, v in values.items(): 114 | if isinstance(v, torch.Tensor): 115 | v = v.detach() 116 | self[k].update(v) 117 | 118 | def clear_meters(self): 119 | for v in self.values(): 120 | v.clear() 121 | -------------------------------------------------------------------------------- /edgeyolo/utils/model_utils.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | 3 | import torch 4 | import torch.nn as nn 5 | from thop import profile 6 | 7 | __all__ = [ 8 | "fuse_conv_and_bn", 9 | "get_model_info", 10 | "replace_module", 11 | ] 12 | 13 | 14 | def get_model_info(model, tsize): 15 | stride = 64 16 | img = torch.zeros((1, 3, stride, stride), device=next(model.parameters()).device) 17 | flops, params = profile(deepcopy(model), inputs=(img,), verbose=False) 18 | params /= 1e6 19 | flops /= 1e9 20 | flops *= tsize[0] * tsize[1] / stride / stride * 2 # Gflops 21 | info = "Params: {:.2f}M, Gflops: {:.2f}".format(params, flops) 22 | return info 23 | 24 | 25 | def fuse_conv_and_bn(conv, bn): 26 | # Fuse convolution and batchnorm layers https://tehnokv.com/posts/fusing-batchnorm-and-conv/ 27 | fusedconv = ( 28 | nn.Conv2d( 29 | conv.in_channels, 30 | conv.out_channels, 31 | kernel_size=conv.kernel_size, 32 | stride=conv.stride, 33 | padding=conv.padding, 34 | groups=conv.groups, 35 | bias=True, 36 | ) 37 | .requires_grad_(False) 38 | .to(conv.weight.device) 39 | ) 40 | 41 | # prepare filters 42 | w_conv = conv.weight.clone().view(conv.out_channels, -1) 43 | w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var))) 44 | fusedconv.weight.copy_(torch.mm(w_bn, w_conv).view(fusedconv.weight.shape)) 45 | 46 | # prepare spatial bias 47 | b_conv = ( 48 | torch.zeros(conv.weight.size(0), device=conv.weight.device) 49 | if conv.bias is None 50 | else conv.bias 51 | ) 52 | b_bn = bn.bias - bn.weight.mul(bn.running_mean).div( 53 | torch.sqrt(bn.running_var + bn.eps) 54 | ) 55 | fusedconv.bias.copy_(torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn) 56 | 57 | return fusedconv 58 | 59 | 60 | 61 | def replace_module(module, replaced_module_type, new_module_type, replace_func=None): 62 | """ 63 | Replace given type in module to a new type. mostly used in deploy. 64 | 65 | Args: 66 | module (nn.Module): models to apply replace operation. 67 | replaced_module_type (Type): module type to be replaced. 68 | new_module_type (Type) 69 | replace_func (function): python function to describe replace logic. Defalut value None. 70 | 71 | Returns: 72 | models (nn.Module): module that already been replaced. 73 | """ 74 | 75 | def default_replace_func(replaced_module_type, new_module_type): 76 | return new_module_type() 77 | 78 | if replace_func is None: 79 | replace_func = default_replace_func 80 | 81 | model = module 82 | if isinstance(module, replaced_module_type): 83 | model = replace_func(replaced_module_type, new_module_type) 84 | else: # recurrsively replace 85 | for name, child in module.named_children(): 86 | new_child = replace_module(child, replaced_module_type, new_module_type) 87 | if new_child is not child: # child is already replaced 88 | model.add_module(name, new_child) 89 | 90 | return model 91 | -------------------------------------------------------------------------------- /edgeyolo/utils/setup_env.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from loguru import logger 4 | 5 | import cv2 6 | 7 | from .dist import get_world_size, is_main_process 8 | 9 | __all__ = ["configure_nccl", "configure_module", "configure_omp"] 10 | 11 | 12 | def configure_nccl(): 13 | """Configure multi-machine environment variables of NCCL.""" 14 | os.environ["NCCL_LAUNCH_MODE"] = "PARALLEL" 15 | os.environ["NCCL_IB_HCA"] = subprocess.getoutput( 16 | "pushd /sys/class/infiniband/ > /dev/null; for i in mlx5_*; " 17 | "do cat $i/ports/1/gid_attrs/types/* 2>/dev/null " 18 | "| grep v >/dev/null && echo $i ; done; popd > /dev/null" 19 | ) 20 | os.environ["NCCL_IB_GID_INDEX"] = "3" 21 | os.environ["NCCL_IB_TC"] = "106" 22 | 23 | 24 | def configure_omp(num_threads=1): 25 | """ 26 | If OMP_NUM_THREADS is not configured and world_size is greater than 1, 27 | Configure OMP_NUM_THREADS environment variables of NCCL to `num_thread`. 28 | 29 | Args: 30 | num_threads (int): value of `OMP_NUM_THREADS` to set. 31 | """ 32 | # We set OMP_NUM_THREADS=1 by default, which achieves the best speed on our machines 33 | # feel free to change it for better performance. 34 | if "OMP_NUM_THREADS" not in os.environ and get_world_size() > 1: 35 | os.environ["OMP_NUM_THREADS"] = str(num_threads) 36 | if is_main_process(): 37 | logger.info( 38 | "\n***************************************************************\n" 39 | "We set `OMP_NUM_THREADS` for each process to {} to speed up.\n" 40 | "please further tune the variable for optimal performance.\n" 41 | "***************************************************************".format( 42 | os.environ["OMP_NUM_THREADS"] 43 | ) 44 | ) 45 | 46 | 47 | def configure_module(ulimit_value=8192): 48 | """ 49 | Configure pytorch module environment. setting of ulimit and cv2 will be set. 50 | 51 | Args: 52 | ulimit_value(int): default open file number on linux. Default value: 8192. 53 | """ 54 | # system setting 55 | try: 56 | import resource 57 | 58 | rlimit = resource.getrlimit(resource.RLIMIT_NOFILE) 59 | resource.setrlimit(resource.RLIMIT_NOFILE, (ulimit_value, rlimit[1])) 60 | except Exception: 61 | # Exception might be raised in Windows OS or rlimit reaches max limit number. 62 | # However, set rlimit value might not be necessary. 63 | pass 64 | 65 | # cv2 66 | # multiprocess might be harmful on performance of torch dataloader 67 | os.environ["OPENCV_OPENCL_RUNTIME"] = "disabled" 68 | try: 69 | cv2.setNumThreads(0) 70 | cv2.ocl.setUseOpenCL(False) 71 | except Exception: 72 | # cv2 version mismatch might rasie exceptions. 73 | pass 74 | -------------------------------------------------------------------------------- /edgeyolo/utils2/__init__.py: -------------------------------------------------------------------------------- 1 | # init -------------------------------------------------------------------------------- /edgeyolo/utils2/activations.py: -------------------------------------------------------------------------------- 1 | # Activation functions 2 | 3 | import torch 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | 7 | # GELU https://arxiv.org/abs/1606.08415 -------------------------------------------------------------------------------- 8 | class GELU(nn.Module): 9 | @staticmethod 10 | def forward(x): 11 | # return 0.5 * x * (1 + torch.tanh(np.sqrt(2 / 3.1415926535) * (x + 0.044715 * torch.pow(x, 3)))) 12 | return x * 0.5 * (1.0 + torch.erf(x / np.sqrt(2.0))) 13 | 14 | # SiLU https://arxiv.org/pdf/1606.08415.pdf ---------------------------------------------------------------------------- 15 | class SiLU(nn.Module): # export-friendly version of nn.SiLU() 16 | @staticmethod 17 | def forward(x): 18 | return x * torch.sigmoid(x) 19 | 20 | 21 | class Hardswish(nn.Module): # export-friendly version of nn.Hardswish() 22 | @staticmethod 23 | def forward(x): 24 | # return x * F.hardsigmoid(x) # for torchscript and CoreML 25 | return x * F.hardtanh(x + 3, 0., 6.) / 6. # for torchscript, CoreML and ONNX 26 | 27 | 28 | class MemoryEfficientSwish(nn.Module): 29 | class F(torch.autograd.Function): 30 | @staticmethod 31 | def forward(ctx, x): 32 | ctx.save_for_backward(x) 33 | return x * torch.sigmoid(x) 34 | 35 | @staticmethod 36 | def backward(ctx, grad_output): 37 | x = ctx.saved_tensors[0] 38 | sx = torch.sigmoid(x) 39 | return grad_output * (sx * (1 + x * (1 - sx))) 40 | 41 | def forward(self, x): 42 | return self.F.apply(x) 43 | 44 | 45 | # Mish https://github.com/digantamisra98/Mish -------------------------------------------------------------------------- 46 | class Mish(nn.Module): 47 | @staticmethod 48 | def forward(x): 49 | return x * F.softplus(x).tanh() 50 | 51 | 52 | class MemoryEfficientMish(nn.Module): 53 | class F(torch.autograd.Function): 54 | @staticmethod 55 | def forward(ctx, x): 56 | ctx.save_for_backward(x) 57 | return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x))) 58 | 59 | @staticmethod 60 | def backward(ctx, grad_output): 61 | x = ctx.saved_tensors[0] 62 | sx = torch.sigmoid(x) 63 | fx = F.softplus(x).tanh() 64 | return grad_output * (fx + x * sx * (1 - fx * fx)) 65 | 66 | def forward(self, x): 67 | return self.F.apply(x) 68 | 69 | 70 | # FReLU https://arxiv.org/abs/2007.11824 ------------------------------------------------------------------------------- 71 | class FReLU(nn.Module): 72 | def __init__(self, c1, k=3): # ch_in, kernel 73 | super().__init__() 74 | self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False) 75 | self.bn = nn.BatchNorm2d(c1) 76 | 77 | def forward(self, x): 78 | return torch.max(x, self.bn(self.conv(x))) 79 | -------------------------------------------------------------------------------- /params/dataset/bdd100k.yaml: -------------------------------------------------------------------------------- 1 | type: "yolo" 2 | 3 | dataset_path: "E:/dataset/bdd100k" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true 8 | 9 | train: 10 | image_dir: "images/trains" 11 | label: "labels/trains" 12 | 13 | val: 14 | image_dir: "images/valids" 15 | label: "labels/valids" 16 | 17 | test: 18 | test_dir: "images/test" 19 | 20 | segmentaion_enabled: false 21 | 22 | names: ['person','rider','car','bus','truck','bike', 23 | 'motor', 'traffic_light_green', 'traffic_light_red', 24 | 'traffic_light_yellow', 'traffic_light_none', 'traffic_sign', 'train'] 25 | -------------------------------------------------------------------------------- /params/dataset/coco.yaml: -------------------------------------------------------------------------------- 1 | type: "coco" 2 | 3 | dataset_path: "/dataset/coco2017" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true # (test on i5-12490f) Actual time cost: 52s -> 10s(seg enabled) and 39s -> 4s (seg disabled) 8 | 9 | train: 10 | image_dir: "images/train2017" 11 | label: "annotations/instances_train2017.json" 12 | 13 | val: 14 | image_dir: "images/val2017" 15 | label: "annotations/instances_val2017.json" 16 | 17 | test: 18 | test_dir: "test2017" 19 | 20 | segmentaion_enabled: true 21 | 22 | names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 23 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 24 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 25 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 26 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 27 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 28 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 29 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 30 | 'hair drier', 'toothbrush'] 31 | -------------------------------------------------------------------------------- /params/dataset/dota.yaml: -------------------------------------------------------------------------------- 1 | type: "dota" 2 | 3 | dataset_path: "/dataset/DOTA" 4 | 5 | kwargs: 6 | suffix: "png" 7 | 8 | train: 9 | image_dir: "train/images" 10 | label: "train/v2.0/hbb" 11 | 12 | val: 13 | image_dir: "val/images" 14 | label: "val/v2.0/hbb" 15 | 16 | test: 17 | test_dir: "test/images" 18 | 19 | segmentaion_enabled: false 20 | 21 | names: ['plane', 'ship', 'storage tank', 'baseball diamond', 'tennis court', 'basketball court', 'ground track field', 22 | 'harbor', 'bridge', 'large vehicle', 'small vehicle', 'helicopter', 'roundabout', 'soccer ball field', 23 | 'swimming pool', 'container crane', 'airport' , 'helipad'] 24 | -------------------------------------------------------------------------------- /params/dataset/samlabel.yaml: -------------------------------------------------------------------------------- 1 | type: "samlabel" 2 | 3 | dataset_path: "E:/dataset/my_sam_dataset" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true 8 | 9 | train: 10 | image_dir: "images/train" 11 | label: "labels/train" 12 | 13 | val: 14 | image_dir: "images/val" 15 | label: "labels/val" 16 | 17 | test: 18 | test_dir: "images/test" 19 | 20 | segmentaion_enabled: true 21 | 22 | names: ['person','rider','car','bus','truck','bike', 23 | 'motor', 'traffic_light_green', 'traffic_light_red', 24 | 'traffic_light_yellow', 'traffic_light_none', 'traffic_sign', 'train'] 25 | -------------------------------------------------------------------------------- /params/dataset/visdrone.yaml: -------------------------------------------------------------------------------- 1 | type: "visdrone" 2 | 3 | dataset_path: "/dataset/VisDrone2019-DET" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true 8 | 9 | train: 10 | image_dir: "VisDrone2019-DET-train/images" 11 | label: "VisDrone2019-DET-train/annotations" 12 | 13 | val: 14 | image_dir: "VisDrone2019-DET-val/images" 15 | label: "VisDrone2019-DET-val/annotations" 16 | 17 | test: 18 | test_dir: "VisDrone2019-DET-test" 19 | 20 | segmentaion_enabled: false 21 | 22 | names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor'] 23 | -------------------------------------------------------------------------------- /params/dataset/visdrone_coco.yaml: -------------------------------------------------------------------------------- 1 | type: "coco" 2 | 3 | dataset_path: "/dataset/visdrone_coco" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true 8 | 9 | train: 10 | image_dir: "train" 11 | label: "annotations/VisDrone2019-DET_train_coco.json" 12 | 13 | val: 14 | image_dir: "val" 15 | label: "annotations/VisDrone2019-DET_val_coco.json" 16 | 17 | test: 18 | test_dir: "test" 19 | 20 | segmentaion_enabled: false 21 | 22 | names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor'] 23 | -------------------------------------------------------------------------------- /params/dataset/voc.yaml: -------------------------------------------------------------------------------- 1 | type: "voc" 2 | 3 | dataset_path: "/dataset/VOC/VOC2012" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true 8 | 9 | train: 10 | image_dir: "JPEGImages" 11 | anno_dir: "Annotations" 12 | label: "ImageSets/Main/train.txt" 13 | 14 | val: 15 | image_dir: "JPEGImages" 16 | anno_dir: "Annotations" 17 | label: "ImageSets/Main/val.txt" 18 | 19 | test: 20 | test_dir: "test" 21 | 22 | segmentaion_enabled: false 23 | 24 | names: ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 25 | 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'] 26 | -------------------------------------------------------------------------------- /params/dataset/yolo.yaml: -------------------------------------------------------------------------------- 1 | type: "yolo" 2 | 3 | dataset_path: "E:/dataset/coco2017" 4 | 5 | kwargs: 6 | suffix: "jpg" 7 | use_cache: true # (test on i5-12490f) Actual time cost: 16.33s -> 0.18s 8 | 9 | train: 10 | image_dir: "images/train2017" 11 | label: "labels/train2017" 12 | 13 | val: 14 | image_dir: "images/val2017" 15 | label: "annotations/val2017" 16 | 17 | test: 18 | test_dir: "test2017" 19 | 20 | segmentaion_enabled: false 21 | 22 | names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 23 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 24 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 25 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 26 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 27 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 28 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 29 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 30 | 'hair drier', 'toothbrush'] 31 | -------------------------------------------------------------------------------- /plot.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os.path as osp 3 | 4 | from edgeyolo.utils.plot_fig import plot, plot_ap, plot_all 5 | 6 | import matplotlib 7 | matplotlib.use('TkAgg') 8 | 9 | DEFAULT_SIZE = (20, 9) 10 | DEFAULT_SUFFIX = ["svg"] 11 | 12 | 13 | def get_args(): 14 | parser = argparse.ArgumentParser() 15 | 16 | parser.add_argument("-ap", "--ap", action="store_true") 17 | parser.add_argument("-loss", "--loss", action="store_true") 18 | parser.add_argument("-lr", "--lr", action="store_true") 19 | parser.add_argument("-a", "--all", action="store_true") 20 | 21 | parser.add_argument("-f", "--file", type=str, required=True) 22 | 23 | parser.add_argument("-s", "--save", action="store_true") 24 | parser.add_argument("--format", type=str, default=DEFAULT_SUFFIX, nargs="+") 25 | parser.add_argument("--no-show", action="store_true") 26 | return parser.parse_args() 27 | 28 | 29 | if __name__ == '__main__': 30 | args = get_args() 31 | if args.ap: 32 | plot_ap(args.file, show=not args.no_show, save=args.save, suffix=args.format, figsize=DEFAULT_SIZE) 33 | elif args.loss: 34 | plot(args.file, plot_type="loss", show=not args.no_show, save=args.save, suffix=args.format, figsize=DEFAULT_SIZE) 35 | elif args.lr: 36 | plot(args.file, plot_type="lr", show=not args.no_show, save=args.save, suffix=args.format, figsize=DEFAULT_SIZE) 37 | elif args.all: 38 | if osp.isfile(args.file): 39 | args.file = osp.dirname(args.file) 40 | plot_all(args.file, show=not args.no_show, figsize=DEFAULT_SIZE, save=args.save, suffix=args.format) 41 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | torch 2 | torchvision 3 | opencv-python 4 | numpy 5 | loguru 6 | pycocotools 7 | requests 8 | tqdm 9 | tabulate 10 | thop 11 | pyyaml 12 | pandas 13 | pathlib 14 | pillow 15 | matplotlib 16 | mahotas 17 | seaborn 18 | scipy 19 | onnx 20 | onnxsim 21 | ###### tensorrt export ##### 22 | # pycuda 23 | # tensorrt 24 | # torch2trt 25 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | from edgeyolo import launch as train 2 | import argparse 3 | 4 | 5 | def make_parser(): 6 | parser = argparse.ArgumentParser("EdgeYOLO train parser") 7 | parser.add_argument("-c", "--cfg", type=str, default="params/train/train_coco.yaml") 8 | 9 | # Not commend 10 | parser.add_argument("--default", action="store_true", help="use default train settings in edgeyolo/train/default.yaml") 11 | return parser.parse_args() 12 | 13 | 14 | if __name__ == '__main__': 15 | args = make_parser() 16 | train("DEFAULT" if args.default else args.cfg) 17 | --------------------------------------------------------------------------------