Opencv保存从网络摄像头捕获的图像

opencv saving image captured from webcam

本文关键字:图像 摄像头 保存 网络 Opencv      更新时间:2023-10-16

当代码试图在HD上保存图像时,我收到一个错误"SIGABRT error "。

我正在用MacBook Pro Mountain Lion使用最后的XCODE,库被很好地重新配置。

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

#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;
}

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

导致符号的代码是你发送指针到指针的地方cvSaveImage("matteo.jpg",&img);。你不应该做&img,因为img已经是一个指针。下面是正确的:

cvSaveImage("matteo.jpg",img);

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

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

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

我花了几天时间在网上寻找简单键盘输入的正确解决方案。使用cv::waitKey时总是有一些延迟。

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

下面的例子是不同论坛主题的组合。

它的工作没有任何延迟/延迟。Windows操作系统。

按"q"键捕捉并保存画面

总是有一个网络摄像头。您可以更改序列以显示捕获的帧/图像。

PS "tipka" -意思是键盘上的"键"。

问候,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 cameran";
        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 grabbedn";
            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;
}