ESP32-CAM之ST7789图像显示

news/2024/12/2 19:57:35/

ESP32-CAM之ST7789

最近笔者在学习使用安信可的ESP32-CAM开发板,该开发板自带一个OV2640摄像头。
官方提供的例程可以将摄像头视频通过WIFI传输到网页显示,而笔者手里正好有一块240x240像素的屏幕,便想将摄像头的图像显示到该屏幕上。

从esp32-camera\sensor.h 头文件中可以找到

#define OV9650_PID     (0x96)
#define OV2640_PID     (0x26)
#define OV7725_PID     (0x77)
#define OV3660_PID     (0x36)
图像分辨率
typedef enum {FRAMESIZE_QQVGA,    // 160x120FRAMESIZE_QQVGA2,   // 128x160FRAMESIZE_QCIF,     // 176x144FRAMESIZE_HQVGA,    // 240x176FRAMESIZE_QVGA,     // 320x240FRAMESIZE_CIF,      // 400x296FRAMESIZE_VGA,      // 640x480FRAMESIZE_SVGA,     // 800x600FRAMESIZE_XGA,      // 1024x768FRAMESIZE_SXGA,     // 1280x1024FRAMESIZE_UXGA,     // 1600x1200FRAMESIZE_QXGA,     // 2048*1536FRAMESIZE_INVALID
} framesize_t;
图像格式
typedef enum {PIXFORMAT_RGB565,    // 2BPP/RGB565PIXFORMAT_YUV422,    // 2BPP/YUV422PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALEPIXFORMAT_JPEG,      // JPEG/COMPRESSEDPIXFORMAT_RGB888,    // 3BPP/RGB888PIXFORMAT_RAW,       // RAWPIXFORMAT_RGB444,    // 3BP2P/RGB444PIXFORMAT_RGB555,    // 3BP2P/RGB555
} pixformat_t;

可以看到Arduino core for the ESP32库支持4种摄像头,ESP32-CAM开发板搭载的是OV2640,而IPS屏幕像素为240x240,所以选FRAMESIZE_HQVGA(240x176)格式。
查看 <Arduino_ST7789.h> 库文件

// Color definitions
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFFvoid Arduino_ST7789::drawPixel(int16_t x, int16_t y, uint16_t color) {if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;setAddrWindow(x,y,x+1,y+1);SPI_BEGIN_TRANSACTION();DC_HIGH();CS_LOW();spiwrite(color >> 8);spiwrite(color);CS_HIGH();SPI_END_TRANSACTION();
}

可以看到该驱动库采用RGB颜色空间,比如
RED=0xF800=11111_000000_00000,
GREEN=0x07E0=00000_111111_00000,BLUE=0x001F=00000_000000_11111,所以每个像素点为16位数据,即RGB565格式。

使用以下函数将OV2640图像格式设置为RGB565,分辨率设置为240x176。

  .pixel_format = PIXFORMAT_RGB565,.frame_size = FRAMESIZE_HQVGA,

使用以下函数将单帧图像数据通过串口输出到串口调试助手

Serial.write(fb->buf, fb->len);

接收数据为下图所示,单帧RGB565格式图像数据为84480字节,刚好等于 240 x 176 x 2,该帧图像数据并不像JPEG图像输出数据那样有头部格式字节,所以当笔者将该图像数据存到内存卡里时,在电脑端会显示无法打开该图像。
在这里插入图片描述
下图为单帧JPEG格式图像数据:
这个单帧数据数据量有点问题,且每次接收到的都不太一样,可能传输过程中出了点错误。
但是数据前面的FF DB FF E0 是正确的JPEG格式。
而且每帧的数据量比RGB565格式少很多,后面有时间再研究图像格式。
在这里插入图片描述
好了。根据上面的内容我们就可以写程序了。
直接根据ESP32官方camera例程修改。
主要的函数为:
每一个像素点数据为RGB565单帧数据的每两个字节组合而成。

void camera_show(void)
{unsigned long i=0;camera_fb_t *fb = esp_camera_fb_get();//单帧图像数据输出
//    delay(2000);
//    delay(2000);
//    delay(2000);
//    Serial.write(fb->buf, fb->len);
//    delay(2000);
//    delay(2000);
//    delay(2000);for(uint8_t y = 0; y <SCREEN_HEIGHT; y ++){for(uint8_t x = 0; x <SCREEN_WIDTH; x ++){//RGB565格式 240X176tft.drawPixel(x,60+y,((fb->buf[2*i])<<8)|(fb->buf[2*i+1]));i++;}}esp_camera_fb_return(fb);
}

图像显示效果:

在这里插入图片描述
这个屏幕正常的显示效果是有目共睹的好,但是测试显示效果不太清晰,可能还需要设置一下OV2640的一些参数才能达到更清晰的效果,然后笔者在屏幕的左上角显示了帧率,可以看到平均两秒一帧(真是有够慢的)。由于是arduino开发,不太好改速率,后面有时间慢慢深入库文件再来提高速度吧。

完整程序及相关驱动库链接


http://www.ppmy.cn/news/272669.html

相关文章

【软考笔记】9. 多媒体基础

文章目录 基本概念音频声音的带宽声音的采样采样频率采样精度 图像亮度色调饱和度彩色空间RGB&#xff1a;彩色显示器YUV&#xff08;YIQ YCBCR&#xff09;&#xff1a;电视CMY&#xff08;CMYK&#xff09;&#xff1a;印刷HSV&#xff08;HSB&#xff09;&#xff1a;艺术家…

Google bot能够执行Javascript,Google bot的分辨率是1600x1200

如图&#xff0c;Google搜索“js 播放器 支持 ipad”&#xff1a; 我用js做了一个字号自动放大功能&#xff0c;检测到用户的浏览器分辨率&#xff0c;然后设置字号。用js innerHTML一段提示显示分辨率。 今天突然发现此js提示出现在Google搜索结果中&#xff0c;显示Google bo…

Stm32标准库函数5——摄像头OV2640 F103C8T6 串口显示高分辨率图像640x480 1024x768 1024x1024 1600x1200 二百万像素

stm32f103c8t6串口发送 OV2640的图像&#xff0c;分辨率可选。网络上资料大部分是低分辨率的&#xff0c;这个可以做高分辨率 完整工程打包&#xff0c;包含VB串口显示界面&#xff1a; Stm32标准库函数5-OV2640PA0-7F103C8T64500000联合VB高分辨率资源-单片机文档类资源-CSDN…

Ubuntu12.04新增屏幕分辨率

有时ubuntu汇总没有我们需要的分辨率,这时需要自己新增,很简单,4个步骤即可完成,下面结合新增1600x1200例子来介绍如何新增分辨率: 使用两个工具&#xff1a; xrandr 和 cvt 1.终端输入 cvt 1600 1200 60 (60为分辨率) 这时终端会出现一串参数,先甭管它,后面会用到. 2.将上…

数字图像处理基本知识

1、数字图像&#xff1a; 数字图像&#xff0c;又称为数码图像或数位图像&#xff0c;是二维图像用有限数字数值像素的表示。数字图像是由模拟图像数字化得到的、以像素为基本元素的、可以用数字计算机或数字电路存储和处理的图像。 2、数字图像处理包括内容&#xff1a; 图像…

Effective第三版 中英 | 第二章 创建和销毁对象 | 固定资源首选使用依赖注入

文章目录 Effective第三版前言第二章 创建和销毁对象固定资源首选使用依赖注入 Effective第三版 前言 大家好&#xff0c;这里是 Rocky 编程日记 &#xff0c;喜欢后端架构及中间件源码&#xff0c;目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记&#xff0…

C#,码海拾贝(37)——求解“托伯利兹方程组“的“列文逊方法“之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> /…

Servlet 详解

目录 什么是 servlet? Servlet 是做甚的? 如何编写一个 Servlet 程序? 解析访问出错情况 Servlet 的运行原理 1. 接收请求 2. 根据请求计算响应 3. 返回响应 Servlet API 详解 HTTPServlet HttpServletRequset HttpServletResponse 什么是 servlet? Servlet 是…