当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 1 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : V4L视频采集程序?
帖子发表于 : 2011-05-14 10:36 

注册: 2011-04-29 10:33
帖子: 3
送出感谢: 0 次
接收感谢: 0 次
大家好,现在做设计遇到一个问题,就是用在网上找的V4L程序采集图像只能采集到一张,但是我们想连续采集到多张,就设置了一个定时,但是还是只能采集到一张JPG图片,程序我会贴出来,请大家帮忙解决。我个人感觉应该是存储地址的问题,但不知道怎么修改。其他情况是,ubuntu10.10的系统,ZC301的摄像头,目前还只是在PC机上实现功能。

另外,最后还涉及一个压缩,就是把多张图片变为MJPEG的AVI格式,我在网上看到有用jpegtoavi-1.5.tar.gz这个源码的,但是试了一下,没找到那个AVI文件,各位有没有谁用过这个,能教下怎么用吗?

#include <unistd.h>
#include "v4l.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <error.h>
#include <sys/types.h>
#include <linux/videodev.h>

#define norm VIDEO_MODE_NTSC
#define DEFAULT_FILE_NAME "picture"
#define DEFAULT_DEVICE "/dev/video0"
int v4l_open(char *dev,v4ldevice *vd)
{
if (!dev)
dev = DEFAULT_DEVICE;

if((vd->fd=open(dev,O_RDWR | O_NONBLOCK,10705))<0) //非阻塞方式打开
{
return -1;
}else{
printf("open success!!!!\n");
}

if(v4l_get_capability(vd)<0)
{return -1;}else{
printf("\n===========Get struct video_capability==============\n");
printf(vd->capability.name);printf(", Type:%d\n",vd->capability.type);
printf("Maxwidth:%d,Maxheight:%d\n",vd->capability.maxwidth ,vd->capability.maxheight);
printf("Minwidth:%d,Minheight:%d\n",vd->capability.minwidth,vd->capability.minheight);
printf("Channels:%d,Audios:%d\n",vd->capability.channels,vd->capability.audios);}
if(v4l_get_picture(vd)<0)
{return -1;}else{
printf("\n==============Get struct video_picture1===============\n"); //修改前获得的图像信息
printf("Brightness:%d,Hue:%d,Colour:%d\n",vd->picture.brightness,vd->picture.hue,vd->picture.colour);
printf("Contrast:%d,Whiteness:%d(Black and white only)\n",
vd->picture.contrast,vd->picture.whiteness);
printf("Capture depth:%d,Palette:%d\n",vd->picture.depth,vd->picture.palette);
}
//return 0;gcc版本: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
printf("\n===============Set vpic.palette to VIDEO_PALETTE_YUV420P,and picture.depth to 16.========\n");
vd->picture.palette=VIDEO_PALETTE_YUV420P; // 设置调色板 设置图像格式 对应 videodev.h 中107行
vd->picture.depth=14; // 设置象素深度
//vd->picture.hue = 25854 ; // 色调
// vd->picture.colour= 25854 ; //
//vd->picture.brightness = 22869 ; //亮度
// vd->picture.contrast = 22768 ; //对比度
// vd->picture.whiteness= 29321 ; //色度
if(ioctl(vd->fd, VIDIOCSPICT, &vd->picture)==-1) // 设置图像特性
{ fprintf(stderr, "Unable to find a supported capture format.\n");
close(vd->fd);
exit(1);
}else{
printf("\n==============Get struct video_picture2===============\n");//修改后获得的信息
printf("Brightness:%d,Hue:%d,Colour:%d\n",vd->picture.brightness,vd->picture.hue,vd->picture.colour);
printf("Contrast:%d,Whiteness:%d(Black and white only)\n",
vd->picture.contrast,vd->picture.whiteness);
printf("Capture depth:%d,Palette:%d\n",vd->picture.depth,vd->picture.palette);
}


return 0;
}

int v4l_get_capability(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability))<0)
{
perror("v4l_get_capability:");
return -1;
}

return 0;

}

int v4l_get_picture(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))<0) //获取图像特征数据结构
{
perror("v4l_get_picture");
return -1;
}

return 0;

}
/*int v4l_set_norm(v4ldevice *vd, int norm) //我的设备获取的信息就一个channel 备注了此段
{
int i;

for (i = 0; i < vd->capability.channels; i++) {
vd->channel[i].norm = norm;}

return 0;
}*/





int v4l_grab_init(v4ldevice *vd,int width,int height) //初始化
{
vd->mmap.width=width;
vd->mmap.height=height;
vd->mmap.format=vd->picture.palette;
vd->frame=0;
vd->framestat[0]=0;
vd->framestat[1]=0;
return 0;
}

int v4l_mmap_init(v4ldevice *vd)
{
if(v4l_get_mbuf(vd)<0)
return -1;
if((vd->map=mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0))<0)
{
return -1;
}
return 0;
}

int v4l_get_mbuf(v4ldevice *vd)//查询实际可用的缓存数
{
if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf))<0)
{
perror("v4l_get_mbuf:");
return -1;
}
printf("size=%d\n",vd->mbuf.size);
return 0;
}

int v4l_grab_start(v4ldevice *vd,int frame) //开始
{
vd->mmap.frame=frame;
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0)
{
exit(-1);
return -1;
}
vd->framestat[frame]=1;
return 0;
}
int v4l_grab_sync(v4ldevice *vd,int frame)
{
if(ioctl(vd->fd,VIDIOCSYNC,&frame)<0)
{
return -1;
}
vd->framestat[frame]=0;
return 0;
}

unsigned char * v4l_get_address(v4ldevice *vd)
{
return (vd->map+vd->mbuf.offsets[vd->frame]);
}
int v4l_close(v4ldevice *vd)
{
close(vd->fd);
return 0;
}



int main()
{
char *buffer=NULL;
v4ldevice VD;
v4ldevice *vd=&VD;

int frame=0;
int f_d;
int loop_count = 100;
int sleep_time_milsec = 1000;//睡1秒
char file_name[100];

if(0==v4l_open("/dev/video0",vd)) //打开设备
printf("open success!\n");
else
printf("open failure\n");
// set (vd);
/* if(0==v4l_set_norm(vd,norm))
printf("set_norm success\n");
else
printf("set_norm failure\n"); */
if(0==v4l_grab_init(vd,CIF_WIDTH,CIF_HEIGHT))//初始化设备,定义获取图像的大小
printf("init success!\n");
else
printf("init failure\n");
if(0==v4l_mmap_init(vd))//内存映射
printf("memory map success!\n");
else
printf("memory map failure\n");

while (loop_count)
{
if(0==v4l_grab_start(vd,frame))//开始获取图像
printf("get picture success!\n");
else
{
printf("get picture failure\n");
break;
}

v4l_grab_sync(vd,frame);//等待传完一帧

buffer=(char *)v4l_get_address(vd);//得到这一帧的地址
printf("img address %p\n",buffer);

sprintf(file_name, "%s - %d", DEFAULT_FILE_NAME, frame);
f_d=open(file_name,O_RDWR|O_CREAT,0666);//获取文件的描述符 打开piture 文件 返回其描述符 DEFAULT_FILE_NAME 在前面开始定义
write(f_d,buffer,CIF_WIDTH*3*CIF_HEIGHT);//保存到文件中 写入piture 文件中
close(f_d);

sleep(sleep_time_milsec);
loop_count--;
frame++;
}

v4l_close(vd);
return 0;

}


菜鸟在线急等。。。。


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 1 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译