OpenCV错误:重置时断言失败(vc_.isOpened())

时间:2014-07-29 10:33:02

标签: c++ c opencv

我已经采用了示例代码super_resolution.cpp。用于从视频源创建高质量图像。所以这里的代码是super_resolution.cpp

#include <iostream>
#include <iomanip>
#include <string>
#include <ctype.h>

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/superres/superres.hpp"
#include "opencv2/superres/optical_flow.hpp"
#include "opencv2/opencv_modules.hpp"

#if defined(HAVE_OPENCV_OCL)
#include "opencv2/ocl/ocl.hpp"
#endif

using namespace std;
using namespace cv;
using namespace cv::superres;
bool useOclChanged;
#define MEASURE_TIME(op) \
    { \
        TickMeter tm; \
        tm.start(); \
        op; \
        tm.stop(); \
        cout << tm.getTimeSec() << " sec" << endl; \
    }

static Ptr<DenseOpticalFlowExt> createOptFlow(const string& name, bool useGpu)
{
    if (name == "farneback")
    {
        if (useGpu)
            return createOptFlow_Farneback_GPU();
        else
            return createOptFlow_Farneback();
    }
    else if (name == "simple")
        return createOptFlow_Simple();
    else if (name == "tvl1")
    {
        if (useGpu)
            return createOptFlow_DualTVL1_GPU();
        else
            return createOptFlow_DualTVL1();
    }
    else if (name == "brox")
        return createOptFlow_Brox_GPU();
    else if (name == "pyrlk")
        return createOptFlow_PyrLK_GPU();
    else
    {
        cerr << "Incorrect Optical Flow algorithm - " << name << endl;
        exit(-1);
    }
}
#if defined(HAVE_OPENCV_OCL)
static Ptr<DenseOpticalFlowExt> createOptFlow(const string& name)
{
    if (name == "farneback")
    {
        return createOptFlow_Farneback_OCL();
    }
    else if (name == "simple")
    {
        useOclChanged = true;
        std::cout<<"simple on OpenCL has not been implemented. Use CPU instead!\n";
        return createOptFlow_Simple();
    }
    else if (name == "tvl1")
        return createOptFlow_DualTVL1_OCL();
    else if (name == "brox")
    {
        std::cout<<"brox has not been implemented!\n";
        return NULL;
    }
    else if (name == "pyrlk")
        return createOptFlow_PyrLK_OCL();
    else
    {
        cerr << "Incorrect Optical Flow algorithm - " << name << endl;
    }
    return 0;
}
#endif
int main(int argc, const char* argv[])
{
    useOclChanged = false;
    CommandLineParser cmd(argc, argv,
        "{ v   | video      |           | Input video }"
        "{ o   | output     |           | Output video }"
        "{ s   | scale      | 4         | Scale factor }"
        "{ i   | iterations | 180       | Iteration count }"
        "{ t   | temporal   | 4         | Radius of the temporal search area }"
        "{ f   | flow       | farneback | Optical flow algorithm (farneback, simple, tvl1, brox, pyrlk) }"
        "{ g   | gpu        |           | CPU as default device, cuda for CUDA and ocl for OpenCL }"
        "{ h   | help       | false     | Print help message }"
    );

    if (cmd.get<bool>("help"))
    {
        cout << "This sample demonstrates Super Resolution algorithms for video sequence" << endl;
        cmd.printParams();
        return 0;
    }

    const string inputVideoName = cmd.get<string>("video");
    const string outputVideoName = cmd.get<string>("output");
    const int scale = cmd.get<int>("scale");
    const int iterations = cmd.get<int>("iterations");
    const int temporalAreaRadius = cmd.get<int>("temporal");
    const string optFlow = cmd.get<string>("flow");
    string gpuOption = cmd.get<string>("gpu");

    std::transform(gpuOption.begin(), gpuOption.end(), gpuOption.begin(), ::tolower);

    bool useCuda = false;
    bool useOcl = false;

    if(gpuOption.compare("ocl") == 0)
        useOcl = true;
    else if(gpuOption.compare("cuda") == 0)
        useCuda = true;

#ifndef HAVE_OPENCV_OCL
    if(useOcl)
    {
        {
            cout<<"OPENCL is not compiled\n";
            return 0;
        }
    }
#endif
#if defined(HAVE_OPENCV_OCL)
    if(useCuda)
    {
        CV_Assert(!useOcl);
    }
#endif
    Ptr<SuperResolution> superRes;


#if defined(HAVE_OPENCV_OCL)
    if(useOcl)
    {
        Ptr<DenseOpticalFlowExt> of = createOptFlow(optFlow);
        if (of.empty())
            exit(-1);
        if(useOclChanged)
        {
            superRes = createSuperResolution_BTVL1();
            useOcl = !useOcl;
        }else
            superRes = createSuperResolution_BTVL1_OCL();
        superRes->set("opticalFlow", of);
    }
    else
#endif
    {
        if (useCuda)
            superRes = createSuperResolution_BTVL1_GPU();
        else
            superRes = createSuperResolution_BTVL1();

        Ptr<DenseOpticalFlowExt> of = createOptFlow(optFlow, useCuda);

        if (of.empty())
            exit(-1);
        superRes->set("opticalFlow", of);
    }

    superRes->set("scale", scale);
    superRes->set("iterations", iterations);
    superRes->set("temporalAreaRadius", temporalAreaRadius);

    Ptr<FrameSource> frameSource;
    if (useCuda)
    {
        // Try to use gpu Video Decoding
        try
        {
            frameSource = createFrameSource_Video_GPU(inputVideoName);
            Mat frame;
            frameSource->nextFrame(frame);
        }
        catch (const cv::Exception&)
        {
            frameSource.release();
        }
    }
    if (frameSource.empty())
        frameSource = createFrameSource_Video(inputVideoName);

    // skip first frame, it is usually corrupted
    {
        Mat frame;
        frameSource->nextFrame(frame);
        cout << "Input           : " << inputVideoName << " " << frame.size() << endl;
        cout << "Scale factor    : " << scale << endl;
        cout << "Iterations      : " << iterations << endl;
        cout << "Temporal radius : " << temporalAreaRadius << endl;
        cout << "Optical Flow    : " << optFlow << endl;
#if defined(HAVE_OPENCV_OCL)
        cout << "Mode            : " << (useCuda ? "CUDA" : useOcl? "OpenCL" : "CPU") << endl;
#else
        cout << "Mode            : " << (useCuda ? "CUDA" : "CPU") << endl;
#endif
    }

    superRes->setInput(frameSource);

    VideoWriter writer;

    for (int i = 0;; ++i)
    {
        cout << '[' << setw(3) << i << "] : ";
        Mat result;

#if defined(HAVE_OPENCV_OCL)
        cv::ocl::oclMat result_;

        if(useOcl)
        {
            MEASURE_TIME(
            {
                superRes->nextFrame(result_);
                ocl::finish();
            });
        }
        else
#endif
        {
            MEASURE_TIME(superRes->nextFrame(result));
        }

#ifdef HAVE_OPENCV_OCL
        if(useOcl)
        {
            if(!result_.empty())
            {
                result_.download(result);
            }
        }
#endif
        if (result.empty())
            break;

        imshow("Super Resolution", result);

        if (waitKey(1000) > 0)
            break;

        if (!outputVideoName.empty())
        {
            if (!writer.isOpened())
                writer.open(outputVideoName, CV_FOURCC('X', 'V', 'I', 'D'), 25.0, result.size());
            writer << result;
        }
    }

    return 0;
}

我已编译过它们。但是在终端运行时。

./SuperResolution -v /home/raiym/Downloads/bird.avi 

程序给出错误:

OpenCV Error: Assertion failed (vc_.isOpened()) in reset, file /home/raiym/Downloads/opencv-2.4.9/modules/superres/src/frame_source.cpp, line 161
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/raiym/Downloads/opencv-2.4.9/modules/superres/src/frame_source.cpp:161: error: (-215) vc_.isOpened() in function reset

Aborted (core dumped)

frame_source.cpp是:

/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"

using namespace std;
using namespace cv;
using namespace cv::gpu;
using namespace cv::superres;
using namespace cv::superres::detail;

cv::superres::FrameSource::~FrameSource()
{
}

//////////////////////////////////////////////////////
// EmptyFrameSource

namespace
{
    class EmptyFrameSource : public FrameSource
    {
    public:
        void nextFrame(OutputArray frame);
        void reset();
    };

    void EmptyFrameSource::nextFrame(OutputArray frame)
    {
        frame.release();
    }

    void EmptyFrameSource::reset()
    {
    }
}

Ptr<FrameSource> cv::superres::createFrameSource_Empty()
{
    return new EmptyFrameSource;
}

//////////////////////////////////////////////////////
// VideoFrameSource & CameraFrameSource

#ifndef HAVE_OPENCV_HIGHGUI

Ptr<FrameSource> cv::superres::createFrameSource_Video(const string& fileName)
{
    (void) fileName;
    CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
    return Ptr<FrameSource>();
}

Ptr<FrameSource> cv::superres::createFrameSource_Camera(int deviceId)
{
    (void) deviceId;
    CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
    return Ptr<FrameSource>();
}

#else // HAVE_OPENCV_HIGHGUI

namespace
{
    class CaptureFrameSource : public FrameSource
    {
    public:
        void nextFrame(OutputArray frame);

    protected:
        VideoCapture vc_;

    private:
        Mat frame_;
    };

    void CaptureFrameSource::nextFrame(OutputArray _frame)
    {
        if (_frame.kind() == _InputArray::MAT)
        {
            vc_ >> _frame.getMatRef();
        }
        else if(_frame.kind() == _InputArray::GPU_MAT)
        {
            vc_ >> frame_;
            arrCopy(frame_, _frame);
        }
        else if(_frame.kind() == _InputArray::OCL_MAT)
        {
            vc_ >> frame_;
            if(!frame_.empty())
            {
                arrCopy(frame_, _frame);
            }
        }
        else
        {
            //should never get here
        }
    }

    class VideoFrameSource : public CaptureFrameSource
    {
    public:
        VideoFrameSource(const string& fileName);

        void reset();

    private:
        string fileName_;
    };

    VideoFrameSource::VideoFrameSource(const string& fileName) : fileName_(fileName)
    {
        reset();
    }

    void VideoFrameSource::reset()
    {
        vc_.release();
        vc_.open(fileName_);
        CV_Assert( vc_.isOpened() );
    }

    class CameraFrameSource : public CaptureFrameSource
    {
    public:
        CameraFrameSource(int deviceId);

        void reset();

    private:
        int deviceId_;
    };

    CameraFrameSource::CameraFrameSource(int deviceId) : deviceId_(deviceId)
    {
        reset();
    }

    void CameraFrameSource::reset()
    {
        vc_.release();
        vc_.open(deviceId_);
        CV_Assert( vc_.isOpened() );
    }
}

Ptr<FrameSource> cv::superres::createFrameSource_Video(const string& fileName)
{
    return new VideoFrameSource(fileName);
}

Ptr<FrameSource> cv::superres::createFrameSource_Camera(int deviceId)
{
    return new CameraFrameSource(deviceId);
}

#endif // HAVE_OPENCV_HIGHGUI

//////////////////////////////////////////////////////
// VideoFrameSource_GPU

#if !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT)

Ptr<FrameSource> cv::superres::createFrameSource_Video_GPU(const string& fileName)
{
    (void) fileName;
    CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
    return Ptr<FrameSource>();
}

#else // HAVE_OPENCV_GPU

namespace
{
    class VideoFrameSource_GPU : public FrameSource
    {
    public:
        VideoFrameSource_GPU(const string& fileName);

        void nextFrame(OutputArray frame);
        void reset();

    private:
        string fileName_;
        VideoReader_GPU reader_;
        GpuMat frame_;
    };

    VideoFrameSource_GPU::VideoFrameSource_GPU(const string& fileName) : fileName_(fileName)
    {
        reset();
    }

    void VideoFrameSource_GPU::nextFrame(OutputArray _frame)
    {
        if (_frame.kind() == _InputArray::GPU_MAT)
        {
            bool res = reader_.read(_frame.getGpuMatRef());
            if (!res)
                _frame.release();
        }
        else
        {
            bool res = reader_.read(frame_);
            if (!res)
                _frame.release();
            else
                arrCopy(frame_, _frame);
        }
    }

    void VideoFrameSource_GPU::reset()
    {
        reader_.close();
        reader_.open(fileName_);
        CV_Assert( reader_.isOpened() );
    }
}

Ptr<FrameSource> cv::superres::createFrameSource_Video_GPU(const string& fileName)
{
    return new VideoFrameSource(fileName);
}

#endif // HAVE_OPENCV_GPU

此代码是frame_source.cpp(第161行)中发现错误的地方:

void VideoFrameSource::reset()
{
    vc_.release();
    vc_.open(fileName_);
    CV_Assert( vc_.isOpened() );
}

有人能帮助我吗?

1 个答案:

答案 0 :(得分:2)

可能是您遇到了编解码器问题。断言检查源是否可以打开。当它失败时,它会给你你描述的错误。它可能会失败,因为源不存在或者因为它无法打开文件格式或读取编解码器。您还可以尝试其他.avi视频,看看是否有效。如果确实如此,您可以确定它是编解码器问题。

有关检查编解码器的一些方法,请参阅此SO帖子:Why can't I open avi video in openCV?

您可以通过打开Linux终端并输入:

来检查文件的编解码器

ffmpeg -i video.3gp

然后您可以看到安装了哪些库以及视频编码是什么。例如:

Stream: #0.0: Video mjpeg (MJPG / 0x47504A4D), yuvj422p, 1280x720, 30.02 tbr

显示两个FFMPEG都正常工作(否则您会收到错误消息)并且该文件是MJPG编码的。

另一个选择是你的openCV安装没有用FFMPEG构建。您可以通过运行cmake来检查它,并检查是否检测到cmake。它应该看起来像:

-- FFMPEG: YES

显然有时您的FFMPEG可以安装和检测,但配置不正确。这篇SO帖子显示了一个解决方案:VideoCapture is not working in OpenCV 2.4.2