接下来2-3篇博文将会更ESP32_CAM的也就是那个小的带有摄像头接口的ESP32的用法
首先要说说这几天玩下来对这个东西的看法
其实很早之前就买过这个东西,但是没有想要做过任何关于图片获取的东西玩,所以这个东西一直吃灰,但是心里对这个东西是一直怀有期待的,但是这几天玩下来,我可以很直接地告诉大家这个东西:“在绝大多数情况下,这个东西玩玩可以,但是嵌入到项目里面很难”。
1.因为首先,这个东西用的和我们之前用的那个ESP32长方形那种板子用的是一样的核心,也就是说他们之间的外设使用是通用的,但是由于本来ESP32外设接口就不多,只有30来个,而ESP32_CAM将为数不多的IO用于驱动摄像头以及SD卡之后,板子上只剩下7-8个IO了,拓展性变得很差了,多半只能充当一个附属模块的作用,比如核心MCU向ESP32_CAM发送一个指令,然后ESP32_CAM就拍摄一张图片,当然,拍摄图片本身没有任何意义,我们必须想办法把这个图片传输出来才行,我目前一下就能想到的只有三种思路,一种是阿里的OSS对象存储,但是没有相关的资料,要去尝试估计不容易,还有一种是FTP推出来,这种相对要容易一些,最后一种,使用UDP/TCP 将图片传输到一个局域网服务器上,再由局域网服务器推到云端,这种也比较容易实现,局域网服务器直接那一个树莓派就能做微服务器了,当做中转非常不错。
2.上面说了,他作为一个辅助模块,也许还能有点用,比如一些场景下传感器检测到了异常,需要将现场图片推到云端供我们用户随时查看,但是他单独使用呢???说实话,我觉得很糟糕,因为他无非就那几个适用方向,监控?简单的视觉?,这两个是最容易想到的,但是别怪我给大家泼冷水,这两个方面他都没有优势可言,监控?大家可以在淘宝上看看监控摄像头成品多少钱,几十块百把块的一大堆,相比之下ESP32_CAM只是便宜了3-4十块钱却还要自己开发,功能也不如别人的成品产品,那拿他去专门搞监控有啥优势可言?而一些简单的比如颜色,形状识别呢?大家运行下面的获取图像例程就会发现,ESP32_CAM已经非常烫了,只是流畅获取图像就已经让ESP32没有多少剩下的CPU算力腾出来给你运行太麻烦的算法,所以我觉得流畅得弄个颜色,形状识别基本也就极限了,毕竟50块钱的东西你就想搞啥大工程,就不要YY了。关于这个识别方面的我暂时不会更,后面会专门更机器视觉的学习笔记(不是针对这个,是针对树莓派),如果那时候有时间,会回头下想办法更一下这个,说简单估计也不简单。
好了,给大家上代码
这个代码是获取图像的,图像的属性在camera_config 这个里面设置(图片大小以及特性(灰度图?RGB565等等)),然后大家可以在串口里面看到我们拍摄的图片的大小,但是看不到实际的图片,下一篇我会教大家用他的SD卡存储将我们的图片存储到SD卡上,大家就能直观看到了,或者在IDE 的例程里面找到ESP32那一栏,第二个硬件驱动例程分文件夹里面有一个CAMERA的web输出例程,是官方的例程,运行之后串口会打印出一个局域网内的访问地址,大家就可以在这个地址里面查看了,但是只能局域网内哈,比如连接的同一个wifi,你要是拿手机流量访问肯定是不行的。
//#include "SSD1306.h"
#include "esp_camera.h"
#include "2_TFT_SPI.h"
//SSD1306 display(0x3c, 15, 14); // sda:15,scl:14
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
static camera_config_t camera_config = {
.pin_pwdn = PWDN_GPIO_NUM,
.pin_reset = RESET_GPIO_NUM,
.pin_xclk = XCLK_GPIO_NUM,
.pin_sscb_sda = SIOD_GPIO_NUM,
.pin_sscb_scl = SIOC_GPIO_NUM,
.pin_d7 = Y9_GPIO_NUM,
.pin_d6 = Y8_GPIO_NUM,
.pin_d5 = Y7_GPIO_NUM,
.pin_d4 = Y6_GPIO_NUM,
.pin_d3 = Y5_GPIO_NUM,
.pin_d2 = Y4_GPIO_NUM,
.pin_d1 = Y3_GPIO_NUM,
.pin_d0 = Y2_GPIO_NUM,
.pin_vsync = VSYNC_GPIO_NUM,
.pin_href = HREF_GPIO_NUM,
.pin_pclk = PCLK_GPIO_NUM,
//XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_RGB565,//YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_QQVGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG
.jpeg_quality = 12, //0-63 lower number means higher quality
.fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG
};
esp_err_t camera_init(){
//initialize the camera
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
Serial.print("Camera Init Failed");
return err;
}
return ESP_OK;
}
void show_image(const uint8_t *image)
{
showimage(image, 120, 160, 0, 0);
}
esp_err_t camera_capture(){
uint8_t * buf = NULL;
size_t buf_len = 0;
//acquire a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
Serial.print("Camera Capture Failed");
return ESP_FAIL;
}
//bool converted = frame2bmp(fb, &buf, &buf_len);
//for(int i = 0;i < fb->len;i++)
//{
//Serial.print(fb->buf[i], HEX);
// Serial.print(" ");
//}
//Serial.println();
Serial.println(fb->len);
Serial.println(fb->buf[0]);
//show_image(fb->buf); //这是我之前的那个LCD的驱动,用这个显示,但是显示效果不好,图像干扰很大,但是能看出来图片是获取到了的,下一篇会教大家使用SD卡模块存储,就能直观看到图片了
esp_camera_fb_return(fb);
return ESP_OK;
}
void setup() {
Serial.begin(115200);
//lcd_io_set(14,15,13,12,2,0);
//LCD_Init();
//LCD_Clear(GREEN);
camera_init(); //摄像头初始化
camera_capture(); //摄像头获取图像
Serial.println("sys is running");
}
void loop() {
camera_capture();
}
2万+

被折叠的 条评论
为什么被折叠?



