esp32-cam使用SD卡/web端保存拍摄图片到本地

目录

      • 一、esp32-cam运行esp-who的人脸识别
        • 报错
      • 二、挂载sd卡到esp32-cam,并将拍摄的图片保存到sd卡
      • 三、通过web示例对拍摄的图片进行保存

保存拍摄图片主要是想加在人脸识别这个项目中,所以先把人脸识别示例跑通,然后在把挂在sd卡的部分放进来,或者使用web端保存图片。

一、esp32-cam运行esp-who的人脸识别

esp-who项目地址:https://github.com/espressif/esp-who

esp32cam一般购买会赠送一个下载器,如果没有下载器,按下面的接线方式进入下载模式(记得短接IOD引脚,可以用一个跳线帽或者杜邦线),可进行烧录程序。(建议自己接线,使用下载器有时候就会报错A fatal error occurred: Failed to connect to ESP32: No serial data received.
在这里插入图片描述
接线模式进行烧录流程如下:

1)按上方接好线以后,使用esp idf进行烧录

F:\esp-who\examples\human_face_detection\terminal  $ idf.py set-target esp32
F:\esp-who\examples\human_face_detection\terminal  $ idf.py flash monitor -p COM34

在这里插入图片描述

2)出现上面的界面时,把IOD的短接取消(拔掉跳线帽或杜邦线),同时按一下RST键,就能烧录成功了。

报错

idf.py flash monitor的时候会报错camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND); who_camera: Camera init failed with error 0x105

在这里插入图片描述

解决方法,做下面两处修改后再重新烧录idf.py flash monitor

1)esp32默认的sdk配置文件,修改一下模组的名字。
在这里插入图片描述
2)idf.py menuconfig对I2C修改

在这里插入图片描述

二、挂载sd卡到esp32-cam,并将拍摄的图片保存到sd卡

主要参考esp idf自带的示例Espressif\frameworks\esp-idf-v5.0.4\examples\storage\sd_card\sdmmc

esp-who\examples\human_face_detection\terminal的基础上修改下面几处:

(1)esp-who\examples\human_face_detection\terminal\main\app_main.cpp,在主函数中将sd卡挂载到系统中。

在这里插入图片描述

#include "who_camera.h"
#include "who_human_face_detection.hpp"

#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "esp_log.h"
#include "driver/sdmmc_host.h"

static const char *TAG = "app_main";
#define MOUNT_POINT "/sdcard"

static QueueHandle_t xQueueAIFrame = NULL;

extern "C" void app_main()
{   
    esp_err_t ret;
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
        .format_if_mount_failed = true,
#else
        .format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
        .max_files = 5,
        .allocation_unit_size = 16 * 1024
    };
    sdmmc_card_t *card;
    const char mount_point[] = MOUNT_POINT;
    ESP_LOGI(TAG, "Initializing SD card");

    ESP_LOGI(TAG, "Using SDMMC peripheral");
    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
    slot_config.width = 4;
#else
    slot_config.width = 1;
#endif

#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
    slot_config.clk = CONFIG_EXAMPLE_PIN_CLK;
    slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD;
    slot_config.d0 = CONFIG_EXAMPLE_PIN_D0;
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
    slot_config.d1 = CONFIG_EXAMPLE_PIN_D1;
    slot_config.d2 = CONFIG_EXAMPLE_PIN_D2;
    slot_config.d3 = CONFIG_EXAMPLE_PIN_D3;
#endif  // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
#endif  // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX

    slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
    ESP_LOGI(TAG, "Mounting filesystem");
    ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
    if (ret != ESP_OK) {
        if (ret == ESP_FAIL) {
            ESP_LOGE(TAG, "Failed to mount filesystem. "
                     "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
        } else {
            ESP_LOGE(TAG, "Failed to initialize the card (%s). "
                     "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
        }
        return;
    }
    ESP_LOGI(TAG, "Filesystem mounted");
    sdmmc_card_print_info(stdout, card);

    xQueueAIFrame = xQueueCreate(2, sizeof(camera_fb_t *));

    register_camera(PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, xQueueAIFrame);
    register_human_face_detection(xQueueAIFrame, NULL, NULL, NULL, true);
}

(2)抓取图片的线程中增加保存图片到sd卡的步骤,修改代码esp-who\components\modules\camera\who_camera.c
在这里插入图片描述

static void task_process_handler(void *arg)
{
    while (true)
    {
        camera_fb_t *frame = esp_camera_fb_get();
    // 保存原始图片到本地
    esp_err_t res = ESP_OK;
    size_t _jpg_buf_len;
    uint8_t *_jpg_buf;
    if (!frame) {
      ESP_LOGE(TAG, "Camera capture failed");
      res = ESP_FAIL;
      break;
    }
    if (frame->format != PIXFORMAT_JPEG) {
      bool jpeg_converted = frame2jpg(frame, 80, &_jpg_buf, &_jpg_buf_len);
      if (! jpeg_converted) {
        ESP_LOGE(TAG, "JPEG compression failed");
        esp_camera_fb_return(frame);
        res = ESP_FAIL;
      }
    } else {
      _jpg_buf_len = frame->len;
      _jpg_buf = frame->buf;
    }
    if (res == ESP_OK) {
        const char *file_name = "/sdcard/image.jpg";
        ESP_LOGE(TAG, "Opening file %s", file_name);
        FILE *f = fopen(file_name, "wb");
        if (f == NULL) {
            ESP_LOGE(TAG, "Failed to open file for writing\n");
            fclose(f);
        } else {
            fwrite((const char *)_jpg_buf, 1, _jpg_buf_len, f);
            fclose(f);
            ESP_LOGE(TAG, "write img finished!\n");
        }
    }
    if (frame->format != PIXFORMAT_JPEG) {
      free(_jpg_buf);
    }
        if (frame)
            xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
    }
}

(3)挂载sd卡用到了fatfs文件系统,esp-idf有自带fatfs组件,要想在自己的工程中调用则在CMake文件中直接添加组件的名字就行了,esp-who\components\modules\CMakeLists.txt
在这里插入图片描述
对上面三处都修改完毕后,再重新烧录idf.py flash monitor,这样拍摄的图片就保存到sd卡中了。
在这里插入图片描述

三、通过web示例对拍摄的图片进行保存

esp-who\examples\human_face_detection\web的基础上修改下面几处:

(1)esp-who\examples\human_face_detection\web\sdkconfig.defaults.esp32配置文件中需要把模组名从ESP_EYE修改为AI_THINKER,并且增加可连接的WIFI的账号和密码。
在这里插入图片描述

(2)同样需要在idf.py set-target esp32idf.py menuconfig修改I2C为I2C0。

在这里插入图片描述

操作完毕就可以idf.py flash monitor烧录了。

F:\esp-who\examples\human_face_detection\web  $ idf.py set-target esp32
F:\esp-who\examples\human_face_detection\web  $ idf.py menuconfig # 修改I2C
F:\esp-who\examples\human_face_detection\web  $ idf.py flash monitor -p COM34

在这里插入图片描述

使用连接了同一个wifi的另一个设备网页端输入这个IP地址打开,点击左下角的Start Stream,就能出现实时的画面了,画面的右上角有个Save键,可以保存当前帧到本地。

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/311196.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7.云原生之jenkins集成SonarQube

1. 私有云实战之基础环境搭建 2. 云原生实战之kubesphere搭建 3.云原生之kubesphere运维 4. 云原生之kubesphere基础服务搭建 5.云原生安全之kubesphere应用网关配置域名TLS证书 6.云原生之DevOps和CICD 7.云原生之jenkins集成SonarQube 8.云原生存储之Ceph集群 文章目录 搭建 …

美国证券交易委员会 X 账户被黑,引发比特币市场震荡

Bleeping Computer 网站消息&#xff0c;威胁攻击者成功“占领”了美国证券交易委员会的 X 账户&#xff0c;并发布一条关于批准比特币 ETF 在证券交易所上市的虚假公告。 帖子原文&#xff1a;今天&#xff0c;美国证券交易委员会批准比特币 ETF 在注册的国家证券交易所上市&a…

Blazor快速开发框架Known-V2.0.0

Known2.0 Known是基于Blazor的企业级快速开发框架&#xff0c;低代码&#xff0c;跨平台&#xff0c;开箱即用&#xff0c;一处代码&#xff0c;多处运行。 官网&#xff1a;http://known.pumantech.comGitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;ht…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第十天-Linux下mplayer音乐播放器练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

实现接口自动化测试

最近接到一个接口自动化测试的case&#xff0c;并展开了一些调研工作&#xff0c;最后发现&#xff0c;使用pytest测试框架并以数据驱动的方式执行测试用例&#xff0c;可以很好的实现自动化测试。这种方式最大的优点在于后续进行用例维护的时候对已有的测试脚本影响很小。当然…

CAN201 计网概念收集

Lecture 1 the theoretical basis for networking Network edge and core 地理覆盖范围&#xff1a;广WAN&#xff0c;城MAN&#xff0c;局LAN&#xff0c;个PAN 交换方式&#xff0c;电路&#xff0c;报文&#xff0c;分组 电路交换vs报文vs分组 Network performance pr…

[AutoSar]基础部分 RTE 07 VFB虚拟功能总线

目录 关键词平台说明一、VFB1.1VFB是什么1.1VFB的好处1.2VFB的坏处 二、VFB在ECU内部的描述2.1Components2.2 Port-Interfaces2.3 Port2.4 Compositions 关键词 嵌入式、C语言、autosar、VFB 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0…

浅析NVMe key per IO加密技术-3

三、Key per IO行业规范支持情况 Key Per I/O功能在行业规范中的支持情况&#xff1a; NVMe标准已经批准并采纳了NVMe TP4055提案&#xff0c;明确支持并定义了如何使用每个I/O操作独立的加密密钥技术。这意味着NVMe设备可以实现对每一个数据传输请求进行单独加密&#xff0c;…

降压恒压 耐压DC60V芯片,SL3037B替代HT7463A、兼容替代HT7463B

在当今的电子设备中&#xff0c;电源管理芯片扮演着至关重要的角色。它们负责为设备提供稳定的电压&#xff0c;确保设备的正常运行。然而&#xff0c;随着技术的不断发展&#xff0c;一些传统的电源管理芯片已经无法满足现代设备的需要。此时&#xff0c;寻找一种能够替代传统…

0111qt

实现闹钟&#xff0c;并播报懒虫...~ daytest.pro: QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (th…

nginx和CDN应用

一、代理的工作机制 1&#xff0e;代替客户机向网站请求数据&#xff0c;从而可以隐藏用户的真实IP地址。 2&#xff0e;将获得的网页数据&#xff08;静态 Web 元素&#xff09;保存到缓存中并发送给客户机&#xff0c;以便下次请求相同的数据时快速响应。 二、代理服务器的…

Windows7共享文档—开启方法及用户权限设置

使用计算机的朋友&#xff0c;在工作中经常需要在局域网中将文件共享给其他用户&#xff0c;这样其他人可以方便的通过局域网查看&#xff0c;甚至修改这些共享文件。当然&#xff0c;根据文件的重要程度&#xff0c;使用等级不同&#xff0c;不同的用户会赋予不同的权限&#…

进行商城的测试用例设计思路是什么?

进行商城的测试用例设计时&#xff0c;可以考虑以下思路&#xff1a; 1. 功能测试&#xff1a;测试商城的基本功能是否正常工作&#xff0c;包括用户注册、登录、浏览商品、搜索商品、添加商品到购物车、下单、支付等。 2. 数据验证测试&#xff1a;验证商城中的数据是否正确…

Linux 配置FTP服务器 + vsftpd服务安装配置 (Good篇)

CSDN 成就一亿技术人&#xff01; VSFTPD 实现客户端和服务器之间传输文件 CSDN 成就一亿技术人&#xff01; 目录 什么是VSFTPD&#xff1f; VSFTPD 的特点和功能 1. 设置和使用FTP服务器的步骤 1. 下载vsftpd包 2. 启动服务 开机自启 3. 关闭防火墙 4. 配置vsftpd服…

Base64编码:数据传输的安全使者

Base64编码是一种将二进制数据转换为可传输的文本表示形式的方法&#xff0c;它在全球范围内被广泛应用于网络通信、数据存储和传输等领域。本文将从多个方面介绍Base64编码的原理、应用及其在现实场景中的优势&#xff0c;帮助您深入了解这一重要的编码技术。 Base64编码解码…

MySql workBench客户端菜单汉化最新版

找到Mysql Workbench安装目录 如&#xff1a;D:\soft\MySQL\MySQL Workbench 8.0 CE\ 进入data目录&#xff1a;D:\soft\MySQL\MySQL Workbench 8.0 CE\data 里面有main_menu.xml文件&#xff0c;将汉化文件覆盖即可 main_menu.xml汉化内容 注意篇幅限制请移步下载完整版完…

Window平台安装MongoDB

在部署前需要在官网先确定系统对应的Mongo DB版本。 本机电脑为Window10&#xff0c;所以这里以MongoDB 6.0版本。 1 在官网下载安装包 2 安装MongoDB MongoDB Compass 是一个图形界面管理工具&#xff0c;如果勾选了安装会花费长一点时间&#xff0c;可以取消掉勾选&#xff…

C++ Primer 6.2参数传递 知识点+练习题

C Primer 6.2参数传递 知识点练习题 指针形参使用引用拷贝Const 形参实参尽量使用常量引用数组形参数组引用形参传递多维数组向main函数传参数含有可变形参的函数练习题待更新 指针形参 void reset(int *p) {*p0;//p指向的整型对象变为0p0;//只是对形参改变p&#xff0c;使其为…

NPN PNP SS8050 SS8550 S8050

SS8050的使用及引脚判断方法 今天讲的是NPN型三极管SS8050&#xff0c;主要分为以下几个方面&#xff1a; 一、前言 二、SS8050简介 三、NPN三极管与PNP三极管 四、三极管管脚识别方法 五、不拆卸三极管判断其好坏 六、S8050和SS8050的区别 七、三极管与MOS管的区别 八…

Modern C++ std::mutex底层原理

前言 我时常有这样的疑问&#xff1a; std::mutex怎么就能保证后面的语句100%安全哪&#xff1f;CPU reordering就不会把这些语句重排到mutex前面执行&#xff1f;而且各个CPU都是有L1、L2缓存的&#xff0c;如果mutex后面要访问的的变量在这些缓存中怎么办&#xff1f; 带着…