|
1 |
| -# MultiThreaded-Object-Detection-and-Tracking-cpp |
| 1 | +# MultiThreaded Object Detection and Tracking |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +This repository contains an implementation of a multithreaded application for detecting objects and tracking objects in a user-specified video. Example output of running the application on the input video (`videos/input_video.mp4`) is the resulting video (`videos/project_track_and_detect.avi`). |
| 6 | + |
| 7 | +The whole detection and tracking application runs on four asynchronous tasks. First task start reading frames using Frame Grabber object (`frame_grabber.h`) and pushes them them into a message queue (`message_queue.h`) which is thread safe implementation using conditional variables. The second tasks detects the frames by pulling the frames from message queue as they become available using Object Detector (`object_detector.h`). The class (`object_detector.h`) is a abtract class. After detection of each frame, the detector puts detected frame along with the required input data for tracking into another queue having a special message is type of tracking messages (`tracking_msg.h`). This two tasks run in parallel. |
| 8 | +Once they are completed another task is started, which pulls the tracking messages from another queue and does the tracking using Object Tracker (`object_tracker.h`). The Object Tracker uses the Tracker (`tracker.h`) which provides functionality to update the tracks. The tracks are implements as abstract class (`track.h`). Each frame after tracking is put in the output queue. |
| 9 | +After the completion of tracking task, the final task is started using Frame Writer object (`frame_writer.h`) which pulls the messages from the output queue and writes them to the user-specified output video file. |
| 10 | + |
| 11 | +### Red dot on the objects shows the tracking and the green dot shows the position measured by detecting the object and calculating center of bounding box |
| 12 | + |
| 13 | +<img src="data/output.gif"/> |
| 14 | + |
| 15 | +## Detectors: |
| 16 | + |
| 17 | +This project provides the abstact implementation of object detector, hence any custom object detector can be added. Currently, YOLO3-Object-Detector is implemented(`yolo_object_detector.h`). |
| 18 | + |
| 19 | +### YOLO3-Object-Detector |
| 20 | + |
| 21 | +This object detector is trained on coco dataset and can recognize upto 80 different classes of objects in the moving frame. |
| 22 | + |
| 23 | +## Trackers: Kalman |
| 24 | + |
| 25 | +The project provides abstract implementation of the tracker in form of tracks, hence any custom object tracker can be added. Currently, kalman tracker (`kalman_track.h`) is implemented using Kalman-Filter (`kalman_filter.h`). An assignment problem is used to associate the objects detected by detectors and tracked by trackers. Here it is solved using Hungarian Algorithm. |
| 26 | + |
| 27 | +Tracking consist of two major steps: |
| 28 | +1. Prediction: Predict the object locations in the next frame. |
| 29 | +2. Data association: Use the predicted locations to associate detections across frames to form tracks. |
| 30 | + |
| 31 | +## Dependencies for Running Locally |
| 32 | +* cmake >= 3.7 |
| 33 | + * All OSes: [click here for installation instructions](https://cmake.org/install/) |
| 34 | +* make >= 4.1 (Linux, Mac), 3.81 (Windows) |
| 35 | + * Linux: make is installed by default on most Linux distros |
| 36 | + * Mac: [install Xcode command line tools to get make](https://developer.apple.com/xcode/features/) |
| 37 | + * Windows: [Click here for installation instructions](http://gnuwin32.sourceforge.net/packages/make.htm) |
| 38 | +* gcc/g++ >= 5.4 |
| 39 | + * Linux: gcc / g++ is installed by default on most Linux distros |
| 40 | + * Mac: same deal as make - [install Xcode command line tools](https://developer.apple.com/xcode/features/) |
| 41 | + * Windows: recommend using [MinGW](http://www.mingw.org/) |
| 42 | +* OpenCV >= 4.1 |
| 43 | + * The OpenCV 4.1.0 source code can be found [here](https://github.com/opencv/opencv/tree/4.1.0) |
| 44 | +* Eigen3 |
| 45 | + * Install using "sudo apt-get install libeigen3" |
| 46 | + |
| 47 | +## Basic Build Instructions |
| 48 | + |
| 49 | +1. Clone this repo. |
| 50 | + |
| 51 | +2. Run the following commands to download object detection models from [Darknet](https://pjreddie.com/darknet/) |
| 52 | + |
| 53 | +``` |
| 54 | +cd CppND-Capstone |
| 55 | +mkdir model && cd model |
| 56 | +wget https://pjreddie.com/media/files/yolov3.weights |
| 57 | +wget https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg?raw=true -O ./yolov3.cfg |
| 58 | +``` |
| 59 | + |
| 60 | +3. Make a build directory in the top level directory: `mkdir build && cd build` |
| 61 | + |
| 62 | +4. Compile: `cmake .. && make` |
| 63 | + |
| 64 | +5. Run it: `./detect_and_track` (**Runtime can vary depending on the number of frames in the video**) |
| 65 | + |
| 66 | +6. Progress can tracked while the program is running |
| 67 | +``` |
| 68 | +Model Loaded Successfully! |
| 69 | +Loaded 80 Class Names |
| 70 | +Initialised the tracker |
| 71 | +Read 10 frames from total 1260 frames |
| 72 | +Read 20 frames from total 1260 frames |
| 73 | +Read 30 frames from total 1260 frames |
| 74 | +Read 40 frames from total 1260 frames |
| 75 | +Read 50 frames from total 1260 frames |
| 76 | +.... |
| 77 | +.... |
| 78 | +Detected 10 frames |
| 79 | +Read 520 frames from total 1260 frames |
| 80 | +Detected 20 frames |
| 81 | +Read 530 frames from total 1260 frames |
| 82 | +Detected 30 frames |
| 83 | +Read 540 frames from total 1260 frames |
| 84 | +.... |
| 85 | +.... |
| 86 | +Tracked 1240 frames |
| 87 | +Tracked 1250 frames |
| 88 | +Written 1253 frames |
| 89 | +------- Done !! ------- |
| 90 | +
|
| 91 | +7. The video can be played from (`videos/project_track_and_detect.avi`) after the program terminates |
| 92 | +
|
| 93 | +## Code Instructions |
| 94 | +
|
| 95 | +1. Change the model_config file path and model_weight_path in main.cpp |
| 96 | +2. Change the input and output video file path in main.cpp |
| 97 | +2. Turn the track flag to false in main.cpp if you want to run detection only |
| 98 | +
|
| 99 | +## Satisfied Rubric Points |
| 100 | +
|
| 101 | +### The application reads data from a file and process the data. |
| 102 | +
|
| 103 | +* The project reads frames from a video file using the `ObjectDetector` class (`line 46 include/Detector/object_detector.h`). |
| 104 | +
|
| 105 | +### The application implements the abstract classes and pure virtual functions. |
| 106 | +
|
| 107 | +* The object detector class (`include/Detector/object_detector.h`) and the tracks class (`include/Tracker/track.h`). |
| 108 | +
|
| 109 | +### Use of Object Oriented Programming techniques. |
| 110 | +
|
| 111 | +* The classes `FrameGrabber` (`src/frame_grabber.cpp` , `include/frame_grabber.h`), `FrameWriter` (`src/frame_writer.cpp` , `include/frame_writer.h`), `MessageQueue` (`include/message_queue.h`), `YOLODetector` (`include/Detector/yolo_object_detector.h`, `src/yolo_object_detector.cpp`), `KalmanFilter` (`include/Tracker/kalman_filter.h` , `src/kalman_filter.cpp`), `Tracker` (`include/Tracker/tracker.h` , `src/tracker.cpp`) and `KalmanTrack` (`include/Tracker/kalman_track.h` , `src/kalman_track.cpp`). |
| 112 | +
|
| 113 | +### Use of Inheritence techniques. |
| 114 | +
|
| 115 | +* The class `YOLODetector` is inherited from parent class `ObjectDetector` (`line 15 include/Detector/yolo_object_detector.h`). |
| 116 | +* The class `KalmanTrack` is inherited from parent class `Track` (`line 8 include/Tracker/yolo_object_detector.h`). |
| 117 | +
|
| 118 | +### Classes use appropriate access specifiers for class members. |
| 119 | +
|
| 120 | +* Example of class-specific access specifiers in `Tracker` class definition (`include/Tracker/tracker.h`). |
| 121 | +
|
| 122 | +### Use of Overloaded Functions. |
| 123 | +
|
| 124 | +* The function getTracks() is overloaded in `Tracker` class (`line 47,49 include/Tracker/tracker.h`). |
| 125 | +
|
| 126 | +### Templates generalize functions. |
| 127 | +
|
| 128 | +* The `MessageQueue` is a templated class (`include/message_queue.h`). |
| 129 | +
|
| 130 | +### Use of references in function declarations. |
| 131 | +
|
| 132 | +* Example of method that uses reference in function declaration is the implementation of the `YOLODetector` constructor (`line 4 src/yolo_object_detector.cpp`). |
| 133 | +
|
| 134 | +### Use of scope / Resource Acquisition Is Initialization (RAII) where appropriate. |
| 135 | +
|
| 136 | +* Example use of RAII can be seen acquisition and release of locks in `MessageQueue` (`lines 19,55,62 include/message_queue.h`). |
| 137 | +
|
| 138 | +### Use of move semantics to move data, instead of copying it, where possible. |
| 139 | +
|
| 140 | +* Example use of move semantics is the pushing and removing of items in `MessageQueue` (`line 41 include/message_queue.h`). |
| 141 | +
|
| 142 | +### Use of smart pointers. |
| 143 | +
|
| 144 | +* Example use of the smart pointers (std::unique_ptr) is (`line 7 src/yolo_object_detector.cpp`), (`line 15 src/tracker.cpp`). |
| 145 | +
|
| 146 | +### Use of multithreading. |
| 147 | +
|
| 148 | +* The project uses two asynchronous tasks (std::async) (`lines 54,57,63,68 src/main.cpp`). |
| 149 | +
|
| 150 | +### Use of condition variable. |
| 151 | +
|
| 152 | +* A condition variable is used in the project in the implementation of message queue (`lines 38,28 include/message_queue.h`). |
| 153 | +
|
| 154 | +## References |
| 155 | +
|
| 156 | +* The video used in this repository was taken from the repository [udacity/CarND-Vehicle-Detection](udacity/CarND-Vehicle-Detection). |
| 157 | +
|
| 158 | +* OpenCV YOLO Object Detection (https://github.com/opencv/opencv/blob/master/samples/dnn/object_detection.cpp) |
| 159 | +
|
| 160 | +* Kalman Filter - [Artificial Intelligence for Robotics](https://www.udacity.com/course/artificial-intelligence-for-robotics--cs373#) Udacity Course |
| 161 | +
|
| 162 | +* Hungarian Algorithm - [here](http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem) |
| 163 | +
|
| 164 | +* Motion-Based Multiple Object Tracking - [here](https://in.mathworks.com/help/vision/examples/motion-based-multiple-object-tracking.html) |
| 165 | +
|
| 166 | +* Multiple Object Tracking - [here](https://in.mathworks.com/help/vision/ug/multiple-object-tracking.html) |
| 167 | +
|
| 168 | +* Computer Vision for tracking - [here](https://towardsdatascience.com/computer-vision-for-tracking-8220759eee85) |
0 commit comments