2010-05-19 15 views
6

generalmente si visualizzano webcam o movimento video in finestre OpenCV con:OpenCV: come visualizzare l'acquisizione della webcam in un'applicazione Windows Form?

 CvCapture* capture = cvCreateCameraCapture(0); 
      cvNamedWindow("title", CV_WINDOW_AUTOSIZE); 
    cvMoveWindow("title",x,y); 
    while(1) 
    { 
    frame = cvQueryFrame(capture); 
    if(!frame) 
    { 
    break; 
    } 
    cvShowImage("title", frame); 
    char c = cvWaitKey(33); 
    if(c == 27) 
    { 
    break; 
    } 
    } 

ho cercato di utilizzare pictureBox che è riuscito a visualizzare l'immagine in finestre formare con questo:

pictureBox1->Image = gcnew System::Drawing::Bitmap(image->width,image->height,image->widthStep,System::Drawing::Imaging::PixelFormat::Undefined, (System::IntPtr) image-> imageData); 

ma quando im cercando di visualizzare l'immagine catturata dal video funziona solito, ecco la fonte:

  CvCapture* capture = cvCreateCameraCapture(0); 
    while(1) 
    { 
    frame = cvQueryFrame(capture); 
    if(!frame) 
    { 
    break; 
    } 
    pictureBox1->Image = gcnew System::Drawing::Bitmap(frame->width,frame->height,frame->widthStep,System::Drawing::Imaging::PixelFormat::Undefined, (System::IntPtr) frame-> imageData); 
    char c = cvWaitKey(33); 
    if(c == 27) 
    { 
    break; 
    } 
    } 

c'è comunque di utilizzare Windows Form invece finestra OpenCV s per mostrare video o webcam?

o c'è qualcosa di sbagliato nel mio codice? grazie per il vostro aiuto .. :)

risposta

1

consiglio: utilizzare VideoInput invece di CvCapture (CvCapture è una parte di highgui una libreria che non è inteso per l'uso in produzione, ma solo per il test rapido). Sì, la homepage di VideoInput sembra strana, ma la libreria è molto utile.

ecco un breve esempio per l'utilizzo di VideoInput (estratto dal file VideoInput.h):

//create a videoInput object 
videoInput VI; 

//Prints out a list of available devices and returns num of devices found 
int numDevices = VI.listDevices(); 

int device1 = 0; //this could be any deviceID that shows up in listDevices 
int device2 = 1; //this could be any deviceID that shows up in listDevices 

//if you want to capture at a different frame rate (default is 30) 
//specify it here, you are not guaranteed to get this fps though. 
//VI.setIdealFramerate(dev, 60);  

//setup the first device - there are a number of options: 

VI.setupDevice(device1);       //setup the first device with the default settings 
//VI.setupDevice(device1, VI_COMPOSITE);    //or setup device with specific connection type 
//VI.setupDevice(device1, 320, 240);     //or setup device with specified video size 
//VI.setupDevice(device1, 320, 240, VI_COMPOSITE); //or setup device with video size and connection type 

//VI.setFormat(device1, VI_NTSC_M);     //if your card doesn't remember what format it should be 
                //call this with the appropriate format listed above 
                //NOTE: must be called after setupDevice! 

//optionally setup a second (or third, fourth ...) device - same options as above 
VI.setupDevice(device2);       

//As requested width and height can not always be accomodated 
//make sure to check the size once the device is setup 

int width = VI.getWidth(device1); 
int height = VI.getHeight(device1); 
int size = VI.getSize(device1); 

unsigned char * yourBuffer1 = new unsigned char[size]; 
unsigned char * yourBuffer2 = new unsigned char[size]; 

//to get the data from the device first check if the data is new 
if(VI.isFrameNew(device1)){ 
    VI.getPixels(device1, yourBuffer1, false, false); //fills pixels as a BGR (for openCV) unsigned char array - no flipping 
    VI.getPixels(device1, yourBuffer2, true, true);  //fills pixels as a RGB (for openGL) unsigned char array - flipping! 
} 

//same applies to device2 etc 

//to get a settings dialog for the device 
VI.showSettingsWindow(device1); 


//Shut down devices properly 
VI.stopDevice(device1); 
VI.stopDevice(device2); 
+0

L'uscita video simultanea e l'elaborazione dell'immagine di sfondo delle stesse informazioni influisce in modo significativo sulle prestazioni? –

+0

Non sono sicuro di aver capito la tua domanda correttamente. Per quanto mi ricordo, l'immagine catturata non viene copiata direttamente nel buffer dello schermo. Tuttavia VideoInput è basato su DirectShow, che implica due cose: è molto veloce, ed è un PITA da compilare (è necessario ottenere l'implementazione DirectShow corrispondente da Microsoft). L'ultima volta che ho provato, ho dovuto ottenere una versione precedente della libreria DirectShow. Tuttavia, nel download viene fornita una versione compilata della libreria VideoInput. –

1

Il formato dei pixel deve essere noto quando si cattura immagini da una fotocamera, è molto probabile che il formato di BGR a 24 bit. System::Drawing::Imaging::PixelFormat::Format24bppRgb sarà il formato più vicino ma potresti ottenere uno strano display a colori. Una riorganizzazione del componente colore risolverà questo problema.

In realtà, ci sono NET OpenCV versione disponibile qui: http://code.google.com/p/opencvdotnet/ e qui: http://www.emgu.com/wiki/index.php/Main_Page

Speranza che aiuta!

1

Non so se ti piacerà, ma potresti usare OpenGL per mostrare il flusso video in altre finestre rispetto a quelle fornite con opencv. (Cattura la cornice e visualizzala su un rettangolo .. o qualcosa del genere ..)

0

Un'altra opzione da prendere in considerazione è l'uso di emgu. Questo è un wrapper .Net per opencv con i controll di winforms.

Problemi correlati