4269|3

44

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

希望大家解决下我的疑惑,关于摄像头的 [复制链接]

我有一块ARM的FL2440的板子,如果我要做个关于摄像头的程序(linux的),从市场上买一块主流的摄像头,像素稍微高点,然后是USB2.0的,希望采集图像在LCD中显然,那么是不是载一个万能驱动配置下,然后参考一些教程写个应用程序,就可以了呢?还需要考虑什么吗? 或者有什么东西可以借鉴?  我是新手现在没有什么概念的。。。。求大家帮忙~~

最新回复

文件2:v4l.h 说明:自定义的头文件 主要是根据 /usr/include/linux/videodev.h 中的一些结构体给自定义的结构体 /***************************** name :v4l.h Ubuntu10.04 2.6.32 gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4) copyright:all is reserved **************************/ #ifndef _V4L_H_ #define _V4L_H_ #include #include //PAL CIF NTSC tuner mode #define PAL_WIDTH 768   //3种分辨率 #define PAL_HEIGHT 576 #define CIF_WIDTH 352   // #define CIF_HEIGHT 288 #define NTSC_WIDTH 80 //设置获取图像的大小 #define NTSC_HEIGHT 60 #define DEFAULT_PALETTE VIDEO_PALETTE_RGB32   //此处设置 并未使用 因为在测试时 得到的数据 是黑图 怀疑格式问题 在main.c中的 62行对这一直进行了频繁的修改 struct _v4l_device     //自定义结构体包含 中的数据结构 { int fd;//设备号 struct video_capability capability;//摄像头属性 struct video_picture picture;//图像的属性,亮度、色度、对比度、灰度、编码属性 struct video_window window;//包含capture area 的信息 struct video_channel channel[8];//采集的通道 struct video_mbuf mbuf;//利用mmap映射得侦信息 struct video_capture capture; struct video_buffer buffer; struct video_mmap mmap; unsigned char *map; int frame; int framestat[2]; }; typedef struct _v4l_device v4ldevice; //main.c中要用到的函数声明 extern int v4l_open(char *,v4ldevice *); //关键字extern 函数在别的文件中定义 extern int v4l_set_norm(v4ldevice *, int); extern int v4l_get_capability(v4ldevice *); extern int v4l_get_window(v4ldevice *); extern int v4l_set_window(v4ldevice *); extern int v4l_get_picture(v4ldevice *); extern int v4l_mmap_init(v4ldevice *); extern int v4l_grab_init(v4ldevice *,int ,int); extern int v4l_grab_start(v4ldevice *,int ); extern int v4l_grab_sync(v4ldevice *,int); extern int v4l_get_capture(v4ldevice *); extern int v4l_set_capture(v4ldevice *); extern unsigned char *v4l_get_address(v4ldevice *); extern int v4l_close(v4ldevice *); extern void set(v4ldevice *); #endif 文件3:main.c 说明 :定义了v4l.h中声明的函数 然后一个 主函数调用。 /****************************************** name :main.c Ubuntu 10.04 2.6.32- gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4) copyright:all is reserved ************************************/ #include #include "v4l.h" #include #include #include #include #include #include #include #include #include #include #include #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))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)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))fd,VIDIOCGPICT,&(vd->picture))capability.channels; i++) { vd->channel.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)map=mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0))fd,VIDIOCGMBUF,&(vd->mbuf))mbuf.size); return 0; } int v4l_grab_start(v4ldevice *vd,int frame)    //开始 { vd->mmap.frame=frame; if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))framestat[frame]=1; return 0; } int v4l_grab_sync(v4ldevice *vd,int frame) { if(ioctl(vd->fd,VIDIOCSYNC,&frame)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; f_d=open(DEFAULT_FILE_NAME,O_RDWR|O_CREAT,0666);//获取文件的描述符   打开piture 文件 返回其描述符 DEFAULT_FILE_NAME 在前面开始定义 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"); if(0==v4l_grab_start(vd,frame))//开始获取图像 printf("get picture success!\n"); else printf("get picture failure\n");    v4l_grab_sync(vd,frame);//等待传完一帧 buffer=(char *)v4l_get_address(vd);//得到这一帧的地址 printf("img address %p\n",buffer); write(f_d,buffer,CIF_WIDTH*3*CIF_HEIGHT);//报存到文件中    写入piture 文件中 v4l_close(vd); return 0; } 文件4:Makefile 说明:自己写的 Makefile 同时生成X86 和ARM 下的可执行文件 交叉编译链为 arm-softfloat-linux-gnu-gcc gcc version 3.4.5 #********************************************************# #注意啊,以下这两行命令要以tab键开头,不可为空格! main   :     gcc -o arm-main -static main.c clean   : @rm -vf main* *~ *.o *.i *.s #********************************************************# 结束 :把mian.c   v4l.h Makefile 3个文件放在一个文件夹下编译即可  详情 回复 发表于 2011-1-27 11:22
点赞 关注

回复
举报

2771

帖子

0

TA的资源

裸片初长成(中级)

沙发
 
楼主可以看看这个资料

axu.pdf

945.27 KB, 下载次数: 42

 
 

回复

2131

帖子

0

TA的资源

至上芯片

板凳
 

回复 楼主 foursking 的帖子

从市场上买一块主流的摄像头都是USB驱动的,如果你在PC机上写好程序移植上去就能用的,有支持好的不需要驱动.
出现问题大家可以一起讨论一下!

[ 本帖最后由 daicheng 于 2011-1-27 11:12 编辑 ]
 
个人签名处处留心皆学问!
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

4
 
文件2:v4l.h 说明:自定义的头文件 主要是根据 /usr/include/linux/videodev.h 中的一些结构体给自定义的结构体

/*****************************

name :v4l.h

Ubuntu10.04 2.6.32

gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

copyright:all is reserved


**************************/

#ifndef _V4L_H_
#define _V4L_H_

#include
#include
//PAL CIF NTSC tuner mode
#define PAL_WIDTH 768   //3种分辨率
#define PAL_HEIGHT 576
#define CIF_WIDTH 352   //
#define CIF_HEIGHT 288
#define NTSC_WIDTH 80 //设置获取图像的大小
#define NTSC_HEIGHT 60
#define DEFAULT_PALETTE VIDEO_PALETTE_RGB32   //此处设置 并未使用 因为在测试时 得到的数据 是黑图 怀疑格式问题 在main.c中的 62行对这一直进行了频繁的修改

struct _v4l_device     //自定义结构体包含 中的数据结构
{
int fd;//设备号
struct video_capability capability;//摄像头属性
struct video_picture picture;//图像的属性,亮度、色度、对比度、灰度、编码属性
struct video_window window;//包含capture area 的信息
struct video_channel channel[8];//采集的通道
struct video_mbuf mbuf;//利用mmap映射得侦信息
struct video_capture capture;
struct video_buffer buffer;
struct video_mmap mmap;
unsigned char *map;
int frame;
int framestat[2];
};
typedef struct _v4l_device v4ldevice; //main.c中要用到的函数声明

extern int v4l_open(char *,v4ldevice *); //关键字extern 函数在别的文件中定义
extern int v4l_set_norm(v4ldevice *, int);
extern int v4l_get_capability(v4ldevice *);
extern int v4l_get_window(v4ldevice *);
extern int v4l_set_window(v4ldevice *);
extern int v4l_get_picture(v4ldevice *);
extern int v4l_mmap_init(v4ldevice *);
extern int v4l_grab_init(v4ldevice *,int ,int);
extern int v4l_grab_start(v4ldevice *,int );
extern int v4l_grab_sync(v4ldevice *,int);
extern int v4l_get_capture(v4ldevice *);
extern int v4l_set_capture(v4ldevice *);
extern unsigned char *v4l_get_address(v4ldevice *);
extern int v4l_close(v4ldevice *);
extern void set(v4ldevice *);
#endif

文件3:main.c 说明 :定义了v4l.h中声明的函数 然后一个 主函数调用。
/******************************************

name :main.c


Ubuntu 10.04 2.6.32-
gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

copyright:all is reserved


************************************/
#include
#include "v4l.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#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:");   //not a video4linux device   比较所否支持该设备   在这里让我很是郁闷了很久 我把我们实验室的摄像头都测试了下
//有几是 Invalid argument 就所在这一步 获取不到它的数据 我在google上查了下
//未果。。。最后的结果就是换。

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.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;

f_d=open(DEFAULT_FILE_NAME,O_RDWR|O_CREAT,0666);//获取文件的描述符   打开piture 文件 返回其描述符 DEFAULT_FILE_NAME 在前面开始定义

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");
if(0==v4l_grab_start(vd,frame))//开始获取图像
printf("get picture success!\n");
else
printf("get picture failure\n");   

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

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

write(f_d,buffer,CIF_WIDTH*3*CIF_HEIGHT);//报存到文件中    写入piture 文件中

v4l_close(vd);
return 0;

}
文件4:Makefile 说明:自己写的 Makefile 同时生成X86 和ARM 下的可执行文件 交叉编译链为
arm-softfloat-linux-gnu-gcc gcc version 3.4.5

#********************************************************#
#注意啊,以下这两行命令要以tab键开头,不可为空格!

main   :
    gcc -o arm-main -static main.c


clean   :
@rm -vf main* *~ *.o *.i *.s
#********************************************************#

结束 :把mian.c   v4l.h Makefile 3个文件放在一个文件夹下编译即可
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表