Last active
February 10, 2022 15:28
-
-
Save svagionitis/0063fd0a5368015ff049c88b0b71a922 to your computer and use it in GitHub Desktop.
Object tracking algorithms for OpenCV 4.5.5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is part of OpenCV project. | |
// It is subject to the license terms in the LICENSE file found in the top-level directory | |
// of this distribution and at http://opencv.org/license.html | |
// Examples from peopledetect.cpp and from https://learnopencv.com/object-tracking-using-opencv-cpp-python/ | |
#include <opencv2/objdetect.hpp> | |
#include <opencv2/highgui.hpp> | |
#include <opencv2/imgcodecs.hpp> | |
#include <opencv2/imgproc.hpp> | |
#include <opencv2/videoio.hpp> | |
#include <opencv2/tracking.hpp> | |
#include <opencv2/tracking/tracking_legacy.hpp> | |
#include <iostream> | |
#include <iomanip> | |
#include <map> | |
#include <string> | |
using namespace cv; | |
using namespace std; | |
static const string keys = "{ help h | | print help message }" | |
"{ algorithm a | CSRT, KCF, Boosting, MedianFlow, MIL, MOSSE, TLD | algorithm to use for object tracking }" | |
"{ camera c | 0 | capture video from camera (device index starting from 0) }" | |
"{ video v | | use video as input }"; | |
const map<string, int> TrackingAlgorithmsMapping = { | |
{"CSRT", 0}, | |
{"KCF", 1}, | |
{"Boosting", 2}, | |
{"MedianFlow", 3}, | |
{"MIL", 4}, | |
{"MOSSE", 5}, | |
{"TLD", 6}, | |
}; | |
int main(int argc, char **argv) | |
{ | |
CommandLineParser parser(argc, argv, keys); | |
parser.about("This sample demonstrates the use of object tracking."); | |
if (parser.has("help")) | |
{ | |
parser.printMessage(); | |
return 0; | |
} | |
Ptr<legacy::Tracker> tracker; | |
string trackingAlgorithm = parser.get<string>("algorithm"); | |
if (!parser.check()) | |
{ | |
parser.printErrors(); | |
return 1; | |
} | |
int trackingAlgorithmId; | |
try | |
{ | |
trackingAlgorithmId = TrackingAlgorithmsMapping.at(trackingAlgorithm); | |
} | |
catch (const std::out_of_range &) | |
{ | |
cerr << "Key: " << trackingAlgorithm << " not found" << endl; | |
parser.printErrors(); | |
return 1; | |
} | |
#ifdef DEFAULR_PARAMS | |
string trackerSettingsFilename = "tracker-" + trackingAlgorithm + "-settings.yaml"; | |
FileStorage fsTrackerSettings(trackerSettingsFilename, FileStorage::WRITE); | |
legacy::TrackerCSRT::Params csrtParams; | |
legacy::TrackerKCF::Params kcfParams; | |
legacy::TrackerBoosting::Params boostingParams; | |
legacy::TrackerMedianFlow::Params medianFlowParams; | |
legacy::TrackerMIL::Params milParams; | |
legacy::TrackerTLD::Params tldParams; | |
#endif | |
switch (trackingAlgorithmId) | |
{ | |
case 0: | |
#ifdef DEFAULR_PARAMS | |
csrtParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerCSRT::create(); | |
break; | |
case 1: | |
#ifdef DEFAULR_PARAMS | |
kcfParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerKCF::create(); | |
break; | |
case 2: | |
#ifdef DEFAULR_PARAMS | |
boostingParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerBoosting::create(); | |
break; | |
case 3: | |
#ifdef DEFAULR_PARAMS | |
medianFlowParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerMedianFlow::create(); | |
break; | |
case 4: | |
#ifdef DEFAULR_PARAMS | |
milParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerMIL::create(); | |
break; | |
case 5: | |
tracker = legacy::TrackerMOSSE::create(); | |
break; | |
case 6: | |
#ifdef DEFAULR_PARAMS | |
tldParams.write(fsTrackerSettings); | |
#endif | |
tracker = legacy::TrackerTLD::create(); | |
break; | |
default: | |
cerr << "Tracking algorithm " << trackingAlgorithm << "is not valid." << endl; | |
parser.printMessage(); | |
return 1; | |
} | |
#ifdef DEFAULR_PARAMS | |
fsTrackerSettings.release(); | |
#endif | |
int camera = parser.get<int>("camera"); | |
string file = parser.get<string>("video"); | |
if (!parser.check()) | |
{ | |
parser.printErrors(); | |
return 1; | |
} | |
VideoCapture capture; | |
if (file.empty()) | |
capture.open(camera); | |
else | |
{ | |
file = samples::findFileOrKeep(file); | |
capture.open(file); | |
} | |
if (!capture.isOpened()) | |
{ | |
cout << "Can not open video stream: '" << (file.empty() ? "<camera>" : file) << "'" << endl; | |
return 2; | |
} | |
cout << "Press 'q' or <ESC> to quit." << endl; | |
cout << "Press <space> to toggle between Default and Daimler detector" << endl; | |
Mat frame; | |
capture.read(frame); | |
// Define initial bounding box | |
Rect2d bbox = selectROI(frame, false); | |
// Display bounding box. | |
rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1); | |
imshow("Tracking", frame); | |
tracker->init(frame, bbox); | |
while (capture.read(frame)) | |
{ | |
// Start timer | |
double timer = (double)getTickCount(); | |
// Update the tracking result | |
bool ok = tracker->update(frame, bbox); | |
// Calculate Frames per second (FPS) | |
float fps = (float)(getTickFrequency() / ((double)getTickCount() - timer)); | |
if (ok) | |
{ | |
// Tracking success : Draw the tracked object | |
rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1); | |
} | |
else | |
{ | |
// Tracking failure detected. | |
putText(frame, "Tracking failure detected", Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2); | |
} | |
// Display tracker type on frame | |
putText(frame, trackingAlgorithm + " Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2); | |
// Display FPS on frame | |
putText(frame, "FPS : " + to_string(fps), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2); | |
// Display frame. | |
imshow("Tracking", frame); | |
// Exit if ESC pressed. | |
int k = waitKey(1); | |
if (k == 27) | |
{ | |
break; | |
} | |
} // while | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment