C++ opencv 保存从网络摄像头捕获的图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16980496/
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-08-27 20:48:15  来源:igfitidea点击:

opencv saving image captured from webcam

c++xcodeimageopencvsave

提问by Matteo Ottaviani

I receive an error "SIGABRT ERROR" when the code is trying to save the image on the HD.

当代码尝试将图像保存在 HD 上时,我收到错误“SIGABRT ERROR”。

I'm working with a MacBook Pro Mountain Lion on last XCODE and the libraries are well reconfigured.

我在最后一个 XCODE 上使用 MacBook Pro Mountain Lion,并且库重新配置得很好。

Someone has a solution or some ideas?

有人有解决方案或想法吗?

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
using namespace cv;
// A Simple Camera Capture Framework
int main() {

    CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
    if ( !capture ) {
        fprintf( stderr, "ERROR: capture is NULL \n" );
        getchar();
        return -1;
                     }
    // Create a window in which the captured images will be presented
    cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
    // Show the image captured from the camera in the window and repeat
    while ( 1 ) {
        // Get one frame
        IplImage* frame = cvQueryFrame( capture );
        if ( !frame ) {
            fprintf( stderr, "ERROR: frame is null...\n" );
            getchar();
            break;
        }
        cvShowImage( "mywindow", frame );
        // Do not release the frame!

        if ( (cvWaitKey(10) & 255) == 's' ) {
            CvSize size = cvGetSize(frame);
            IplImage* img= cvCreateImage(size, IPL_DEPTH_16S, 1);
            img = frame;
             cvSaveImage("matteo.jpg",&img);
                                            }
     if ( (cvWaitKey(10) & 255) == 27 ) break;
    }
    // Release the capture device housekeeping
    cvReleaseCapture( &capture );
    cvDestroyWindow( "mywindow" );
    return 0;
}

回答by PureW

The problem is that you are mixing your pointer syntax. You are creating a new IplImagewith IplImage* img= cvCreateImage(size, IPL_DEPTH_16S, 1);but on the following line, you lose this structure as you overwrite the pointer imgwith frame.

问题是您正在混合指针语法。您正在创建一个新的IplImagewith IplImage* img= cvCreateImage(size, IPL_DEPTH_16S, 1);但在下一行,当您用 覆盖指针img时,您会丢失此结构frame

The code causing your sigabrt is where you're sending a pointer to a pointer in cvSaveImage("matteo.jpg",&img);. You should not do &imgas imgalready is a pointer. The following is correct:

导致您的 sigabrt 的代码是您发送指向 cvSaveImage("matteo.jpg",&img);. 你不应该这样做,&img因为img已经是一个指针。以下是正确的:

cvSaveImage("matteo.jpg",img);

There is actually no reason for you to create a new IplImageunless you want to do some preprocessing before saving it to file.

实际上没有理由让你创建一个新的,IplImage除非你想在将它保存到文件之前做一些预处理。

I modified your if-clause to the following which works fine on my computer:

我将您的if-clause修改为以下内容,这在我的计算机上运行良好:

if ( cvWaitKey(10) < 0 ) {
    cvSaveImage("matteo.jpg",frame);
}

回答by Andrej

I have spent several days searching the internet for the right solution with simple keyboard input. There was always some lag / delay while using cv::waitKey.

我花了几天的时间在互联网上通过简单的键盘输入搜索正确的解决方案。使用cv::waitKey.

The solution I have found is with adding Sleep(5)just after capturing the frame from webcam.

我找到的解决方案是Sleep(5)在从网络摄像头捕获帧后添加。

The below example is a combination of different forum threads.

以下示例是不同论坛主题的组合。

It works without any lag / delay. Windows OS.

它的工作没有任何滞后/延迟。视窗操作系统。

Press "q" to capture and save the frame.

按“q”捕获并保存帧。

There is a webcam feed always present. You can change the sequence to show the captured frame / image.

始终存在网络摄像头源。您可以更改顺序以显示捕获的帧/图像。

PS "tipka" - means "key" on the keyboard.

PS“tipka” - 表示键盘上的“键”。

Regards, Andrej

问候, 安德烈

#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <windows.h> // For Sleep


using namespace cv;
using namespace std;


int ct = 0; 
char tipka;
char filename[100]; // For filename
int  c = 1; // For filename

int main(int, char**)
{


    Mat frame;
    //--- INITIALIZE VIDEOCAPTURE
    VideoCapture cap;
    // open the default camera using default API
    cap.open(0);
    // OR advance usage: select any API backend
    int deviceID = 0;             // 0 = open default camera   
    int apiID = cv::CAP_ANY;      // 0 = autodetect default API
                                  // open selected camera using selected API
    cap.open(deviceID + apiID);
    // check if we succeeded
    if (!cap.isOpened()) {
        cerr << "ERROR! Unable to open camera\n";
        return -1;
    }
    //--- GRAB AND WRITE LOOP
    cout << "Start grabbing" << endl
        << "Press a to terminate" << endl;
    for (;;)
    {
        // wait for a new frame from camera and store it into 'frame'
        cap.read(frame);

        if (frame.empty()) {
            cerr << "ERROR! blank frame grabbed\n";
            break;
        }


        Sleep(5); // Sleep is mandatory - for no leg!



        // show live and wait for a key with timeout long enough to show images
        imshow("CAMERA 1", frame);  // Window name


        tipka = cv::waitKey(30);


        if (tipka == 'q') {

            sprintf_s(filename, "C:/Images/Frame_%d.jpg", c); // select your folder - filename is "Frame_n"
            cv::waitKey(10); 

            imshow("CAMERA 1", frame);
            imwrite(filename, frame);
            cout << "Frame_" << c << endl;
            c++;
        }


        if (tipka == 'a') {
            cout << "Terminating..." << endl;
            Sleep(2000);
            break;
        }


    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}