From be5864748af0cbd28c2603b62986a442ef744bca Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Tue, 23 Nov 2021 16:29:40 +0100 Subject: [PATCH] Use yaml config file for the demo instead of param list Signed-off-by: Micaela Verucchi --- demo/demo/demo.cpp | 81 ++++++++++++++++++++++++------------------- demo/demoConfig.yaml | 14 ++++++++ docs/demo.md | 31 +++++++++-------- include/tkDNN/utils.h | 16 +++++++++ 4 files changed, 91 insertions(+), 51 deletions(-) create mode 100644 demo/demoConfig.yaml diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index 317a574..069c272 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -9,7 +9,6 @@ #include "Yolo3Detection.h" bool gRun; -bool SAVE_RESULT = false; void sig_handler(int signo) { std::cout<<"request gateway stop\n"; @@ -18,43 +17,53 @@ void sig_handler(int signo) { int main(int argc, char *argv[]) { - std::cout<<"detection\n"; signal(SIGINT, sig_handler); - - std::string net = "yolo4tiny_fp32.rt"; - if(argc > 1) - net = argv[1]; + // get config file path and read it #ifdef __linux__ - std::string input = "../demo/yolo_test.mp4"; + std::string config_file = "../demo/demoConfig.yaml"; #elif _WIN32 - std::string input = "..\\..\\..\\demo\\yolo_test.mp4"; + std::string config_file = "..\\..\\..\\demo\\demoConfig.yaml"; #endif + if(argc > 1) + config_file = config_file[1]; + + YAML::Node conf = YAMLloadConf(config_file); + if(!conf) + FatalError("Problem with config file"); - if(argc > 2) - input = argv[2]; - char ntype = 'y'; - if(argc > 3) - ntype = argv[3][0]; - int n_classes = 80; - if(argc > 4) - n_classes = atoi(argv[4]); - int n_batch = 1; - if(argc > 5) - n_batch = atoi(argv[5]); - bool show = true; - if(argc > 6) - show = atoi(argv[6]); - float conf_thresh=0.3; - if(argc > 7) - conf_thresh = atof(argv[7]); + // read settings from config file + std::string net = YAMLgetConf(conf, "net", "yolo4tiny_fp32.rt"); + if(!fileExist(net.c_str())) + FatalError("The given network does not exist. Create the rt first."); + #ifdef __linux__ + std::string input = YAMLgetConf(conf, "input", "../demo/yolo_test.mp4"); + #elif _WIN32 + std::string input = YAMLgetConf(conf, "win_input", "..\\..\\..\\demo\\yolo_test.mp4"); + #endif + if(!fileExist(input.c_str())) + FatalError("The given input video does not exist."); + + char ntype = YAMLgetConf(conf, "ntype", 'y'); + int n_classes = YAMLgetConf(conf, "n_classes", 80); + int n_batch = YAMLgetConf(conf, "n_batch", 1); if(n_batch < 1 || n_batch > 64) FatalError("Batch dim not supported"); + float conf_thresh = YAMLgetConf(conf, "conf_thresh", 0.3); + bool show = YAMLgetConf(conf, "show", true); + bool save = YAMLgetConf(conf, "save", false); - if(!show) - SAVE_RESULT = true; - + std::cout <<"Net settings - net: "<< net + <<", ntype: "<< ntype + <<", n_classes: "<< n_classes + <<", n_batch: "<< n_batch + <<", conf_thresh: "<< conf_thresh<<"\n"; + std::cout <<"Demo settings - input: "<< input + <<", show: "<< show + <<", save: "<< save<<"\n\n"; + + // create detection network tk::dnn::Yolo3Detection yolo; tk::dnn::CenternetDetection cnet; tk::dnn::MobilenetDetection mbnet; @@ -79,8 +88,7 @@ int main(int argc, char *argv[]) { detNN->init(net, n_classes, n_batch, conf_thresh); - gRun = true; - + // open video stream cv::VideoCapture cap(input); if(!cap.isOpened()) gRun = false; @@ -88,19 +96,21 @@ int main(int argc, char *argv[]) { std::cout<<"camera started\n"; cv::VideoWriter resultVideo; - if(SAVE_RESULT) { + if(save) { int w = cap.get(cv::CAP_PROP_FRAME_WIDTH); int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT); resultVideo.open("result.mp4", cv::VideoWriter::fourcc('M','P','4','V'), 30, cv::Size(w, h)); } - cv::Mat frame; if(show) cv::namedWindow("detection", cv::WINDOW_NORMAL); + cv::Mat frame; std::vector batch_frame; std::vector batch_dnn_input; + // start detection loop + gRun = true; while(gRun) { batch_dnn_input.clear(); batch_frame.clear(); @@ -128,19 +138,18 @@ int main(int argc, char *argv[]) { cv::waitKey(1); } } - if(n_batch == 1 && SAVE_RESULT) + if(n_batch == 1 && save) resultVideo << frame; } std::cout<<"detection end\n"; - double mean = 0; + double mean = 0; std::cout<stats.begin(), detNN->stats.end())/n_batch<<" ms\n"; + std::cout<<"Min: "<<*std::min_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n"; std::cout<<"Max: "<<*std::max_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n"; for(int i=0; istats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size(); std::cout<<"Avg: "< ``` -In general the demo program takes 7 parameters: -``` -./demo -``` -where +In general the demo program takes 1 parameter, the `````` that is the path to che configuration file. The parameter is optional and its default value is ```"../demo/demoConfig.yaml"```. -* `````` is the rt file generated by a test -* ```<``` is the path to a video file or a camera input -* `````` is the type of network. Thee types are currently supported: ```y``` (YOLO family), ```c``` (CenterNet family) and ```m``` (MobileNet-SSD family) -* ``````is the number of classes the network is trained on -* `````` number of batches to use in inference (N.B. you should first export TKDNN_BATCHSIZE to the required n_batches and create again the rt file for the network). -* `````` if set to 0 the demo will not show the visualization but save the video into result.mp4 (if n-batches ==1) -* `````` confidence threshold for the detector. Only bounding boxes with threshold greater than conf-thresh will be displayed. +The config file is a yaml file with the following attributes: +* ```net``` is the rt file generated by a test +* ```input``` is the path to a video file or a camera input (on Linux) +* ```win_input``` is the path to a video file or a camera input (on Windows) +* ```ntype``` is the type of network. Thee types are currently supported: ```y``` (YOLO family), ```c``` (CenterNet family) and ```m``` (MobileNet-SSD family) +* ```n_classes``` is the number of classes the network is trained on +* ```n_batch``` number of batches to use in inference (N.B. you should first export TKDNN_BATCHSIZE to the required n_batches and create again the rt file for the network). +* ```conf_thresh``` confidence threshold for the detector. Only bounding boxes with threshold greater than conf-thresh will be displayed. +* ```show``` if set to 0 the demo will not show the visualization (if n-batches ==1) +* ```save``` if set to 1 the demo will save the video of the demo into result.mp4 (if n-batches ==1) N.B. By default it is used FP32 inference @@ -61,7 +60,8 @@ To run the demo with FP16 inference follow these steps (example with yolov3): export TKDNN_MODE=FP16 # set the half floating point optimization rm yolo3_fp16.rt # be sure to delete(or move) old tensorRT files ./test_yolo3 # run the yolo test (is slow) -./demo yolo3_fp16.rt ../demo/yolo_test.mp4 y +# set net: yolo3_fp16.rt in the config-file +./demo ``` N.B. Using FP16 inference will lead to some errors in the results (first or second decimal). @@ -86,7 +86,8 @@ export TKDNN_CALIB_LABEL_PATH=../demo/COCO_val2017/all_labels.txt export TKDNN_CALIB_IMG_PATH=../demo/COCO_val2017/all_images.txt rm yolo3_int8.rt # be sure to delete(or move) old tensorRT files ./test_yolo3 # run the yolo test (is slow) -./demo yolo3_int8.rt ../demo/yolo_test.mp4 y +# set net: yolo3_int8.rt in the config-file +./demo ``` N.B. diff --git a/include/tkDNN/utils.h b/include/tkDNN/utils.h index 65375ba..4965a7a 100644 --- a/include/tkDNN/utils.h +++ b/include/tkDNN/utils.h @@ -21,6 +21,7 @@ #include #include +#include #define dnnType float @@ -137,4 +138,19 @@ static inline bool isCudaPointer(void *data) { cudaPointerAttributes attr; return cudaPointerGetAttributes(&attr, data) == 0; } + +inline YAML::Node YAMLloadConf(const std::string& conf_file) { + std::cerr<<"Loading YAML: "< +inline T YAMLgetConf(YAML::Node conf, std::string key, T defaultVal) { + T val = defaultVal; + if(conf && conf[key]) { + val = conf[key].as(); + } + return val; +} + #endif //UTILS_H