diff --git a/CMakeLists.txt b/CMakeLists.txt index 814494a..bdc30e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,9 @@ target_link_libraries(test_yolo_tiny tkDNN) add_executable(test_rtinference tests/test_rtinference/rtinference.cpp) target_link_libraries(test_rtinference tkDNN) +add_executable(detection demo/detection/detection.cpp) +target_link_libraries(detection tkDNN) + #install if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set (CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" diff --git a/demo/detection/detection.cpp b/demo/detection/detection.cpp new file mode 100644 index 0000000..5374846 --- /dev/null +++ b/demo/detection/detection.cpp @@ -0,0 +1,191 @@ +#include +#include "tkdnn.h" +#include /* srand, rand */ + +#include +#include +#include + +const char *reg_bias = "../tests/yolo/layers/g31.bin"; + +int prob_sort(const void *pa, const void *pb) { + tkDNN::box a = *(tkDNN::box *)pa; + tkDNN::box b = *(tkDNN::box *)pb; + float diff = a.prob - b.prob; + if(diff < 0) return 1; + else if(diff > 0) return -1; + return 0; +} + +cv::Mat GetSquareImage(const cv::Mat& img, int target_width) { + int width = img.cols, height = img.rows; + + cv::Mat square = cv::Mat::zeros( target_width, target_width, img.type() ); + + int max_dim = ( width >= height ) ? width : height; + float scale = ( ( float ) target_width ) / max_dim; + cv::Rect roi; + if ( width >= height ) + { + roi.width = target_width; + roi.x = 0; + roi.height = height * scale; + roi.y = ( target_width - roi.height ) / 2; + } + else + { + roi.y = 0; + roi.height = target_width; + roi.width = width * scale; + roi.x = ( target_width - roi.width ) / 2; + } + + cv::resize( img, square( roi ), roi.size() ); + + return square; +} + +void compute_image( cv::Mat imageORIG, + tkDNN::NetworkRT *netRT, tkDNN::RegionInterpret *rI, + dnnType *input, dnnType *output) { + + //Resize with padding and convert to float + cv::Mat image = GetSquareImage(imageORIG, netRT->input_dim.w); + cv::Mat imageF; + image.convertTo(imageF, CV_32FC3, 1/255.0); + + //split channels + cv::Mat bgr[3]; //destination array + cv::split(imageF,bgr);//split source + + //write channels + int idx = 0; + memcpy((void*)&input[idx], (void*)bgr[2].data, imageF.rows*imageF.cols*sizeof(dnnType)); + idx = imageF.rows*imageF.cols; + memcpy((void*)&input[idx], (void*)bgr[1].data, imageF.rows*imageF.cols*sizeof(dnnType)); + idx *= 2; + memcpy((void*)&input[idx], (void*)bgr[0].data, imageF.rows*imageF.cols*sizeof(dnnType)); + + //DO INFERENCE + printCenteredTitle(" TENSORRT inference ", '=', 30); + TIMER_START + checkCuda( cudaMemcpyAsync(netRT->buffersRT[netRT->buf_input_idx], input, + netRT->input_dim.tot()*sizeof(float), + cudaMemcpyHostToDevice, netRT->stream)); + netRT->enqueue(); + checkCuda( cudaMemcpyAsync(output, netRT->buffersRT[netRT->buf_output_idx], + netRT->output_dim.tot()*sizeof(float), + cudaMemcpyDeviceToHost, netRT->stream)); + cudaStreamSynchronize(netRT->stream); + TIMER_STOP + + + rI->interpretData(output, imageORIG.cols, imageORIG.rows); + +} + + +int main(int argc, char *argv[]) { + + if(argc < 2 || !fileExist(argv[1])) + FatalError("unable to read serialRT file"); + + //convert network to tensorRT + tkDNN::NetworkRT netRT(NULL, argv[1]); + tkDNN::RegionInterpret rI(netRT.input_dim, netRT.output_dim, 80, 4, 5, 0.3f, reg_bias); + + dnnType *input = new float[netRT.input_dim.tot()]; + dnnType *output = new float[netRT.output_dim.tot()]; + + std::string line; + std::ifstream imageset(argv[2]); + if(!imageset.is_open()) + FatalError("could not read imageset"); + + + float mAP = 0; + int processed_images; + for(processed_images=1; getline(imageset, line); processed_images++) { + + std::string image_path = line.substr(0, line.find(" ")); + std::string label_path = line.substr(line.find(" ")+1, line.size()); + std::cout<>cl) { + labels>>x>>y>>w>>h; + w *= img.cols; x *= img.cols; + h *= img.rows; y *= img.rows; + std::cout<=1; i--) { //for each detected evaluate sub group + + int prec = 0; + for(int j=0; j 0.6f && rI.res_boxes[j].cl == gt[z].cl) { + prec++; + break; + } + } + } + + AP += float(prec)/i; + } + AP = AP/gt_n; + std::cout<<"AP: "< (a.w+b.w)/2 || fabs(a.y - b.y) > (a.h+b.h)/2) - return 0; - return box_intersection(a, b)/box_union(a, b); -} int max_index(float *a, int n) { if(n <= 0) return -1; int i, max_i = 0; @@ -237,13 +232,24 @@ int max_index(float *a, int n) { return max_i; } //############################################################################### +float RegionInterpret::box_iou(box a, box b) { + if(fabs(a.x - b.x) > (a.w+b.w)/2 || fabs(a.y - b.y) > (a.h+b.h)/2) + return 0; + return box_intersection(a, b)/box_union(a, b); +} +void RegionInterpret::interpretData(dnnType *data_h, int imageW, int imageH) { -void RegionInterpret::interpretData(dnnType *data_h) { - - int imW = input_dim.w, imH = input_dim.h; + int imW, imH; + if(imageW <= 0 || imageH <= 0) { + imW = input_dim.w; + imH = input_dim.h; + } else { + imW = imageW; + imH = imageH; + } int tot = output_dim.w*output_dim.h*num; @@ -256,7 +262,7 @@ void RegionInterpret::interpretData(dnnType *data_h) { s[i].probs = probs; } qsort(s, tot, sizeof(sortable_bbox), nms_comparator); - TIMER_START + for(int i = 0; i < tot; ++i){ if(probs[s[i].index][classes] == 0) continue; box a = boxes[s[i].index]; @@ -269,7 +275,7 @@ void RegionInterpret::interpretData(dnnType *data_h) { } } } - TIMER_STOP + res_boxes_n = 0; //print results for(int i = 0; i < tot; ++i){ @@ -278,17 +284,23 @@ void RegionInterpret::interpretData(dnnType *data_h) { if(prob > thresh) { box b = boxes[i]; - int x = (b.x-b.w/2.)*imW; - int w = (b.x+b.w/2.)*imW - b.x; - int y = (b.y-b.h/2.)*imH; - int h = (b.y+b.h/2.)*imH - b.y; + int x = (b.x)*imW; + int w = (b.w)*imW - b.x; + int y = (b.y)*imH; + int h = (b.h)*imH - b.y; - printf("%d: %.0f%% box(x1, y1, x2, y2): %d %d %d %d\n", cl, prob*100, x, y, w, h); + //if(x < 0) x = 0; + //if(y < 0) y = 0; + //if(w > imW) w = imW; + //if(h > imH) h = imH; + + //printf("%d: %.0f%% box(x1, y1, x2, y2): %d %d %d %d\n", cl, prob*100, x, y, w, h); b.x = x; b.y = y; b.h = h; b.w = w; b.cl = cl; + b.prob = prob; res_boxes[res_boxes_n] = b; res_boxes_n++; }