This repository has been archived on 2026-02-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
tkDNN/demo/demo/demo.cpp
T
Davide Sapienza bb7d382d96 Handle cases captured by asserts
This commit removes asserts and handles their cases.
2019-09-27 15:37:14 +02:00

1090 lines
40 KiB
C++

#include <iostream>
#include <signal.h>
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#include <mutex>
#include <ctime>
#include <pthread.h>
#include <time.h>
#include <chrono>
#include <math.h>
#include <typeinfo>
#include "utils.h"
#include "BoxDetection.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//saliency
#include <opencv2/core/utility.hpp>
#include <opencv2/saliency.hpp>
#include <opencv2/highgui.hpp>
#include "Yolo3Detection.h"
#include "classutils.h"
#include "../masa_protocol/include/send.hpp"
#include "../masa_protocol/include/serialize.hpp"
#include "ekf.h"
#include "trackutils.h"
#include "plot.h"
#include "tracker.h"
#include <assert.h>
#define MAX_DETECT_SIZE 100
std::chrono::steady_clock::time_point local_clock_start;
std::mutex mutexgRun;
bool gRun;
std::string obj_class[10]{"person", "car", "truck", "bus", "motor", "bike", "rider", "traffic light", "traffic sign", "train"};
//mutex for some opencv operations
std::mutex mutex_cv;
struct ModFrame_t{
std::vector<Tracker> trackers;
geodetic_converter::GeodeticConverter gc;
double adfGeoTransform[6];
cv::Mat H;
cv::Mat original_frame;
tk::dnn::Yolo3Detection yolo;
cv::Mat mask;
// sem for mainthread, detectionthread and topviewthread
std::mutex sem;
};
struct Frame_t{
char *input;
cv::Mat frame;
int frame_nbr;
// sem_vc for mainthread, videocapturethread, originalthread and disparitythread
std::mutex sem_vc;
};
struct Camera_t{
int CAM_IDX;
char *input;
char *pmatrix;
char *maskfile;
char *cameraCalib;
char *maskFileOrient;
bool to_show;
tk::dnn::Yolo3Detection yolo;
double adfGeoTransform[6];
};
struct Show_t{
cv::Mat original, detection, topview, disparity;
bool update_o, update_de, update_t, update_di;
// a single mutex for each operation - the show_updates function must get all mutex
std::mutex mutex_o, mutex_de, mutex_t, mutex_di;
}updates;
void sig_handler(int signo)
{
std::cout << "request gateway stop\n";
mutexgRun.lock();
gRun = false;
mutexgRun.unlock();
}
void *readVideoCapture(void *x_void_ptr)
{
std::cout<<"readVideoCapture start...\n";
Frame_t *info_f = (Frame_t *) x_void_ptr;
mutex_cv.lock();
cv::VideoCapture cap(info_f->input, cv::CAP_FFMPEG);
mutex_cv.unlock();
cv::Mat frame_loc, frame0;
int frame_nbr_loc = 0;
// bool to_show = false;
if (!cap.isOpened())
{
mutexgRun.lock();
gRun = false;
mutexgRun.unlock();
}
else
std::cout << "camera started\n";
// cap.set(cv::CAP_PROP_BUFFERSIZE,3);
// std::cout<<"buf size: "<<cap.get(CV_CAP_PROP_BUFFERSIZE)<<std::endl;
auto start_t = std::chrono::steady_clock::now();
auto step_t = std::chrono::steady_clock::now();
auto end_t = std::chrono::steady_clock::now();
auto current_timestamp = std::chrono::steady_clock::now();
// compute fps and find camera's clock
double shift, mean_time = 0;
std::cout << "Frames per second using video.get(CV_CAP_PROP_FPS) : " << cap.get(CV_CAP_PROP_FPS) << std::endl;
std::cout<<"readVideoCapture computes frame rate...\n";
// //compute frame rate
int i=0;
int num_f = 120;
// the first 20 frames are null
while (i<21)
{
cap >> frame_loc;
i++;
}
i=0;
start_t = std::chrono::steady_clock::now();
while (i<num_f)
{
step_t = std::chrono::steady_clock::now();
cap >> frame_loc;
mean_time = mean_time + std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - step_t).count();
std::cout << " step "<<i<<" : "<<std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - step_t).count() << " ms"<<std::endl;
i++;
}
end_t = std::chrono::steady_clock::now();
std::cout << "Capturing " << num_f << " frames" << std::endl ;
std::cout << " Time taken : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - start_t).count() << " ms"<<std::endl;
/*
mean_time indicates the milliseconds from a frame and the next. (frame rate)
local_clock_sync is the camera clock.
shift is the difference from local camera clock and local process clock.
a frame is allowed if its local timestamp minus its local clock is less then a tollerance,
otherwise it will be considered old.
*/
auto local_clock_sync = std::chrono::steady_clock::now();
mean_time = mean_time/num_f;
shift = ((double)std::chrono::duration_cast<std::chrono::milliseconds>(local_clock_sync - local_clock_start).count()) / mean_time;
shift = (shift - (int)shift) * mean_time;
std::cout<<".-------------------------------\n";
std::cout<<" mean time: "<<mean_time<<std::endl;
std::cout<<" shift: "<<shift<<std::endl;
std::cout<<" TIMEDIFFERENCE: "<<std::chrono::duration_cast<std::chrono::milliseconds>(local_clock_sync - local_clock_start).count()<<std::endl;
std::cout<<"\n\n\n\n";
std::cout<<"readVideoCapture start to capture...\n";
while (gRun)
{
// mutex_cv.lock();
cap >> frame_loc;
// mutex_cv.unlock();
current_timestamp = std::chrono::steady_clock::now();
shift = std::chrono::duration_cast<std::chrono::milliseconds>(current_timestamp - local_clock_sync).count() ;
std::cout << " RELATIVE TIMESTAMP FRAME : "<<shift << " ms"<<std::endl;
shift = shift / mean_time;
shift = (shift - (int)shift) * mean_time;
shift = (shift - mean_time/2 >= 0)? -(mean_time - shift) : shift;
std::cout<<"DELAY frame_"<<frame_nbr_loc<<" : "<< shift << " ms"<<std::endl;
// TODO: here introduce a tollerance to discard old frame
// std::cout<< "CV_CAP_PROP_POS_MSEC: "<< cap.get( cv::CAP_PROP_POS_MSEC) <<std::endl;
// std::cout<< "CV_CAP_PROP_POS_FRAMES: "<< cap.get( cv::CAP_PROP_POS_FRAMES) <<std::endl; // <-- the v4l2 'sequence' field
// std::cout<< "CV_CAP_PROP_FPS: "<< cap.get( cv::CAP_PROP_FPS)<<std::endl;
// std::cout << "Format: " << cap.get(CV_CAP_PROP_FORMAT) << "\n";
// CAP_PROP_POS_MSEC Current position of the video file in milliseconds or video capture timestamp.
std::cout<<"id: "<<cap.get(cv::CAP_PROP_POS_MSEC)<<std::endl;
// CAP_PROP_FRAME_COUNT Number of frames in the video file.
std::cout<<"id: "<<cap.get(cv::CAP_PROP_FRAME_COUNT)<<std::endl;
if (!frame_loc.data)
{
usleep(1000000);
mutex_cv.lock();
cap.open(info_f->input);
printf("cap reinitialize\n");
mutex_cv.unlock();
continue;
}
end_t = std::chrono::steady_clock::now();
std::cout << " VC-TIME 1 : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - start_t).count() << " ms"<<std::endl;
start_t = end_t;
info_f->sem_vc.lock();
info_f->frame = frame_loc.clone();
info_f->frame_nbr = frame_nbr_loc;
info_f->sem_vc.unlock();
// usleep(50000);
end_t = std::chrono::steady_clock::now();
std::cout << " VC-TIME 2 : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - start_t).count() << " ms"<<std::endl;
start_t = end_t;
frame_nbr_loc ++;
}
return (void *)0;
}
/* Thread function to show the updated images
**/
void *show_updates(void *x_void_ptr)
{
cv::namedWindow("original", cv::WINDOW_NORMAL);
cv::namedWindow("detection", cv::WINDOW_NORMAL);
cv::namedWindow("topview", cv::WINDOW_NORMAL);
cv::namedWindow("disparity", cv::WINDOW_NORMAL);
cv::Mat original_loc, detection_loc, topview_loc, disparity_loc;
bool update_o_loc, update_de_loc, update_t_loc, update_di_loc;
while (gRun)
{
TIMER_START
// critical section: copy the struct in local variable
// in this way we can unlock the sem for the main thread
if(updates.mutex_o.try_lock())
{
update_o_loc = updates.update_o;
updates.update_o = false;
if(update_o_loc)
original_loc = updates.original.clone();
updates.mutex_o.unlock();
}
if(updates.mutex_de.try_lock())
{
update_de_loc = updates.update_de;
updates.update_de = false;
if(update_de_loc)
detection_loc = updates.detection.clone();
updates.mutex_de.unlock();
}
if(updates.mutex_t.try_lock())
{
update_t_loc = updates.update_t;
updates.update_t = false;
if(update_t_loc)
topview_loc = updates.topview.clone();
updates.mutex_t.unlock();
}
if(updates.mutex_di.try_lock())
{
update_di_loc = updates.update_di;
updates.update_di = false;
if(update_di_loc)
disparity_loc = updates.disparity.clone();
updates.mutex_di.unlock();
}
if(update_o_loc)
cv::imshow("original", original_loc);
if(update_de_loc)
cv::imshow("detection", detection_loc);
if(update_t_loc)
cv::imshow("topview", topview_loc);
if(update_di_loc)
cv::imshow("disparity", disparity_loc);
cv::waitKey(1);
// usleep(20000); //sleep 20 msec
std::cout<<"show_updates: ";
TIMER_STOP
}
return (void *)0;
}
void *originalFrame(void *x_void_ptr)
{
Frame_t *info_show_orig = (Frame_t *) x_void_ptr;
cv::Mat frame_loc;
int frame_nbr_loc = 0;
while (gRun)
{
TIMER_START
// critical section: copy the struct in local variable
// in this way we can unlock the sem for the main thread
info_show_orig->sem_vc.lock();
frame_loc = info_show_orig->frame.clone();
frame_nbr_loc = info_show_orig->frame_nbr;
info_show_orig->sem_vc.unlock();
if (frame_nbr_loc == 0)
{
usleep(1000000);
printf("no frame received\n");
continue;
}
updates.mutex_o.lock();
updates.original = frame_loc.clone();
updates.update_o = true;
updates.mutex_o.unlock();
usleep(10000); //sleep 10 msec
std::cout<<"originalFrame: ";
TIMER_STOP
}
return (void *)0;
}
void *detectionFrame(void *x_void_ptr)
{
ModFrame_t *info_show = (ModFrame_t *) x_void_ptr;
double lat, lon, alt;
int pix_x, pix_y;
cv::Mat original_frame_loc;
std::vector<Tracker> trackers;
geodetic_converter::GeodeticConverter gc;
double adfGeoTransform[6];
cv::Mat H;
tk::dnn::Yolo3Detection yolo;
int num_detected;
cv::Mat mask;
// box variable
tk::dnn::box b;
int x0, w, x1, y0, h, y1;
int objClass;
std::string det_class;;
// float prob;
cv::Scalar intensity;
std::vector<cv::Point2f> map_p, camera_p;
int baseline = 0;
float fontScale = 0.5;
int thickness = 2;
while (gRun)
{
TIMER_START
// critical section: copy the struct in local variable
// in this way we can unlock the sem for the main thread
info_show->sem.lock();
original_frame_loc = info_show->original_frame.clone();
// std::vector<Tracker> trackers;
trackers = info_show->trackers;
// geodetic_converter::GeodeticConverter gc;
gc = info_show->gc;
for(int i = 0; i < 6; i++ )
adfGeoTransform[i] = info_show->adfGeoTransform[i];
// cv::Mat H;
H = info_show->H.clone();
yolo = info_show->yolo;
mask = info_show->mask.clone();
info_show->sem.unlock();
if (trackers.empty())
{
usleep(1000000);
printf("no data available\n");
continue;
}
num_detected = yolo.detected.size();
for (int i = 0; i < num_detected; i++)
{
b = yolo.detected[i];
x0 = b.x;
w = b.w;
x1 = b.x + w;
y0 = b.y;
h = b.h;
y1 = b.y + h;
objClass = b.cl;
det_class = obj_class[b.cl];
// prob = b.prob;
intensity = mask.at<uchar>(cv::Point(int(x0 + b.w / 2), y1));
if (intensity[0] && objClass < 6)
{
//std::cout<<objClass<<" ("<<prob<<"): "<<x0<<" "<<y0<<" "<<x1<<" "<<y1<<"\n";
cv::rectangle(original_frame_loc, cv::Point(x0, y0), cv::Point(x1, y1), yolo.colors[objClass], 2);
// draw label
cv::Size textSize = getTextSize(det_class, cv::FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
cv::rectangle(original_frame_loc, cv::Point(x0, y0), cv::Point((x0 + textSize.width - 2), (y0 - textSize.height - 2)), yolo.colors[b.cl], -1);
cv::putText(original_frame_loc, det_class, cv::Point(x0, (y0 - (baseline / 2))), cv::FONT_HERSHEY_SIMPLEX, fontScale, cv::Scalar(255, 255, 255), thickness);
}
}
for (auto t : trackers)
{
for (size_t p = 1; p < t.pred_list_.size(); p++)
{
gc.enu2Geodetic(t.pred_list_[p].x_, t.pred_list_[p].y_, 0, &lat, &lon, &alt);
coord2pixel(lat, lon, pix_x, pix_y, adfGeoTransform);
map_p.clear();
camera_p.clear();
map_p.push_back(cv::Point2f(pix_x, pix_y));
//transform camera pixel to map pixel
cv::perspectiveTransform(map_p, camera_p, H.inv());
// std::cout<<"x,y: "<<pix_x<<", "<<pix_y<<std::endl;
// std::cout<<"map_p: "<<map_p<<std::endl;
// std::cout<<"camera_p: "<<camera_p<<std::endl;
// std::cout<<"size original_frame_loc: "<<original_frame_loc.cols<<", "<<original_frame_loc.rows<<std::endl;
// assert (camera_p[0].x < original_frame_loc.cols);
// assert (camera_p[0].y < original_frame_loc.rows);
if (camera_p[0].x < original_frame_loc.cols && camera_p[0].y < original_frame_loc.rows && camera_p[0].x >= 0 && camera_p[0].y >= 0)
cv::circle(original_frame_loc, cv::Point(camera_p[0].x, camera_p[0].y), 3.0, cv::Scalar(t.r_, t.g_, t.b_), CV_FILLED, 8, 0);
}
}
updates.mutex_de.lock();
updates.detection = original_frame_loc.clone();
updates.update_de = true;
updates.mutex_de.unlock();
std::cout<<"detectionFrame: ";
TIMER_STOP
}
return (void *)0;
}
void *topviewFrame(void *x_void_ptr)
{
ModFrame_t *info_show = (ModFrame_t *) x_void_ptr;
double lat, lon, alt;
int pix_x, pix_y;
cv::Mat frame_top;
cv::Mat original_frame_top;
// original_frame_top = cv::imread("../demo/demo/data/map/map_geo.jpg");
original_frame_top = cv::imread("../demo/demo/data/map/MASA_4670.png");
// original_frame_top = cv::imread("../demo/demo/data/map/MASA_4670_V.png");
std::vector<Tracker> trackers;
geodetic_converter::GeodeticConverter gc;
double adfGeoTransform[6];
cv::Mat H;
while (gRun)
{
TIMER_START
// critical section: copy the struct in local variable
// in this way we can unlock the sem for the main thread
info_show->sem.lock();
// std::vector<Tracker> trackers;
trackers = info_show->trackers;
// geodetic_converter::GeodeticConverter gc;
gc = info_show->gc;
for(int i = 0; i < 6; i++ )
adfGeoTransform[i] = info_show->adfGeoTransform[i];
// cv::Mat H;
H = info_show->H.clone();
info_show->sem.unlock();
if (trackers.empty())
{
usleep(1000000);
printf("no data available\n");
continue;
}
frame_top = original_frame_top.clone();
for (auto t : trackers)
{
for (size_t p = 1; p < t.pred_list_.size(); p++)
{
gc.enu2Geodetic(t.pred_list_[p].x_, t.pred_list_[p].y_, 0, &lat, &lon, &alt);
coord2pixel(lat, lon, pix_x, pix_y, adfGeoTransform);
if (pix_x < frame_top.cols && pix_y < frame_top.rows && pix_x >= 0 && pix_y >= 0)
cv::circle(frame_top, cv::Point(pix_x, pix_y), 7.0, cv::Scalar(t.r_, t.g_, t.b_), CV_FILLED, 8, 0);
}
}
//outputVideo<< frame_top;
// ------------------------------------------------
updates.mutex_t.lock();
updates.topview = frame_top.clone();
updates.update_t = true;
updates.mutex_t.unlock();
std::cout<<"topviewFrame: ";
TIMER_STOP
}
return (void *)0;
}
void *disparityFrame(void *x_void_ptr)
{
Frame_t *info_show_disparity = (Frame_t *) x_void_ptr;
bool first_iteration = true;
cv::Mat frame_loc;
int frame_nbr_loc = 0, pre_frame_nbr_loc = 0;
auto start_t = std::chrono::steady_clock::now();
auto step_t = std::chrono::steady_clock::now();
auto end_t = std::chrono::steady_clock::now();
// information for the disparity map
cv::Mat canny, pre_canny, canny_RGB, pre_canny_RGB;
cv::Mat canny_img;
cv::Mat disparity_frame;
while (gRun)
{
start_t = std::chrono::steady_clock::now();
step_t = start_t;
// critical section: copy the struct in local variable
// in this way we can unlock the sem for the main thread
info_show_disparity->sem_vc.lock();
frame_loc = info_show_disparity->frame.clone();
frame_nbr_loc = info_show_disparity->frame_nbr;
info_show_disparity->sem_vc.unlock();
if (frame_nbr_loc == 0)
{
usleep(1000000);
printf("no frame received\n");
continue;
}
// compute frame disparity only in there is a new frame
if(frame_nbr_loc - pre_frame_nbr_loc > 0)
{
pre_frame_nbr_loc = frame_nbr_loc;
//preprocessing frame
step_t = std::chrono::steady_clock::now();
// src_gray
canny_img = img_laplacian(frame_loc,0);
cv::Canny(canny_img, canny, 100, 100*2 );
// sprintf(buf_frame_crop_name,"../demo/demo/data/img_disparity/%d_%d_canny.jpg",frame_nbr_loc, 999);
// cv::imwrite(buf_frame_crop_name, canny);
end_t = std::chrono::steady_clock::now();
std::cout << " TIME END pre canny : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms"<<std::endl;
step_t = end_t;
// std::cout<<"o: "<<frame_loc.cols<<" - "<<frame_loc.rows<<std::endl;
// std::cout<<"canny: "<<canny.cols<<" - "<<canny.rows<<std::endl;
// std::cout<<"pre: "<<pre_canny.cols<<" - "<<pre_canny.rows<<std::endl;
if(!first_iteration)
{
// backtorgb = cv::cvtColor(pre_canny,cv::COLOR_GRAY2RGB)
cv::cvtColor(pre_canny, pre_canny_RGB, CV_GRAY2RGB);
cv::cvtColor(canny, canny_RGB, CV_GRAY2RGB);
disparity_frame = frame_disparity(pre_canny_RGB, canny_RGB, frame_nbr_loc, 999, 0);
// std::cout<<"size: "<<disparity_frame.rows<<" - "<<disparity_frame.cols<<std::endl;
// if (disparity_frame.rows == 0 || disparity_frame.cols == 0)
// return -1;
// if (disparity_frame.empty())
// { // only fools don't check...
// std::cout << "image not loaded !" << std::endl;
// return -1;
// }
end_t = std::chrono::steady_clock::now();
std::cout << " TIME canny : frame_disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms"<<std::endl;
step_t = end_t;
// //--------------------------------
// //frame box disparity on the original image
// step_t_segmentation = std::chrono::steady_clock::now();
// frame_box_disparity(pre_frame, frame, pre_rois, frame_nbr_loc);
// // reset pre_rois for the new roi of the current frame
// // pre_rois.erase(pre_rois.begin(), pre_rois.end());
// end_t_segmentation = std::chrono::steady_clock::now();
// std::cout << " TIME Frame disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// step_t_segmentation = end_t_segmentation;
// //frame box disparity on the preprocessed image
// cv::cvtColor(pre_canny, pre_canny_RGB, CV_GRAY2RGB);
// cv::cvtColor(canny, canny_RGB, CV_GRAY2RGB);
// frame_box_disparity(pre_canny_RGB, canny_RGB, pre_rois, frame_nbr_loc);
// // reset pre_rois for the new roi of the current frame
// pre_rois.erase(pre_rois.begin(), pre_rois.end());
// end_t_segmentation = std::chrono::steady_clock::now();
// std::cout << " TIME Canny Frame disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// step_t_segmentation = end_t_segmentation;
// //---------------------------------
updates.mutex_di.lock();
updates.disparity = disparity_frame.clone();
updates.update_di = true;
updates.mutex_di.unlock();
}
pre_canny = canny.clone();
if(first_iteration)
first_iteration = false;
end_t = std::chrono::steady_clock::now();
std::cout<<"disparityFrame : TIME END pre canny : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - start_t).count() << " ms"<<std::endl;
}
}
return (void *)0;
}
void *computationTask(void *x_void_ptr)
{
Camera_t *camera = (Camera_t *) x_void_ptr;
pthread_t visual, originalshow, detectionshow, topviewshow, disparityshow;
pthread_t videocap;
//create video capture thread
Frame_t info_f;
info_f.input = camera->input;
if (pthread_create(&videocap, NULL, readVideoCapture, (void*)&info_f))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
bool to_show = camera->to_show;
double adfGeoTransform[6];
for(int i=0; i<6; i++)
adfGeoTransform[i] = camera->adfGeoTransform[i];
ModFrame_t info_show;
if (to_show)
{
// initialize updates struct
updates.update_o = false;
updates.update_de = false;
updates.update_t = false;
updates.update_di = false;
if (pthread_create(&visual, NULL, show_updates, (void*)NULL))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
if (pthread_create(&originalshow, NULL, originalFrame, (void*)&info_f))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
if (pthread_create(&disparityshow, NULL, disparityFrame, (void*)&info_f))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
info_show.H = cv::Mat(cv::Size(3, 3), CV_64FC1);
if (pthread_create(&detectionshow, NULL, detectionFrame, (void*)&info_show))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
if (pthread_create(&topviewshow, NULL, topviewFrame, (void*)&info_show))
{
fprintf(stderr, "Error creating thread\n");
return (void *)1;
};
}
char* pmatrix = camera->pmatrix;
/*projection matrix from camera to map*/
cv::Mat H(cv::Size(3, 3), CV_64FC1);
read_projection_matrix(H, pmatrix);
assert (cv::countNonZero(H) > 0);
// std::cout<<H<<std::endl;
// return (void*)0;
/*Camera calibration*/
cv::Mat cameraMat, distCoeff;
readCameraCalibrationYaml(camera->cameraCalib, cameraMat, distCoeff);
std::cout << cameraMat << std::endl;
std::cout << distCoeff << std::endl;
/*GPS information*/
std::vector<ObjCoords> coords;
/*socket*/
Communicator Comm(SOCK_DGRAM);
Comm.open_client_socket((char *)"127.0.0.1", 8888);
Message *m = new Message;
m->cam_idx = camera->CAM_IDX;
m->lights.clear();
/*Conversion for tracker, from gps to meters and viceversa*/
// mutex_cv.lock();
geodetic_converter::GeodeticConverter gc;
gc.initialiseReference(44.655540, 10.934315, 0);
// mutex_cv.unlock();
double east, north, up;
// double lat, lon, alt;
/*Mask info*/
cv::Mat mask = cv::imread(camera->maskfile, cv::IMREAD_GRAYSCALE);
cv::Mat maskOrient = cv::imread(camera->maskFileOrient);
// cv::Mat maskOrient = cv::imread(camera->maskFileOrient, 0);
/*for(int i=0; i< mask.cols; i++)
{
for(int j=0; j< mask.rows; j++)
{
std::cout<<maskOrient.at<cv::Vec3b>(i,j) <<std::endl;
}
}
return 0;*/
/*tracker infos*/
std::vector<Tracker> trackers;
std::vector<Data> cur_frame;
int initial_age = -5;
int age_threshold = -8;
int n_states = 5;
float dt = 0.03;
int frame_nbr = 0;
//save video
/*cv::VideoWriter outputVideo;
cv::Size S = cv::Size((int)cap.get(cv::CAP_PROP_FRAME_WIDTH), //Acquire input size
(int)cap.get(cv::CAP_PROP_FRAME_HEIGHT));
outputVideo.open("test.avi", static_cast<int>(cap.get(cv::CAP_PROP_FOURCC)), cap.get(cv::CAP_PROP_FPS), S, true);*/
cv::Mat map1, map2;
auto start_t = std::chrono::steady_clock::now();
auto step_t = std::chrono::steady_clock::now();
auto end_t = std::chrono::steady_clock::now();
// auto step_t_segmentation = std::chrono::steady_clock::now();
// auto end_t_segmentation = std::chrono::steady_clock::now();
//TODO: move in a thread
// // information for the disparity map
// std::vector <cv::Rect> pre_rois;
// cv::Mat pre_frame;
cv::Mat orig_frame;
// cv::Mat canny, pre_canny, canny_RGB, pre_canny_RGB;
// cv::Mat canny_img;
// box variable
tk::dnn::box b;
int x0, h, y1; //w, x1, y0;
int objClass;
std::string det_class;;
// float prob;
cv::Scalar intensity;
cv::Mat frame;
cv::Mat frame_crop;
cv::Mat dnn_input;
bool first_iteration = true;
while (gRun)
{
TIMER_START
start_t = std::chrono::steady_clock::now();
step_t = start_t;
info_f.sem_vc.lock();
frame = info_f.frame.clone();
if(info_f.frame_nbr - frame_nbr > 1)
std::cout<<"more than one - f_n (diff "<<info_f.frame_nbr - frame_nbr<<")\n";
frame_nbr = info_f.frame_nbr;
info_f.sem_vc.unlock();
std::cout<<"f_n: "<<frame_nbr<<std::endl;
// if (!frame.data)
if (frame_nbr == 0)
{
usleep(1000000);
printf("no frame received\n");
continue;
}
orig_frame = frame.clone();
// mutex_cv.lock();
if (first_iteration)
cv::initUndistortRectifyMap(cameraMat, distCoeff, cv::Mat(), cameraMat, frame.size(), CV_16SC2, map1, map2);
cv::Mat temp = frame.clone();
cv::remap(temp, frame, map1, map2, 1);
//undistort(temp, frame, cameraMat, distCoeff);
// mutex_cv.unlock();
// this will be resized to the net format
dnn_input = frame.clone();
// TODO: async infer
camera->yolo.update(dnn_input);
int num_detected = camera->yolo.detected.size();
if (num_detected > MAX_DETECT_SIZE)
num_detected = MAX_DETECT_SIZE;
coords.clear();
end_t = std::chrono::steady_clock::now();
std::cout << " TIME 1 : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms"<<std::endl;
step_t = end_t;
// draw dets
std::cout<<"camera: "<<camera->CAM_IDX <<" - num detected: "<<num_detected<<std::endl;
//TODO: move in a thread
// //preprocessing frame
// step_t_segmentation = std::chrono::steady_clock::now();
// // src_gray
// canny_img = img_laplacian(orig_frame,0);
// cv::Canny(canny_img, canny, 100, 100*2 );
// // sprintf(buf_frame_crop_name,"../demo/demo/data/img_disparity/%d_%d_canny.jpg",frame_nbr, 999);
// // cv::imwrite(buf_frame_crop_name, canny);
// end_t_segmentation = std::chrono::steady_clock::now();
// std::cout << " - TIME END pre canny : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// step_t_segmentation = end_t_segmentation;
// // std::cout<<"o: "<<orig_frame.cols<<" - "<<orig_frame.rows<<std::endl;
// // std::cout<<"canny: "<<canny.cols<<" - "<<canny.rows<<std::endl;
// // std::cout<<"pre: "<<pre_canny.cols<<" - "<<pre_canny.rows<<std::endl;
// if(!first_iteration)
// {
// // backtorgb = cv::cvtColor(pre_canny,cv::COLOR_GRAY2RGB)
// cv::cvtColor(pre_canny, pre_canny_RGB, CV_GRAY2RGB);
// cv::cvtColor(canny, canny_RGB, CV_GRAY2RGB);
// disparity_frame = frame_disparity(pre_canny_RGB, canny_RGB, frame_nbr, 999, 0);
// std::cout<<"size: "<<disparity_frame.rows<<" - "<<disparity_frame.cols<<std::endl;
// if (disparity_frame.rows == 0 || disparity_frame.cols == 0)
// return -1;
// if (disparity_frame.empty())
// { // only fools don't check...
// std::cout << "image not loaded !" << std::endl;
// return -1;
// }
// end_t_segmentation = std::chrono::steady_clock::now();
// std::cout << " TIME canny : frame_disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// step_t_segmentation = end_t_segmentation;
// // //--------------------------------
// // //frame box disparity on the original image
// // step_t_segmentation = std::chrono::steady_clock::now();
// // frame_box_disparity(pre_frame, frame, pre_rois, frame_nbr);
// // // reset pre_rois for the new roi of the current frame
// // // pre_rois.erase(pre_rois.begin(), pre_rois.end());
// // end_t_segmentation = std::chrono::steady_clock::now();
// // std::cout << " TIME Frame disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// // step_t_segmentation = end_t_segmentation;
// // //frame box disparity on the preprocessed image
// // cv::cvtColor(pre_canny, pre_canny_RGB, CV_GRAY2RGB);
// // cv::cvtColor(canny, canny_RGB, CV_GRAY2RGB);
// // frame_box_disparity(pre_canny_RGB, canny_RGB, pre_rois, frame_nbr);
// // // reset pre_rois for the new roi of the current frame
// // pre_rois.erase(pre_rois.begin(), pre_rois.end());
// // end_t_segmentation = std::chrono::steady_clock::now();
// // std::cout << " TIME Canny Frame disparity : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t_segmentation - step_t_segmentation).count() << " ms"<<std::endl;
// // step_t_segmentation = end_t_segmentation;
// // //---------------------------------
// }
// compute some metrics on the whole frame
// segmentation(pre_frame, frame, frame_nbr, 0, 0);
for (int i = 0; i < num_detected; i++)
{
b = camera->yolo.detected[i];
x0 = b.x;
// w = b.w;
// x1 = b.x + w;
// y0 = b.y;
h = b.h;
y1 = b.y + h;
objClass = b.cl;
det_class = obj_class[b.cl];
// prob = b.prob;
intensity = mask.at<uchar>(cv::Point(int(x0 + b.w / 2), y1));
if (intensity[0])
{
if (objClass < 6)
{
// find the rectangular on the frame (sub-figure)
// roi.x = (x0 > 0)? x0 : 0;
// roi.y = (y0 > 0)? y0 : 0;
// // std::cout<<"x "<<roi.x<<" - y "<<roi.y<<std::endl;
// roi.width = (roi.x+w >= frame.cols)? frame.cols-1-roi.x : w;
// roi.height = (roi.y+h >= frame.rows)? frame.rows-1-roi.y : h;
// std::cout<<"w "<<roi.width<<" - h "<<roi.height<<std::endl;
// std::cout<<"wf "<<frame.cols<<" - hf "<<frame.rows<<std::endl;
// std::cout<<"---"<<std::endl;
// std::cout<<"x "<<roi.x<<" to "<<roi.width+roi.x<<" wf "<<frame.cols<<std::endl;
// std::cout<<"y "<<roi.y<<" to "<<roi.height+roi.y<<" hf "<<frame.rows<<std::endl;
//update pre_roi for the next frame
// pre_rois.push_back(roi);
// segmentation(frame(roi), frame(roi), frame_nbr, i, 1);
/////
convert_coords(coords, x0 + b.w / 2, y1, objClass, H, adfGeoTransform, frame_nbr);
// //std::cout<<objClass<<" ("<<prob<<"): "<<x0<<" "<<y0<<" "<<x1<<" "<<y1<<"\n";
// cv::rectangle(frame, cv::Point(x0, y0), cv::Point(x1, y1), camera->yolo.colors[objClass], 2);
// // draw label
// int baseline = 0;
// float fontScale = 0.5;
// int thickness = 2;
// cv::Size textSize = getTextSize(det_class, cv::FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
// cv::rectangle(frame, cv::Point(x0, y0), cv::Point((x0 + textSize.width - 2), (y0 - textSize.height - 2)), camera->yolo.colors[b.cl], -1);
// cv::putText(frame, det_class, cv::Point(x0, (y0 - (baseline / 2))), cv::FONT_HERSHEY_SIMPLEX, fontScale, cv::Scalar(255, 255, 255), thickness);
}
}
}
end_t = std::chrono::steady_clock::now();
std::cout << " TIME 2 : "<<std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms"<<std::endl;
step_t = end_t;
//convert from latitude and longitude to meters for ekf
cur_frame.clear();
for (size_t i = 0; i < coords.size(); i++)
{
gc.geodetic2Enu(coords[i].lat_, coords[i].long_, 0, &east, &north, &up);
cur_frame.push_back(Data(east, north, frame_nbr, coords[i].class_));
}
if (first_iteration)
{
// if there aren't detections and it is the first iteration, we can't initialize the tracker, so continue
if(cur_frame.empty())
continue;
for (auto f : cur_frame)
trackers.push_back(Tracker(f, initial_age, dt, n_states));
}
else
{
Track(cur_frame, dt, n_states, initial_age, age_threshold, trackers);
}
std::cout << "There are " << trackers.size() << " trackers" << std::endl;
//prepare message with tracker info
if(trackers.size()==0)
{
// mutex_cv.lock();
addRoadUserfromTracker(trackers, m, gc, maskOrient, adfGeoTransform, H);
// mutex_cv.unlock();
//prepare the message with detection info
//prepare_message(m, coords, CAM_IDX);
//send message
if (!m->objects.empty())
Comm.send_message(m);
}
if (to_show)
{
//populate the ModFrame_t
info_show.sem.lock();
info_show.original_frame = frame.clone();
// std::vector<Tracker> trackers;
info_show.trackers = trackers;
// geodetic_converter::GeodeticConverter gc;
info_show.gc = gc;
for(int i = 0; i < 6; i++ )
info_show.adfGeoTransform[i] = adfGeoTransform[i];
// cv::Mat H;
info_show.H = H.clone();
info_show.yolo = camera->yolo;
// std::copy(camera->yolo.begin(), camera->yolo.end(), info_show.yolo.begin());
info_show.mask = mask.clone();
info_show.sem.unlock();
}
// update pre_frame for the disparity map
// pre_frame = orig_frame.clone();
// pre_canny = canny.clone();
if(first_iteration)
first_iteration = false;
frame_nbr++;
std::cout<<camera->CAM_IDX<<" camera thread: ";
TIMER_STOP
}
return (void *)0;
}
int main(int argc, char *argv[])
{
std::cout << "detection\n";
signal(SIGINT, sig_handler);
srand(time(NULL));
bool no_params = false; //flag to indicate if there are camera parameters or we use mp4 test video
char *net = (char *)"yolo3_coco4.rt";
if (argc > 1)
net = argv[1];
char *tiffile = (char *)"../demo/demo/data/map_b.tif";
if (argc > 2)
tiffile = argv[2];
char *n;
if (argc > 3)
{
n = argv[3];
if(strcmp(n, "-n"))
return -1;
};
int n_cameras = 0;
if (argc > 4)
{
n_cameras = atoi(argv[4]);
if(argc < 5+ 7 * n_cameras)
{
std::cout<<"too few parameters\n";
return -1;
}
if(!n_cameras)
{
n_cameras = 1;
no_params = true;
}
}
Camera_t cameras[n_cameras];
bool *to_show = (bool *) malloc(n_cameras * sizeof(bool));
if(no_params)
{
cameras[0].CAM_IDX = 20936;
cameras[0].input = (char *)"../demo/demo/data/single_ped_2.mp4";
cameras[0].pmatrix = (char *)"../demo/demo/data/pmundist.txt";
cameras[0].maskfile = (char *)"../demo/demo/data/mask36.jpg";
cameras[0].cameraCalib = (char *)"../demo/demo/data/calib36.params";
cameras[0].maskFileOrient = (char *)"../demo/demo/data/mask_orient/6315_mask_orient.jpg";
cameras[0].to_show = true;
to_show[0] = true;
}
else
{
for(int i = 0; i<n_cameras; i++)
cameras[i].CAM_IDX = atoi(argv[5+i]);
for(int i = 0; i<n_cameras; i++)
cameras[i].input = argv[5+n_cameras+i];
for(int i = 0; i<n_cameras; i++)
cameras[i].pmatrix = argv[5+2*n_cameras+i];
for(int i = 0; i<n_cameras; i++)
cameras[i].maskfile = argv[5+3*n_cameras+i];
for(int i = 0; i<n_cameras; i++)
cameras[i].cameraCalib = argv[5+4*n_cameras+i];
for(int i = 0; i<n_cameras; i++)
cameras[i].maskFileOrient = argv[5+5*n_cameras+i];
for(int i = 0; i<n_cameras; i++)
{
cameras[i].to_show = atoi(argv[5+6*n_cameras+i]); //only one camera can be shown
to_show[i] = atoi(argv[5+6*n_cameras+i]);
}
}
//TODO now only one camera can be visualized
int check_visualization=0;
for(int i = 0; i<n_cameras; i++)
check_visualization += to_show[i];
if(check_visualization > 1)
return -1;
tk::dnn::Yolo3Detection yolo[n_cameras];
for(int i=0; i<n_cameras; i++)
{
yolo[i].init(net);
yolo[i].thresh = 0.25;
}
// tk::dnn::Yolo3Detection yolo;
// yolo.init(net);
// yolo.thresh = 0.25;
gRun = true;
// start the local clock. It is used to check the incoming frames (by different cameras)
local_clock_start = std::chrono::steady_clock::now();
/*GPS information*/
double *adfGeoTransform = (double *)malloc(6 * sizeof(double));
readTiff(tiffile, adfGeoTransform);
for(int i=0; i<n_cameras; i++)
{
for(int j = 0; j < 6; j++ )
cameras[i].adfGeoTransform[j] = adfGeoTransform[j];
cameras[i].yolo = yolo[i];
// cameras[i].yolo = yolo;
}
std::cout<<"INIZIA:\n";
pthread_t camera_task[n_cameras];
for(int i=0; i<n_cameras; i++)
{
std::cout<<"creating thread\n";
if(pthread_create(&camera_task[i], NULL, computationTask, (void*)&cameras[i]))
{
fprintf(stderr, "error creating thread\n");
return 1;
}
std::cout<<"WHAT2\n";
}
for(int i=0; i<n_cameras; i++)
{
pthread_join(camera_task[i], NULL);
}
std::cout <<" free adfGeoT \n";
free(adfGeoTransform);
std::cout << "detection end\n";
return 0;
}