C++Opencv对视频进行运动物体运动轨迹的提取代码
时间: 2023-09-05 14:09:38 浏览: 70
以下是使用C++和OpenCV实现对视频中运动物体运动轨迹的提取的示例代码:
```c++
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// 读取视频文件
VideoCapture cap("test.mp4");
// 定义背景差分器和光流计算器
Ptr<BackgroundSubtractor> bs = createBackgroundSubtractorMOG2();
Ptr<DenseOpticalFlow> flow = createOptFlow_DualTVL1();
// 定义用于绘制轨迹的颜色
Scalar color(0, 0, 255);
// 定义轨迹点列表
vector<Point2f> points;
// 循环读取视频帧
Mat frame, gray, fgmask, flowmap;
while (cap.read(frame))
{
// 转换为灰度图像
cvtColor(frame, gray, COLOR_BGR2GRAY);
// 背景差分
bs->apply(gray, fgmask);
// 计算光流
Mat prev = gray.clone();
flow->calc(prev, gray, flowmap);
// 提取运动物体
Mat magnitude, angle;
cartToPolar(flowmap(Rect(0, 0, frame.cols, frame.rows)).ptr<float>(0),
flowmap(Rect(0, 0, frame.cols, frame.rows)).ptr<float>(1),
magnitude, angle);
threshold(magnitude, fgmask, 10, 255, THRESH_BINARY);
// 查找运动物体的轮廓
vector<vector<Point>> contours;
findContours(fgmask, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// 绘制运动物体的轨迹
for (const auto& contour : contours)
{
Rect bbox = boundingRect(contour);
Point2f center = Point2f(bbox.x + bbox.width / 2, bbox.y + bbox.height / 2);
// 记录轨迹点
points.push_back(center);
// 绘制轨迹
for (size_t i = 1; i < points.size(); i++)
{
line(frame, points[i - 1], points[i], color, 2);
}
}
// 显示原始帧和运动物体的轨迹
imshow("frame", frame);
// 退出循环
if (waitKey(30) == 'q')
break;
}
// 释放资源
cap.release();
destroyAllWindows();
return 0;
}
```
以上代码中,我们使用了cv::createBackgroundSubtractorMOG2()函数创建了背景差分器,使用了cv::createOptFlow_DualTVL1()函数创建了光流计算器。在每一帧中,我们先对图像进行背景差分和光流计算,然后提取运动物体的轮廓,并将每个运动物体的中心点保存到轨迹点列表中。最后,我们使用cv::line()函数绘制运动物体的轨迹,并使用cv::imshow()函数显示原始帧和运动物体的轨迹。