赞
踩
其实很早之前就买过这个东西,但是没有想要做过任何关于图片获取的东西玩,所以这个东西一直吃灰,但是心里对这个东西是一直怀有期待的,但是这几天玩下来,我可以很直接地告诉大家这个东西:“在绝大多数情况下,这个东西玩玩可以,但是嵌入到项目里面很难”。
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(); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。