这段时间成功的开发了中星微301H摄像头的wince驱动和视频采集程序。中星微摄像头出来的数据为JPEG格式,我们将其直接读出,交给应用程序来解
码,就可以显示图像。中间的过程我们可以参考Linux
GSPCA的驱动,将其移植到wince中就可以了。中间的关键是要理解Linux的驱动,知道摄像头的初始化,取得一幅完整的图像。幸好我以前开发过
Linux USB的主和从设备,Wince
USB的主和从设备的驱动,虽然如此,我还是花了一些时间,主要是要稳定,可靠。下面是我参考的一些资料,非常有用。
USB摄像头的数据采集
的一般流程为传感器接口――>图像信号处理-->图像压缩-->USB传输。一般USB摄像头对采集图像都作了压缩(内置JPEG硬件
压缩),压缩是为了提高图像传输效率,也就是动态分配USB带宽技术,使DSP采集的图像可以在USB1.0上传输效率提高,现在能够使640*480帧
率高达30帧/秒。至于传输协议,目前几乎所有的厂商使用自己的图像传输协议。将来USB摄像头会有统一的标准。要将USB摄像头和嵌入式系统相连时可能
的,但是最好嵌入式系统使用Linux来做操作系统。这样可以找到开发源代码的驱动,然后再针对自己的要求作二次开发。
JPEG的文件格式
JPEG
的文件格式 JPEG文件大体上可以分成以下两个部分:标记码(Tag)加压缩数据。先介绍标记码部分。
标记码部分给出了JPEG图象的所有信息(有点类似于BMP中的头信息,但要复杂的多),如图象的宽、高、Huffman表、量化表等等。标记码有很多,
但绝大多数的JPEG文件只包含几种。注意 JPEG/JFIF 文件格式使用 Motorola
格式,而不是Intel格式,就是说,如果是一个字的话, 高字节在前, 低字节在后.
JPG文件是由一个个段(segments)构成的.
每个段长度<=65535.每个段从一个标记字开始.标记字都是0xff打头的,以非0字节和 0xFF
结束.例如"FFDA","FFC4","FFC0".每个标记有它特定意义,这是由第2字节指明的.例如,SOS(StartOf Scan=
"FFDA")指明了你应该开始解码.另一个标记DQT(Define Quantization Table =
0xFFDB)就是说它后面有64字节的quantization表在处理JPG文件时,如果你碰到一个0xFF,而它后面的字节不是0,并且这个字节没
有意义.那么你遇到的0xFF字节必须被忽略.(一些JPG
里,常用用0xFF做某些填充用途)如果你在做huffman编码时碰巧产生了一个0xFF,那么就用0xFF
0x00代替.就是说在jpeg图形解码时碰到FF00就把它当作FF处理.另外在huffman编码区域结束时,碰到几个bit没有用的时候,应该用1
去填充.然后后面跟 FF.
下面是必须处理的标记
SOF0 = Start Of Frame 0 = FFC0
SOS = Start Of Scan = FFDA
APP0 = it"s the marker used to identify a JPG file which uses the JFIF
specification = FFE0
COM = Comment = FFFE
DNL = Define Number of Lines = FFDC
DRI = Define Restart Interval = FFDD
DQT = Define Quantization Table = FFDB
DHT = Define Huffman Table = FFC4
段的类型:
SOF0: Start Of Frame 0:
~~~~~~~~~~~~~~~~~~~~~~~
- $ff, $c0 (SOF0)
- 长度 (高字节, 低字节), 8+components*3
- 数据精度 (1 byte) 每个样本位数, 通常是 8 (大多数软件不支持 12 和 16)
- 图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
- 图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
- components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图
是 4
- 每个 component: 3 bytes
- component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
- 采样系数 (bit 0-3 vert., 4-7 hor.)
- quantization table 号
DRI: Define Restart Interval:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- $ff, $dd (DRI)
- 长度 (高字节, 低字节), 必须是 4
- MCU 块的单元中的重新开始间隔 (高字节, 低字节),
意思是说, 每 n 个 MCU 块就有一个 RSTn 标记.
第一个标记是 RST0, 然后是 RST1 等, RST7 后再从 RST0 重复
DQT: Define Quantization Table:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- $ff, $db (DQT)
- 长度 (高字节, 低字节)
- QT 信息 (1 byte):
bit 0..3: QT 号(0..3, 否则错误)
bit 4..7: QT 精度, 0 = 8 bit, 否则 16 bit
- n 字节的 QT, n = 64*(精度+1)
备注:
- 一个单独的 DQT 段可以包含多个 QT, 每个都有自己的信息字节
- 当精度=1 (16 bit), 每个字都是高位在前低位在后
DAC: Define Arithmetic Table:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
法律原因, 现在的软件不支持 arithmetic 编码.
不能生产使用 arithmetic 编码的 JPEG 文件
DHT: Define Huffman Table:
~~~~~~~~~~~~~~~~~~~~~~~~~~
- $ff, $c4 (DHT)
- 长度 (高字节, 低字节)
- HT 信息 (1 byte):
bit 0..3: HT 号 (0..3, 否则错误)
bit 4 : HT 类型, 0 = DC table, 1 = AC table
bit 5..7: 必须是 0
- 16 bytes: 长度是 1..16 代码的符号数. 这 16 个数的和应该 <=256
- n bytes: 一个包含了按递增次序代码长度排列的符号表
(n = 代码总数)
备注:
- 一个单独的 DHT 段可以包含多个 HT, 每个都有自己的信息字节
COM: 注释:
~~~~~~~~~~
- $ff, $fe (COM)
- 注释长度 (高字节, 低字节) = L+2
- 注释为长度为 L 的字符流
SOS: Start Of Scan:
~~~~~~~~~~~~~~~~~~~
- $ff, $da (SOS)
- 长度 (高字节, 低字节), 必须是 6+2*(扫描行内组件的数量)
- 扫描行内组件的数量 (1 byte), 必须 >= 1 , <=4 (否则是错的) 通常是 3
- 每个组件: 2 bytes
- component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q), 见 SOF0
- 使用的 Huffman 表:
- bit 0..3: AC table (0..3)
- bit 4..7: DC table (0..3)
- 忽略 3 bytes (???)
备注:
- 图片数据 (一个个扫描行) 紧接着 SOS 段.
http://blog.csdn.net/wincemobile/archive/2008/05/05/2396547.aspx