OpenCV  4.2.0
Open Source Computer Vision
samples/cpp/lkdemo.cpp

An example using the Lucas-Kanade optical flow algorithm

#include <iostream>
#include <ctype.h>
using namespace cv;
using namespace std;
static void help()
{
// print a welcome message, and the OpenCV version
cout << "\nThis is a demo of Lukas-Kanade optical flow lkdemo(),\n"
"Using OpenCV version " << CV_VERSION << endl;
cout << "\nIt uses camera by default, but you can provide a path to video as an argument.\n";
cout << "\nHot keys: \n"
"\tESC - quit the program\n"
"\tr - auto-initialize tracking\n"
"\tc - delete all the points\n"
"\tn - switch the \"night\" mode on/off\n"
"To add/remove a feature point click it\n" << endl;
}
Point2f point;
bool addRemovePt = false;
static void onMouse( int event, int x, int y, int /*flags*/, void* /*param*/ )
{
if( event == EVENT_LBUTTONDOWN )
{
point = Point2f((float)x, (float)y);
addRemovePt = true;
}
}
int main( int argc, char** argv )
{
Size subPixWinSize(10,10), winSize(31,31);
const int MAX_COUNT = 500;
bool needToInit = false;
bool nightMode = false;
help();
cv::CommandLineParser parser(argc, argv, "{@input|0|}");
string input = parser.get<string>("@input");
if( input.size() == 1 && isdigit(input[0]) )
cap.open(input[0] - '0');
else
cap.open(input);
if( !cap.isOpened() )
{
cout << "Could not initialize capturing...\n";
return 0;
}
namedWindow( "LK Demo", 1 );
setMouseCallback( "LK Demo", onMouse, 0 );
Mat gray, prevGray, image, frame;
vector<Point2f> points[2];
for(;;)
{
cap >> frame;
if( frame.empty() )
break;
frame.copyTo(image);
cvtColor(image, gray, COLOR_BGR2GRAY);
if( nightMode )
image = Scalar::all(0);
if( needToInit )
{
// automatic initialization
goodFeaturesToTrack(gray, points[1], MAX_COUNT, 0.01, 10, Mat(), 3, 3, 0, 0.04);
cornerSubPix(gray, points[1], subPixWinSize, Size(-1,-1), termcrit);
addRemovePt = false;
}
else if( !points[0].empty() )
{
vector<uchar> status;
vector<float> err;
if(prevGray.empty())
gray.copyTo(prevGray);
calcOpticalFlowPyrLK(prevGray, gray, points[0], points[1], status, err, winSize,
3, termcrit, 0, 0.001);
size_t i, k;
for( i = k = 0; i < points[1].size(); i++ )
{
if( addRemovePt )
{
if( norm(point - points[1][i]) <= 5 )
{
addRemovePt = false;
continue;
}
}
if( !status[i] )
continue;
points[1][k++] = points[1][i];
circle( image, points[1][i], 3, Scalar(0,255,0), -1, 8);
}
points[1].resize(k);
}
if( addRemovePt && points[1].size() < (size_t)MAX_COUNT )
{
vector<Point2f> tmp;
tmp.push_back(point);
cornerSubPix( gray, tmp, winSize, Size(-1,-1), termcrit);
points[1].push_back(tmp[0]);
addRemovePt = false;
}
needToInit = false;
imshow("LK Demo", image);
char c = (char)waitKey(10);
if( c == 27 )
break;
switch( c )
{
case 'r':
needToInit = true;
break;
case 'c':
points[0].clear();
points[1].clear();
break;
case 'n':
nightMode = !nightMode;
break;
}
std::swap(points[1], points[0]);
cv::swap(prevGray, gray);
}
return 0;
}
cv::Point_< float >
cv::Scalar_< double >::all
static Scalar_< double > all(double v0)
returns a scalar with all elements set to v0
cv::TermCriteria
The class defining termination criteria for iterative algorithms.
Definition: types.hpp:852
cv::cvtColor
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
cv::goodFeaturesToTrack
void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04)
Determines strong corners on an image.
cv::Point2f
Point_< float > Point2f
Definition: types.hpp:192
cv::cornerSubPix
void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria)
Refines the corner locations.
cv::VideoCapture
Class for video capturing from video files, image sequences or cameras.
Definition: videoio.hpp:608
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.
cv::TermCriteria::COUNT
the maximum number of iterations or elements to compute
Definition: types.hpp:860
CV_VERSION
#define CV_VERSION
Definition: version.hpp:19
cv::TermCriteria::EPS
the desired accuracy or change in parameters at which the iterative algorithm stops
Definition: types.hpp:862
cv::Size_
Template class for specifying the size of an image or rectangle.
Definition: types.hpp:315
highgui.hpp
cv::namedWindow
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
Creates a window.
cv::norm
static double norm(const Matx< _Tp, m, n > &M)
cv::EVENT_LBUTTONDOWN
indicates that the left mouse button is pressed.
Definition: highgui.hpp:207
cv::Size
Size2i Size
Definition: types.hpp:347
cv::Mat::empty
bool empty() const
Returns true if the array has no elements.
cv::swap
void swap(Mat &a, Mat &b)
Swaps two matrices.
cv::VideoCapture::isOpened
virtual bool isOpened() const
Returns true if video capturing has been initialized already.
tracking.hpp
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv::Scalar
Scalar_< double > Scalar
Definition: types.hpp:669
cv::setMouseCallback
void setMouseCallback(const String &winname, MouseCallback onMouse, void *userdata=0)
Sets mouse handler for the specified window.
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:791
cv::Mat::copyTo
void copyTo(OutputArray m) const
Copies the matrix to another one.
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:796
cv::COLOR_BGR2GRAY
convert between RGB/BGR and grayscale, color conversions
Definition: imgproc.hpp:542
cv
"black box" representation of the file storage associated with a file on disk.
Definition: affine.hpp:51
imgproc.hpp
cv::calcOpticalFlowPyrLK
void calcOpticalFlowPyrLK(InputArray prevImg, InputArray nextImg, InputArray prevPts, InputOutputArray nextPts, OutputArray status, OutputArray err, Size winSize=Size(21, 21), int maxLevel=3, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), int flags=0, double minEigThreshold=1e-4)
Calculates an optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyra...
videoio.hpp
cv::circle
void circle(InputOutputArray img, Point center, int radius, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
Draws a circle.
cv::VideoCapture::open
virtual bool open(const String &filename, int apiPreference=CAP_ANY)
Opens a video file or a capturing device or an IP video stream for video capturing.