Computer/Coding

[opencv] C++ 광류흐름 (Optical flow) cuda 소스코드

순박한시골청년 2021. 10. 25. 17:15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <fstream>
#include "opencv2/core.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/highgui.hpp"
#include "opencv2/cudaoptflow.hpp"
#include "opencv2/cudaarithm.hpp"
#include "opencv2/imgproc.hpp"
 
using namespace std;
using namespace cv;
using namespace cv::cuda;
 
 
int main()
{
    VideoCapture capture("D:/test.mp4");
 
    if (!capture.isOpened())
    {
        printf("AVI file can not open.\n");
        return -1;
    }
 
    // Optical 객체 초기화
    int opticalWindowSize = 15;
    Ptr<cuda::FarnebackOpticalFlow> farn = cuda::FarnebackOpticalFlow::create(50.5false, opticalWindowSize, 105);
 
    // 영상 저장용 Mat
    Mat framePrev;
    Mat frameCurr;
    capture >> framePrev;
    cv::cvtColor(framePrev, framePrev, cv::COLOR_BGR2GRAY);
 
 
 
    while (1)
    {
        capture >> frameCurr;
        if (frameCurr.empty()) //Is video end?
            break;
 
        cv::cvtColor(frameCurr, frameCurr, cv::COLOR_BGR2GRAY);
 
        // GPU Mat 초기화
        GpuMat g_framePrev(framePrev);
        GpuMat g_frameCurr(frameCurr);
 
        // Optical 동작
        GpuMat g_flow(frameCurr.size(), CV_32FC2);
        farn->calc(g_framePrev, g_frameCurr, g_flow);
 
        // 결과 저장
        Mat flowMat;
        g_flow.download(flowMat);
 
        // 결과 그리기
        for (int y = 0; y < frameCurr.rows - 1; y += opticalWindowSize)
        {
            for (int x = 0; x < frameCurr.cols - 1; x += opticalWindowSize)
            {
                // get the flow from y, x position * 10 for better visibility
                const Point2f flowatxy = flowMat.at<Point2f>(y, x) ;
                // draw line at flow direction
                int tempSize = 1;
                line(frameCurr, Point(x, y), Point(cvRound(x + tempSize * flowatxy.x), cvRound(y + tempSize * flowatxy.y)), Scalar(02550), 1);
                // draw initial point
                circle(frameCurr, Point(x, y), 1, Scalar(00255), -1);
            }
        }
 
        cv::imshow("Display window", frameCurr);
        cv::waitKey(1);
 
        // 모든 반복이 끝나고 이전 프레임 업데이트
        framePrev = frameCurr;
    }
 
    return 0;
}
cs