detect demo with mAP

This commit is contained in:
Francesco Gatti
2017-08-29 16:48:18 +00:00
parent ab45c24efc
commit b2d6dcd207
4 changed files with 225 additions and 16 deletions
+3
View File
@@ -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"
+191
View File
@@ -0,0 +1,191 @@
#include<iostream>
#include "tkdnn.h"
#include <stdlib.h> /* srand, rand */
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
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<<image_path<<"\n"<<label_path<<"\n";
//LOAD IMAGE
cv::Mat img = cv::imread(image_path.c_str(), CV_LOAD_IMAGE_COLOR);
if(!img.data)
FatalError("Could not open image");
std::cout<<"Image size: ("<<img.cols<<"x"<<img.rows<<")\n";
compute_image(img, &netRT, &rI, input, output);
std::ifstream labels(label_path.c_str());
if(!labels.is_open())
FatalError("could not read labels");
qsort(rI.res_boxes, rI.res_boxes_n, sizeof(tkDNN::box), prob_sort);
for(int i=0; i<rI.res_boxes_n; i++) {
tkDNN::box bx = rI.res_boxes[i];
std::cout<<" ("<<int(bx.prob*100)<<"%) "<<bx.cl
<<": "<<bx.x<<" "<<bx.y<<" "<<bx.w<<" "<<bx.h<<"\n";
cv::rectangle(img, cv::Point(bx.x - bx.w/2, bx.y - bx.h/2),
cv::Point(bx.x + bx.w/2, bx.y + bx.h/2),
cv::Scalar( 0, 0, 255), 2);
}
std::cout<<"GROUND TRUTH\n";
tkDNN::box gt[256];
int gt_n = 0;
int cl;
float x, y, w, h;
while(labels>>cl) {
labels>>x>>y>>w>>h;
w *= img.cols; x *= img.cols;
h *= img.rows; y *= img.rows;
std::cout<<cl<<": "<<x<<" "<<y<<" "<<w<<" "<<h<<"\n";
gt[gt_n].x = x;
gt[gt_n].y = y;
gt[gt_n].w = w;
gt[gt_n].h = h;
gt[gt_n].cl = cl;
gt_n++;
cv::rectangle(img, cv::Point(x -w/2, y -h/2),
cv::Point(x +w/2, y +h/2),
cv::Scalar( 255, 0, 0), 2);
}
//AP calculation
float AP = 0;
for(int i=rI.res_boxes_n; i>=1; i--) { //for each detected evaluate sub group
int prec = 0;
for(int j=0; j<i; j++) { //for each detected in sub group
for(int z=0; z<gt_n; z++) { //control each ground truth
float iou = tkDNN::RegionInterpret::box_iou(rI.res_boxes[j], gt[z]);
if(iou > 0.6f && rI.res_boxes[j].cl == gt[z].cl) {
prec++;
break;
}
}
}
AP += float(prec)/i;
}
AP = AP/gt_n;
std::cout<<"AP: "<<AP<<"\n";
mAP += AP;
std::cout<<"#### processed: "<<processed_images
<<", mAP: "<<mAP/processed_images<<"\n";
//show results
//cv::namedWindow("result");
//cv::imshow("result", img);
//cv::waitKey(1);
}
return 0;
}
+4 -1
View File
@@ -276,6 +276,7 @@ public:
struct box {
int cl;
float x, y, w, h;
float prob;
};
struct sortable_bbox {
int index;
@@ -323,8 +324,10 @@ public:
float **probs, box *boxes, int only_objectness,
int *map, float tree_thresh, int relative);
void correct_region_boxes(box *boxes, int n, int w, int h, int netw, int neth, int relative);
void interpretData(dnnType *data_h);
void interpretData(dnnType *data_h, int imageW = 0, int imageH = 0);
void showImageResult(dnnType *input_h);
static float box_iou(box a, box b);
};
}
+27 -15
View File
@@ -219,11 +219,6 @@ float box_union(box a, box b) {
float u = a.w*a.h + b.w*b.h - i;
return u;
}
float 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);
}
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++;
}