2012-08-06 71 views
10

Estaba experimentando un poco con fread y fwrite en C. Así que escribí este pequeño programa en C para obtener datos de una cámara web y volcarla en un archivo. La siguiente es la fuente:Lectura de salida de una cámara web USB en Linux

#include <stdio.h> 
#include <stdlib.h> 
#define SIZE 307200 // number of pixels (640x480 for my webcam) 
int main() { 
    FILE *camera, *grab; 
    camera=fopen("/dev/video0", "rb"); 
    grab=fopen("grab.raw", "wb"); 
    float data[SIZE]; 
    fread(data, sizeof(data[0]), SIZE, camera); 
    fwrite(data, sizeof(data[0]), SIZE, grab); 
    fclose(camera); 
    fclose(grab); 
    return 0; 
} 

El programa funciona cuando se compila (gcc -o snap camera.c). Lo que me sorprendió fue que el archivo de salida no era un volcado de datos en bruto, sino un archivo JPEG. La salida del comando file en Linux en el archivo de salida de los programas mostró que se trataba de una imagen JPEG: JFIF Standard 1.01. El archivo era visible en un visor de imágenes, aunque un poco saturado.

¿Cómo o por qué sucede esto? No utilicé ninguna biblioteca de codificación JPEG en la fuente o el programa. ¿La cámara emite JPEG de forma nativa? La cámara web es una Sony Playstation 2 EyeToy que fue fabricada por Logitech. El sistema es Debian Linux.

+1

bien podría ser que los archivos JPEG salidas de cámara. – doron

Respuesta

7

El Sony EyeToy tiene un sensor OV7648 con el popular puente OV519. El OV519 genera fotogramas en formato JPEG, y si recuerdo correctamente de mis propias cámaras, ese es el único formato que admite.

Cámaras como esta requieren compatibilidad con aplicaciones o un controlador especial que descomprimirá los marcos antes de la entrega al espacio de usuario. Aparentemente, en su caso, el controlador entrega los marcos JPEG en su forma original, por lo que está obteniendo datos JPEG en la salida.

Por cierto, que realmente debería echar un vistazo a la Video4Linux2 API de la manera apropiada para acceder a dispositivos de vídeo en Linux - un simple open()/read()/close() generalmente no es suficiente ...