利用V4L2架构 实现从笔记本摄像头拍摄一张照片写入本地 一

一下内容实现环境:

Ubuntu 12.04+libjpeg62-dev,采用vi编写,gcc/g++编译,当然一下程序均使用Makefile统一管理。

首先第一点:           我们得明白我们的V4L2架构的基本信息:Video4linux2(简称 V4L2),是 linux 中关于视频设备的内核驱动。在 Linux 中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video0 下,以下用到的结构提也都定义在/usr/include/linux/videodev2.h头文件下。

我们的步骤:

1. 打开设备文件。 int fd=open(”/dev/video0′′,O_RDWR);
2. 取得设备的 capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_
QUERYCAP,struct v4l2_capability
3. 选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input
4. 设置视频的制式和帧格式,制式包括 PAL,NTSC,帧的格式个包括宽度和高度等。
VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format
5. 开始视频的采集。VIDIOC_STREAMON
6. 出队列以取得已采集数据的帧缓冲,取得原始采集数据。VIDIOC_DQBUF
7. 将缓冲重新入队列尾,这样可以循环采集。VIDIOC_QBUF
8. 停止视频的采集。VIDIOC_STREAMOFF
9. 关闭视频设备。close(fd)

第一步:首先是要查询你笔记本的相关的摄像头信息,这里我把它做成了一个模块,用于查询摄像头的相关信息,定义一个文件:query.h 摄像头查询模块接口文件,定义三个方法:query_cap(int fd);查询摄像头参数及驱动信息,

query_fps(int fd);VIDIOC_G_PARM查询帧率信息,

query_fmt(int fd);使用VIDIOC_ENUM_FMT查询摄像头信息

下面我们分别实现这三个方法:

/**
* @brief query_cap
* 查询摄像头参数及驱动信息:打印struct v4l2_capability
* @param fd 摄像头文件描述符
*
*/
void query_cap(int fd)
{

Cap cap;
CLEAR(cap);
if(ioctl(fd,VIDIOC_QUERYCAP,&cap) < 0) //查询摄像头的功能
{
perror(“query_cap()”); //也是出错处理
exit(EXIT_FAILURE);
}
printf(“===============Camera Info===============\n”);
printf(“Driver: %s \n”,cap.driver);
printf(“Card: %s \n”,cap.card);
printf(“BusInfo: %s \n”,cap.bus_info);
printf(“Version: %d \n”,cap.version);
printf(“Capabilities: 0x%x \n”,cap.capabilities);
//printf(“Device Cap: 0x%x \n”,cap.device_caps);
//printf(“Reserved: 0x%x \n”,cap.reserved);
}

 
/**
* @brief query_fps
* 使用VIDIOC_G_PARM查询帧率信息
* @param fd
*/
void query_fps(int fd)
{
Fps fps;
CLEAR(fps);
fps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //设置类型
//ioctl(fd,VIDIOC_G_PARM,&fps);
if(ioctl(fd,VIDIOC_G_PARM,&fps) < 0)
{
fprintf(stderr,”Usage:query_fps:%s error\n”,strerror(errno));
exit(EXIT_FAILURE);
}
printf(“=======================Camera Fps==============\n”);
printf(“Type:%d \n”,fps.type);
printf(“Capture->capability:%d \n”,fps.parm.capture.capability);
printf(“Capture->capturemode:%d \n”,fps.parm.capture.capturemode); //1为高清模式
printf(“Capture->captureparm->timeperframe->numerator:%d \n”,\
fps.parm.capture.timeperframe.numerator); //默认为1
printf(“Capture->captureparm->timeperframe->denominator:%d \n”,\
fps.parm.capture.timeperframe.denominator); //帧率
printf(“Capture->extendedmode:%d \n”,fps.parm.capture.extendedmode);
printf(“Capture->readbuffer:%d \n”,fps.parm.capture.readbuffers);

//printf(“Capture->outputparm->\n”,fps.parm.output.);
}

 

 

/**
* @brief query_fmt
* 使用VIDIOC_ENUM_FMT查询摄像头信息
* @param fd
*/
void query_fmt(int fd)
{
Fmtd fmtd;
CLEAR(fmtd);
fmtd.index = 0;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf(“================Fmtd Info================\n”);
while(-1 != ioctl(fd,VIDIOC_ENUM_FMT,&fmtd))
{
printf(“query fmtd %d %s\n”,fmtd.index,fmtd.description);
fmtd.index++;
}
}

实现以上三个函数之后我们就可以编写一个测试函数了:cam_test.c

int main(int argc,char *argv[])
{

int fd = cam_open(argc,argv); //打开摄像头
//query_cap(fd);
//query_fps(fd);
//query_fmt(fd);

cam_close(fd);
return 0;

}

还有就是以上使用的结构体都预先定义在文件:common.h

#ifndef __COMMON_H_
#define __COMMON_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <linux/videodev2.h>
#include <jpeglib.h>

#define CLEAR(x) memset(&x,0,sizeof(x))
typedef enum
{
MJPEG = V4L2_PIX_FMT_MJPEG,
YUYV = V4L2_PIX_FMT_YUYV
}fmt_t;
#define WIDTH 640
#define HEIGHT 480

typedef struct v4l2_capability Cap; //
typedef struct v4l2_format Fmt; //
typedef struct v4l2_fmtdesc Fmtd; //
typedef struct v4l2_streamparm Fps; //
typedef struct v4l2_requestbuffers ReqBuf; //
typedef struct v4l2_buffer Vbuf; //

#endif

linux 装doxygen文档自动生成器

大牛请略过此文章,不好的请拍砖!

以下为本人在unbutu 12.04下安装过程记录

可能我们很多时候总是习惯了WIN下IDE中强大的开发环境,和自动化的文档生成器,然后来到LINUX就觉得各种不变,使用vi开发的时候总是各种命令,也没有自动生成文档的工具,那么这里就介绍一款可以自动生成文档的插件工具,当然这是建立在你按规范写代码的基础之上的,废话就不说了下面看步骤:

首先是获得doxygen,你可以选择下载源码,然后进入目录,运行一下步骤安装

./configure —>make—–>make install—-> make distclean当然最后一部要不要都无所谓了

这里主要讲的是,有时候我们没有源码的话,我们可以在终端下直接运行命令安装:

git clone https://github.com/doxygen/doxygen.git  这也是官方给出的克隆源码到本地目录的方法

之后还是跟上面的安装步骤一样

这里主要是安装期间还会遇到一些问题就是依赖关系的问题,有时候我们安装软件或者工具的时候最难搞的就是各种以来关系

如果出现: Checking for dot (part of GraphViz)…这样的提示说,不存在时,这时我们可以使用一下命令更行依赖关系:sudo apt-get install graphviz_2.34.0-1~precise_i386.deb

还有类似的缺少依赖的:Checking for flex…

也是同样的使用命令安装依赖关系即可:sudo apt-get install flex…..

这里给出一个各个版本的依赖包下载的地址:http://www.graphviz.org/Download_linux_ubuntu.php

其实vim下也有很多很强大的类似WIN下IDE中提供的各种命令补全和函数查看跳转工具

这里给出一个我在别人博客中看见的几个工具的介绍:

http://my.oschina.net/u/554995/blog/59927

 

如果我在桂林遇见你

如果我在桂林遇见你,我们一定要在阳春四月去南溪山看樱花,互相替对方拂开肩上落花;

如果我在桂林遇见你,我们一定要在六月去西山看荷花,见鱼儿摆尾流连荷叶连田田;

如果我在桂林遇见你,我们一定要在金秋十月漫步于普陀路,看街道两旁红枫浸染霜色;

如果我在桂林遇见你,我们一定要在腊月去尧山看雪,在尧山顶许愿,遥望四方皆似白玉砌云端;

如果我在桂林遇见你,我们一定要在早晨去小店吃米粉,一个三两要锅烧不要酸辣,一个二两什么都要;

如果我在桂林遇见你,我们一定要在夜晚走过滨江路,看对面七星峰闪耀七彩的光;

如果我在桂林遇见你,我们一定要在七星公园逗弄冥顽猴子,看它为我们手中的花生搔首弄姿而笑个满怀;

如果我在桂林遇见你,我们一定要去伏波山,听导游说说还珠洞的美丽传说,然后摸摸试剑石,再在铁佛寺算个命;

如果我在桂林遇见你,我们一定要勾手去逛一逛正阳街,它见证了桂林城数百年的世事更迭,有你我共同的回忆;

如果我在桂林遇见你,我们一定要在钟楼下照个相,任凭人潮汹涌,却能够认定你我就是彼此的那个人;

如果我在桂林遇见你,我们一定要在微笑堂整点开市的时候共同进入商场,看商场人员九十度鞠躬地说:“欢迎光临”;

如果我在桂林遇见你,我们一定要装作学生屏息凝气进入王城,拿着假学生证爬上独秀峰,摸一摸石老龟,祈求彼此长命百岁;

如果我在桂林遇见你,我们一定要在刀锋书店要两杯拿铁咖啡,看一看书,再等待傍晚时分,百度酒吧的喧闹;

如果我在桂林遇见你,我们一定要在桂花飘香的街道上走过,你不必多高,但可以为我折一枝饱香的花枝;

如果我在桂林遇见你,我们一定要在海天肠粉吃一顿肠粉,你去买肠粉,我打两碗白粥,等候在后堂;

如果我在桂林遇见你,我们一定要在王城商厦后面吃那位老婆婆做的马蹄糕,五毛钱两个,加价不加量;

如果我在桂林遇见你,我们一定要在油炸大王里大快朵颐,再去旁边的奶茶店要两杯鲜榨果汁,给老板娘十元,她会端着果汁过来并找还两元钱硬币;

如果我在桂林遇见你,我们一定要去彤言物语吃蛋挞,坐在沙发上和老外说蹩脚的英语,惹得旁边的小朋友也嘻嘻地笑起来;

如果我在桂林遇见你,我们一定要走上解放桥,吃几块新疆同胞做的名不副实的板栗糕,保证心疼肉也疼;

如果我在桂林遇见你,我们一定要去临桂,摘桃金娘,吃五通的甘蔗和马蹄,瞻仰李先生和白先生,看两江机场里飞机起降;

如果我在桂林遇见你,我们一定要去灵川海洋看银杏,顺便吃锅灵川狗肉,一黄二白三花四黑,同食腐乳辣酱不腥膻;

如果我在桂林遇见你,我们一定要坐车去阳朔过月牙山,在大榕树公园里对歌、抛绣球,买花冠,吃沙田柚,再在西街徜徉几回,对着洋娃娃say hello;

如果我在桂林遇见你,我们一定要在兴安留宿一宿,早上穿着拖鞋去灵渠,再穿戏服扮一回皇上皇后,同时撕咬一块钱一串的烤虾烤螃蟹;

如果我在桂林遇见你,我们一定要去资源漂流,手放河灯一盏盏,再攀上丹霞之魂——八角寨;

 

如果我在桂林遇见你,我们一定要去恭城看桃花,喝油茶,吃月柿;

如果我在桂林遇见你,我们一定要去灌阳喝好友亲自酿的葛根酒,然后相视一笑;

如果我在桂林遇见你,我们一定要去永福吃罗汉果,摘山葡萄,然后瞻仰历史文化遗迹,学习福寿文化;

如果我在桂林遇见你,我们一定要去龙胜摘新鲜的杨梅,吃血肠,看少数民族长发姑娘起歌舞;

如果我在桂林遇见你,我们一定要在有朋自远方来时买一碗荔浦芋扣肉,告诉他这就是《宰相刘罗锅》里让乾隆皇帝也赞不绝口的美味;

如果我在桂林遇见你,我们一定要学着平乐话纠正平乐不是贫穷落后,是平安快乐;

如果我在桂林遇见你,我们一定要到全州湘山寺拜一拜,再在天湖钓禾花鱼,吃醋血鸭——要问正宗的醋血鸭哪里有,何必舍近求远,蒋氏家味馆的醋血鸭就很正宗;

如果我在桂林遇见你,我们一定要在南站北站乘车进站接受**叔叔盘问,让我们出示身份证时,义正言辞地鄙视他,请他先出示警官证;

如果我在桂林遇见你,请你一定要在节假日陪我在七星公园正门默默观察那个指挥交通的**若干分钟,陪我长叹今生不能得嫁此帅哥叔叔真是遗憾,然后弹一下我的脑瓜儿,说我花痴;

如果我在桂林遇见你,我们一定要在结婚的时候到春记烧鹅摆上几十桌,我们接受亲戚朋友的祝福,背景是在维纳斯或者巴黎印象拍的结婚照,上面有大大的玉兰花球;

如果我在桂林遇见你,我们一定要去彰泰第六园看看,不必费心费力买下其中一幢,只要看看,然后远远地呸一句:“妈哟,这房子也值一万块一平?”

如果我在桂林遇见你,我们的蜜月旅行不必去马尔代夫,也不要拘囿于桂林城区,去远一点的地方吧,诸如阳朔、龙胜和兴坪结婚岛;

如果,如果我真的在桂林遇见你,可以和你携手一段新的人生旅程,我将感谢上苍将你赐予我——因为即使我可以决定爱不爱你,在你需要关怀时是否献上一副柔弱却有力的肩膀,我总是把握不了缘分。而如果真的遇见你,不早一分,不晚一秒,我不会奢求万年,只要你我在世的每分每秒,每时每刻。

如果,如果我真的在桂林遇见你,可以和你携手一段新的人生旅程,我不能承诺将我的爱百分之百给你,因为还有一部分,我会给我的父母,你的父母,以及我们的孩子;

而如果,如果我真的在桂林遇见你,可以和你携手一段新的人生旅程,不管开头是:“仲夏的桂林城闷热得像是蒸笼,XXX坐于树下看书”;抑或是:“如果XX还记得他与XXX第一次相遇的情形,他或许会想到自己翻墙去时家内院躲在石榴树上被她发现”;还是:“他们是哪个时候相遇的呢?XXX坐在电视机前看着《越狱》暗自思忖道。她是记得的,九月份的艳阳,衬着李氏博物馆内的冷气,让穿着白棉布短衫的她冷不防打了个喷嚏”,我都会预计到结局——

“有老妪与老翁相携走在滨江路上,看见一年轻男子背着女友,说你最近可是胖了,女子拿着书作势要打,却反将男子搂得更紧,又辩驳道不是我舍不得打你,只是这书宝贵。”

桂林城的故事总是特别多,有多少鲜事被掩埋?有多少常闻被风传?多年后人们的记忆中是否有这样一个你?和这一样一个我?

或许,或许滨江路两旁郁葱的参天大树会记得,记得这让人怦然心动的爱意萌芽的时光,记得往来的风,吹散了心头的尘。

我,遇见你。

VI 自动文件头

由于最近个人在写码字的时候总是想一个文件创建起来总想着希望他可以自动的描述一下文件的基本信息,然后又看见貌似别人在创建.c文件的时候会自动的生成一些文件头信息,于是自己试着google配置了一下,详细的配置情况如下:

autocmd BufNewFile *.[ch],*.hpp,*.cpp exec “:call SetComment()”
func SetComment()
call setline(1,”/*===============================================================”)
call append(line(“.”), “* Copyright (C) “.strftime(“%Y”).” All rights reserved.”)
call append(line(“.”)+1, “* “)
call append(line(“.”)+2, “* #File :”.expand(“%:t”))
call append(line(“.”)+3, “* #Author : Arts”)
call append(line(“.”)+4, “* #Create date :”.strftime(“%Y-%m-%d %H:%M”))
call append(line(“.”)+5, “* #Express : “)
call append(line(“.”)+6, “* #Modified date :”.strftime(“%Y-%m-%d %H:%M”))
call append(line(“.”)+7, “* #Company : Arts”)
call append(line(“.”)+8, “* “)
call append(line(“.”)+9, “================================================================*/”)
call append(line(“.”)+10, “”)
endfunc
“更新最近修改时间和文件名
function UpdateTitle()
call setline(4,”* #File :”.expand(“%:t”))
call setline(8,”* #Modified date :”.strftime(“%Y-%m-%d %H:%M”))
endf
“判断前10行代码里面,是否有Modified这个单词,
“如果没有的话,代表没有添加过作者信息,需要新添加;
“如果有的话,那么只需要更新即可
function TitleDet()
let n=1
while n < 10
let line = getline(n)
if line =~’^.*Modified.*$’
call UpdateTitle()
return
endif
let n=n+1
endwhile
call AddTitle()
endfunction
au BufWritePost * :call UpdateTitle()
autocmd BufNewFile * normal 7G 17l

效果如下:
vi

 

1 8 9 10 11 12 20