以下是实现该程序的代码,分为读入视频、车辆识别、矩形框标出、几何中心标出和车速计算五个部分。

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    // 读入视频
    VideoCapture cap("test.mp4");
    if (!cap.isOpened())
    {
        std::cout << "Error opening video file" << std::endl;
        return -1;
    }

    // 车辆识别
    Mat frame, gray, prevGray, flow, hsv;
    std::vector<std::vector<Point>> contours;
    while (cap.read(frame))
    {
        cvtColor(frame, gray, COLOR_BGR2GRAY);
        if (!prevGray.empty())
        {
            calcOpticalFlowFarneback(prevGray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
            cvtColor(frame, hsv, COLOR_BGR2HSV);
            for (int i = 0; i < flow.rows; i += 10)
            {
                for (int j = 0; j < flow.cols; j += 10)
                {
                    Point2f f = flow.at<Point2f>(i, j);
                    if (norm(f) > 5)
                    {
                        circle(frame, Point(j, i), 2, Scalar(0, 255, 0), -1);
                        rectangle(frame, Rect(j - 20, i - 20, 40, 40), Scalar(0, 0, 255), 2);
                    }
                }
            }
            findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
            for (int i = 0; i < contours.size(); i++)
            {
                Rect rect = boundingRect(contours[i]);
                if (rect.width > 50 && rect.height > 50)
                {
                    rectangle(frame, rect, Scalar(0, 0, 255), 2);
                    Point center = Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
                    line(frame, Point(center.x - 10, center.y), Point(center.x + 10, center.y), Scalar(0, 255, 0), 2);
                    line(frame, Point(center.x, center.y - 10), Point(center.x, center.y + 10), Scalar(0, 255, 0), 2);
                }
            }
        }
        prevGray = gray.clone();

        // 车速计算
        // ...

        imshow("frame", frame);
        if (waitKey(30) == 27) break;
    }

    return 0;
}

首先,我们使用VideoCapture类读入视频文件,如果读入失败则输出错误信息并退出程序。然后,我们使用calcOpticalFlowFarneback函数计算光流,将光流向量的大小作为车辆运动的速度判断车辆是否在运动。如果车辆在运动,则在车辆周围绘制红色矩形框和绿色十字标记;如果车辆静止,则只绘制红色矩形框。

接着,我们使用findContours函数找到所有的轮廓,对于每个轮廓,如果其宽度和高度都大于50像素,则认为其是一辆车,绘制红色矩形框和绿色十字标记。

最后,我们需要根据光流原理计算车速。这部分代码需要根据具体情况实现,不在本题的要求范围内


原文地址: https://www.cveoy.top/t/topic/clAF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录