diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b54891a4..7fc8c4325 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5) -project(MultitargetTracking) +project(MTTracking) unset(CMAKE_CXX_FLAGS CACHE) @@ -18,7 +18,6 @@ elseif (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /W4 -DGTL_STATIC" CACHE STRING COMPILE_FLAGS FORCE) endif() - set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) @@ -26,6 +25,14 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) FIND_PACKAGE(OpenCV) add_subdirectory(src) -add_subdirectory(example) -add_subdirectory(cars_counting) +option(BUILD_EXAMPLES "Should compiled examples (motion detection, pedestrians, faces, DNNs etc)?" ON) +if (BUILD_EXAMPLES) + add_subdirectory(example) +endif(BUILD_EXAMPLES) + +option(BUILD_CARS_COUNTING "Should compiled Cars counting example?" OFF) +if (BUILD_CARS_COUNTING) + add_subdirectory(cars_counting) +endif(BUILD_CARS_COUNTING) + diff --git a/cars_counting/CMakeLists.txt b/cars_counting/CMakeLists.txt index 953c19c73..b3507099f 100644 --- a/cars_counting/CMakeLists.txt +++ b/cars_counting/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.5) project(CarsCounting) diff --git a/cars_counting/CarsCounting.cpp b/cars_counting/CarsCounting.cpp index 01b364b75..9f6c6fdf2 100644 --- a/cars_counting/CarsCounting.cpp +++ b/cars_counting/CarsCounting.cpp @@ -76,6 +76,8 @@ void CarsCounting::Process() m_fps = std::max(1.f, (float)capture.get(cv::CAP_PROP_FPS)); + m_fps = std::max(1.f, (float)capture.get(cv::CAP_PROP_FPS)); + cv::Mat colorFrame; cv::UMat grayFrame; for (;;) @@ -189,11 +191,19 @@ void CarsCounting::DrawTrack(cv::Mat frame, if (isStatic) { - cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, cv::LINE_AA); +#else + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, CV_AA); +#endif } else { - cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, cv::LINE_AA); +#else + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, CV_AA); +#endif } if (drawTrajectory) @@ -204,11 +214,18 @@ void CarsCounting::DrawTrack(cv::Mat frame, { const TrajectoryPoint& pt1 = track.m_trace.at(j); const TrajectoryPoint& pt2 = track.m_trace.at(j + 1); - - cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, cv::LINE_AA); +#else + cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, CV_AA); +#endif if (!pt2.m_hasRaw) { - cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, cv::LINE_AA); +#else + cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, CV_AA); +#endif } } } @@ -219,7 +236,11 @@ void CarsCounting::DrawTrack(cv::Mat frame, for (auto pt : track.m_lastRegion.m_points) { - cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, cv::LINE_AA); +#else + cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, CV_AA); +#endif } } } @@ -254,24 +275,24 @@ bool CarsCounting::InitTracker(cv::UMat frame) settings.m_distType = tracking::DistCenters; settings.m_kalmanType = tracking::KalmanLinear; settings.m_filterGoal = tracking::FilterRect; - settings.m_lostTrackType = tracking::TrackKCF; // Use KCF tracker for collisions resolving + settings.m_lostTrackType = tracking::TrackerCSRT; // Use KCF tracker for collisions resolving settings.m_matchType = tracking::MatchHungrian; settings.m_dt = 0.5f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.5f; // Accel noise magnitude for Kalman filter - settings.m_distThres = frame.rows / 15; // Distance threshold between region and object on two frames + settings.m_distThres = frame.rows / 15.f; // Distance threshold between region and object on two frames settings.m_useAbandonedDetection = false; if (settings.m_useAbandonedDetection) { settings.m_minStaticTime = minStaticTime; settings.m_maxStaticTime = 60; - settings.m_maximumAllowedSkippedFrames = settings.m_minStaticTime * m_fps; // Maximum allowed skipped frames + settings.m_maximumAllowedSkippedFrames = cvRound(settings.m_minStaticTime * m_fps); // Maximum allowed skipped frames settings.m_maxTraceLength = 2 * settings.m_maximumAllowedSkippedFrames; // Maximum trace length } else { - settings.m_maximumAllowedSkippedFrames = 2 * m_fps; // Maximum allowed skipped frames - settings.m_maxTraceLength = 4 * m_fps; // Maximum trace length + settings.m_maximumAllowedSkippedFrames = cvRound(2 * m_fps); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(4 * m_fps); // Maximum trace length } m_tracker = std::make_unique(settings); diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index a5b8829eb..8e9048ace 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.5) project(MultitargetTracker) diff --git a/example/MouseExample.h b/example/MouseExample.h index a8a2a022d..00bd421b8 100644 --- a/example/MouseExample.h +++ b/example/MouseExample.h @@ -86,7 +86,11 @@ void MouseTracking(cv::CommandLineParser parser) for (size_t i = 0; i < pts.size(); i++) { - cv::circle(frame, pts[i], 3, cv::Scalar(0, 255, 0), 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::circle(frame, pts[i], 3, cv::Scalar(0, 255, 0), 1, cv::LINE_AA); +#else + cv::circle(frame, pts[i], 3, cv::Scalar(0, 255, 0), 1, CV_AA); +#endif } tracker.Update(regions, cv::UMat(), 100); @@ -101,7 +105,11 @@ void MouseTracking(cv::CommandLineParser parser) { for (size_t j = 0; j < track->m_trace.size() - 1; j++) { - cv::line(frame, track->m_trace[j], track->m_trace[j + 1], colors[i % colors.size()], 2, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::line(frame, track->m_trace[j], track->m_trace[j + 1], colors[i % colors.size()], 2, cv::LINE_AA); +#else + cv::line(frame, track->m_trace[j], track->m_trace[j + 1], colors[i % colors.size()], 2, CV_AA); +#endif } } } diff --git a/example/VideoExample.cpp b/example/VideoExample.cpp index 63b9df320..96c93607c 100644 --- a/example/VideoExample.cpp +++ b/example/VideoExample.cpp @@ -322,11 +322,19 @@ void VideoExample::DrawTrack(cv::Mat frame, if (isStatic) { - cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, cv::LINE_AA); +#else + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(255, 0, 255), 2, CV_AA); +#endif } else { - cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, cv::LINE_AA); +#else + cv::rectangle(frame, ResizeRect(track.GetLastRect()), cv::Scalar(0, 255, 0), 1, CV_AA); +#endif } if (drawTrajectory) @@ -337,11 +345,18 @@ void VideoExample::DrawTrack(cv::Mat frame, { const TrajectoryPoint& pt1 = track.m_trace.at(j); const TrajectoryPoint& pt2 = track.m_trace.at(j + 1); - - cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, cv::LINE_AA); +#else + cv::line(frame, ResizePoint(pt1.m_prediction), ResizePoint(pt2.m_prediction), cl, 1, CV_AA); +#endif if (!pt2.m_hasRaw) { - cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, cv::LINE_AA); +#else + cv::circle(frame, ResizePoint(pt2.m_prediction), 4, cl, 1, CV_AA); +#endif } } } @@ -352,7 +367,11 @@ void VideoExample::DrawTrack(cv::Mat frame, for (auto pt : track.m_lastRegion.m_points) { - cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, CV_AA); +#if (CV_VERSION_MAJOR >= 4) + cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, cv::LINE_AA); +#else + cv::circle(frame, cv::Point(cvRound(pt.x), cvRound(pt.y)), 1, cl, -1, CV_AA); +#endif } } } diff --git a/example/VideoExample.h b/example/VideoExample.h index 58f468f06..62581963b 100644 --- a/example/VideoExample.h +++ b/example/VideoExample.h @@ -138,20 +138,20 @@ class MotionDetectorExample : public VideoExample settings.m_matchType = tracking::MatchHungrian; settings.m_dt = 0.4f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.5f; // Accel noise magnitude for Kalman filter - settings.m_distThres = frame.rows / 20; // Distance threshold between region and object on two frames + settings.m_distThres = frame.rows / 20.f; // Distance threshold between region and object on two frames settings.m_useAbandonedDetection = true; if (settings.m_useAbandonedDetection) { settings.m_minStaticTime = minStaticTime; settings.m_maxStaticTime = 60; - settings.m_maximumAllowedSkippedFrames = settings.m_minStaticTime * m_fps; // Maximum allowed skipped frames + settings.m_maximumAllowedSkippedFrames = cvRound(settings.m_minStaticTime * m_fps); // Maximum allowed skipped frames settings.m_maxTraceLength = 2 * settings.m_maximumAllowedSkippedFrames; // Maximum trace length } else { - settings.m_maximumAllowedSkippedFrames = 2 * m_fps; // Maximum allowed skipped frames - settings.m_maxTraceLength = 4 * m_fps; // Maximum trace length + settings.m_maximumAllowedSkippedFrames = cvRound(2 * m_fps); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(4 * m_fps); // Maximum trace length } m_tracker = std::make_unique(settings); @@ -235,8 +235,8 @@ class FaceDetectorExample : public VideoExample settings.m_dt = 0.3f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.1f; // Accel noise magnitude for Kalman filter settings.m_distThres = 0.8f; // Distance threshold between region and object on two frames - settings.m_maximumAllowedSkippedFrames = m_fps / 2; // Maximum allowed skipped frames - settings.m_maxTraceLength = 5 * m_fps; // Maximum trace length + settings.m_maximumAllowedSkippedFrames = cvRound(m_fps / 2); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(5 * m_fps); // Maximum trace length m_tracker = std::make_unique(settings); @@ -313,9 +313,9 @@ class PedestrianDetectorExample : public VideoExample settings.m_matchType = tracking::MatchHungrian; settings.m_dt = 0.3f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.1f; // Accel noise magnitude for Kalman filter - settings.m_distThres = frame.rows / 10; // Distance threshold between region and object on two frames - settings.m_maximumAllowedSkippedFrames = m_fps; // Maximum allowed skipped frames - settings.m_maxTraceLength = 5 * m_fps; // Maximum trace length + settings.m_distThres = frame.rows / 10.f; // Distance threshold between region and object on two frames + settings.m_maximumAllowedSkippedFrames = cvRound(m_fps); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(5 * m_fps); // Maximum trace length m_tracker = std::make_unique(settings); @@ -391,9 +391,9 @@ class SSDMobileNetExample : public VideoExample settings.m_matchType = tracking::MatchHungrian; settings.m_dt = 0.3f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.1f; // Accel noise magnitude for Kalman filter - settings.m_distThres = frame.rows / 10; // Distance threshold between region and object on two frames - settings.m_maximumAllowedSkippedFrames = 2 * m_fps; // Maximum allowed skipped frames - settings.m_maxTraceLength = 5 * m_fps; // Maximum trace length + settings.m_distThres = frame.rows / 10.f; // Distance threshold between region and object on two frames + settings.m_maximumAllowedSkippedFrames = cvRound(2 * m_fps); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(5 * m_fps); // Maximum trace length m_tracker = std::make_unique(settings); @@ -424,7 +424,11 @@ class SSDMobileNetExample : public VideoExample int baseLine = 0; cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); auto rect(track->GetLastRect()); - cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), cv::FILLED); +#else + cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED); +#endif cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0)); } } @@ -502,9 +506,9 @@ class YoloExample : public VideoExample settings.m_matchType = tracking::MatchHungrian; settings.m_dt = 0.3f; // Delta time for Kalman filter settings.m_accelNoiseMag = 0.2f; // Accel noise magnitude for Kalman filter - settings.m_distThres = frame.rows / 10; // Distance threshold between region and object on two frames - settings.m_maximumAllowedSkippedFrames = 2 * m_fps; // Maximum allowed skipped frames - settings.m_maxTraceLength = 5 * m_fps; // Maximum trace length + settings.m_distThres = frame.rows / 10.f; // Distance threshold between region and object on two frames + settings.m_maximumAllowedSkippedFrames = cvRound(2 * m_fps); // Maximum allowed skipped frames + settings.m_maxTraceLength = cvRound(5 * m_fps); // Maximum trace length m_tracker = std::make_unique(settings); @@ -535,7 +539,11 @@ class YoloExample : public VideoExample int baseLine = 0; cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); auto rect(track->GetLastRect()); - cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED); +#if (CV_VERSION_MAJOR >= 4) + cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), cv::FILLED); +#else + cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED); +#endif cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0)); } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1b2a65e6..ab53a59bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,10 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5) project(mtracking) - set(folder_source +set(main_sources nms.h defines.h) + + set(detector_sources Detector/BaseDetector.cpp Detector/MotionDetector.cpp Detector/BackgroundSubtract.cpp @@ -17,17 +19,6 @@ project(mtracking) Detector/SSDMobileNetDetector.cpp Detector/YoloDetector.cpp - Tracker/Ctracker.cpp - Tracker/track.cpp - Tracker/HungarianAlg/HungarianAlg.cpp - Tracker/LocalTracker.cpp - Tracker/Kalman.cpp -) - - set(folder_headers - nms.h - defines.h - Detector/BaseDetector.h Detector/MotionDetector.h Detector/BackgroundSubtract.h @@ -43,6 +34,14 @@ project(mtracking) Detector/pedestrians/c4-pedestrian-detector.h Detector/SSDMobileNetDetector.h Detector/YoloDetector.h +) + + set(tracker_sources + Tracker/Ctracker.cpp + Tracker/track.cpp + Tracker/HungarianAlg/HungarianAlg.cpp + Tracker/LocalTracker.cpp + Tracker/Kalman.cpp Tracker/Ctracker.h Tracker/track.h @@ -143,11 +142,13 @@ project(mtracking) Tracker/graph/GTL/include/GTL/GTL.h ) - SOURCE_GROUP("Source Files" FILES ${folder_source}) - SOURCE_GROUP("Header Files" FILES ${folder_headers}) + SOURCE_GROUP("Src" FILES ${main_sources}) + + SOURCE_GROUP("Detector" FILES ${detector_sources}) + SOURCE_GROUP("Tracker" FILES ${tracker_sources}) - SOURCE_GROUP("graph" FILES ${graph_source} ${graph_header}) - SOURCE_GROUP("GTL" FILES ${gtl_source} ${gtl_header}) + SOURCE_GROUP("Tracker/graph" FILES ${graph_source} ${graph_header}) + SOURCE_GROUP("Tracker/GTL" FILES ${gtl_source} ${gtl_header}) include(CheckIncludeFileCXX) check_include_file_cxx(opencv2/bgsegm.hpp HAVE_OPENCV_CONTRIB) @@ -186,7 +187,21 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/Tracker/graph/GTL/include ) -add_library(${PROJECT_NAME} SHARED ${folder_source} ${folder_headers} ${graph_source} ${graph_header} ${gtl_source} ${gtl_header}) +if (CMAKE_COMPILER_IS_GNUCXX) + add_library(${PROJECT_NAME} SHARED + ${main_sources} + ${detector_sources} + ${tracker_sources} + ${graph_source} ${graph_header} + ${gtl_source} ${gtl_header}) +else(CMAKE_COMPILER_IS_GNUCXX) + add_library(${PROJECT_NAME} + ${main_sources} + ${detector_sources} + ${tracker_sources} + ${graph_source} ${graph_header} + ${gtl_source} ${gtl_header}) +endif() if (CMAKE_COMPILER_IS_GNUCXX) set(LIBS diff --git a/src/Detector/YoloDetector.cpp b/src/Detector/YoloDetector.cpp index 1e89b7707..23ac8cde1 100644 --- a/src/Detector/YoloDetector.cpp +++ b/src/Detector/YoloDetector.cpp @@ -1,10 +1,6 @@ #include "YoloDetector.h" #include "nms.h" -#if (CV_VERSION_MAJOR > 3) -#include -#endif - /// /// \brief YoloDetector::YoloDetector /// \param collectPoints diff --git a/src/Tracker/Kalman.h b/src/Tracker/Kalman.h index 93ee2412b..0b68262cb 100644 --- a/src/Tracker/Kalman.h +++ b/src/Tracker/Kalman.h @@ -2,7 +2,7 @@ #include "defines.h" #include -#include +#include #ifdef USE_OCV_UKF #include diff --git a/src/Tracker/track.cpp b/src/Tracker/track.cpp index ba7356a8e..6a0d398b2 100644 --- a/src/Tracker/track.cpp +++ b/src/Tracker/track.cpp @@ -327,6 +327,7 @@ void CTrack::RectUpdate( case tracking::TrackMedianFlow: case tracking::TrackGOTURN: case tracking::TrackMOSSE: + case tracking::TrackerCSRT: #ifdef USE_OCV_KCF if (!dataCorrect) { @@ -546,6 +547,16 @@ void CTrack::CreateExternalTracker() } #endif break; + + case tracking::TrackerCSRT: +#ifdef USE_OCV_KCF + if (!m_tracker || m_tracker.empty()) + { + cv::TrackerCSRT::Params params; + m_tracker = cv::TrackerCSRT::create(params); + } +#endif + break; } } diff --git a/src/defines.h b/src/defines.h index 8f6bf2520..4037ea023 100644 --- a/src/defines.h +++ b/src/defines.h @@ -120,6 +120,7 @@ enum LostTrackType TrackMIL, TrackMedianFlow, TrackGOTURN, - TrackMOSSE + TrackMOSSE, + TrackerCSRT }; }