基於Video4Linux 的USB 攝像頭圖像採集實現

基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 1 -
基於Video4Linux 的USB 攝像頭圖像採集實現
Write by daily3(戴小鼠) 著作權:戴麗(合肥工業大學)
(email:[email protected])
做了一段時間的攝像頭圖像採集,有了一些心得。在論壇上開的2410攝像頭
問題專貼(http://www.hhcn.com/cgi-bin/topic.cgi?forum=1&topic=247&show=0
也得到了大家的關注。在此,我將這一階段遇到的問題,解決方法等做個總結,
希望對您有所幫助。
Linux本身自帶了採用ov511芯片的攝像頭,而市場上應用最廣泛的是採用中
芯微公司生產的zc301芯片的攝像頭,下面我將針對這兩大系列的攝像頭分別做
介紹。(注:所有的開發都是在華恆HHARM-2410-EDU上完成,ov511攝像頭採
用的是網眼webeye3000,zc301攝像頭採用的是ANC奧尼S888)。
一 驅動加載
1.1 ov511 驅動
1.靜態加載
(1)在arm linux的kernel目錄下make menuconfig。
(2)首先(*)選擇Multimedia device->下的Video for linux。加載video4linux模塊,
爲視頻採集設備提供了編程接口;
(3)然後在usb support->目錄下(*)選擇support for usb和usb camera ov511
support。這使得在內核中加入了對採用OV511接口芯片的USB數字攝像頭的驅動
支持。
(4)保存配置退出。
(5)make dep;make zImage
此時在/tftpboot 下就生成了帶有ov511 驅動的內核。
2.動態加載
(1)在arm linux的kernel目錄下make menuconfig。
(2)首先<*>選擇Multimedia device->下的Video for linux。
(3)然後在usb support->目錄下<*>選擇support for usb和<M>選擇usb camera
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 2 -
ov511 support。
(4)保存退出。
(5)Make dep;make zImage;make modules然後就在/driver/usb下生成ov511.o,同
時生成的zImage自動放在/tftpboot下。
(6)然後用新內核啓動板子後insmod ov511.o就可以成功加載。
動態方式與靜態方式相比,測試時要簡單的多。不需要下載整個內核,只需
通過nfs,加載驅動即可測試。在測試成功後就可以編譯進內核。
模塊加載中出現的問題:
1.insmod 和modprobe 間的一個區別試後者不會在當前目錄中查找模塊,它只
在/lib/modules 下的缺省目錄下查找,這是因爲該程序只是一個系統實用例程,
不是一個交互工具。可以通過在/etc/modules.conf 中指定自己的目錄,來把它們
加到缺省目錄集中。
2.如果插入模塊ov511.o 時,出現以下信息:
Ov511.o:unresolved symbol video********之類的,說明還有其它模塊videodev.o
沒有加。
3.出現錯誤:ov511.o:couldn’t find the kernel version this modules was compiled
for。這是試圖插入一個不是可裝入模塊的目標文件。因爲在內核配置階段,是
把ov511 模塊靜態加到內核中的,雖然看起來和可裝入模塊的文件名ov511.o 完
全一樣,但是不能用insmod 命令加入。
4.如果出現Ov511.o:unresolved symbol video********,那就<M>選中video for
linux,用新生成的內核啓動系統,再insmod videodev.o,insmod ov511.o 就可以啦。
1.2 zc301 驅動
攝像頭的驅動是從http://mxhaard.free.fr/下的針對embeded環境,有專門的patch,
我用的是usb-2.4.31LE06.patch。
(1)把它放到/HHARM9-EDU/kernel/driver/usb下,解壓,打補丁。就會在此目
錄下看到spca5xx文件夾了。可能會有一些錯誤,我的錯誤是在Makefile和config.in
文件中,根據它的提示,進行相應的修改即可。Patch時會將修改方法寫到
Makefile.rej和config.in.rej文件中,把這兩個文件裏的內容加到Makefile和config.in
中就行了。
(2)編譯內核,進入/HHARM9-EDU/kernel,make menuconfig。我採用和上面
介紹的ov511驅動的方法一樣,動態加載。(M)選中SPCA5XX這一項。
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 3 -
( 3 ) make dep ; make zImage ; make modules 。就會在
/HHARM9-EDU/kernel/driver/usb/spca5xx 中生成
spca5xx.o,spcadecoder.o,spca_core.o啦。這就是我們要的驅動。
(4)用新內核啓動,insmod這三個.o文件(可以不用加載spcadecoder.o),攝像
頭就加載成功啦。
不過這種LE的驅動有許多問題,比如運行到設置圖像格式(RGB565或RGB24)時
出錯, 說不支持此參數。原因在於: ( 摘自驅動程序主頁
http://mxhaard.free.fr/spca5le.html)
The spca5xx-LE design is very different from the spca5xx full package(LE版的驅動
和完全版的差很多)。
The memory in use are the most smaller as possible(LE版的驅動會盡量減少內存的
使用)
The spcadecoder is reduce and only raw jpeg webcam are used.(驅動模塊只支持輸
出原始jpeg格式)。
還 有 一 種方法, 從http://mxhaard.free.fr/download.html 下載最新的驅動
spca5xx-20060402.tar.gz。這個可獨立編譯,無需放到linux內核裏面,編譯生成一個spca5xx.o
即可,不要三個.o做驅動了。因爲這個驅動是針對2.6的,編譯時會出現很多錯誤,修改
CFLAGS即可。華恆的羣裏已經有編譯好的驅動提供大家下載。
模塊加載中出現的問題:
1.運行./servfox時出現Error Opening V4L interface.
我測試一下,是沒有加載驅動。雖然內核中(M)選中了驅動,但是啓動後要手
工加進去。insmod一下啦。
2.insmod spcadecoder.o時,出現錯誤:spcadecoder.o:couldn’t find the kernel version
this modules was compiled for。如果你insmod spca5xx.o成功的話就不需要再
insmod其他模塊了。
3.insmod video.o時卻說can't find the kernel version the modules was compiled for。
這是因爲video for linux一般是直接編譯到內核中去的.不需要加載的。
二 Video4linux 編程
2.1 Video4linux 簡介
Video4Linux是爲市場現在常見的電視捕獲卡和並口及USB口的攝像頭提供
統一的編程接口。同時也提供無線電通信和文字電視廣播解碼和垂直消隱的數據
接口。本文主要針對USB攝像頭設備文件/dev/video0,進行視頻圖像採集方面的
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 4 -
程序設計。
2.2 Video4linux 編程指南
1.視頻編程的流程
(1)打開視頻設備:
(2)讀取設備信息
(3)更改設備當前設置(可以不做)
(4)進行視頻採集,兩種方法:
a.內存映射
b.直接從設備讀取
(5)對採集的視頻進行處理
(6)關閉視頻設備。
定義的數據結構及使用函數
struct _v4l_struct
{
int fd;
struct video_capability capability;
struct video_buffer buffer;
struct video_window window;
struct video_channel channel[8];
struct video_picture picture;
struct video_mmap mmap;
struct video_mbuf mbuf;
unsigned char *map;
};
typedef struct _v4l_struct v4l_device;
extern int v4l_open(char *, v4l_device *);
extern int v4l_close(v4l_device *);
extern int v4l_get_capability(v4l_device *);
extern int v4l_set_norm(v4l_device *, int);
extern int v4l_get_picture(v4l_device *);
extern int v4l_grab_init(v4l_device *, int, int);
extern int v4l_grab_frame(v4l_device *, int);
extern int v4l_grab_sync(v4l_device *);
extern int v4l_mmap_init(v4l_device *);
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 5 -
extern int v4l_get_mbuf(v4l_device *);
extern int v4l_get_picture(v4l_device *);
extern int v4l_grab_picture(v4l_device *, unsigned int);
extern int v4l_set_buffer(v4l_device *);
extern int v4l_get_buffer(v4l_device *);
extern int v4l_switch_channel(v4l_device *, int);
3.Video4linux支持的數據結構及其用途
(1)video_capability 包含設備的基本信息(設備名稱、支持的最大最小分辨
率、信號源信息等)
name[32] 設備名稱
maxwidth
maxheight
minwidth
minheight
Channels 信號源個數
type 是否能capture , 彩色還是黑白, 是否能裁剪等等。值如
VID_TYPE_CAPTURE等
(2)video_picture 設備採集的圖象的各種屬性
Brightness 0~65535
hue
colour
contrast
whiteness
depth 8 16 24 32
palette VIDEO_PALETTE_RGB24 | VIDEO_PALETTE_RGB565|
VIDEO_PALETTE_JPEG| VIDEO_PALETTE_RGB32
(3)video_channel 關於各個信號源的屬性
Channel 信號源的編號
name
tuners
Type VIDEO_TYPE_TV | IDEO_TYPE_CAMERA
Norm 制式 PAL|NSTC|SECAM|AUTO
(4)video_window 包含關於capture area的信息
x x windows 中的座標.
y y windows 中的座標.
width The width of the image capture.
height The height of the image capture.
chromakey A host order RGB32 value for the chroma key.
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 6 -
flags Additional capture flags.
clips A list of clipping rectangles. (Set only)
clipcount The number of clipping rectangles. (Set only)
(5)video_mbuf 利用mmap進行映射的幀的信息
size 每幀大小
Frames 最多支持的幀數
Offsets 每幀相對基址的偏移
(6)video_mmap 用於mmap
4.關鍵步驟介紹
【注】接多個攝像頭。方法如下:買一個usb hub接到開發板的usb host上。cat
/proc/devices可以知道video capture device的major是81,再ls –l /dev看到video0
的次設備號是0。兩個攝像頭當然要兩個設備號,所以mknod /dev/video1 c 81 1,
如果接4個,就mknod /dev/video2 c 81 2,mknod /dev/video3 c 81 3。依次類推。
(1)打開視頻:
int v4l_open(char *dev, v4l_device *vd)
{
if (!dev)
dev = ”/dev/video0”;
if ((vd ->fd = open(dev, O_RDWR)) < 0) {
perror("v4l_open:");
return -1;
}
if (v4l_get_capability(vd))
return -1;
if (v4l_get_picture(vd))
retu rn -1;
return 0;
}
(2)讀video_capability 中信息
int v4l_get_capability(v4l_device *vd)
{
if (ioctl(vd ->fd, VIDIOCGCAP, &(vd->capability)) < 0) {
perror("v4l_get_capability:");
return -1;
}
return 0;
}
成功後可讀取vd->capability各分量
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 7 -
(3)讀video_picture中信息
int v4l_get_picture(v4l_device *vd)
{
if (ioctl(vd ->fd, VIDIOCGPICT, &(vd->picture)) < 0) {
perror("v4l_get_picture:");
return -1;
}
return 0;
}
成功後可讀取圖像的屬性
(4)改變video_picture中分量的值(可以不做的)
先爲分量賦新值,再調用VIDIOCSPICT
vd->picture.colour = 65535;
if(ioctl(vd->fd, VIDIOCSPICT, &(vd->picture)) < 0)
{
perror("VIDIOCSPICT");
return -1;
}
(5)初始化channel (可以不做的)
必須先做得到vd->capability中的信息
int v4l_get_channels(v4l_device *vd)
{
int i;
for (i = 0; i < vd ->capability.channels; i++) {
vd ->channel[i].channel = i;
if (ioctl(vd ->fd, VIDIOCGCHAN, &(vd->channel[i])) < 0) {
perror("v4l_get_channel:");
return -1;
}
}
return 0;
}
(6)關閉設備
int v4l_close(v4l_device *vd)
{
close(vd ->fd);
return 0;
}
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 8 -
重點:截取圖象的兩種方法
一、用mmap(內存映射)方式截取視頻
mmap( )系統調用使得進程之間通過映射同一個普通文件實現共享內存。普
通文件被映射到進程地址空間後,進程可以向訪問普通內存一樣對文件進行訪
問,不必再調用read(),write()等操作。兩個不同進程A、B共享內存的意思是,
同一塊物理內存被映射到進程A、B各自的進程地址空間。進程A可以即時看到進
程B對共享內存中數據的更新,反之亦然。
採用共享內存通信的一個顯而易見的好處是效率高,因爲進程可以直接讀寫
內存,而不需要任何數據的拷貝
(1)設置picture的屬性
(2) 初始化video_mbuf,以得到所映射的buffer的信息
ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))
(3)可以修改video_mmap和幀狀態的當前設置
(4)將mmap與video_mbuf綁定
void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )
len:映射到調用進程地址空間的字節數,它從被映射文件開頭offset個字節開始
算起
Prot:指定共享內存的訪問權限 PROT_READ(可讀), PROT_WRITE (可寫),
PROT_EXEC (可執行)
Flags:MAP_SHARED MAP_PRIVATE中必選一個,MAP_ FIXED不推薦使用
Addr:共內存享的起始地址,一般設0,表示由系統分配
Mmap( ) 返回值是系統實際分配的起始地址
int v4l_mmap_init(v4l_device *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) {
perror("v4 l_mmap_init:mmap");
return -1;
}
return 0;
}
(5)Mmap方式下真正做視頻截取的 VIDIOCMCAPTURE
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 9 -
ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) ;
若調用成功,開始一幀的截取,是非阻塞的,
是否截取完畢留給VIDIOCSYNC來判斷
(6)調用VIDIOCSYNC等待一幀截取結束
if(ioctl(vd->fd, VIDIOCSYNC, &frame) < 0)
{
perror("v4l_sync:VIDIOCSYNC");
return -1;
}
若成功,表明一幀截取已完成。可以開始做下一次 VIDIOCMCAPTURE
frame是當前截取的幀的序號。
********關於雙緩衝************
video_bmuf bmuf.frames = 2;一幀被處理時可以採集另一幀
int frame; //當前採集的是哪一幀
int framestat[2]; //幀的狀態沒開始採集|等待採集結束
幀的地址由vd->map + vd->mbuf.offsets[vd->frame]得到。
採集工作結束後調用munmap取消綁定
munmap(vd->map, vd->mbuf.size)
在實際應用時還可以採用緩衝隊列等方式。
二、視頻截取的第二種方法:直接讀設備
關於緩衝大小,圖象等的屬性須由使用者事先設置
調用read();
int read (要訪問的文件描述符;指向要讀寫的信息的指針;應該讀寫的字符數);
返回值爲實際讀寫的字符數
int len ;
unsigned char
*vd->map=
(unsigned char *) malloc(vd◊capability.maxwidth*vd◊capability.maxheight );
len = read(vd◊fd,vd◊ vd->map,
vd◊capability.maxwidth*vd◊capability.maxheight*3 );
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 10 -
2.3 編程實例(mouse_capture)
不管是ov511還是zc301的攝像頭,它們採集的方式都是相同的,只不過採集
到的數據有所差異,ov511的就是rgb的位流,而zc301是jpeg編碼的位流。
mouse_capture是根據servfox改編的一個專門從zc301攝像頭獲取一張jpeg圖片,
用來測試攝像頭是否加載成功的小程序。這樣就可以不用cat /dev/video0>1.jpg來
測試攝像頭是否正常。cat命令一運行,就源源不斷地採集jpeg流。但是採到的圖
片只能顯示第一個jpeg頭和jpeg尾之間的數據。mouse_capture僅僅獲得一張完整
的jpeg。可以從
http://www.hhcn.com/cgi-bin/topic.cgi?forum=1&topic=247&start=144&show=0
處下載參考。
現將主要函數的功能介紹如下:
static int GetVideoPict (struct vdIn *vd);//獲取圖片屬性信息。
static int SetVideoPict (struct vdIn *vd);//設置圖片屬性。
static int isSpcaChip (const char *BridgeName);//測試芯片類型
static int GetStreamId (const char *BridgeName); //測試輸出數據的格式
static int GetDepth (int format);//獲取顏色深度。
void exit_fatal(char *messages);//錯誤顯示。
int init_videoIn(struct vdIn *vd,char *device,int width,int height,int format,int
grabmethod);//初始化設備。
int convertframe(unsigned char *dst,unsigned char *src, int width,int height, int
formatIn, int size);//把共享緩衝區中的數據放到一個變量中,通知系統已獲得一
幀。
int v4lGrab (struct vdIn *vd,char *filename );//從攝像頭採集圖片。
int close_v4l (struct vdIn *vd);//關閉攝像頭。
int get_jpegsize (unsigned char *buf, int insize);//獲取jpeg圖片大小。
三 實例程序
3.1 LCD 實時顯示從ov511 上採集的圖像
參考HHARM9-EDU/applications/usbcam2lcd。從攝像頭獲取bmp位流直接顯示
在framebuffer中。此程序圖像的採集採用read的方式,注意由於lcd液晶屏顯示的
是16bits的RGB圖片,所以,ov511輸出的圖片格式也應該是16bits的RGB圖片數
據,宏VIDEO_PALETTE_RGB565定義的就是16bits的RGB數據圖片。而linux自
帶的ov511驅動中圖像採集是32位的,這樣採集到的圖片顯示在lcd上是雪花點。
因此需要修改驅動。在kernet/driver/usb/目錄下有ov511芯片的驅動ov511.c,驅
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 11 -
動裏的ov51x_set_default_params函數是設置芯片默認的輸出圖片的格式,該函數
中的
for (i = 0; i < OV511_NUMFRAMES; i++)
{
ov511->frame[i].width = ov511->maxwidth;
ov511->frame[i].height = ov511->maxheight;
ov511->frame[i].bytes_read = 0;
if (force_palette)
ov511->frame[i].format = force_palette;
else
ov511->frame[i].format = VIDEO_PALETTE_RGB24;
ov511->frame[i].depth = ov511_get_depth(ov511->frame[i].format);
}
部分語句是主要設置ov511默認輸出圖片格式的,其中maxwidth和maxheight
設置了圖片的最大的寬度和高度。Ifelse語句設置了圖片的格式,作如下的修改:
for (i = 0; i < OV511_NUMFRAMES; i++)
{
ov511->frame[i].width = ov511->maxwidth;
ov511->frame[i].height = ov511->maxheight;
ov511->frame[i].bytes_read = 0;
ov511->frame[i].format = VIDEO_PALETTE_RGB565;
ov511->frame[i].depth = ov511_get_depth(ov511->frame[i].format);
}
如果需要,也可以改變圖片的默認輸出大小。
3.2 LCD 實時顯示從zc301 上採集的圖像
編程思想:從攝像頭採集到的圖片存放在本地文件夾,通過minigui加載jpeg
來實現顯示。
具體過程:
1.從網上下載jpegsrc-6b的jpeg庫,交叉編譯。
(1)./configure –enable-static –enable-shared –prefix=.libs
(2)修改Makefile,將編譯器改成交叉編譯器。
例如:我改成/opt/host/armv4l/bin/armv4l-unknown-linux-gcc
(3)make 後即在.libs目錄中生成for arm的
libjpeg.a, libjpeg.la,libjpeg.so,libjpeg.so.62,libjpeg.so.62.0.0。將這些文件拷貝到系
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 12 -
統庫文件目錄,我的是/usr/lib中。
2.因爲看從zc301採集的圖片的二進制位流,jpeg頭是ff d8 ff db。而在minigui庫
文件libminigui的源文件src/mybmp/jpeg.c中,load_jpg和check_jpg的時候測試的頭
位EXIF和JFIF兩種格式的jpeg圖片。這兩種對應的二進制分別是ff d8 ff e1和ff d8
ff e0。所以我們minigui通過判斷認爲這是錯誤的jpeg格式而不加載,故無法顯示。
實際上通過測試,在源碼中去掉這兩個判斷就能正確加載。
3.交叉編譯minigui
( 1 ) 編譯庫: ./configure --host=arm-unknown-linux --enable-jpgsupport=yes
--enable-pngsupport=no --enable-gifsupport=no --disable-lite
--prefix=/HHARM9-EDU/applications/minigui-free/nfsroot
--enable-smdk2410ial=yes
make
make install
(2)編譯實例程序時,要加上jpeg庫的支持,即在Makefile中加上-ljpeg。此時
將在nfsroot生成的庫文件和可執行文件移到ramdisk.image.gz相應的目錄下。(具
體參考華恆的2410開發手冊)。
3.Minigui程序的編寫
編程小技巧,我採取的方法是一刻不停地從攝像頭採集到圖片存儲在
/tmp/1.jpg中,在minigui中通過loadbitmap函數來加載圖片。而圖片加載後不會自
動更新,不能自動根據1.jpg的改變自動變化。因此,我在程序中設定一個timer。
每隔100ms刷新屏幕,基本上實現實時更新了。而出現另外一個問題,刷新時會
以背景色來填充桌面,導致屏幕閃爍嚴重。故想到採用MSG_ERASEBKGND的
方式,用前一張圖片做爲刷新屏幕時的填充背景圖片。這樣就保證了lcd上圖像
的連續性啦。
Minigui程序如下:其中一些自定義的函數跟mouse_capture中的一樣,只是
變採集單幅到採集多幅。具體您可以自己改一下:)。也可以向我索取源碼。
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "spcav4l.h"
#define IDTIMER 100
static BITMAP bmp;
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 13 -
static int LoadBmpWinProc(HWND hWnd, int message, WPARAM wParam,
LPARAM lParam)
{
HDC hdc;
RECT rc={0,0,240,320};
switch (message) {
case MSG_CREATE:
SetTimer(hWnd,IDTIMER,100);
return 0;
case MSG_ERASEBKGND:
{
RECT rcTemp;
if( LoadBitmap(HDC_SCREEN,&bmp,"/tmp/1.jpg"))
{
printf("load wrong!\n");
return -1;
}
GetClientRect(hWnd, &rcTemp);
hdc = BeginPaint (hWnd);
FillBoxWithBitmap (hdc, rcTemp.left, rcTemp.top, rcTemp.right-rcTemp.left,
rcTemp.bottom-rcTemp.top, &bmp);
EndPaint(hWnd, hdc);
return 0;
}
case MSG_TIMER:
InvalidateRect(hWnd,&rc,TRUE);
return 0;
case MSG_CLOSE:
UnloadBitmap (&bmp);
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;
HWND hMainWnd;
MAINWINCREATE CreateInfo;
char videodevice[] = "/dev/video0";
char jpegfile[] = "/tmp/1.jpg";
int grabmethod = 0;
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 14 -
int format = VIDEO_PALETTE_JPEG;
int width = 240;
int height = 320;
int i;
#ifdef _LITE_VERSION
SetDesktopRect(0, 0, 1024, 768);
#endif
CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Load and display a bitmap";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = LoadBmpWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 240;
CreateInfo.by = 320;
CreateInfo.iBkColor = PIXEL_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow (hMainWnd, SW_SHOWNORMAL);
memset(&videoIn, 0, sizeof (struct vdIn));
if(init_videoIn(&videoIn, videodevice, width, height, format,grabmethod) == 0)
{
printf("init is ok!\n");
}
else printf("init is wrong!\n");
while (GetMessage(&Msg, hMainWnd)) {
TranslateMessage(&Msg);
v4lGrab(&videoIn, jpegfile);
DispatchMessage(&Msg);
}
close_v4l (&videoIn);
MainWindowThreadCleanup (hMainWnd);
return 0;
}
#ifndef _LITE_VERSION
#include <minigui/dti.c>
#endif
基於Video4Linux 的USB 攝像頭圖像採集實現戴小鼠 daily3
- 15 -
先寫到這裏吧,呵呵,希望能對您有所幫助。如果您在閱讀的過程中發現問
題,歡迎和我交流。
2006-7-7 晚
參考文獻
1.HHARM2410攝像頭調試記錄華恆科技
2.基於video4linux的視頻設備編程 Lingzhi_Shi Apr 7 2004
3.《video4linux programming》 Alan Cox
4.《video streaming 探討》陳俊宏
5.《Video4Linux Kernel API Reference 》
6.http://www.hhcn.com/cgi-bin/topic.cgi?forum=1&topic=247&show=0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章