yolo3 berkeley ok

This commit is contained in:
Francesco Gatti
2019-02-18 15:37:39 +00:00
parent 2c63bf05be
commit 0d682136de
10 changed files with 278 additions and 459 deletions
+75
View File
@@ -0,0 +1,75 @@
#include <iostream>
#include <signal.h>
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#include <mutex>
#include "utils.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "Yolo3Detection.h"
bool gRun;
void sig_handler(int signo) {
std::cout<<"request gateway stop\n";
gRun = false;
}
int main(int argc, char *argv[]) {
std::cout<<"detection\n";
signal(SIGINT, sig_handler);
Yolo3Detection yolo;
yolo.init("./");
gRun = true;
char *input = "../demo/yolo_test.mp4";
if(argc > 1)
input = argv[1];
cv::VideoCapture cap(input);
if(!cap.isOpened())
gRun = false;
else
std::cout<<"camera started\n";
cv::Mat frame;
cv::namedWindow("detection", cv::WINDOW_NORMAL);
cv::resizeWindow("detection", 544*1.2, 320*1.2);
while(gRun) {
cap >> frame;
if(!frame.data) {
continue;
}
yolo.update(frame);
// draw dets
for(int i=0; i<yolo.detected.size(); i++) {
tk::dnn::box b = yolo.detected[i];
int x0 = b.x;
int x1 = b.x + b.w;
int y0 = b.y;
int y1 = b.y + b.h;
int obj_class = b.cl;
float prob = b.prob;
std::cout<<obj_class<<" ("<<prob<<"): "<<x0<<" "<<y0<<" "<<x1<<" "<<y1<<"\n";
cv::rectangle(frame, cv::Point(x0, y0), cv::Point(x1, y1), yolo.colors[obj_class], 2);
}
cv::imshow("detection", frame);
cv::waitKey(1);
}
std::cout<<"detection end\n";
return 0;
}
-249
View File
@@ -1,249 +0,0 @@
#include<iostream>
#include "tkdnn.h"
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#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) {
tk::dnn::box a = *(tk::dnn::box *)pa;
tk::dnn::box b = *(tk::dnn::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;
}
//return inference time
double compute_image( cv::Mat imageORIG,
tk::dnn::NetworkRT *netRT, tk::dnn::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);
return t_ns;
}
int print_usage() {
std::cout<<"usage: ./detection net.rt validation_list.txt"
<<" [-t <thresh>] [-s] [-i <iterations>]\n"
<<" -t: set thresh value\n -s: show images as compute\n"
<<" -i: images to compute\n\n"
<<"> validation_list.txt format: \n"
<<" path/to/image.jpg path/to/label.txt\n"
<<"> label.txt format: \n"
<<" <object-class> <x> <y> <width> <height>\n"
<<" x and y are the box center, "
<<"all values are relative to the image size\n\n";
return 1;
}
int main(int argc, char *argv[]) {
//params
char *tensor_path = NULL;
char *imageset_path = NULL;
float thresh = 0.3f;
bool show = false;
int iterations = INT_MAX;
//parse params
int c;
while ((c = getopt (argc, argv, "t:si:")) != -1) {
switch(c) {
case 't': thresh = atof(optarg); break;
case 's': show = true; break;
case 'i': iterations = atoi(optarg); break;
case '?':
return print_usage();
default: return print_usage();
}
}
if(argc - optind == 2) {
tensor_path = argv[optind];
imageset_path = argv[optind+1];
} else {
std::cout<<"not enough arguments.\n";
return print_usage();
}
//end parsing
if(!fileExist(tensor_path))
FatalError("unable to read serialRT file");
//convert network to tensorRT
tk::dnn::NetworkRT netRT(NULL, tensor_path);
tk::dnn::RegionInterpret rI(netRT.input_dim, netRT.output_dim, 80, 4, 5, thresh, reg_bias);
dnnType *input = new float[netRT.input_dim.tot()];
dnnType *output = new float[netRT.output_dim.tot()];
std::string line;
std::ifstream imageset(imageset_path);
if(!imageset.is_open())
FatalError("could not read imageset");
double mTime = 0;
float mAP = 0;
int processed_images;
for(processed_images=1;
processed_images-1 < iterations && 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";
mTime += 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(tk::dnn::box), prob_sort);
for(int i=0; i<rI.res_boxes_n; i++) {
tk::dnn::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";
tk::dnn::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 = tk::dnn::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
if(show) {
cv::namedWindow("result");
cv::imshow("result", img);
cv::waitKey(10);
}
}
//print results to file
processed_images -= 1;
std::ofstream res("results.txt", std::ios::app);
res<<"#### "<<tensor_path<<"\n";
res<<"processed images: "<<processed_images<<"\n";
res<<"mean inference time: "<<mTime/processed_images<<"\n";
res<<"mean AP: "<<mAP/processed_images<<"\n";
res<<"thesh used: "<<thresh<<"\n\n";
return 0;
}
-196
View File
@@ -1,196 +0,0 @@
#include<iostream>
#include "tkdnn.h"
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#define VOC
#ifdef VOC
const char *reg_bias = "../tests/yolo_voc/layers/g31.bin";
#define CLASS 20
#else
const char *reg_bias = "../tests/yolo/layers/g31.bin";
#define CLASS 80
#endif
int prob_sort(const void *pa, const void *pb) {
tk::dnn::box a = *(tk::dnn::box *)pa;
tk::dnn::box b = *(tk::dnn::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;
}
//return inference time
double compute_image( cv::Mat imageORIG,
tk::dnn::NetworkRT *netRT, tk::dnn::RegionInterpret *rI,
dnnType *input, dnnType *output) {
TIMER_START
//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
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);
rI->interpretData(output, imageORIG.cols, imageORIG.rows);
TIMER_STOP
return t_ns;
}
int print_usage() {
std::cout<<"usage: ./live net.rt input_uri\n";
return 1;
}
int main(int argc, char *argv[]) {
//params
char *tensor_path = NULL;
char *device = 0;
float thresh = 0.3f;
bool show = false;
//parse params
int c;
while ((c = getopt (argc, argv, "t:si:")) != -1) {
switch(c) {
case 't': thresh = atof(optarg); break;
case 's': show = true; break;
case '?':
return print_usage();
default: return print_usage();
}
}
if(argc - optind == 2) {
tensor_path = argv[optind];
device = argv[optind+1];
} else {
std::cout<<"not enough arguments.\n";
return print_usage();
}
//end parsing
std::cout<<"open video stream on device: "<<device<<"\n";
cv::VideoCapture cap(device);
/*
const char* pipe = "nvcamerasrc ! video/x-raw(memory:NVMM), width=(int)640, height=(int)480, format=(string)I420, framerate=(fraction)30/1 ! nvvidconv ! video/x-raw, format=(string)I420 ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
cv::VideoCapture cap(pipe);
*/
if(!cap.isOpened())
FatalError("unable to open video stream");
//cap.set(CV_CAP_PROP_BUFFERSIZE, 1); // process only last frame
if(!fileExist(tensor_path))
FatalError("unable to read serialRT file");
//convert network to tensorRT
tk::dnn::NetworkRT netRT(NULL, tensor_path);
tk::dnn::RegionInterpret rI(netRT.input_dim, netRT.output_dim, CLASS, 4, 5, thresh, reg_bias);
dnnType *input = new float[netRT.input_dim.tot()];
dnnType *output = new float[netRT.output_dim.tot()];
double mTime = 0;
int processed_images = 0;
for(;;) {
//LOAD IMAGE
cv::Mat img; //= cv::imread("../demo/live/test.jpeg", CV_LOAD_IMAGE_COLOR);
cap >> img;
if(!img.data)
FatalError("Could not open image");
std::cout<<"Image size: ("<<img.cols<<"x"<<img.rows<<")\n";
mTime += compute_image(img, &netRT, &rI, input, output);
qsort(rI.res_boxes, rI.res_boxes_n, sizeof(tk::dnn::box), prob_sort);
for(int i=0; i<rI.res_boxes_n; i++) {
tk::dnn::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);
}
//show results
if(show) {
cv::namedWindow("result");
cv::imshow("result", img);
cv::waitKey(1);
}
processed_images++;
std::cout<<"mean time per frames: "<<mTime/processed_images/1000<<" ms\n"<<"\n";
}
return 0;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.