도와주세요!!
글 수 15,339
2007.11.20 18:52:59 (*.31.150.144)
6658
안녕하세요 V4L를 가지고 머좀 만들어볼려는 학생입니다.
이렇게 처음으로 질문을 드리네요 ^^
EZ-X5보드와 로직텍 퀵캠 4000에 장비를 가지고
V4L로 "file.bmp"란 파일을 생성하는 프로그램을 만들었습니다.
그런데 사진이 이상하게 깨져서 나오더군요.(아마설정을 잘못해준거 같은데...)
QT를 이용한 camstream을 이용하면 영상이 깨끗하게 나옵니다.
밑에는 재가 코딩한 프로그램입니다.
또 한가지만 더 물어볼께요
프레임버퍼로 그림을 출력시키는 방법을 잘모르겠습니다.
인터넷에서 많은 자료를 찻았는데
저의 머리가 돌머리인지 이해가 잘 안되더라고요 -_ㅜ
도와주세요ㅡㅜ
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <getopt.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/videodev.h>
#define SERVO_LEFT 1
#define SERVO_RIGHT 2
#define SERVO_MIDDLE 3
#define Dev_Name "dev/Cam_Stream_Module"
static int Timer = 0;
static int Servo = 0;
static int frames2 = 0;
static int frame_number = 0;
//extern int frame_number2;
struct picbuf
{
char *data;
};
typedef struct camera
{
int dev;
int x;
int y;
int dither;
int contrast, brightness, colour, hug;
struct video_capability vid_cap;
struct video_picture vid_pic;
struct video_channel vid_chnl;
struct video_window vid_win;
struct video_mbuf vid_buf;
struct video_mmap vid_map[2];
char video_dev[256];
char *pic;
char *image;
char *ppmfile;
struct picbuf pic_buf[2];
}cam;
struct bgrpixel
{
unsigned char b, g , r;
};
typedef struct lcd_frmae_buffer
{
int dev;
char lcd_dev[256];
struct fb_var_screeninfo fbvar;
struct bgrpixel pixel;
int x;
int y;
int bp;
int byte_total;
unsigned short *vbase;
}lcd;
int video_open(lcd *lcd)
{
if(ioctl(lcd->dev, FBIOGET_VSCREENINFO, &lcd->fbvar) < 0)
{
printf("fbvar open failn");
return 0;
}
if(lcd -> fbvar.bits_per_pixel != 16)
{
printf("bpp is not 16n");
exit(0);
}
lcd -> x = lcd -> fbvar.xres;
lcd -> y = lcd -> fbvar.yres;
lcd -> bp = lcd -> fbvar.bits_per_pixel;
lcd -> byte_total = (lcd->x * lcd->y * (lcd->bp/8));
lcd -> vbase = (unsigned short *) mmap(0, lcd->byte_total, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->dev, 0);
if((unsigned)lcd->vbase == (unsigned)-1)
{
printf("Lcd MMAP FAILn");
exit(0);
}
return 0;
}
static unsigned short makepixel(lcd *lcd, unsigned char r, unsigned char g, unsigned char b)
{
unsigned short rnew, gnew, bnew;
rnew = r >> (8 - (lcd->fbvar.red.length));
gnew = g >> (8 - (lcd->fbvar.green.length));
bnew = b >> (8 - (lcd->fbvar.blue.length));
return (unsigned short) ((rnew << lcd->fbvar.red.offset)
| (gnew << lcd->fbvar.green.offset)
| (bnew << lcd->fbvar.blue.offset));
}
void screen(lcd *lcd,cam *cam)
{
int x, y;
for(x = 0; x <= cam->x ; x ++)
{
for(y = 0; y <= cam->y ; y++)
{
lcd->pixel.r = 10;
lcd->pixel.g = 10;
lcd->pixel.b = 10;
*(lcd->vbase + x *lcd->fbvar.xres+y) = makepixel(&lcd->fbvar, lcd->pixel.r, lcd->pixel.g, lcd->pixel.b);
}
}
}
void draw(int x, int y, unsigned short color,lcd *lcd)
{
unsigned short *ptr;
ptr = lcd->vbase + ((y * lcd->x) + x);
*ptr = color;
}
int ppm_save(cam *cam)
{
FILE *fp;
int fc;
printf("Capturing...n");
fp = fopen(cam->ppmfile, "w");
if(fp == NULL)
{
printf("OPEN FAIL FOR WIRTING...n");
return -1;
}
fprintf(fp, "P6n%d %dn%dn",cam->x,cam->y,255);
fc = fwrite(cam->pic_buf[frame_number].data, 1, cam->vid_buf.size, fp);
fclose(fp);
return 0;
}
void camera_cap(cam *cam)
{
if(ioctl(cam->dev, VIDIOCGCAP, &cam->vid_cap) == -1)
{
printf("Camera Capabilities OPEN FAIL, EXIT...n");
exit(0);
}
if(cam -> vid_cap.maxwidth < cam -> x)
{
cam->x = cam->vid_cap.maxwidth;
}
if(cam -> vid_cap.minwidth > cam -> x)
{
cam->x = cam->vid_cap.minwidth;
}
if(cam -> vid_cap.maxheight < cam -> y)
{
cam->y = cam->vid_cap.maxheight;
}
if(cam -> vid_cap.minheight > cam -> y)
{
cam->y = cam->vid_cap.minheight;
}
}
void set_pic_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
{
printf("VIDEO PICTURE OPEN FILE EXIT.....n");
exit(0);
}
}
void get_pic_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
{
printf("VIDEO GET PICTURE OPEN FAIL EXIT.....n");
exit(0);
}
}
void get_win_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
{
printf("VIDEO GET WINDOW OPEN FAIL EXIT.....n");
exit(0);
}
}
void set_win_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
{
printf("VIDEO SET WINDOW OPEN FAIL EXIT.....n");
exit(0);
}
}
void set_buffer(cam *cam)
{
if(ioctl(cam->dev, VIDIOCGMBUF, &cam->vid_buf) == -1)
{
printf("BUFFER SET FAIL EXIT.....n");
exit(0);
}
}
void dev_open(void)
{
Servo = open(Dev_Name, O_RDWR | O_NOCTTY);
Timer = open("dev_timer", O_RDWR | O_NOCTTY);
if(Servo < 0)
{
printf("%s OPEN FAIL.....n",Dev_Name);
exit(0);
}
printf("Servo OPEN SUCCESS.....n");
if(Timer < 0)
{
printf("Timer OPEN Fail [dev/timer]nn");
exit(1);
}
printf("Timer OPENn");
}
void init_cam(cam *cam)
{
cam->pic = mmap(0,cam->vid_buf.size,PROT_READ | PROT_WRITE,MAP_SHARED, cam->dev,0);
cam->vid_map[0].height = cam->y;
cam->vid_map[0].width = cam->x;
cam->vid_map[0].frame = 0;
cam->vid_map[0].format = cam->vid_pic.palette;
cam->pic_buf[0].data = cam->pic;
cam->vid_map[1].height = cam->y;
cam->vid_map[1].width = cam->x;
cam->vid_map[1].frame = 1;
cam->vid_map[1].format = cam->vid_pic.palette;
cam->pic_buf[1].data = cam->pic + cam->vid_buf.offsets[1];
if((unsigned char*) -1 == (unsigned char *) cam->pic)
{
printf("MMAP FAILEDn");
exit(-1);
}
if(ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map) == -1)
{
printf("100n");
}
if(ioctl(cam->dev, VIDIOCSYNC, cam->vid_map) == -1)
{
printf("1000n");
}
}
void frameloop(cam *cam)
{
int ctl = 0;
ctl = ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map + frame_number);
if(ctl == -1)
{
printf("CAPTURE FROM DEVICE OPEN FAIL.....n");
exit(-1);
}
frames2++;
ctl = ioctl(cam->dev, VIDIOCSYNC, cam->vid_map + frame_number);
if(ctl == -1)
{
printf("VIDIOCSYNC FAILED.....n");
munmap(cam->vid_map, cam->vid_buf.size);
exit(-1);
}
}
int main(int argc,char **argv)
{
//int one = 1;
//int done = 0;
cam cam;
lcd lcd;
cam.x = 320;
cam.y = 240;
strcpy(lcd.lcd_dev, "/dev/fb0");
strcpy(cam.video_dev, "/dev/video0");
cam.dither = 128;
lcd.dev = open(lcd.lcd_dev, O_RDWR);
cam.dev = open(cam.video_dev, O_RDWR);
cam.image = malloc(cam.x * cam.y * 3);
// cam.vid_buf.size = cam.x * cam.y * 3;
video_open(&lcd);
camera_cap(&cam);
if(ioctl(cam.dev, VIDIOCSCHAN, cam.vid_chnl) == -1);
cam.vid_pic.palette = VIDEO_PALETTE_RGB24;
cam.vid_win.x = 0;
cam.vid_win.y = 0;
cam.vid_win.width = cam.x;
cam.vid_win.height = cam.y;
cam.ppmfile = "file.bmp";
set_pic_info(&cam);
cam.contrast = cam.vid_pic.contrast * 256;
cam.brightness = cam.vid_pic.brightness * 256;
cam.colour = cam.vid_pic.colour * 256;
cam.hug = cam.vid_pic.hue * 256;
set_win_info(&cam);
set_buffer(&cam);
init_cam(&cam);
//dev_open();
while(1)
{
frameloop(&cam);
ppm_save(&cam);
}
return 0;
}
이렇게 처음으로 질문을 드리네요 ^^
EZ-X5보드와 로직텍 퀵캠 4000에 장비를 가지고
V4L로 "file.bmp"란 파일을 생성하는 프로그램을 만들었습니다.
그런데 사진이 이상하게 깨져서 나오더군요.(아마설정을 잘못해준거 같은데...)
QT를 이용한 camstream을 이용하면 영상이 깨끗하게 나옵니다.
밑에는 재가 코딩한 프로그램입니다.
또 한가지만 더 물어볼께요
프레임버퍼로 그림을 출력시키는 방법을 잘모르겠습니다.
인터넷에서 많은 자료를 찻았는데
저의 머리가 돌머리인지 이해가 잘 안되더라고요 -_ㅜ
도와주세요ㅡㅜ
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <getopt.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/videodev.h>
#define SERVO_LEFT 1
#define SERVO_RIGHT 2
#define SERVO_MIDDLE 3
#define Dev_Name "dev/Cam_Stream_Module"
static int Timer = 0;
static int Servo = 0;
static int frames2 = 0;
static int frame_number = 0;
//extern int frame_number2;
struct picbuf
{
char *data;
};
typedef struct camera
{
int dev;
int x;
int y;
int dither;
int contrast, brightness, colour, hug;
struct video_capability vid_cap;
struct video_picture vid_pic;
struct video_channel vid_chnl;
struct video_window vid_win;
struct video_mbuf vid_buf;
struct video_mmap vid_map[2];
char video_dev[256];
char *pic;
char *image;
char *ppmfile;
struct picbuf pic_buf[2];
}cam;
struct bgrpixel
{
unsigned char b, g , r;
};
typedef struct lcd_frmae_buffer
{
int dev;
char lcd_dev[256];
struct fb_var_screeninfo fbvar;
struct bgrpixel pixel;
int x;
int y;
int bp;
int byte_total;
unsigned short *vbase;
}lcd;
int video_open(lcd *lcd)
{
if(ioctl(lcd->dev, FBIOGET_VSCREENINFO, &lcd->fbvar) < 0)
{
printf("fbvar open failn");
return 0;
}
if(lcd -> fbvar.bits_per_pixel != 16)
{
printf("bpp is not 16n");
exit(0);
}
lcd -> x = lcd -> fbvar.xres;
lcd -> y = lcd -> fbvar.yres;
lcd -> bp = lcd -> fbvar.bits_per_pixel;
lcd -> byte_total = (lcd->x * lcd->y * (lcd->bp/8));
lcd -> vbase = (unsigned short *) mmap(0, lcd->byte_total, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->dev, 0);
if((unsigned)lcd->vbase == (unsigned)-1)
{
printf("Lcd MMAP FAILn");
exit(0);
}
return 0;
}
static unsigned short makepixel(lcd *lcd, unsigned char r, unsigned char g, unsigned char b)
{
unsigned short rnew, gnew, bnew;
rnew = r >> (8 - (lcd->fbvar.red.length));
gnew = g >> (8 - (lcd->fbvar.green.length));
bnew = b >> (8 - (lcd->fbvar.blue.length));
return (unsigned short) ((rnew << lcd->fbvar.red.offset)
| (gnew << lcd->fbvar.green.offset)
| (bnew << lcd->fbvar.blue.offset));
}
void screen(lcd *lcd,cam *cam)
{
int x, y;
for(x = 0; x <= cam->x ; x ++)
{
for(y = 0; y <= cam->y ; y++)
{
lcd->pixel.r = 10;
lcd->pixel.g = 10;
lcd->pixel.b = 10;
*(lcd->vbase + x *lcd->fbvar.xres+y) = makepixel(&lcd->fbvar, lcd->pixel.r, lcd->pixel.g, lcd->pixel.b);
}
}
}
void draw(int x, int y, unsigned short color,lcd *lcd)
{
unsigned short *ptr;
ptr = lcd->vbase + ((y * lcd->x) + x);
*ptr = color;
}
int ppm_save(cam *cam)
{
FILE *fp;
int fc;
printf("Capturing...n");
fp = fopen(cam->ppmfile, "w");
if(fp == NULL)
{
printf("OPEN FAIL FOR WIRTING...n");
return -1;
}
fprintf(fp, "P6n%d %dn%dn",cam->x,cam->y,255);
fc = fwrite(cam->pic_buf[frame_number].data, 1, cam->vid_buf.size, fp);
fclose(fp);
return 0;
}
void camera_cap(cam *cam)
{
if(ioctl(cam->dev, VIDIOCGCAP, &cam->vid_cap) == -1)
{
printf("Camera Capabilities OPEN FAIL, EXIT...n");
exit(0);
}
if(cam -> vid_cap.maxwidth < cam -> x)
{
cam->x = cam->vid_cap.maxwidth;
}
if(cam -> vid_cap.minwidth > cam -> x)
{
cam->x = cam->vid_cap.minwidth;
}
if(cam -> vid_cap.maxheight < cam -> y)
{
cam->y = cam->vid_cap.maxheight;
}
if(cam -> vid_cap.minheight > cam -> y)
{
cam->y = cam->vid_cap.minheight;
}
}
void set_pic_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
{
printf("VIDEO PICTURE OPEN FILE EXIT.....n");
exit(0);
}
}
void get_pic_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
{
printf("VIDEO GET PICTURE OPEN FAIL EXIT.....n");
exit(0);
}
}
void get_win_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
{
printf("VIDEO GET WINDOW OPEN FAIL EXIT.....n");
exit(0);
}
}
void set_win_info(cam *cam)
{
if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
{
printf("VIDEO SET WINDOW OPEN FAIL EXIT.....n");
exit(0);
}
}
void set_buffer(cam *cam)
{
if(ioctl(cam->dev, VIDIOCGMBUF, &cam->vid_buf) == -1)
{
printf("BUFFER SET FAIL EXIT.....n");
exit(0);
}
}
void dev_open(void)
{
Servo = open(Dev_Name, O_RDWR | O_NOCTTY);
Timer = open("dev_timer", O_RDWR | O_NOCTTY);
if(Servo < 0)
{
printf("%s OPEN FAIL.....n",Dev_Name);
exit(0);
}
printf("Servo OPEN SUCCESS.....n");
if(Timer < 0)
{
printf("Timer OPEN Fail [dev/timer]nn");
exit(1);
}
printf("Timer OPENn");
}
void init_cam(cam *cam)
{
cam->pic = mmap(0,cam->vid_buf.size,PROT_READ | PROT_WRITE,MAP_SHARED, cam->dev,0);
cam->vid_map[0].height = cam->y;
cam->vid_map[0].width = cam->x;
cam->vid_map[0].frame = 0;
cam->vid_map[0].format = cam->vid_pic.palette;
cam->pic_buf[0].data = cam->pic;
cam->vid_map[1].height = cam->y;
cam->vid_map[1].width = cam->x;
cam->vid_map[1].frame = 1;
cam->vid_map[1].format = cam->vid_pic.palette;
cam->pic_buf[1].data = cam->pic + cam->vid_buf.offsets[1];
if((unsigned char*) -1 == (unsigned char *) cam->pic)
{
printf("MMAP FAILEDn");
exit(-1);
}
if(ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map) == -1)
{
printf("100n");
}
if(ioctl(cam->dev, VIDIOCSYNC, cam->vid_map) == -1)
{
printf("1000n");
}
}
void frameloop(cam *cam)
{
int ctl = 0;
ctl = ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map + frame_number);
if(ctl == -1)
{
printf("CAPTURE FROM DEVICE OPEN FAIL.....n");
exit(-1);
}
frames2++;
ctl = ioctl(cam->dev, VIDIOCSYNC, cam->vid_map + frame_number);
if(ctl == -1)
{
printf("VIDIOCSYNC FAILED.....n");
munmap(cam->vid_map, cam->vid_buf.size);
exit(-1);
}
}
int main(int argc,char **argv)
{
//int one = 1;
//int done = 0;
cam cam;
lcd lcd;
cam.x = 320;
cam.y = 240;
strcpy(lcd.lcd_dev, "/dev/fb0");
strcpy(cam.video_dev, "/dev/video0");
cam.dither = 128;
lcd.dev = open(lcd.lcd_dev, O_RDWR);
cam.dev = open(cam.video_dev, O_RDWR);
cam.image = malloc(cam.x * cam.y * 3);
// cam.vid_buf.size = cam.x * cam.y * 3;
video_open(&lcd);
camera_cap(&cam);
if(ioctl(cam.dev, VIDIOCSCHAN, cam.vid_chnl) == -1);
cam.vid_pic.palette = VIDEO_PALETTE_RGB24;
cam.vid_win.x = 0;
cam.vid_win.y = 0;
cam.vid_win.width = cam.x;
cam.vid_win.height = cam.y;
cam.ppmfile = "file.bmp";
set_pic_info(&cam);
cam.contrast = cam.vid_pic.contrast * 256;
cam.brightness = cam.vid_pic.brightness * 256;
cam.colour = cam.vid_pic.colour * 256;
cam.hug = cam.vid_pic.hue * 256;
set_win_info(&cam);
set_buffer(&cam);
init_cam(&cam);
//dev_open();
while(1)
{
frameloop(&cam);
ppm_save(&cam);
}
return 0;
}