0

嘿,我正在尝试整理 openCV 的光流功能,但由于某种原因,我在 Visual Studio 中遇到了异常:

Optical_flow.exe 中 0x772615de 处未处理的异常:Microsoft C++ 异常:内存位置 0x0036f334 处的 cv::Exception..

通过断点,我发现错误存在于 cvCalcOpticalFlowHS 函数中。

我正在使用 openCV 2.1

#include <cv.h>
#include <highgui.h>
using namespace cv;

int init() {
  return 0;
}

int main(int argc, char **args) {
  CvCapture* capture = cvCaptureFromFile("Video/Wildlife.wmv");
  double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);

  CvSize size;
  size.width = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  size.height = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  CvVideoWriter* writer = cvCreateVideoWriter("result.avi", 0, fps,size, 1);

  IplImage* curFrame = cvQueryFrame(capture);

  Mat u = Mat(size, CV_32FC2);
  Mat v = Mat(size, CV_32FC2);

  CvTermCriteria IterCriteria;
  IterCriteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
  IterCriteria.max_iter = 500;
  IterCriteria.epsilon = 0.01;

  while(1) {
    IplImage* nextFrame = cvQueryFrame(capture);

    if(!nextFrame) break;

    u = Mat::zeros(size, CV_32FC2);
    v = Mat::zeros(size, CV_32FC2);

    /* Do optical flow computation */
    cvCalcOpticalFlowHS(&curFrame, &nextFrame, 0, &u, &v, 0.01, IterCriteria);

    cvWriteFrame(writer, curFrame);

    curFrame = nextFrame;
  }

  cvReleaseVideoWriter(&writer);
  cvReleaseCapture(&capture);

  return 0;
}

有人以前见过这个问题或看到我犯的错误吗?

最好的祝福

雷姆科

4

1 回答 1

2

文档中,curFrame 和 nextFrame 应该是 8 位单通道。您目前只是从加载的文件中提取这些内容,而无需根据需要检查/转换它们。你能确认输入的类型是正确的吗?

此外,您还有 C++ 风格的 cv::Mat 与 C 风格的 IplImage* 的糟糕组合。我建议您升级到更新版本的 OpenCV(最近发布了 2.4),并尝试使用 C++ 或 C 风格方法中的一种或另一种。

另请注意,此光流方法被归类为已过时,建议使用calcOpticalFlowPyrLK()处理稀疏特征或使用 calcOpticalFlowFarneback()处理密集特征。

下面是一些演示 calcOpticalFlowFarneback() 的示例代码,我相信您正在努力实现这一目标。它从网络摄像头而不是文件中获取数据。

#include <opencv2/opencv.hpp>

using namespace cv;

void drawOptFlowMap(const cv::Mat& flow,
                    cv::Mat& cflowmap,
                    int step,
                    const cv::Scalar& color
                   )
{
    for(int y = 0; y < cflowmap.rows; y += step)
        for(int x = 0; x < cflowmap.cols; x += step)
        {
            const cv::Point2f& fxy = flow.at<cv::Point2f>(y, x);
            cv::line(cflowmap,
                             cv::Point(x,y),
                             cv::Point(cvRound(x+fxy.x),cvRound(y+fxy.y)),
                 color);
            cv::circle(cflowmap, cv::Point(x,y), 2, color, -1);
        }
}

int main(int argc, char **args) {

    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    Mat newFrame, newGray, prevGray;


    cap >> newFrame; // get a new frame from camera
    cvtColor(newFrame, newGray, CV_BGR2GRAY);
    prevGray = newGray.clone();

    double pyr_scale = 0.5;
    int levels = 3;
    int winsize = 5;
    int iterations = 5;
    int poly_n = 5;
    double poly_sigma = 1.1;
    int flags = 0;

    while(1) {
        cap >> newFrame;
        if(newFrame.empty()) break;
        cvtColor(newFrame, newGray, CV_BGR2GRAY);

        Mat flow = Mat(newGray.size(), CV_32FC2);

        /* Do optical flow computation */
        calcOpticalFlowFarneback(
            prevGray,
            newGray,
            flow,
            pyr_scale,
            levels,
            winsize,
            iterations,
            poly_n,
            poly_sigma,
            flags
            );

        drawOptFlowMap(flow, newFrame, 20, CV_RGB(0,255,0));

        namedWindow("Output",1);
        imshow("Output", newFrame);
        waitKey(1);

        prevGray = newGray.clone();
    }

    return 0;
}

上面的代码与 OpenCV 附带的 fback.cpp 示例代码非常相似。

于 2012-06-06T14:41:46.407 回答