当前位置: 首页 > news >正文

ESP32 cam (3)http协议 上传图片给电脑flask服务器 - MKT

ESP32 cam (3)http协议 上传图片给电脑flask服务器

 

 

 

image

 

image

 

image

 1 修改wifi

2 修改服务器ip和端口,笔记本分享的wifi 链接笔记本自己可能有问题,让笔记本和esp32 cam 一起连接在另一个热点

#include "esp_camera.h"
#include <WiFi.h>
#include <HTTPClient.h>// 使用AI Thinker ESP32-CAM
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"// WiFi配置
const char* ssid = "CMCC-yaoyao";
const char* password = "love123456";// Flask服务器地址
const char* serverUrl = "http://192.168.1.12:5000/upload";// 照片拍摄间隔(毫秒)
const long interval = 5000;
unsigned long previousMillis = 0;
void startCameraServer();void setup() {Serial.begin(115200);Serial.setDebugOutput(true);Serial.println("\nESP32-CAM Flask服务器图像上传程序");// 摄像头配置camera_config_t config;config.ledc_channel = LEDC_CHANNEL_0;config.ledc_timer = LEDC_TIMER_0;config.pin_d0 = Y2_GPIO_NUM;config.pin_d1 = Y3_GPIO_NUM;config.pin_d2 = Y4_GPIO_NUM;config.pin_d3 = Y5_GPIO_NUM;config.pin_d4 = Y6_GPIO_NUM;config.pin_d5 = Y7_GPIO_NUM;config.pin_d6 = Y8_GPIO_NUM;config.pin_d7 = Y9_GPIO_NUM;config.pin_xclk = XCLK_GPIO_NUM;config.pin_pclk = PCLK_GPIO_NUM;config.pin_vsync = VSYNC_GPIO_NUM;config.pin_href = HREF_GPIO_NUM;config.pin_sscb_sda = SIOD_GPIO_NUM;config.pin_sscb_scl = SIOC_GPIO_NUM;config.pin_pwdn = PWDN_GPIO_NUM;config.pin_reset = RESET_GPIO_NUM;config.xclk_freq_hz = 20000000;config.pixel_format = PIXFORMAT_JPEG;// 如果有PSRAM,使用更高的分辨率if(psramFound()){config.frame_size = FRAMESIZE_UXGA;config.jpeg_quality = 10;config.fb_count = 2;} else {config.frame_size = FRAMESIZE_SVGA;config.jpeg_quality = 12;config.fb_count = 1;config.fb_location = CAMERA_FB_IN_DRAM;}#if defined(CAMERA_MODEL_ESP_EYE)pinMode(13, INPUT_PULLUP);pinMode(14, INPUT_PULLUP);#endif// 初始化摄像头esp_err_t err = esp_camera_init(&config);if (err != ESP_OK) {Serial.printf("摄像头初始化失败: 0x%x\n", err);return;}Serial.println("摄像头初始化成功");sensor_t * s = esp_camera_sensor_get();// initial sensors are flipped vertically and colors are a bit saturatedif (s->id.PID == OV3660_PID) {s->set_vflip(s, 1); // flip it backs->set_brightness(s, 1); // up the brightness just a bits->set_saturation(s, -2); // lower the saturation}// drop down frame size for higher initial frame rates->set_framesize(s, FRAMESIZE_QVGA);#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)s->set_vflip(s, 1);s->set_hmirror(s, 1);
#endif// 连接WiFiWiFi.begin(ssid, password);Serial.print("正在连接WiFi");int timeout = 20; // 20秒超时while (WiFi.status() != WL_CONNECTED && timeout > 0) {delay(500);Serial.print(".");timeout--;}if (WiFi.status() == WL_CONNECTED) {Serial.println("\nWiFi连接成功");Serial.print("IP地址: ");Serial.println(WiFi.localIP());} else {Serial.println("\nWiFi连接失败");return;}}// 拍摄并上传照片
void captureAndUpload() {Serial.println("正在拍摄照片...");// 获取摄像头帧缓冲区camera_fb_t *fb = esp_camera_fb_get();if (!fb) {Serial.println("摄像头捕获失败");return;}Serial.printf("图片大小: %d 字节\n", fb->len);if (WiFi.status() == WL_CONNECTED) {HTTPClient http;// 开始HTTP连接http.begin(serverUrl);http.addHeader("Content-Type", "image/jpeg");http.addHeader("Content-Length", String(fb->len));// 发送POST请求int httpResponseCode = http.POST(fb->buf, fb->len);if (httpResponseCode > 0) {Serial.printf("HTTP响应代码: %d\n", httpResponseCode);if (httpResponseCode == 200) {String response = http.getString();Serial.println("服务器响应: " + response);}} else {Serial.printf("上传失败,错误: %s\n", http.errorToString(httpResponseCode).c_str());}http.end();} else {Serial.println("WiFi未连接");}// 释放帧缓冲区esp_camera_fb_return(fb);Serial.println("完成");
}void loop() {unsigned long currentMillis = millis();// 每隔interval毫秒拍摄并上传照片if (currentMillis - previousMillis >= interval) {previousMillis = currentMillis;captureAndUpload();}delay(100);
}

  

image

 

image

 

from flask import Flask, request, jsonify
import time
import os
from datetime import datetimeapp = Flask(__name__)# 创建保存图片的目录
SAVE_DIR = "captured_images"
if not os.path.exists(SAVE_DIR):os.makedirs(SAVE_DIR)@app.route('/upload', methods=['POST'])
def upload_image():try:# 获取图像数据image_data = request.dataif not image_data:return jsonify({"error": "No image data received"}), 400# 生成文件名(使用时间戳)timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")filename = f"esp32_cam_{timestamp}.jpg"filepath = os.path.join(SAVE_DIR, filename)# 保存图片with open(filepath, 'wb') as f:f.write(image_data)print(f"图片已保存: {filepath}, 大小: {len(image_data)} 字节")return jsonify({"status": "success","filename": filename,"size": len(image_data),"message": "Image uploaded successfully"}), 200except Exception as e:print(f"上传错误: {str(e)}")return jsonify({"error": str(e)}), 500@app.route('/')
def index():return "ESP32-CAM Flask服务器正在运行"if __name__ == '__main__':app.run(host='0.0.0.0', port=5000, debug=True)

  

 

http://www.jsqmd.com/news/512517/

相关文章:

  • 聊聊菲尔格林产品的优势,2026年干冰清洗机选购哪家好 - myqiye
  • IT 补丁管理的8大深坑,如何破解?
  • CNN架构解析:TranslateGemma模型中的卷积神经网络应用
  • 告别机械音!Qwen3-TTS实测:97ms低延迟生成真人级语音
  • 短视频种草新时代:传声港新媒体平台五大平台赋能品牌增长新引擎 - 博客湾
  • 刚学完苍穹外卖,大模型就杀到家门口了?传统后端开发何去何从,我该转型Agent吗?
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4:Win11右键菜单改回Win10风格——操作指南与原理讲解
  • 讲讲2026年专业的欧亚联盟EAC认证机构,荣仪达有啥优势 - mypinpai
  • [特殊字符] GLM-4V-9B系统集成:与现有CRM系统的对接实践
  • MicroPython嵌入式开发实战:GPIO/UART/I2C外设控制与低功耗设计
  • 分析AI搜索优化,南方网通讯灵AI性价比和效果究竟如何? - 工业品网
  • STM32 + RTOS移植成功率提升300%的关键动作(基于ARM Cortex-M3/M4/M7的8项寄存器级校验清单,含MPU配置checklist)
  • 谁懂!京东e卡到底怎么用啊!!!
  • Swift面试题2024:从基础到高阶的全面解析
  • AI+医疗工程化:模型上线到医院内网前,要补哪些系统能力?
  • 从GCN到GNN:图神经网络的核心演进与工业级应用剖析
  • nlp_structbert_sentence-similarity_chinese-large应对对抗性文本攻击的鲁棒性分析
  • 聊聊菲尔格林的售后响应速度快吗,价格和服务匹配吗? - 工业品牌热点
  • 企业内部智能体,能不能实现代码的自动编写、测试和运维?
  • Nanbeige 4.1-3B效果展示:同一问题下极简风vs像素风AI交互体验对比分析
  • 菲尔格林品牌靠谱不,企业文化是啥 - 工业推荐榜
  • 中国互联网大公司发展历程概述
  • 利用威尔逊电流镜优化高精度电流源的稳定性与放大倍数设计
  • Libtool-bin:翻译官的工具箱使用手册
  • 2026年北京拆迁律所推荐:宅基地家庭析产纠纷口碑律师及实战经验汇总 - 十大品牌推荐
  • 最新 AI 论文盘点(2026-03-21):8 篇新作看可靠推理、GUI Agent 奖励、VLA 可解释性与机器人真实效率
  • Qwen3.5-9B高效推理教程:vLLM后端集成+Gradio前端无缝对接方案
  • 怎么设计企业内部智能体的交互方式,让员工愿意用、用得懂?
  • csdn访问量越来越低-----可能要做好转移数据的准备
  • Qwen3-32B-Chat人力资源助手:招聘JD生成、面试问题库、员工手册编写