opencv光流法调用电脑摄像头测速的c++代码
时间: 2023-08-31 14:04:55 浏览: 125
guagnliufa_yuanma.zip_Simpleflow_simpleflow.cpp_光流_光流法
以下是一个简单的使用OpenCV光流法进行测速的C++代码示例,它可以调用计算机摄像头:
```c++
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 打开摄像头
VideoCapture cap(0);
// 检查摄像头是否打开
if (!cap.isOpened())
{
std::cerr << "Error opening video capture." << std::endl;
return -1;
}
// 定义变量
Mat prevGray, gray;
std::vector<Point2f> prevPts, nextPts;
std::vector<uchar> status;
std::vector<float> err;
// 循环处理每一帧
while (true)
{
Mat frame;
cap >> frame;
// 转换为灰度图像
cvtColor(frame, gray, COLOR_BGR2GRAY);
// 检查是否需要重新初始化点
if (prevPts.empty())
{
// 选择感兴趣的区域,例如道路上的车道线
Rect roi(0, 240, 640, 240);
// 提取特征点
goodFeaturesToTrack(gray(roi), prevPts, 100, 0.01, 10, noArray(), 3, false, 0.04);
// 将点的坐标偏移
for (auto& pt : prevPts)
{
pt.x += roi.x;
pt.y += roi.y;
}
}
else
{
// 计算光流
calcOpticalFlowPyrLK(prevGray, gray, prevPts, nextPts, status, err);
// 计算速度
float speed = 0.f;
int count = 0;
for (int i = 0; i < prevPts.size(); ++i)
{
if (status[i])
{
speed += norm(nextPts[i] - prevPts[i]);
++count;
}
}
if (count > 0)
{
speed /= count;
speed *= 30.f; // 假设每秒有30帧
std::cout << "Speed: " << speed << " pixels/s" << std::endl;
}
// 画出特征点和光流
Mat vis;
cvtColor(gray, vis, COLOR_GRAY2BGR);
for (int i = 0; i < prevPts.size(); ++i)
{
if (status[i])
{
line(vis, prevPts[i], nextPts[i], Scalar(0, 255, 0));
circle(vis, nextPts[i], 2, Scalar(0, 0, 255), -1);
}
}
imshow("Optical Flow", vis);
}
// 保存当前状态
prevGray = gray.clone();
prevPts = nextPts;
}
return 0;
}
```
这个例子中,我们使用`goodFeaturesToTrack`函数来提取感兴趣的区域中的特征点,然后使用`calcOpticalFlowPyrLK`函数计算这些特征点在连续帧之间的光流,最后计算速度并显示光流和特征点。
请注意,这只是一个简单的例子,实际中需要考虑许多其他因素,例如像素尺寸和实际速度之间的转换,相机的视角和位置等。
阅读全文