红联Linux门户
Linux帮助

摄像头图像采集程序

发布时间:2009-05-11 13:17:36来源:红联作者:sydnash
[i=s] 本帖最后由 sydnash 于 2009-5-13 10:30 编辑 [/i]

下面是我写的一个摄像头图像采集程序,该程序执行vd->fd = open ("/dev/video0" , O_RDWR);时出现段错误,大家帮忙看看吧,我实在不知道为什么这里会读取错误的地址段
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct v4l_struct{
int fd;

struct video_capability capability;

struct video_channel channel[4];

struct video_picture picture;

struct video_window window;

struct video_capture capture;

struct video_buffer buffer;

struct video_mmap mmap;

struct video_mbuf mbuf;

unsigned char *map;

int frame;

int framestat[2];

}device;
/*函数名: v4l_get_capability

功能: 获取设备属性

输入: vd

输出: 无

返回: -1----失败 0----成功
*/
/*int v4lopen(char *name,device *vd){
if(( vd->fd = open( "/dev/video0",O_RDWR ) ) < 0 ){
perror( "v4lopen" );
return -1;
}
return 0;
}*/
/*函数名: v4lgetcapability

功能: 获取设备属性

输入: vd

输出: 无

返回: -1----失败 0----成功

*/

int v4lgetcapability(device *vd){

if( ioctl( vd->fd, VIDIOCGCAP, &( vd->capability)) <0 ){

perror( "v4lgetcapability" );

return -1 ;

}

return 0;

}
/*函数名: v4lgetpicture

功能: 获取影像视窗信息

输入: vd

输出: 无

返回: -1----失败 0----成功

*/
int v4lgetpicture( device *vd){
if (ioctl( vd->fd, VIDIOCGPICT, &( vd->picture)) < 0) {
perror( "v4lgetpicture");
return -1;
}
return 0;
}
/*函数名: v4lgetmbuf

功能: 获取影像大小

输入: vd

输出: 无

返回: -1----失败 0----成功

*/
int v4lgetmbuf( device *vd){
if( ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))<0) {
perror("v4lgetmbuf:VIDIOCGMBUF");
return -1;
}
return 0;
}
/*函数名: v4lgrabinit

功能: 初始化设备,定义获取的影像大小

输入: vd,width,height

输出: 无

返回: -1----失败 0----成功

*/
int v4lgrabinit( device *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;
}
/*函数名: v4lmmap

功能: 内存映射

输入: vd

输出: 无

返回: -1----失败 0----成功

*/
int v4lmmap( device *vd){
if( v4lgetmbuf( vd) < 0){
return -1;
}
if(( vd->map = (char*)mmap( 0, vd->mbuf.size, PROT_READ |
PROT_WRITE, MAP_SHARED, vd->fd, 0))<0){
return -1;
}
return 0;
}
/*函数名: v4lgrabstart

功能: 开始获取影像

输入: vd,frame

输出: 无

返回: -1----失败 0----成功

*/
int v4lgrabstart( device *vd,int frame){
vd->mmap.frame = frame;
if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
return -1;
}
vd->framestat[frame] = 1;
return 0;
}
/*函数名: v4lgetaddress

功能: 计算图象内存首地址

输入: vd,frame

输出: 无

返回: -1----失败 0----成功

*/
unsigned char *v4lgetaddress( device *vd,int frame){
vd->frame = frame;
return (vd->map + vd->mbuf.offsets[vd->frame]);
}
/*函数名: v4lsync

功能: 等待传完以?

输入: vd,frame

输出: 无

返回: -1----失败 0----成功

*/
int v4lsync( device *vd, int frame){
if(ioctl(vd->fd, VIDIOCSYNC, &frame) < 0) {
return -1;
}
vd->framestat[frame] = 0;
return 0;
}
/*函数名: v4lcapture
功能: 获取影像
输入: vd,frame
输出: 无
返回: -1-----失败 0----成功
*/
int v4lcapture( device *vd,int frame){
vd->mmap.frame = frame;
if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
return -1;
}
vd->framestat[frame] = 1;
return 0;
}
int main(int argc,char *argv[]){
device *vd;
char *buffer;
int width = 640;
int height = 480;
int frame = 0;
/*if( v4lopen("/dev/video0",vd)<0){
perror( "v4lopen");
exit(1);
}//打开设备*/
vd->fd = open ("/dev/video0" , O_RDWR);

if( v4lgetcapability(vd) <0 ){
perror ( "v4lgetcapability");
exit(1);
}//获取设备属性
if ( v4lgetpicture(vd) <0 ){
perror( "v4lgetpicture");
exit(1);
}//获取影像视窗信息
if( v4lgrabinit(vd,width,height)<0){
perror( "v4lgrabinit");
exit(1);
}//初始化设备,定义获取的影像的大小
if( v4lmmap(vd) <0 ){
perror( "v4lmmap");
exit(1);
}//内存映射
if( v4lgrabstart(vd,frame) < 0){
perror( "v4lgrabstart");
exit(1);
}//开始获取影像
while(1){
while(v4lsync(vd,frame)) {
perror( " waite");
}//等待传完一帧
buffer = (char*)v4lgetaddress(vd,frame);//得到这一帧的地址
//buffer给出了图像的首地址,你可以选择将图像显示或保存传送......
//图像的大小为 width*height*3 这里最好建立新线程或者进程
int fd;
fd = open ( "1.jpeg", O_RDWR );
write( fd, buffer, 640*480*3 );
close( fd);
frame = (frame+1)%2;//下一帧的frame
if ( v4lcapture(vd,frame) < 0){
perror( "v4lcapture");
exit(1);
}//获取下一帧
}
if( close(vd->fd) <0){
perror( "close");
exit(1);
}
return 0;
}
文章评论

共有 3 条评论

  1. sydnash 于 2009-05-12 23:25:42发表:

    2# jhx0301


    那你知道这个什么原因吗 帮帮忙 我现在头都2个大了 今天有看了一天 还找不到什么原因

  2. sydnash 于 2009-05-12 23:25:05发表:

    谁能帮我看看这个是什么原因啊 谢谢了

  3. jhx0301 于 2009-05-11 16:50:52发表:

    1# sydnash
    不错 我现在也在做 这方面的 工作