Use yaml config file for the demo instead of param list

Signed-off-by: Micaela Verucchi <micaelaverucchi@gmail.com>
This commit is contained in:
Micaela Verucchi
2021-11-23 16:29:40 +01:00
parent 75c3cb0038
commit be5864748a
4 changed files with 91 additions and 51 deletions
+44 -35
View File
@@ -9,7 +9,6 @@
#include "Yolo3Detection.h" #include "Yolo3Detection.h"
bool gRun; bool gRun;
bool SAVE_RESULT = false;
void sig_handler(int signo) { void sig_handler(int signo) {
std::cout<<"request gateway stop\n"; std::cout<<"request gateway stop\n";
@@ -18,43 +17,53 @@ void sig_handler(int signo) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
std::cout<<"detection\n";
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
// get config file path and read it
std::string net = "yolo4tiny_fp32.rt";
if(argc > 1)
net = argv[1];
#ifdef __linux__ #ifdef __linux__
std::string input = "../demo/yolo_test.mp4"; std::string config_file = "../demo/demoConfig.yaml";
#elif _WIN32 #elif _WIN32
std::string input = "..\\..\\..\\demo\\yolo_test.mp4"; std::string config_file = "..\\..\\..\\demo\\demoConfig.yaml";
#endif #endif
if(argc > 1)
config_file = config_file[1];
if(argc > 2) YAML::Node conf = YAMLloadConf(config_file);
input = argv[2]; if(!conf)
char ntype = 'y'; FatalError("Problem with config file");
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<std::string>(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<std::string>(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<char>(conf, "ntype", 'y');
int n_classes = YAMLgetConf<int>(conf, "n_classes", 80);
int n_batch = YAMLgetConf<int>(conf, "n_batch", 1);
if(n_batch < 1 || n_batch > 64) if(n_batch < 1 || n_batch > 64)
FatalError("Batch dim not supported"); FatalError("Batch dim not supported");
float conf_thresh = YAMLgetConf<float>(conf, "conf_thresh", 0.3);
bool show = YAMLgetConf<bool>(conf, "show", true);
bool save = YAMLgetConf<bool>(conf, "save", false);
if(!show) std::cout <<"Net settings - net: "<< net
SAVE_RESULT = true; <<", 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::Yolo3Detection yolo;
tk::dnn::CenternetDetection cnet; tk::dnn::CenternetDetection cnet;
tk::dnn::MobilenetDetection mbnet; tk::dnn::MobilenetDetection mbnet;
@@ -79,8 +88,7 @@ int main(int argc, char *argv[]) {
detNN->init(net, n_classes, n_batch, conf_thresh); detNN->init(net, n_classes, n_batch, conf_thresh);
gRun = true; // open video stream
cv::VideoCapture cap(input); cv::VideoCapture cap(input);
if(!cap.isOpened()) if(!cap.isOpened())
gRun = false; gRun = false;
@@ -88,19 +96,21 @@ int main(int argc, char *argv[]) {
std::cout<<"camera started\n"; std::cout<<"camera started\n";
cv::VideoWriter resultVideo; cv::VideoWriter resultVideo;
if(SAVE_RESULT) { if(save) {
int w = cap.get(cv::CAP_PROP_FRAME_WIDTH); int w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT); 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)); resultVideo.open("result.mp4", cv::VideoWriter::fourcc('M','P','4','V'), 30, cv::Size(w, h));
} }
cv::Mat frame;
if(show) if(show)
cv::namedWindow("detection", cv::WINDOW_NORMAL); cv::namedWindow("detection", cv::WINDOW_NORMAL);
cv::Mat frame;
std::vector<cv::Mat> batch_frame; std::vector<cv::Mat> batch_frame;
std::vector<cv::Mat> batch_dnn_input; std::vector<cv::Mat> batch_dnn_input;
// start detection loop
gRun = true;
while(gRun) { while(gRun) {
batch_dnn_input.clear(); batch_dnn_input.clear();
batch_frame.clear(); batch_frame.clear();
@@ -128,20 +138,19 @@ int main(int argc, char *argv[]) {
cv::waitKey(1); cv::waitKey(1);
} }
} }
if(n_batch == 1 && SAVE_RESULT) if(n_batch == 1 && save)
resultVideo << frame; resultVideo << frame;
} }
std::cout<<"detection end\n"; std::cout<<"detection end\n";
double mean = 0;
double mean = 0;
std::cout<<COL_GREENB<<"\n\nTime stats:\n"; std::cout<<COL_GREENB<<"\n\nTime stats:\n";
std::cout<<"Min: "<<*std::min_element(detNN->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"; std::cout<<"Max: "<<*std::max_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n";
for(int i=0; i<detNN->stats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size(); for(int i=0; i<detNN->stats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size();
std::cout<<"Avg: "<<mean/n_batch<<" ms\t"<<1000/(mean/n_batch)<<" FPS\n"<<COL_END; std::cout<<"Avg: "<<mean/n_batch<<" ms\t"<<1000/(mean/n_batch)<<" FPS\n"<<COL_END;
return 0; return 0;
} }
+14
View File
@@ -0,0 +1,14 @@
# video input
input : "../demo/yolo_test.mp4"
win_input : "..\\..\\..\\demo\\yolo_test.mp4"
# network config
net : "yolo4tiny_fp32.rt"
ntype : 'y'
n_classes : 80
n_batch : 1
conf_thresh : 0.3
# demo config
show : true
save : true
+16 -15
View File
@@ -32,21 +32,20 @@ make
Once you have successfully created your rt file, run the demo: Once you have successfully created your rt file, run the demo:
``` ```
./demo yolo4_fp32.rt ../demo/yolo_test.mp4 y ./demo <path-to-config>
``` ```
In general the demo program takes 7 parameters: In general the demo program takes 1 parameter, the ```<path-to-config>``` that is the path to che configuration file. The parameter is optional and its default value is ```"../demo/demoConfig.yaml"```.
```
./demo <network-rt-file> <path-to-video> <kind-of-network> <number-of-classes> <n-batches> <show-flag> <conf-thresh>
```
where
* ```<network-rt-file>``` is the rt file generated by a test The config file is a yaml file with the following attributes:
* ```<<path-to-video>``` is the path to a video file or a camera input * ```net``` is the rt file generated by a test
* ```<kind-of-network>``` is the type of network. Thee types are currently supported: ```y``` (YOLO family), ```c``` (CenterNet family) and ```m``` (MobileNet-SSD family) * ```input``` is the path to a video file or a camera input (on Linux)
* ```<number-of-classes>```is the number of classes the network is trained on * ```win_input``` is the path to a video file or a camera input (on Windows)
* ```<n-batches>``` 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). * ```ntype``` is the type of network. Thee types are currently supported: ```y``` (YOLO family), ```c``` (CenterNet family) and ```m``` (MobileNet-SSD family)
* ```<show-flag>``` if set to 0 the demo will not show the visualization but save the video into result.mp4 (if n-batches ==1) * ```n_classes``` is the number of classes the network is trained on
* ```<conf-thresh>``` confidence threshold for the detector. Only bounding boxes with threshold greater than conf-thresh will be displayed. * ```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 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 export TKDNN_MODE=FP16 # set the half floating point optimization
rm yolo3_fp16.rt # be sure to delete(or move) old tensorRT files rm yolo3_fp16.rt # be sure to delete(or move) old tensorRT files
./test_yolo3 # run the yolo test (is slow) ./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). 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 export TKDNN_CALIB_IMG_PATH=../demo/COCO_val2017/all_images.txt
rm yolo3_int8.rt # be sure to delete(or move) old tensorRT files rm yolo3_int8.rt # be sure to delete(or move) old tensorRT files
./test_yolo3 # run the yolo test (is slow) ./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. N.B.
+16
View File
@@ -21,6 +21,7 @@
#include <ios> #include <ios>
#include <chrono> #include <chrono>
#include <yaml-cpp/yaml.h>
#define dnnType float #define dnnType float
@@ -137,4 +138,19 @@ static inline bool isCudaPointer(void *data) {
cudaPointerAttributes attr; cudaPointerAttributes attr;
return cudaPointerGetAttributes(&attr, data) == 0; return cudaPointerGetAttributes(&attr, data) == 0;
} }
inline YAML::Node YAMLloadConf(const std::string& conf_file) {
std::cerr<<"Loading YAML: "<<conf_file<<"\n";
return YAML::LoadFile(conf_file);
}
template<typename T>
inline T YAMLgetConf(YAML::Node conf, std::string key, T defaultVal) {
T val = defaultVal;
if(conf && conf[key]) {
val = conf[key].as<T>();
}
return val;
}
#endif //UTILS_H #endif //UTILS_H