稠密特征的光流opencv3.2+VS

1.光流简单概述

Optical flow or optic flow is the pattern of apparent motion of objects, surfaces, and edges in a visual scene caused by the relative motion between an observer and a scene.
Sequences of ordered images allow the estimation of motion as either instantaneous image velocities or discrete image displacements.
图像序列允许使用图片(像素)速度离散图片位置来估计光流。


2.opencv3.2可用的三种计算稠密特征的算法

  • 2.0函数简介

    1. Lucas–Kanade算法在opencv3.2(calcOpticalFlowPyrLK)得到的就是离散的位置,也就是输出像素点。
    2. Gunnar Farneback(calcOpticalFlowFarneback)得到的是速度(个人认为),flow是像素点的差值。
    3. SimpleFlow(calcOpticalFlowSF)也得到的是速度
  • 2.1函数API介绍

    Lucas–Kanade, Gunnar Farneback属于 Object TrackingVideo Analysis模块docs.opencv
    SimpleFlow属于 Optical Flow Algorithms模块docs.opencv

  • 2.2运行时间

    SimpleFlow运行大概要10sec,处理475*402*3的图片。Lucas–Kanade,Gunnar Farneback,处理475*402*1,则不到1sec。

3.代码部分C++

参考博客参考这个博客的显示的方法,这个博客是将视频逐frame标出光流。
函数API见上文模块信息。

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 
#include 
#include "opencv2/optflow.hpp"
#include "opencv2/highgui.hpp"


using namespace std;
using namespace cv;
using namespace cv::optflow;//calcOpticalFlowSF 's namespace
const size_t choice = 3 ;
// choice
// 1    2    3
// calcOpticalFlowFarneback   calcOpticalFlowSF   calcOpticalFlowPyrLK
void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, const Scalar& color) {
    // cflowmap is the pre frame with the line of Optical Flow
    // flow is a V-by-2 array, store float point
    //      store the delta of x,y
    // step is every step pixel
    for (int y = 0; y < cflowmap.rows; y += step)
        for (int x = 0; x < cflowmap.cols; x += step)
        {
            const Point2f& fxy = flow.at< Point2f>(y, x);
            line(cflowmap, Point(x, y), Point(cvRound(x + fxy.x), cvRound(y + fxy.y)),
                color);
            circle(cflowmap, Point(cvRound(x + fxy.x), cvRound(y + fxy.y)), 1, color, -1);
        }
}
void drawOptFlowMap(Mat& cflowmap, int step, const Scalar& color, vector &retPts) {
    // same as above, retPts is the next frame point
    auto it = retPts.begin();
    for (int y = 0; y < cflowmap.rows; y += step)
        for (int x = 0; x < cflowmap.cols; x += step)
        {
            line(cflowmap, Point(x, y), *it, color);
            circle(cflowmap, *it, 1, color, -1);
            it++;
        }
}

int main(int argc, char *argv[])
{
    Mat flow;//flow = aft - pre
    Mat pre = imread("1hf.png", IMREAD_COLOR);
    Mat aft = imread("2hf.png", IMREAD_COLOR);//           CV_LOAD_IMAGE_GRAYSCALE   gray ; IMREAD_COLOR   color
    if (pre.empty() || aft.empty()){
        printf("Unable to load the image");
        return 1;
    }


    Mat cflow = pre; Mat cflow2 = aft;// store the  3-channel mat of frame, cflow is for show color with line
    cvtColor(pre, pre, CV_BGR2GRAY);
    cvtColor(aft, aft, CV_BGR2GRAY);

    //below parameter of calcOpticalFlowPyrLK
    vector prePts;
    size_t step = 10; 
    vector nextPts(pre.rows * pre.cols);
    vector status;
    vector<float> err;
    TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);

    switch (choice)
    {
    case 1:// calcOpticalFlowFarneback 
        calcOpticalFlowFarneback(pre, aft, flow, 0.5, 3, 15, 3, 5, 1.2, 0); // info in the flow; note that input mat should in 1-channel
        drawOptFlowMap(flow, cflow, 10, CV_RGB(0, 255, 0));  break;
    case 2:// calcOpticalFlowFarneback 
        calcOpticalFlowSF(cflow, cflow2,
            flow,
            3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);// info in the flow; note that input mat should in 3-channel
        drawOptFlowMap(flow, cflow, 10, CV_RGB(0, 255, 0)); break;
    case 3:// calcOpticalFlowPyrLK 
        for (int y = 0; y < pre.rows; y += step)
            for (int x = 0; x < pre.cols; x += step)
            {
            prePts.push_back(Point(x, y));
            }

        // above get a point vector in step
        calcOpticalFlowPyrLK(pre, aft, prePts, nextPts, status, err, Size(31, 31), 3, termcrit, 0, 0.001);// info in the flow; note that input mat should in 1-channel
        drawOptFlowMap(cflow, step, CV_RGB(0, 255, 0), nextPts);
        break;
    default:
        break;
    }

    imshow("pre", pre);
    imshow("after", aft);
    //cflow is the pre with OpticalFlow line
    imshow("pre with OpticalFlow line", cflow);
    waitKey(0);
    return 0;
}

4.截图

  1. Lucas–Kanade
    稠密特征的光流opencv3.2+VS_第1张图片

  2. Gunnar Farneback
    稠密特征的光流opencv3.2+VS_第2张图片

  3. SimpleFlow
    稠密特征的光流opencv3.2+VS_第3张图片
    ps:上传图片,windows自带的截图工具的图片不能全部显示,用matlab重新write以后,大小变小后在上传的

你可能感兴趣的:(opencv)