工具:
Mat frame;
Mat prevImg;
Mat nextImg;
Mat copy_frame;
Mat warp_matrix;
Mat perspecttive_frame;
vector<Point2f> features;
vector<Point2f> prevPts;
vector<Point2f> nextPts;
vector<Point2f> initial;
int maxCount = 30;
double qLevel = 0.01;
double minDist = 10.0;
vector<uchar> status;
vector<float> err;
int detect_station;
void my_mouse_callback_9(int event, int x, int y, int flags, void* param)
{
switch (event) {
case CV_EVENT_LBUTTONDOWN:
//点击鼠标左键标定跟踪点
{
prevPts.push_back(cvPoint(x, y));
initial.push_back(cvPoint(x, y));
}
break;
case CV_EVENT_RBUTTONDOWN:
{
detect_station = 1;
//点击鼠标右键确认完成跟踪点标定
}
break;
}
}
应用:
void opencv_4_3::ans_9() {
cvNamedWindow("OpticalFlow", 0);
cvNamedWindow("Perspective_Image", 1);
cvSetMouseCallback("OpticalFlow", my_mouse_callback_9);
VideoCapture capture(0);
cvWaitKey(100);
while (1)
{
capture >> frame;
imshow("OpticalFlow", frame);
cvWaitKey(1);
if (detect_station == 1)
{
cvtColor(frame, nextImg, CV_BGR2GRAY);
if (prevImg.empty())
{
nextImg.copyTo(prevImg);
}
}
while (detect_station == 1)
{
if (prevPts.size() == 0)
{
break;
}
calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, nextPts, status, err);
int k = 0;
for (int i = 0; i<nextPts.size(); i++)
{
if (status[i])
{
initial[k] = initial[i];
nextPts[k++] = nextPts[i];
}
}
nextPts.resize(k);
initial.resize(k);
for (int i = 0; i<nextPts.size(); i++)
{
line(frame, initial[i], nextPts[i], Scalar(0, 0, 255));
circle(frame, nextPts[i], 3, Scalar(255, 0, 0), -1);
}
swap(prevPts, nextPts);
swap(prevImg, nextImg);
imshow("OpticalFlow", frame);
//显示跟踪点移动位置
//图像稳定(透视变换,基于标定点(4个)将新图像投影到原始图像的平面)
if (prevPts.size() == 4)
{
warp_matrix = getPerspectiveTransform(nextPts, prevPts);
warpPerspective(nextImg, perspecttive_frame, warp_matrix, cvSize(frame.cols, frame.rows));
imshow("Perspective_Image", perspecttive_frame);
}
//继续下一帧的处理
capture >> frame;
cvtColor(frame, nextImg, CV_BGR2GRAY);
char c = cvWaitKey(10);
if (c == 27)
{
detect_station = 0;
initial.resize(0);
prevPts.resize(0);
break;
}
}
char d = cvWaitKey(10);
if (d == 27) break;
}
cvDestroyWindow("OpticalFlow");
cvDestroyWindow("Perspective_Image");
}