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
)";
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);
}
`