it-swarm.com.de

Speichern eines Bildes in OpenCV

Ich bin neu bei OpenCV und versuche, ein Bild aufzunehmen und es dann in einer Datei zu speichern. Ich poste den Code unten als Referenz.

Die JPG-Datei wird gespeichert, ist jedoch schwarz.

// Capture the Image from the webcam
CvCapture *pCapturedImage = cvCreateCameraCapture(0);

// Get the frame
IplImage *pSaveImg = cvQueryFrame(pCapturedImage);

// Save the frame into a file
cvSaveImage("test.jpg". ,pSaveImg); // A JPG FILE IS BEING SAVED
                                    // OF 6KB , BUT IT IS BLACK

Alle Funktionen sind erfolgreich. Ich habe den obigen Code sowohl in XP als auch in Vista ausprobiert - das Ergebnis ist ein schwarzes Bild auf beiden. Bitte lassen Sie mich wissen, was ich vermisse.

24
Sujay Ghosh

Wenn Sie C++ verwenden, empfiehlt es sich, die C++ - Schnittstelle zu verwenden :

using namespace cv;
// Capture the Image from the webcam
VideoCapture cap(0);

// Get the frame
Mat save_img; cap >> save_img;

if(save_img.empty())
{
  std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
}
// Save the frame into a file
imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
19

In meiner Erfahrung schreibt OpenCV ein schwarzes Bild, wenn SaveImage eine Matrix mit einer von 8 Bit verschiedenen Bittiefe erhält. In der Tat ist dies irgendwie dokumentiert:

Nur 8-Bit-Einzelkanal oder 3-Kanal (mit 'BGR'-Kanalreihenfolge) Bilder können mit dieser Funktion gespeichert werden. Wenn der Format, Tiefe oder Kanalreihenfolge ist Anders, verwenden Sie cvCvtScale und cvCvtColor zum Konvertieren vor speichern, oder verwenden Sie universal cvSave zu Speichern Sie das Bild im XML- oder YAML-Format.

In Ihrem Fall können Sie zunächst untersuchen, welche Art von Bildern erfasst wird, die Capture-Eigenschaften ändern (ich denke, CV_CAP_PROP_CONVERT_RGB könnte wichtig sein) oder sie anschließend manuell konvertieren.

Dies ist ein Beispiel, wie mit OpenCV in eine 8-Bit-Darstellung konvertiert wird. cc Hier ist eine Originalmatrix vom Typ CV_32FC1, cc8u ist die skalierte Version, die tatsächlich von SaveImage geschrieben wird:

# I want to save cc here
cc8u = CreateMat(cc.rows, cc.cols, CV_8U)
ccmin,ccmax,minij,maxij = MinMaxLoc(cc)
ccscale, ccshift = 255.0/(ccmax-ccmin), -ccmin
CvtScale(cc, cc8u, ccscale, ccshift)
SaveImage("cc.png", cc8u)

(Entschuldigung, das ist Python-Code, aber es sollte leicht sein, ihn in C/C++ zu übersetzen.)

5
sastanin

Manchmal gibt der erste Aufruf von cvQueryFrame () ein leeres Bild zurück. Versuchen:

IplImage *pSaveImg = cvQueryFrame(pCapturedImage);
pSaveImg = cvQueryFrame(pCapturedImage);

Wenn dies nicht funktioniert, versuchen Sie, das Erfassungsgerät automatisch auszuwählen:

CvCapture *pCapturedImage = cvCreateCameraCapture(-1);

Oder Sie können versuchen, andere Erfassungsgeräte mit n = 1,2,3 auszuwählen.

CvCapture *pCapturedImage = cvCreateCameraCapture(n);

PS: Ich glaube auch, dass es ein Missverständnis gibt, wenn das erfasste Bild Ihren Variablennamen betrachtet. Die Variable pCapturedImage ist kein Image, sondern eine Capture. Sie können ein Bild immer aus der Aufnahme "lesen".

5
nimcap

entschuldigung, wenn das zu offensichtlich ist. Sind Sie sicher, dass die Webcam von OpenCV richtig gesehen und erkannt wird? Mit anderen Worten, erhalten Sie ein Bild, wenn Sie den erfassten Frame in ein "highGui" -Fenster umleiten? Zum Beispiel so:

 frame = cvQueryFrame( capture );
 cvNamedWindow( "myWindow", CV_WINDOW_AUTOSIZE );
 cvShowImage( "myWindow", frame );
3
david h

Ich kenne das Problem! ... Sie setzen einfach einen Punkt nach "test.jpg"!

cvSaveImage ("test.jpg"., pSaveImg);

Ich kann mich irren, aber ich finde es nicht gut!

3
lf.

Ich hatte ein ähnliches Problem mit meiner Microsoft WebCam. Ich habe in der Bilderfassungs-Toolbox in Matlab nachgesehen und festgestellt, dass die maximal unterstützte Auflösung 640 * 480 ist. 

Ich habe gerade den Code in openCV geändert und hinzugefügt

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288);

vor der cvQueryFrame-Funktion, die die nächste unterstützte Auflösung war, wurden einige Anfangsbilder übersprungen, bevor das Bild gespeichert wurde.

Ich teile meinen Arbeitscode

#include "cv.h" 
#include "highgui.h" 
#include <stdio.h> 



using namespace cv;
using namespace std;

int main() 
{
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288)


 // Get one frame
IplImage* frame;

for (int i = 0; i < 25; i++) 
{
frame = cvQueryFrame( capture );
}


printf( "Image captured \n" );  
//IplImage* RGB_frame = frame;
//cvCvtColor(frame,RGB_frame,CV_YCrCb2BGR);
//cvWaitKey(1000);
cvSaveImage("test.jpg" ,frame);
//cvSaveImage("cam.jpg" ,RGB_frame);

printf( "Image Saved \n" );

//cvWaitKey(10);

// Release the capture device Housekeeping
cvReleaseCapture( &capture );
//cvDestroyWindow( "mywindow" );
return 0;
}

Meine Vorschläge:

  1. Nicht mit maximaler Auflösung aufnehmen
  2. Überspringen Sie einige Bilder zur korrekten Kamerainitialisierung
2

Ich hatte das gleiche Problem unter Windows Vista. Ich habe diesen Code vor cvQueryFrame hinzugefügt:

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 720);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
1
jmp4281

Ich benutze folgenden Code, um Bilder aufzunehmen:

CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
if(!capture) error((char*)"No Capture");
IplImage *img=cvQueryFrame(capture);

Ich weiß, dass das sicher funktioniert

1
Yogi

SayntLewis hat recht. Wenn Sie die Kamera mit cvCaptureFromCAM aktivieren, ist der automatische Weißabgleich noch nicht eingestellt (dies ist ein langsamer Vorgang), so dass Sie bei den ersten Bildern meistens Weiß oder meist Schwarz erhalten (abhängig von der Kamera und Ihren Blitzbedingungen). Das Gleiche passiert, wenn sich der Blitz der Szene plötzlich ändert. Warten Sie nach dem Öffnen der Kamera einige Zeit, spülen Sie den Puffer aus und schon kann es losgehen.

1
Vitor

Ich schlage vor, Sie führen eine OpenCV-Sanitätsprüfung durch

Es ist eine Serie von kleinen ausführbaren Dateien, die sich im bin-Verzeichnis von opencv befinden.

Es wird geprüft, ob Ihre Kamera in Ordnung ist

1
Eric

Tut mir leid, einen alten Beitrag zu veröffentlichen, aber ich wollte jedem, der auf diesen Thread stößt, eine weitere Antwort geben.

Ich hatte das gleiche Problem. Egal was ich tat, das Bild sah aus, als wäre es komplett schwarz. Ich habe versucht, mehrere aufeinanderfolgende Aufrufe von cvQueryFrame auszuführen, und habe festgestellt, dass ich das Bild sehen konnte, wenn ich 5 oder mehr gemacht habe. Also entfernte ich die Anrufe nacheinander, um zu sehen, wo der "Bruchpunkt" war. Ich fand heraus, dass das Bild dunkler und dunkler wurde, als ich jeden Anruf entfernte. Wenn Sie nur einen einzigen Anruf tätigen, erhalten Sie ein Bild, das fast vollständig schwarz ist. Wenn ich jedoch sehr genau hinschaue, könnte ich mein Bild erkennen.

Ich habe zehnmal hintereinander versucht, meine Theorie zu testen, und tatsächlich wurde mir ein sehr helles Bild verliehen, wenn man bedenkt, dass ich in einem schwach beleuchteten Raum bin. Hoffentlich war dies das gleiche Problem, auf das Sie gestoßen sind.

Ich weiß nicht viel über das Imaging, aber es sieht so aus, als würden mehrere aufeinander folgende Aufrufe von cvQueryFrame die Belichtungsdauer der Kamera erhöhen. Dies behebt das Problem definitiv, obwohl es nicht die eleganteste Lösung zu sein scheint. Ich werde sehen, ob ich einen Parameter finden kann, der die Belichtung erhöht, oder vielleicht einen anderen Parameter, der meine Bilder aufhellt.

Viel Glück!

1
SayntLewis

Das Speichern von Videoframes und Standbildern funktionierte unter OSX nur, wenn ich einen vollständigen Pfad zu cvSaveImage angegeben habe:

cvSaveImage("/Users/nicc/image.jpg",img);
0
nicc

ich denke, die Kamera wird im ersten Bild nicht initialisiert ... Versuchen Sie, das Bild nach 10 Bildern zu speichern.

0
chronos

Aus meinen Erfahrungen sind die ersten Frames, die bei der Verwendung erfasst werden:

frame = cvQueryFrame( capture );

Neigen dazu, leer zu sein. Möglicherweise möchten Sie eine kurze Zeit (ca. 3 Sekunden) warten und dann versuchen, das Bild aufzunehmen.

0
Nexus

hoffentlich werden dadurch Bilder von Ihrer Webcam gespeichert 

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
   VideoCapture cap(0);

   Mat save_img;

   cap >> save_img;

   char Esc = 0;

   while (Esc != 27 && cap.isOpened()) {        
    bool Frame = cap.read(save_img);        
    if (!Frame || save_img.empty()) {       
        cout << "error: frame not read from webcam\n";      
        break;                                              
    }
    namedWindow("save_img", CV_WINDOW_NORMAL);  
    imshow("imgOriginal", save_img);            
    Esc = waitKey(1);
}
imwrite("test.jpg",save_img); 
}
0
Haris Hussain