Code Monkey home page Code Monkey logo

esp32-cam-style-transfer's Introduction

ESP32-CAM-Style-Transfer

How to apply Machine Learning to ESP32-CAM. Tranform images using Neural Style Transfer. This repository contains the code to apply Style Transfer to images captured by the ESP32-CAM. It uses Magenta.js to apply Neural style transfer. Explore how to use Machine Learning to create artificial images. Find more information at Art with ESP32-CAM: Style Transfer - Magenta JS

esp32-cam-style-transfer's People

Contributors

survivingwithandroid avatar

Stargazers

 avatar

Watchers

 avatar  avatar

esp32-cam-style-transfer's Issues

Stream is not being sourced in the webpage.

I have been trying to do the Neural Style Transfer using ESP32 cam with the help of your post. I cloned the source code for the ESP from your Git Hub and added the extra code for the webpage from your post as a string in the provided ESP setup code. The stream is visible on port 81 on my IP and the webpage is visible on adding /art to the IP, but the webpage is showing an error in sourcing the stream as it is trying to get the stream from your IP which is given in the post. I changed the IP everywhere in the code but I'm still receiving the same error message. It would be very helpful if you provide me with some guidance.
The code is provided below:
`#include <Arduino.h>
#include <WiFi.h>
#include "esp_http_server.h"
#include "esp_timer.h"
#include "esp_camera.h"
#include "img_converters.h"
#include "camera_pins.h"
#include "page.h"

#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";

httpd_handle_t camera_httpd = NULL;
httpd_handle_t stream_httpd = NULL;

const char* ssid = "";
const char
password = "
**";

const char htmlContent[] = R"(

<title>ESP32-CAM Style Transfer</title> <style> body { font-family: "PT Sans", sans-serif; background: radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%); color: #636060; line-height: 1.6; } a { text-decoration: none; color: #ccc; } h2 { margin-left: auto; margin-right: auto; color: #ffffff; margin-bottom: 10px; } h3 { color: #ffffff; } .custom-file-upload { border: 1px solid #ccc; display: inline-block; padding: 6px 12px; cursor: pointer; margin-top: 5px; background: #a944a6; color: #FFFFFF; } input[type="file"] { display: none; } button { margin-top: 5px; } </style> <script src="https://cdn.jsdelivr.net/npm/@magenta/image@^0.2.1"></script>

Current IP Address: 192.168.1.1

<script language="javascript"> function loadImage(event) { var selectedFile = event.target.files[0]; var reader = new FileReader(); var styleImg = document.getElementById("img_style"); styleImg.title = selectedFile.name;
        reader.onload = function(event) {
           styleImg.src = event.target.result;
        };
     
        reader.readAsDataURL(selectedFile);
     }
     
     function applyStyle() {
        console.log("Applying style...");
        const model = new mi.ArbitraryStyleTransferNetwork();
       
        const contentImg = document.getElementById("img_source");
        const styleImg = document.getElementById("img_style");
        const stylizedCanvas = document.getElementById("stylized");
     
        contentImg.onload = function() {
           console.log("Capturing content image..");
           model.initialize().then( function() {
              model.stylize(contentImg, styleImg).then((imageData) => {
                 stylizedCanvas.getContext("2d").putImageData(imageData, 0, 0);
                 contentImg.onload = null;
                 contentImg.src = "http://192.168.1.6/capture?t=" + Math.random();
              });
           });
        }
       
        contentImg.src = "http://192.168.1.6/capture?t=" + Math.random();
     }
  </script>

Magenta Style Transfer with ESP32-CAM

Select your style file
Apply Style to Image

Your styled image

)";

static esp_err_t capture_handler(httpd_req_t *req){
Serial.println("Capture image");
camera_fb_t *fb = NULL;
esp_err_t res = ESP_OK;
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}

httpd_resp_set_type(req, "image/jpeg");
httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");

res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
esp_camera_fb_return(fb);

return res;
}

static esp_err_t page_handler(httpd_req_t req) {
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "
");
httpd_resp_send(req, page, sizeof(page));
return ESP_OK;
}

static esp_err_t stream_handler(httpd_req_t *req){
camera_fb_t *fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t *_jpg_buf = NULL;
char part_buf[64];

res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if (res != ESP_OK) {
return res;
}

httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");

while (true) {
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if (fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if (!jpeg_converted) {
Serial.println("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
if (res == ESP_OK) {
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if (res == ESP_OK) {
size_t hlen = snprintf(part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, part_buf, hlen);
}
if (res == ESP_OK) {
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if (fb) {
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if (_jpg_buf) {
free(_jpg_buf);
_jpg_buf = NULL;
}
if (res != ESP_OK) {
break;
}
}
return res;
}

void startCameraServer(){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();

httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};

httpd_uri_t page_uri = {
.uri = "/art",
.method = HTTP_GET,
.handler = page_handler,
.user_ctx = NULL
};

httpd_uri_t capture_uri = {
.uri = "/capture",
.method = HTTP_GET,
.handler = capture_handler,
.user_ctx = NULL
};

Serial.printf("Starting web server on port: '%d'\n", config.server_port);
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(camera_httpd, &capture_uri);
httpd_register_uri_handler(camera_httpd, &page_uri);
}

// Start stream using another webserver
config.server_port += 1;
config.ctrl_port += 1;
Serial.printf("Starting stream server on port: '%d'\n", config.server_port);
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &index_uri);
}
}

void setup() {
Serial.begin(9600);
Serial.println("Serial communication started.");

// ... (Other setup code)

WiFi.begin(ssid, password);

Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("");
Serial.println("Failed to connect to WiFi");
return;
}

// Camera configuration
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_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;

// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
if (psramFound()) {
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}

#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif

// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}

sensor_t *s = esp_camera_sensor_get();
// initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_vflip(s, 1); // flip it back
s->set_brightness(s, 1); // up the brightness just a bit
s->set_saturation(s, 0); // lower the saturation
}
// drop down frame size for higher initial frame rate
s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE)
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
#endif

startCameraServer();

Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
}

void loop() {
// put your main code here, to run repeatedly:
delay(10);
}
`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.