OpencV:calcOpticalFlowPYRLK函数

时间:2013-10-02 12:59:24

标签: c++ opencv opticalflow

我尝试使用calcOpticalFlowSF()函数,但是当我启动它时,程序没有响应,这里是使用它的部分代码:

frame1 = cv::imread("frame10.png");
frame2 = cv::imread("frame11.png");

if (frame1.empty()) {
   cout<<"could not read image oldori"<<endl;

  return;
}

if (frame2.empty()) {
   cout<<"could not read image ori"<<endl;
  return;
}

if (frame1.rows != frame2.rows && frame1.cols != frame2.cols) {
     cout<<"images should be of equal sizes "endl;
  return;
}

if (frame1.type() != 16 || frame2.type() != 16) {
     cout<<"images should be of equal type CV_8UC3")endl;
  return;
}

cv::Mat flow;

cv::calcOpticalFlowSF(frame1, frame2, flow, 2, 2, 4);
// calcOpticalFlowSF(frame1, frame1,  // doesn't work too.
//                    flow,
//                    3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);

我知道错误来自函数calcOpticalFlowSF,因为如果我发表评论,程序就可以运行。我使用与SimpleFlow演示中相同的图片。如果你看这里:How to get cv::calcOpticalFlowSF to work?似乎他对函数本身没有任何问题......

你知道为什么它不起作用吗?

感谢,

最好的问候。

1 个答案:

答案 0 :(得分:0)

确保图片为3通道,最好查看文档here

#if 1
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#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 = 2 ;
// 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 xxx 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<Point2f> &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<Point2f> prePts;
    size_t step = 10; 
    vector<Point2f> nextPts(pre.rows * pre.cols);
    vector<uchar> 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:// calcOpticalFlowSF
        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;
}
#endif