#include #include #include /* srand, rand */ #include #include #include #include #include #include #include #include #include "utils.h" #include "BoxDetection.h" #include #include #include //saliency #include #include #include #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 #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 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: "<> frame_loc; i++; } i=0; start_t = std::chrono::steady_clock::now(); while (i> frame_loc; mean_time = mean_time + std::chrono::duration_cast(std::chrono::steady_clock::now() - step_t).count(); std::cout << " step "<(std::chrono::steady_clock::now() - step_t).count() << " ms"<(end_t - start_t).count() << " ms"<(local_clock_sync - local_clock_start).count()) / mean_time; shift = (shift - (int)shift) * mean_time; std::cout<<".-------------------------------\n"; std::cout<<" mean time: "<(local_clock_sync - local_clock_start).count()<> frame_loc; // mutex_cv.unlock(); current_timestamp = std::chrono::steady_clock::now(); shift = std::chrono::duration_cast(current_timestamp - local_clock_sync).count() ; std::cout << " RELATIVE TIMESTAMP FRAME : "<= 0)? -(mean_time - shift) : shift; std::cout<<"DELAY frame_"<input); printf("cap reinitialize\n"); mutex_cv.unlock(); continue; } end_t = std::chrono::steady_clock::now(); std::cout << " VC-TIME 1 : "<(end_t - start_t).count() << " ms"<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 : "<(end_t - start_t).count() << " ms"<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 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 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 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(cv::Point(int(x0 + b.w / 2), y1)); if (intensity[0] && objClass < 6) { //std::cout<= 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 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 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 : "<(end_t - step_t).count() << " ms"<(end_t - step_t).count() << " ms"<(end_t_segmentation - step_t_segmentation).count() << " ms"<(end_t_segmentation - step_t_segmentation).count() << " ms"<(end_t - start_t).count() << " ms"<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<cameraCalib, cameraMat, distCoeff); std::cout << cameraMat << std::endl; std::cout << distCoeff << std::endl; /*GPS information*/ std::vector 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<(i,j) < trackers; std::vector 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(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 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 "<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 : "<(end_t - step_t).count() << " ms"<CAM_IDX <<" - num detected: "<(end_t_segmentation - step_t_segmentation).count() << " ms"<(end_t_segmentation - step_t_segmentation).count() << " ms"<(end_t_segmentation - step_t_segmentation).count() << " ms"<(end_t_segmentation - step_t_segmentation).count() << " ms"<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(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 "<= frame.cols)? frame.cols-1-roi.x : w; // roi.height = (roi.y+h >= frame.rows)? frame.rows-1-roi.y : h; // std::cout<<"w "<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 : "<(end_t - step_t).count() << " ms"<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 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<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 1) return -1; tk::dnn::Yolo3Detection yolo[n_cameras]; for(int i=0; i