【问题标题】:Optical Flow visualization光流可视化
【发布时间】:2016-05-25 16:14:42
【问题描述】:

我正在尝试可视化calcOpticalFlowPyrLK() (OpenCv v3.0.0) 的输出。我不是想用光流画整个图像,只是方向箭头。问题是,我无法像示例中那样获得输出。每 10 帧我更新点以计算流量。函数本身

calcOpticalFlowPyrLK(CentroidFrOld, CentroidFrNow, mc, CornersCentroidNow, feat_found, feat_errors, Size(15, 15), 2, cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10, 0.03), 0);

其中CentroidFrOld 是灰度帧,CentroidFrNow 是灰度帧+1,mc 是一个vector<Point2f> 点数组,CornersCentroidNow 是一个空数组,等待被新点填充。

绘制它们时,我使用简单的代码:

for (size_t i = 0; i < CornersCentroidNow.size(); i++){             
    if (feat_errors[i] > MAX_ERR || feat_found[i] == 0) continue; 
    Point p0(ceil(mc[i].x), ceil(mc[i].y)); // are the points of interest (centroids of contours)
    Point p1(ceil(CornersCentroidNow[i].x), ceil(CornersCentroidNow[i].y));     
    arrowedLine(empty, p0, p1, Scalar(0, 0, 255), 2, 8, 0, 0.2);
}

在这段代码之后。当我每帧绘制它们时,我得到以下输出:

如果我更新用于calcOpticalFlowPyrLK() 函数的前一帧

CentroidFrOld = CentroidFrNow.clone();

我得到这个输出(这条线很短,它每 10 帧向前移动一次 - 设置为获得新点)

如果前面的点恰好也是后面的点

CentroidFrOld = CentroidFrNow.clone();
mc = CornersCentroidNow;

我得到这个输出(这条线很短,但它随着物体移动)

我无法达到的期望输出是

我需要手动加长线路吗?没有人在类似的光流实现示例中这样做

【问题讨论】:

  • 完全不相关 - 我不是想用 OF 绘制整个图像,并且帖子末尾提出的算法与我基本相同,但在 2013 年的较新版本的 Opencv 中是 2.3.1 版,与现在的完全不同
  • 您将需要显示更多代码来解决此问题 - 特别是对 calcOpticalFlowPyrLK 函数的实际调用。如果您设置正确,它应该可以在prevPts 数组和nextPts 数组中的点之间简单地画线。我建议您在调试时将 arrowedLine 减少为更简单的 line 绘制 - 那些短线可能是错误的箭头。
  • @foundry 我编辑了一个问题

标签: opencv opticalflow


【解决方案1】:
void drawOptFlowMapF(const Mat& flow, Mat& cflowmap, int step, const Scalar& color) {
    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 displayF(Mat flow)
{
    //extraxt x and y channels
    cv::Mat xy[2]; //X,Y
    cv::split(flow, xy);

    //calculate angle and magnitude
    cv::Mat magnitude, angle;
    cv::cartToPolar(xy[0], xy[1], magnitude, angle, true);

    //translate magnitude to range [0;1]
    double mag_max;
    cv::minMaxLoc(magnitude, 0, &mag_max);
    magnitude.convertTo(magnitude, -1, 1.0 / mag_max);

    //build hsv image
    cv::Mat _hsv[3], hsv;
    _hsv[0] = angle;
    _hsv[1] = cv::Mat::ones(angle.size(), CV_32F);
    _hsv[2] = magnitude;
    cv::merge(_hsv, 3, hsv);

    //convert to BGR and show
    cv::Mat bgr;//CV_32FC3 matrix
    cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);
    cv::imshow("optical flow", bgr);
    imwrite("c://resultOfOF.jpg", bgr);
    cv::waitKey(0);
}

【讨论】:

    猜你喜欢
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2020-11-08
    相关资源
    最近更新 更多