在LCD显示摄像头图像

Posted 勇士后卫头盔哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在LCD显示摄像头图像相关的知识,希望对你有一定的参考价值。

框架

我们将从摄像头读到数据在LCD上显示,首先将摄像头数据读出到一块内存上,然后设置好LCD控制器从这块内存读取数据到LCD显示屏上,对于摄像头数据格式来说有YUV,MJPEG,RGB,而我们的LCD只支持RGB格式的数据格式,所以这里面还要将读取到的摄像头头数据进行一数据格式的转化,除了数据格式的转换外还需要分辨率的转化,如下图所示流程:

我们以面向对象的思路来写这个应用程序,首先抽象出对象的结构体,对于读过程我们可以抽象出如下结构体
用V4L2框架读取摄像头图像

struct VideoDevice 
    int iFd;
    int iPixelFormat;
    int iWidth;
    int iHeight;

    int iVideoBufCnt;
    int iVideoBufMaxLen;
    int iVideoBufCurIndex;
    unsigned char *pucVideBuf[NB_BUFFER];

    /* 函数 */
    PT_VideoOpr ptOPr;
;
/*视频数据缓冲区*/
typedef struct VideoBuf 
    T_PixelDatas tPixelDatas;//视频数据的参数
    int iPixelFormat;//视频数据格式
T_VideoBuf, *PT_VideoBuf;

struct VideoOpr 
    char *name;/*设备名字*/
    int (*InitDevice)(char *strDevName, PT_VideoDevice ptVideoDevice);//初始化设备
    int (*ExitDevice)(PT_VideoDevice ptVideoDevice);//退出设备
    int (*GetFrame)(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf); //得到缓冲区数据
    int (*GetFormat)(PT_VideoDevice ptVideoDevice);//获取格式
    int (*PutFrame)(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf);//将缓冲区放入队列
    int (*StartDevice)(PT_VideoDevice ptVideoDevice);//开始运行设备
    int (*StopDevice)(PT_VideoDevice ptVideoDevice);//停止运行设备
    struct VideoOpr *ptNext;
;
/*设备结构体*/
struct VideoDevice

   .iPixelFormat //格式
   .width        //图像的宽
   .height       //图像的高

/*操作该设备的结构体*/
struct VideoOper

   .InitDevice //初始化设备
   .exitDevice //退出设备
   .GetFrame   //得到缓冲区数据
   .PutFrame   //将缓冲区放入队列
   .StartDevice //开始运行设备
   .stopDevice  //停止运行设备

对于转换过程我们抽象出以下的结构体,如果我们的摄像头支持YUV转化为RGB,MJPEG转化为RGB,RGB转化为RGB,我们就构造出3个结构体我们实现不同的转化
转化结构体

typedef struct VideoConvert 
    char *name;/* 显示模块的名字 */
    int (*isSupport)(int iPixelFormatIn, int iPixelFormatOut);/*是否支持该格式的转化*/
    int (*Convert)(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut);/*转化函数*/
    int (*ConvertExit)(PT_VideoBuf ptVideoBufOut);/*退出转化函数*/
    struct VideoConvert *ptNext;/*链表*/
T_VideoConvert, *PT_VideoConvert;

对于显示过程我们抽象出如下的结构,我们只需要构造出两个结构体,一个表示在LCD屏幕显示,一个在VGA显示
显示结构体

typedef struct DispOpr 
	char *name;              /* 显示模块的名字 */
	int iXres;               /* X分辨率 */
	int iYres;               /* Y分辨率 */
	int iBpp;                /* 一个象素用多少位来表示 */
	int iLineWidth;          /* 一行数据占据多少字节 */
	unsigned char *pucDispMem;   /* 显存地址 */
	int (*DeviceInit)(void);     /* 设备初始化函数 */
	int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor);    /* 把指定座标的象素设为某颜色 */
	int (*CleanScreen)(unsigned int dwBackColor);                    /* 清屏为某颜色 */
	int (*ShowPage)(PT_PixelDatas ptPixelDatas);                         /* 显示一页,数据源自ptVideoMem */
	struct DispOpr *ptNext;      /* 链表 */
T_DispOpr, *PT_DispOpr;

代码讲解

1.将各个结构体注册到其管理文件中并选择想要的结构体进行初步的操作

2.启动摄像头并将摄像头的视频数据放到临时缓冲区

3.对摄像头的视频数据缓冲区进行格式转化

4.进行图片数据的缩放

5.刷数据的LCD的显存上

以上是关于在LCD显示摄像头图像的主要内容,如果未能解决你的问题,请参考以下文章

V4L2采集图像并在LCD上显示的图像格式问题

LCD屏幕的驱动

LCD屏幕的驱动

LCD屏幕的驱动

STM32CubeMX学习笔记(38)——FSMC接口使用(TFT-LCD屏显示)

STM32CubeMX学习笔记(39)——FSMC接口使用(TFT-LCD屏触摸)