OPENCV例子opencv-4.5.5\samples\gpu\farneback_optical_flow.cpp的代码分析

该示例的作用:演示calcOpticalFlowFarneback的使用,​
calcOpticalFlowFarneback( InputArray prev, InputArray next, InputOutputArray flow,
                                            double pyr_scale, int levels, int winsize,
                                            int iterations, int poly_n, double poly_sigma,
                                            int flags );

prev:前一帧图像
next: 后一帧图像
flow: 输出的光流矩阵。矩阵大小同输入的图像一样大,但是矩阵中的每一个元素可不是一个值,而是两个值,分别表示这个点在x方向与y方向的运动量(偏移量)。
pyr_scale: 金字塔上下两层之间的尺度关系
levels: 金字塔层数
winsize: 均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域
iterations: 迭代次数
poly_n: 像素领域大小,一般为5,7等
poly_sigma: 高斯标注差,一般为1-1.5
flags: 计算方法

​Farneback算法计算即图像上所有像素点的光流,calcOpticalFlowFarneback运行的结果flow是包含x/y两个方向的偏移量,需要分别提取出来。

示例CPP文件的函数调用关系:

 

main函数调用关系:

 

main函数流程图:

 

main函数UML逻辑图:

 

示例的源代码:

#include <iostream>

#include <vector>

#include <sstream>

#include <cmath>

#include "opencv2/core.hpp"

#include "opencv2/core/utility.hpp"

#include "opencv2/highgui.hpp"

#include "opencv2/video.hpp"

#include "opencv2/cudaoptflow.hpp"

#include "opencv2/cudaarithm.hpp"

using namespace std;

using namespace cv;

using namespace cv::cuda;

template <typename T>

inline T mapVal(T x, T a, T b, T c, T d)

{

    x = ::max(::min(x, b), a);

    return c + (d-c) * (x-a) / (b-a);

}

static void colorizeFlow(const Mat &u, const Mat &v, Mat &dst)

{

    double uMin, uMax;

    cv::minMaxLoc(u, &uMin, &uMax, 0, 0);

    double vMin, vMax;

    cv::minMaxLoc(v, &vMin, &vMax, 0, 0);

    uMin = ::abs(uMin); uMax = ::abs(uMax);

    vMin = ::abs(vMin); vMax = ::abs(vMax);

    float dMax = static_cast<float>(::max(::max(uMin, uMax), ::max(vMin, vMax)));

    dst.create(u.size(), CV_8UC3);

    for (int y = 0; y < u.rows; ++y)

    {

        for (int x = 0; x < u.cols; ++x)

        {

            dst.at<uchar>(y,3*x) = 0;

            dst.at<uchar>(y,3*x+1) = (uchar)mapVal(-v.at<float>(y,x), -dMax, dMax, 0.f, 255.f);

            dst.at<uchar>(y,3*x+2) = (uchar)mapVal(u.at<float>(y,x), -dMax, dMax, 0.f, 255.f);

        }

    }

}

int main(int argc, char **argv)

{

    CommandLineParser cmd(argc, argv,

            "{ l left  | ../data/basketball1.png | specify left image }"

            "{ r right | ../data/basketball2.png | specify right image }"

            "{ h help  | | print help message }");

    cmd.about("Farneback's optical flow sample.");

    if (cmd.has("help") || !cmd.check())

    {

        cmd.printMessage();

        cmd.printErrors();

        return 0;

    }

    string pathL = cmd.get<string>("left");

    string pathR = cmd.get<string>("right");

    if (pathL.empty()) cout << "Specify left image path\n";

    if (pathR.empty()) cout << "Specify right image path\n";

    if (pathL.empty() || pathR.empty()) return -1;

    Mat frameL = imread(pathL, IMREAD_GRAYSCALE);

    Mat frameR = imread(pathR, IMREAD_GRAYSCALE);

    if (frameL.empty()) cout << "Can't open '" << pathL << "'\n";

    if (frameR.empty()) cout << "Can't open '" << pathR << "'\n";

    if (frameL.empty() || frameR.empty()) return -1;

    GpuMat d_frameL(frameL), d_frameR(frameR);

    GpuMat d_flow;

    Ptr<cuda::FarnebackOpticalFlow> d_calc = cuda::FarnebackOpticalFlow::create();

    Mat flowxy, flowx, flowy, image;

    bool running = true, gpuMode = true;

    int64 t, t0=0, t1=1, tc0, tc1;

    cout << "Use 'm' for CPU/GPU toggling\n";

    while (running)

    {

        t = getTickCount();

        if (gpuMode)

        {

            tc0 = getTickCount();

            d_calc->calc(d_frameL, d_frameR, d_flow);

            tc1 = getTickCount();

            GpuMat planes[2];

            cuda::split(d_flow, planes);

            planes[0].download(flowx);

            planes[1].download(flowy);

        }

        else

        {

            tc0 = getTickCount();

            calcOpticalFlowFarneback(

                        frameL, frameR, flowxy, d_calc->getPyrScale(), d_calc->getNumLevels(), d_calc->getWinSize(),

                        d_calc->getNumIters(), d_calc->getPolyN(), d_calc->getPolySigma(), d_calc->getFlags());

            tc1 = getTickCount();

            Mat planes[] = {flowx, flowy};

            split(flowxy, planes);

            flowx = planes[0]; flowy = planes[1];

        }

        colorizeFlow(flowx, flowy, image);

        stringstream s;

        s << "mode: " << (gpuMode?"GPU":"CPU");

        putText(image, s.str(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);

        s.str("");

        s << "opt. flow FPS: " << cvRound((getTickFrequency()/(tc1-tc0)));

        putText(image, s.str(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);

        s.str("");

        s << "total FPS: " << cvRound((getTickFrequency()/(t1-t0)));

        putText(image, s.str(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);

        imshow("flow", image);

        char ch = (char)waitKey(3);

        if (ch == 27)

            running = false;

        else if (ch == 'm' || ch == 'M')

            gpuMode = !gpuMode;

        t0 = t;

        t1 = getTickCount();

    }

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: opencv-4.5.5-vc14_vc15.exe 是OpenCV框架的一个版本,并且它适用于使用VC14和VC15编译器的Windows操作系统。VC14和VC15分别指的是Visual Studio 2015和Visual Studio 2017等版本。 如果您需要在Windows操作系统上使用OpenCV框架进行图像处理和计算机视觉任务,您可以下载opencv-4.5.5-vc14_vc15.exe安装程序。这个安装程序包含编译好的OpenCV库与相关的配置文件,并且它提供了一些示例代码和文档来帮助您快速开始使用OpenCV。 一旦您下载并安装了这个exe文件,您就可以在您的项目中包含OpenCV库,并使用OpenCV函数进行图像处理、特征提取、对象检测等操作。这个版本还支持各种图像格式的读取和写入,并提供了一些常用的图像处理算法和工具。 总之,opencv-4.5.5-vc14_vc15.exe提供了一个方便的方式来获取和使用OpenCV框架,让您能够在Windows平台上进行图像处理和计算机视觉开发。但在安装之前,请确保您的操作系统和编译器版本与它的要求相符合。 ### 回答2: opencv-4.5.5-vc14_vc15.exe 是OpenCV的一个版本。OpenCV是一个开源的计算机视觉库,用于图像处理和计算机视觉任务。下载这个文件意味着你可以安装这个版本的OpenCV库到你的计算机上。 首先,你需要找到这个文件的下载链接。你可以在OpenCV的官方网站上找到这个版本的下载页面,并从中获取到下载链接。下载这个文件之前,你需要确保你的计算机满足安装OpenCV所需的最低系统要求。 一旦下载完成,你可以双击运行这个.exe文件。运行这个文件会打开一个安装向导,它将引导你完成安装过程。安装向导会问你选择安装路径和其他一些选项。你可以按照默认设置进行安装,或者根据自己的需要进行个性化设置。安装过程可能需要一些时间,具体取决于你的计算机性能和文件大小。 安装完成后,你可以在你选择的安装路径中找到OpenCV的文件和库。你可以使用这些文件和库来开发和运行图像处理和计算机视觉应用程序。 总结来说,下载opencv-4.5.5-vc14_vc15.exe是为了安装OpenCV库到你的计算机上,它提供了图像处理和计算机视觉功能。安装过程相对简单,一旦完成,你就可以开始使用OpenCV并开发自己的应用程序。 ### 回答3: OpenCV是一个开源计算机视觉库,用于处理图像和视频的编程工具。在OpenCV的官方网站上,我们可以找到多个版本的OpenCV进行下载。其中,opencv-4.5.5-vc14_vc15.exe是适用于使用Microsoft Visual Studio 2015和2017的用户的Windows版本。 下载该文件非常简单。首先,我们需要打开OpenCV的官方网站。然后,在网站的下载页面上找到相应的版本,即opencv-4.5.5-vc14_vc15.exe。点击该文件后,可以选择下载镜像源,例如,SourceForge、GitHub等。选择一个合适的镜像源后,点击下载按钮即可开始下载。 下载完成后,我们可以找到下载的.exe文件在计算机上的存储位置,一般是在默认的下载文件夹中。我们可以双击该文件来运行它,并按照安装向导的指引来安装OpenCV。安装过程中,可以选择所需的组件和功能来满足个人需求。 一旦安装完成,我们就可以开始使用OpenCV来处理图像和视频了。通过编写代码,并使用OpenCV的函数和方法,我们可以实现各种功能,例如图像增强、目标检测、人脸识别等。 总而言之,通过下载opencv-4.5.5-vc14_vc15.exe文件,并按照安装指引来安装OpenCV,我们可以获得一个用于图像和视频处理的强大工具库。无论是对于计算机视觉的研究还是应用开发,OpenCV都是一个非常有用的资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqq9668

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值