2013-05-04 16 views
9

Sto provando a scrivere un programma C++/Qt per linux, dove scattare una foto di fermo immagine da una webcam, apportare alcune trasformazioni a una foto (ritaglio, ridimensionamento, ecc.) e salvarlo in un file jpeg.Come acquisire immagini fisse dalla webcam su linux

Ma ho riscontrato alcuni problemi. Il problema principale è che il driver linux standard UVC (usb video device class) attualmente non supporta l'acquisizione diretta di immagini fisse: http://www.ideasonboard.org/uvc/.

Quindi, ci sono due modi possibili per catturare immagini fisse. Puoi scattare una foto dal flusso video dalla fotocamera oppure puoi scattare una foto separata, come una fotocamera digitale portatile. Il secondo modo non è supportato nel driver uvc linux, quindi il primo metodo è l'unico modo. Ma il problema è che, se vuoi prendere un frame dal flusso video, la dimensione della foto non può essere più grande della dimensione del video nella finestra di anteprima del video. Quindi, se voglio prendere una foto da 2 megapixel, devo iniziare il videostream con la dimensione 1600x1200, che non è così comodo (Almeno, in Qt la dimensione del videostream dipende dalle dimensioni della finestra di videopreview).

So che esiste un video per l'API di linux 2, che potrebbe essere utile in questa attività, ma non so come usarlo. Attualmente sto imparando gstreamer, ma ora non riesco a capire come fare ciò di cui ho bisogno usando questi strumenti.

Quindi, apprezzerò qualsiasi aiuto. Penso che non sia un problema difficile per le persone che conoscono Linux, GStreamer, API v4l2 e altre cose specifiche di Linux.

A proposito, il programma verrà utilizzato solo con la videocamera Web Logitech C270 HD.

Per favore, aiutatemi. Non so quale API o framework può aiutarmi a farlo. Potresti sapere.

+0

Non so se questo potrebbe essere d'aiuto, motivo per cui lo sto mettendo come commento. C'è un programma oss chiamato "formaggio" che prende le immagini e le registrazioni video. Dai un'occhiata qui: https://apps.ubuntu.com/cat/applications/precise/cheese/ ... Forse dare un'occhiata al codice potrebbe aiutarti. – Joe

+0

Possibile duplicato di [libreria webcam per C su Linux?] (Http: // stackoverflow.it/questions/278112/webcam-library-for-c-on-linux) –

risposta

1
**Download And Install 'mplayer'** 
mplayer -vo png -frames 1 tv:// 
+0

Come noto, mplayer usa gstreamer per riprodurre file multimediali ... potresti conoscere qualche codice gstreamer per fare la stessa cosa? – locomotion

+0

> mplayer -vo png -frames 1 tv: // non funziona. L'immagine verde normale viene visualizzata nella home directory. – locomotion

+0

No, mplayer non usa gstreamer per riprodurre file multimediali, ma entrambi usano le stesse librerie di base come x264 e ffmpeg. –

0

Che dire di questo programma?

#include<opencv2/opencv.hpp> 
using namespace cv; 
int main() 
{ 
    VideoCapture webcam; 
    webcam.open(0); 
    Mat frame; 
    char key; 

    while(true) 
    { 
     webcam >> frame; 
     imshow("My Webcam",frame); 
     key = waitKey(10); 

     if(key=='s') 
     break; 
    } 
    imwrite("webcam_capture.jpg", frame); 
    webcam.release(); 
    return 0; 
} 

Questo catturerà un'immagine della dimensione massima consentita dalla webcam. Ora puoi aggiungere effetti o ridimensionare l'immagine catturata con Qt. E OpenCV è molto molto facile da integrare con Qt, :)

+0

non funziona. Ho rimosso parte del tuo codice e ora è sufficiente scattare una foto e salvarla su file senza essere visualizzata in una finestra. e l'uscita è HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP – locomotion

+0

bene, quindi è necessario impostare alcune opzioni per aprire la funzione, come la dimensione di cattura, la cornice ecc. In alternativa è possibile utilizzare GLWidget per mostrare il video della webcam all'interno di una finestra Qt. –

3

Sfortunatamente le chiamate C4V2 in opencv non hanno funzionato per l'acquisizione di immagini fisse con qualsiasi fotocamera che ho provato senza usare il driver UVC.

Per eseguire il debug del problema con cui sto giocando, provare a realizzare questo con il codice c che chiama c4v2 direttamente.

Ho giocato con il codice di esempio trovato here. Utilizza il metodo di estrazione dei frame dal flusso video.

È possibile compilare con:

gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename 

Ho sperimentato con 3 telecamere Logitech. Il meglio del lotto sembra essere il Logitech C910. Ma ha anche problemi significativi.

Ecco i problemi che ho riscontrato cercando di eseguire lo stesso compito con questo codice.

Funziona praticamente ogni volta con larghezza e altezza impostate su 1920x1080.

Quando interrogo altre possibilità direttamente dalla linea di comando usando per esempio:

v4l2-ctl --list-formats-ext 

e provo alcune delle altre dimensioni "disponibili" piccoli si blocca nel selezionare attesa per la macchina per sbloccare il tampone .

anche quando provo a impostare altre dimensioni direttamente dalla riga di comando utilizzando ad esempio:

v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV 

Poi controllare con

v4l2-ctl -V 

Trovo che restituisce il formato pixel corretto ma molto spesso non la dimensione corretta.

Apparentemente questa telecamera che è elencata su UVC site come UVC e quindi compatibile con v4l2 non è all'altezza. Sospetto che sia altrettanto brutto per altre fotocamere. Anche gli altri due che ho provato erano elencati come compatibili sul sito ma avevano problemi peggiori.

Ho eseguito altri test sul LogitechC910 dopo averlo postato. Ho pensato di pubblicare i risultati nel caso in cui aiuti qualcun altro.

Ho scritto uno script per testare v4l2 codice grabber di cui sopra su tutti i formati di fotocamera sostiene che sostiene quando viene interrogato con v4l2 ecco i risultati:

640x480 => Hangs on clearing buffer 
160x120 => Works 
176x144 => Works 
320x176 => Works 
320x240 => Works 
432x240 => Works 
352x288 => Works 
544x288 => Works 
640x360 => Works 
752x416 => Hangs on clearing buffer 
800x448 => Hangs on clearing buffer 
864x480 => Works 
960x544 => Works 
1024x576 => Works 
800x600 => Works 
1184x656 => Works 
960x720 => Works 
1280x720 => Works 
1392x768 => Works 
1504x832 => Works 
1600x896 => Works 
1280x960 => Works 
1712x960 => Works 
1792x1008 => Works 
1920x1080 => Works 
1600x1200 => Works 
2048x1536 => Works 
2592x1944 => Hangs on clearing buffer. 

Si scopre che l'impostazione di default 640x480 non funziona e questo è ciò che ha intrappolato me e molti altri che hanno pubblicato su bacheche.

Poiché sta catturando un fotogramma video, il primo fotogramma che cattura all'avvio potrebbe avere un'esposizione errata (spesso nero o vicino ad esso). Credo che questo sia dovuto al fatto che, essendo utilizzato come videocamera, regola l'esposizione mentre va e non si preoccupa dei primi fotogrammi. Credo che questo abbia intrappolato me e altri che hanno visto il primo fotogramma come nero o quasi nero e hanno pensato che fosse una specie di errore. Telai successivi hanno l'esposizione corretta

Si scopre che opencv con wrapper python funziona bene con questa fotocamera se si evitano le mine terrestri elencate sopra e si ignorano tutti i messaggi di errore. I messaggi di errore sono dovuti al fatto che la videocamera accetta i comandi v4l2 ma non risponde correttamente. Quindi, se si imposta la larghezza in realtà viene impostata correttamente ma risponde con una larghezza errata.

per l'esecuzione in OpenCV con involucri di pitone che si possono fare le seguenti operazioni:

import cv2 
import numpy 

cap = cv2.VideoCapture(0) #ignore the errors 
cap.set(3, 960)  #Set the width important because the default will timeout 
         #ignore the error or false response 
cap.set(4, 544)  #Set the height ignore the errors 
r, frame = cap.read() 
cv2.imwrite("test.jpg", frame) 
1
mplayer -vo png -frames 1 tv:// 

potrebbe dare un output su schermo verde, come la fotocamera non è ancora pronto.

mplayer -vo png -frames 2 tv:// 

È possibile provare ad aumentare il numero di frame e scegliere un numero da cui la fotocamera fornisce immagini corrette.

Problemi correlati