您当前位置:深圳微智科技有限公司>公司新闻, 焦点关注> 液晶显示器上显示USB摄像头图像
液晶显示器上显示USB摄像头图像
发布时间: 2018-06-19      大小:  16px  14px  12px

 

如何让USB摄像头的图像在显示屏上显示呢,下面的案例实现了VGA图像在LCD液晶上面的显示,希望各位提出宝贵的意见,非常感谢;

1.摄像头读取数据,放在缓冲区videobuf中,格式有YUV,MJPEG,RGB等。然后再进行转换成LCD所支持的RGB格式。除此之外还需要进行数据的缩放,以适合各种格式的分辨率,最后将数据写入framebuffer。这样LCD控制器将会framebuffer中的数据显示到LCD上。

2.先构造一个videodeivce结构体,成员有表示格式的iPixelFormat成员,表示大小的iWidth,iHeight,用于操作的VideoOpr结构体,其中有各种操作函数。这个操作函数结构体中的函数有:InitDevice,ExitDevice,GetFrame,PutFrame,StartFrame,StopFrame等操作函数。

3.转换结构体有YUV2RGB,MJEPG2RGB,RGB2RGB三种结构体。

4.采集模块中:定义结构体typedef struct VideoDevice;操作函数结构体typedef struct VideoOpr;//用于操作摄像头,这个操作函数结构体放在上面那个VideoDevice结构体中,作为成员;再定义一个typedef struct VideoBuf结构体,用于存储摄像头读取到的数据和格式。定义的操作都放在Video_manager.h文件中。

5.在video_manager.c文件中有函数RegisterVideoOpr(),ShowVideoOpr(),GetVideoOpr(),VideoInit()等。在V4l2.c文件中,构造一个VideoOpr结构体:static T_VideoOpr g_tV4l2VideoOpr;注册结构体函数是int V4l2Init(void);接下来的步骤就是填充这个g_tV4l2VideoOpr结构体。参考luvcview可以逐步实现具体功能。

6.在上面这个结构体中填充操作函数:v4l2InitDevice()

Open() //调用系统调用,打开设备节点。

Ioctl(VIDIOC_QUERYCAP)//调用ioctl函数,通过驱动查询设备类型的结构体tV4l2Cap。我们通过结构体成员capabilities确定是否支持V4L2_CAP_VIDEO_CAPTURE即视频捕捉设备,是否支持V4L2_CAP_STREAMING和V4L2_CAP_READWRITE接口的数据读取方式。

Ioctl(VIDIOC_ENUM_FMT)//通过驱动以遍历的方式查看当前驱动支持的所有设备格式,并与当前可支持的所有格式相比较,如果发现其中有可支持的格式,则可说明此驱动支持应用中所需的格式。

Ioctl(VIDIOC_SET_FMT)//设置摄像头输出指定的格式。这个格式中使用的格式为上面函数得到的可支持的格式,使用的分辨率为LCD显示设备的分辨率,如果驱动程序发现某些参数无法支持,如分辨率,它会调整这些参数并且返回应用程序,这些实际设置的分辨率的返回值也将它保存起来。

Ioctl(VIDIOC_REQBUFS)//来请求分配缓冲区,其中可设置将buf映射到应用空间中。

Ioctl(VIDIOC_QUERYBUFS)我们设置申请4个缓冲区,实际不一定申请了4个,申请结果也将它保存起来。如果我们是read,write调用,则不必mmap就可直接读取数据,如果是streaming接口方式读取数据,则接下来必须进行mmap方式,应用层才能读取数据,且映射时针对每一个具体的 buffer,根据实际申请的缓冲区映射,并将每个映射后的地址保存起来。

Ioctl(VIDIOC_QBUF)//将缓冲区放入队列

V4l2StartDevice

Ioctl(VIDIOC_STREAMON)//启动摄像头

V4l2StopDevice

Ioctl(VIDIOC_STREAMOFF)//关闭摄像头

V4l2GetFrameForStreaming

Poll()//通过摄像头文件节点来监控设备数据。有数据后,将数据放入缓冲区,并调用ioctl(VIDIOC_DQBUF)将缓冲区从队列中取出来。

V4l2PutFrameForStreaming

Ioctl(VIDIOC_QBUF)//将缓冲区放入队列。

V4l2GetFrameForReadWrite

Read();//读取数据,并将数据存放起来

7.每个格式下像素的大小:对应YUV格式的像素,位宽为16位;对于MJPEG格式,没有像素位宽而言;对于RGB565格式,像素位宽为16位。

8.接下来我们来进行格式的转换。当我们编写Yuv2Rgb.c文件时我们设置只允许输入格式为YUV格式,输出格式为RGB565和RGB32格式。YUV转到RGB的算法这里使用网上的算法,将YUV数据中取出R,G,B三种颜色的数据。并将RGB三种颜色数据分别保留第5位,6位,5位,最后合成16位颜色值。最后将这两个字节的颜色值保存。当我们编写Mjpeg2Rgb.c文件时,我们需要把内存中的JPEG图像转换为RGB图像。MJPEG格式转换为RGB格式的算法方法也是网上提供的,这个算法里JPEG图片通过jpeg_read_scanlines函数读出一行一行的数据,并进行转换。当我们编写Rgb2Rgb.c文件时,我们设置只允许输入格式为RGB565格式。如果输出格式也是RGB565格式的,则直接memcpy()复制得到输出数据即可。如果输出格式为RGB32,则先取出R,G,B三种颜色数据,然后将数据重新合成RBG32格式即可。