macos OpenCV C++ 视频捕获似乎不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3940780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 07:17:12  来源:igfitidea点击:

OpenCV C++ Video Capture does not seem to work

c++macosopencv

提问by amatsukawa

I am using a Mac OS X 10.6 machine. I have OpenCV 2.1 x64 compiled from source using Xcode and its GCC compiler.

我使用的是 Mac OS X 10.6 机器。我使用 Xcode 及其 GCC 编译器从源代码编译了 OpenCV 2.1 x64。

I am having trouble using the C++ video reading features of OpenCV. Here is the simple test code I am using (came straight from OpenCV documentation):

我在使用 OpenCV 的 C++ 视频阅读功能时遇到问题。这是我正在使用的简单测试代码(直接来自 OpenCV 文档):

#include "cv.h"
#include "highgui.h"

using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    Mat edges;
    namedWindow("edges",1);
    for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        cvtColor(frame, edges, CV_BGR2GRAY);
        GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
        Canny(edges, edges, 0, 30, 3);
        imshow("edges", edges);
        if(waitKey(200) >= 0) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}

The program compiles fine, but when I try to run it, I see the green light on my webcam come on for a few seconds, then the program exits with the error message:

该程序编译正常,但是当我尝试运行它时,我看到网络摄像头上的绿灯亮了几秒钟,然后程序退出并显示错误消息:

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /Users/mark/Downloads/OpenCV-2.1.0/src/cxcore/cxarray.cpp, line 2476
terminate called after throwing an instance of 'cv::Exception'
  what():  /Users/mark/Downloads/OpenCV-2.1.0/src/cxcore/cxarray.cpp:2476: error: (-206) Unrecognized or unsupported array type in function cvGetMat

Under debug mode, the matrix still seems to be empty after the cap >> frame line.

在调试模式下,在 cap >> frame 行之后,矩阵似乎仍然是空的。

I get similar behavior when I try to capture from a video file or an image, so it's not the camera. What is wrong, do you think? Anything I can do to make this work?

当我尝试从视频文件或图像中捕获时,我得到了类似的行为,所以它不是相机。怎么了,你觉得呢?我可以做些什么来完成这项工作?

EDIT: I'd like to add that if I use the C features, everything works fine. But I would like to stick with C++ if I can.

编辑:我想补充一点,如果我使用 C 功能,一切正常。但如果可以的话,我想坚持使用 C++。

Thanks

谢谢

回答by GhostRichard

I've seen the same problem. When I use the C features, sometimes the similar question also comes up. From the error message of the C code, I think it happened because the camera got a NULL frame. So I think it can be solved in this way:

我见过同样的问题。当我使用C特性时,有时也会出现类似的问题。从C代码的错误信息来看,我认为这是因为相机得到了一个N​​ULL帧。所以我觉得可以这样解决:

do
{
    capture>>frame;
}while(frame.empty());

That way it works on my machine.

这样它就可以在我的机器上运行。

回答by amatsukawa

I encountered the same problem, it seems that the first two attempts to get the video wont return any signal, so if you try to use it you'll get an error, here is how I got around this, simply by adding a counter and checking the size of the video.

我遇到了同样的问题,似乎前两次尝试获取视频不会返回任何信号,所以如果你尝试使用它你会得到一个错误,这是我解决这个问题的方法,只需添加一个计数器和检查视频的大小。

int cameraNumber = 0;
if ( argc > 1 )
    cameraNumber = atoi(argv[1]);

cv::VideoCapture camera;
camera.open(cameraNumber);
if ( !camera.isOpened() ) {
    cerr << "ERROR: Could not access the camera or video!" << endl;
    exit(1);
}

//give the camera 40 frames attempt to get the camera object, 
//if it fails after X (40) attemts the app will terminatet, 
//till then it will display 'Accessing camera' note;

int CAMERA_CHECK_ITERATIONS = 40;
while (true) {

    Mat cameraFrame;
    camera >> cameraFrame;
    if ( cameraFrame.total() > 0 ) {
        Mat displayFrame( cameraFrame.size(), CV_8UC3 );
        doSomething( cameraFrame, displayFrame );
        imshow("Image", displayFrame );
    } else {
        cout << "::: Accessing camera :::" << endl;
        if ( CAMERA_CHECK_ITERATIONS > 0 ) CAMERA_CHECK_ITERATIONS--;
        if ( CAMERA_CHECK_ITERATIONS < 0 ) break;
    }


    int key = waitKey(200);
    if (key == 27) break;

}

回答by Paul R

Try simplifying the program so that you can identify the exact location of the problem, e.g. change your loop so that it looks like this:

尝试简化程序,以便您可以确定问题的确切位置,例如更改您的循环,使其看起来像这样:

for(;;)
{
    Mat frame;
    cap >> frame; // get a new frame from camera
//  cvtColor(frame, edges, CV_BGR2GRAY);
//  GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
//  Canny(edges, edges, 0, 30, 3);
//  imshow("edges", edges);
    imshow("edges", frame);
    if(waitKey(200) >= 0) break;
}

If that works OK then try adding the processing calls back in, one at a time, e.g

如果工作正常,然后尝试添加处理调用,一次一个,例如

for(;;)
{
    Mat frame;
    cap >> frame; // get a new frame from camera
    cvtColor(frame, edges, CV_BGR2GRAY);
//  GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
//  Canny(edges, edges, 0, 30, 3);
    imshow("edges", edges);
    if(waitKey(200) >= 0) break;
}

and so on...

等等...

Once you've identified the problematic line you can then focus on that and investigate further.

一旦您确定了有问题的线路,您就可以专注于该线路并进行进一步调查。

回答by manit kumar

Go to project->project properties->configuration properties->linker->input

project->project properties->configuration properties->linker->input

In the additional dependencies paste cv210.lib cvaux210.lib cxcore210.lib highgui210.lib

在附加依赖项中粘贴 cv210.lib cvaux210.lib cxcore210.lib highgui210.lib

回答by csocso

Hi I got the solution for you :)

嗨,我为您找到了解决方案:)

VideoCapture san_cap(0);
if (san_cap.isOpened()) {
    while (1) {



        san_cap.read(san);

        imshow("Video", san);

        Mat frame;
        san_cap.read(frame);      // get a new frame from camera
        cvtColor(frame, edges, CV_BGR2GRAY);

        imshow("Video2", edges);



        int key = cv::waitKey(waitKeyValue);

        if (key == 27 ) {
            break;
        }
    }
}