OPENCV例子opencv-4.5.5samplesgpufarneback

OPENCV例子opencv-4.5.5samplesgpufarneback,第1张

该示例的作用:演示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

#include

#include

#include

#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(y,3*x) = 0;

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

            dst.at(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("left");

    string pathR = cmd.get("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 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;

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/562476.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-01
下一篇 2022-04-01

发表评论

登录后才能评论

评论列表(0条)

保存