0% found this document useful (0 votes)
59 views28 pages

Laporan Praktikum 1

This document describes a student's practice report on face recognition video streaming using an ESP32-CAM. The report details the code used to configure the camera, connect to WiFi, and run a web server to perform face detection and analyze expressions, gender and age from the video stream.

Uploaded by

Daniel Putra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
59 views28 pages

Laporan Praktikum 1

This document describes a student's practice report on face recognition video streaming using an ESP32-CAM. The report details the code used to configure the camera, connect to WiFi, and run a web server to perform face detection and analyze expressions, gender and age from the video stream.

Uploaded by

Daniel Putra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 28

LAPORAN PRAKTIKUM

Nama : Daniel Putra Ariyanto


Kelas : BM 6B

Unit 1 : Face Recognition Video Streaming (Age,Face Expression, etc).

Code :

/*

Rui Santos

Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files.

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

*/

#include <WiFi.h>

#include <WiFiClientSecure.h>

#include "esp_camera.h"

#include "soc/soc.h"

#include "soc/rtc_cntl_reg.h"

// Replace with your network credentials

const char* ssid = "Astar0th";

const char* password = "wakemeup";

String Feedback="";

String Command="",cmd="",P1="",P2="",P3="",P4="",P5="",P6="",P7="",P8="",P9="";

byte ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;

// CAMERA_MODEL_AI_THINKER
#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

WiFiServer server(80);

void ExecuteCommand() {

if (cmd!="getstill") {

Serial.println("cmd= "+cmd+" ,P1= "+P1+" ,P2= "+P2+" ,P3= "+P3+" ,P4= "+P4+" ,P5= "+P5+" ,P6=
"+P6+" ,P7= "+P7+" ,P8= "+P8+" ,P9= "+P9);

Serial.println("");

if (cmd=="resetwifi") {

WiFi.begin(P1.c_str(), P2.c_str());

Serial.print("Connecting to ");

Serial.println(P1);
long int StartTime=millis();

while (WiFi.status() != WL_CONNECTED)

delay(500);

if ((StartTime+5000) < millis()) break;

Serial.println("");

Serial.println("STAIP: "+WiFi.localIP().toString());

Feedback="STAIP: "+WiFi.localIP().toString();

else if (cmd=="restart") {

ESP.restart();

else if (cmd=="quality") {

sensor_t * s = esp_camera_sensor_get();

int val = P1.toInt();

s->set_quality(s, val);

else if (cmd=="contrast") {

sensor_t * s = esp_camera_sensor_get();

int val = P1.toInt();

s->set_contrast(s, val);

else if (cmd=="brightness") {

sensor_t * s = esp_camera_sensor_get();

int val = P1.toInt();

s->set_brightness(s, val);

else {

Feedback="Command is not defined.";

}
if (Feedback=="") {

Feedback=Command;

void setup() {

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

Serial.begin(115200);

Serial.setDebugOutput(true);

Serial.println();

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;

//init with high specs to pre-allocate larger buffers

if(psramFound()){

config.frame_size = FRAMESIZE_UXGA;

config.jpeg_quality = 10; //0-63 lower number means higher quality

config.fb_count = 2;

} else {

config.frame_size = FRAMESIZE_SVGA;

config.jpeg_quality = 12; //0-63 lower number means higher quality

config.fb_count = 1;

// camera init

esp_err_t err = esp_camera_init(&config);

if (err != ESP_OK) {

Serial.printf("Camera init failed with error 0x%x", err);

delay(1000);

ESP.restart();

//drop down frame size for higher initial frame rate

sensor_t * s = esp_camera_sensor_get();

s->set_framesize(s, FRAMESIZE_CIF); //UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|


QQVGA 設定初始化影像解析度

WiFi.mode(WIFI_AP_STA);

WiFi.begin(ssid, password);

delay(1000);
long int StartTime=millis();

while (WiFi.status() != WL_CONNECTED) {

delay(500);

if ((StartTime+10000) < millis())

break;

if (WiFi.status() == WL_CONNECTED) {

Serial.print("ESP IP Address: http://");

Serial.println(WiFi.localIP());

server.begin();

static const char PROGMEM INDEX_HTML[] = R"rawliteral(

<!DOCTYPE html>

<head>

<title>ESP32-CAM Face Detection</title>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width,initial-scale=1">

<script src="https:\/\/code.jquery.com/jquery-3.3.1.min.js"></script>

<script src="https:\/\/cdn.jsdelivr.net/gh/justadudewhohacks/face-api.js@0.22.1/dist/face-
api.min.js"></script>

</head><body>

<div id="container"></div>

<img id="ShowImage" src="" style="display:none">

<canvas id="canvas" style="display:none"></canvas>

<table>

<tr>

<td colspan="2"><input type="button" id="getStill" value="Start Face Detection"


style="display:none"></td>

<td><input type="button" id="restart" value="Reset Board"></td>


</tr>

<tr>

<td>MirrorImage</td>

<td colspan="2">

<select id="mirrorimage">

<option value="1">yes</option>

<option value="0">no</option>

</select>

</td>

</tr>

<tr>

<td>Quality</td>

<td colspan="2"><input type="range" id="quality" min="10" max="63" value="10"></td>

</tr>

<tr>

<td>Brightness</td>

<td colspan="2"><input type="range" id="brightness" min="-2" max="2" value="0"></td>

</tr>

<tr>

<td>Contrast</td>

<td colspan="2"><input type="range" id="contrast" min="-2" max="2" value="0"></td>

</tr>

</table>

<iframe id="ifr" style="display:none"></iframe>

<div id="message" style="color:red"><div>

</body>

</html>

<script>

var getStill = document.getElementById('getStill');

var ShowImage = document.getElementById('ShowImage');

var canvas = document.getElementById("canvas");


var context = canvas.getContext("2d");

var mirrorimage = document.getElementById("mirrorimage");

var message = document.getElementById('message');

var ifr = document.getElementById('ifr');

var myTimer;

var restartCount=0;

const modelPath = 'https://ruisantosdotme.github.io/face-api.js/weights/';

let currentStream;

let displaySize = { width:400, height: 296 }

let faceDetection;

Promise.all([

faceapi.nets.tinyFaceDetector.load(modelPath),

faceapi.nets.faceLandmark68TinyNet.load(modelPath),

faceapi.nets.faceRecognitionNet.load(modelPath),

faceapi.nets.faceExpressionNet.load(modelPath),

faceapi.nets.ageGenderNet.load(modelPath)

])

getStill.onclick = function (event) {

clearInterval(myTimer);

myTimer = setInterval(function(){error_handle();},5000);

ShowImage.src=location.origin+'/?getstill='+Math.random();

function error_handle() {

restartCount++;

clearInterval(myTimer);

if (restartCount<=2) {

message.innerHTML = "Get still error. <br>Restart ESP32-CAM "+restartCount+" times.";

myTimer = setInterval(function(){getStill.click();},10000);

ifr.src = document.location.origin+'?restart';

else
message.innerHTML = "Get still error. <br>Please close the page and check ESP32-CAM.";

getStill.style.display = "block";

ShowImage.onload = function (event) {

clearInterval(myTimer);

restartCount=0;

canvas.setAttribute("width", ShowImage.width);

canvas.setAttribute("height", ShowImage.height);

canvas.style.display = "block";

if (mirrorimage.value==1) {

context.translate((canvas.width + ShowImage.width) / 2, 0);

context.scale(-1, 1);

context.drawImage(ShowImage, 0, 0, ShowImage.width, ShowImage.height);

context.setTransform(1, 0, 0, 1, 0, 0);

else {

context.drawImage(ShowImage,0,0,ShowImage.width,ShowImage.height);

DetectImage();

restart.onclick = function (event) {

fetch(location.origin+'/?restart=stop');

quality.onclick = function (event) {

fetch(document.location.origin+'/?quality='+this.value+';stop');

brightness.onclick = function (event) {

fetch(document.location.origin+'/?brightness='+this.value+';stop');

contrast.onclick = function (event) {


fetch(document.location.origin+'/?contrast='+this.value+';stop');

async function DetectImage() {

const detections = await faceapi.detectAllFaces(canvas, new


faceapi.TinyFaceDetectorOptions()).withFaceLandmarks(true).withFaceExpressions().withAgeAnd
Gender()

const resizedDetections = faceapi.resizeResults(detections, displaySize)

faceapi.draw.drawDetections(canvas, resizedDetections)

faceapi.draw.drawFaceLandmarks(canvas, resizedDetections)

faceapi.draw.drawFaceExpressions(canvas, resizedDetections)

resizedDetections.forEach(result => {

const { detection,expressions,gender,genderProbability,age } = result

message.innerHTML ="";

var maxEmotion="neutral";

var maxProbability=expressions.neutral;

if (expressions.happy>maxProbability) {

maxProbability=expressions.happy;

maxEmotion="happy";

if (expressions.sad>maxProbability) {

maxProbability=expressions.sad;

maxEmotion="sad";

if (expressions.angry>maxProbability) {

maxProbability=expressions.angry;

maxEmotion="angry";

if (expressions.fearful>maxProbability) {

maxProbability=expressions.fearful;

maxEmotion="fearful";

if (expressions.disgusted>maxProbability) {
maxProbability=expressions.disgusted;

maxEmotion="disgusted";

if (expressions.surprised>maxProbability) {

maxProbability=expressions.surprised;

maxEmotion="surprised";

document.getElementById("message").innerHTML = "<table><tr><td>Age: "


+Math.round(age)+"</td></tr><tr><td>Gender: "+gender+"</td></tr><tr><td>Gender
Probability: "+Round(genderProbability)+"</td></tr><tr><td>Emotion:
"+maxEmotion+"</td></tr><tr><td>Neutral:
"+Round(expressions.neutral)+"</td></tr><tr><td>Happy:
"+Round(expressions.happy)+"</td></tr><tr><td>Sad:
"+Round(expressions.sad)+"</td></tr><tr><td>Angry:
"+Round(expressions.angry)+"</td></tr><tr><td>Fearful:
"+Round(expressions.fearful)+"</td></tr><tr><td>Disgusted: "+Round(expressions.disgusted)
+"</td></tr><tr><td>Surprised: "+Round(expressions.surprised)+"</td></tr></table>";

var ageF = Math.round(age);

var genderProbabilityF = Math.round(genderProbability);

new faceapi.draw.DrawTextField(

`${ageF} years`,

`${gender} (${genderProbabilityF})`

],

result.detection.box.bottomRight

).draw(canvas)

})

try {

document.createEvent("TouchEvent");

setTimeout(function(){getStill.click();},500);

catch(e) {

setTimeout(function(){getStill.click();},500);

}
}

function Round(n) { return Math.round(Number(n)*100)/100; }

</script>

)rawliteral";

void loop() {

Feedback="";Command="";cmd="";P1="";P2="";P3="";P4="";P5="";P6="";P7="";P8="";P9="";

ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;

WiFiClient client = server.available();

if (client) {

String currentLine = "";

while (client.connected()) {

if (client.available()) {

char c = client.read();

getCommand(c);

if (c == '\n') {

if (currentLine.length() == 0) {

if (cmd=="getstill") {

camera_fb_t * fb = NULL;

fb = esp_camera_fb_get();

if(!fb) {

Serial.println("Camera capture failed");

delay(1000);

ESP.restart();

}
client.println("HTTP/1.1 200 OK");

client.println("Access-Control-Allow-Origin: *");

client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type,


Accept");

client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");

client.println("Content-Type: image/jpeg");

client.println("Content-Disposition: form-data; name=\"imageFile\";


filename=\"picture.jpg\"");

client.println("Content-Length: " + String(fb->len));

client.println("Connection: close");

client.println();

uint8_t *fbBuf = fb->buf;

size_t fbLen = fb->len;

for (size_t n=0;n<fbLen;n=n+1024) {

if (n+1024<fbLen) {

client.write(fbBuf, 1024);

fbBuf += 1024;

else if (fbLen%1024>0) {

size_t remainder = fbLen%1024;

client.write(fbBuf, remainder);

esp_camera_fb_return(fb);

else {

client.println("HTTP/1.1 200 OK");

client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type,


Accept");

client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");

client.println("Content-Type: text/html; charset=utf-8");


client.println("Access-Control-Allow-Origin: *");

client.println("Connection: close");

client.println();

String Data="";

if (cmd!="")

Data = Feedback;

else {

Data = String((const char *)INDEX_HTML);

int Index;

for (Index = 0; Index < Data.length(); Index = Index+1000) {

client.print(Data.substring(Index, Index+1000));

client.println();

Feedback="";

break;

} else {

currentLine = "";

else if (c != '\r') {

currentLine += c;

if ((currentLine.indexOf("/?")!=-1)&&(currentLine.indexOf(" HTTP")!=-1)) {

if (Command.indexOf("stop")!=-1) {

client.println();

client.println();

client.stop();

}
currentLine="";

Feedback="";

ExecuteCommand();

delay(1);

client.stop();

void getCommand(char c){

if (c=='?') ReceiveState=1;

if ((c==' ')||(c=='\r')||(c=='\n')) ReceiveState=0;

if (ReceiveState==1) {

Command=Command+String(c);

if (c=='=') cmdState=0;

if (c==';') strState++;

if ((cmdState==1)&&((c!='?')||(questionstate==1))) cmd=cmd+String(c);

if ((cmdState==0)&&(strState==1)&&((c!='=')||(equalstate==1))) P1=P1+String(c);

if ((cmdState==0)&&(strState==2)&&(c!=';')) P2=P2+String(c);

if ((cmdState==0)&&(strState==3)&&(c!=';')) P3=P3+String(c);

if ((cmdState==0)&&(strState==4)&&(c!=';')) P4=P4+String(c);

if ((cmdState==0)&&(strState==5)&&(c!=';')) P5=P5+String(c);

if ((cmdState==0)&&(strState==6)&&(c!=';')) P6=P6+String(c);

if ((cmdState==0)&&(strState==7)&&(c!=';')) P7=P7+String(c);

if ((cmdState==0)&&(strState==8)&&(c!=';')) P8=P8+String(c);

if ((cmdState==0)&&(strState>=9)&&((c!=';')||(semicolonstate==1))) P9=P9+String(c);

if (c=='?') questionstate=1;

if (c=='=') equalstate=1;
if ((strState>=9)&&(c==';')) semicolonstate=1;

Hasil :

Unit 2 : Face Recognition (Comparing Two Photos)


Code :

/*********

Rui Santos

Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files.

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

*********/

#include "WiFi.h"

#include "esp_camera.h"

#include "esp_timer.h"

#include "img_converters.h"

#include "Arduino.h"

#include "soc/soc.h" // Disable brownout problems

#include "soc/rtc_cntl_reg.h" // Disable brownout problems

#include "driver/rtc_io.h"

#include <ESPAsyncWebServer.h>

#include <StringArray.h>

#include <SPIFFS.h>

#include <FS.h>

// Replace with your network credentials

const char* ssid = "Astar0th";

const char* password = "wakemeup";

// Create AsyncWebServer object on port 80

AsyncWebServer server(80);

boolean takeNewPhoto = false;


boolean takeNewPhoto2 = false;

// Photo File Name to save in SPIFFS

String FILE_PHOTO = "/photo.jpg";

String FILE_PHOTO_2 = "/test-photo.jpg";

// CAMERA_MODEL_AI_THINKER

#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

const char index_html[] PROGMEM = R"rawliteral(

<!DOCTYPE html>

<html>

<head>

<title>ESP32-CAM Face Recognition</title>

<meta name="viewport" content="width=device-width,initial-scale=1">


<meta http-equiv="Access-Control-Allow-Headers" content="Origin, X-Requested-With,
Content-Type, Accept">

<meta http-equiv="Access-Control-Allow-Methods" content="GET,POST,PUT,DELETE,OPTIONS">

<meta http-equiv="Access-Control-Allow-Origin" content="*">

<title>ESP32-CAM Face Detection and Recognition</title>

<script src="https:\/\/code.jquery.com/jquery-3.3.1.min.js"></script>

<script src='https:\/\/cdn.jsdelivr.net/gh/justadudewhohacks/face-api.js@0.22.1/dist/face-
api.min.js'></script>

<style>

#container { padding: 0; }

canvas {

position: absolute;

top: 0;

left: 0;

z-index:999;

img {

width: auto ;

max-width: 100% ;

height: auto ;

.flex-container { display: flex; }

@media only screen and (max-width: 600px) {

.flex-container {

flex-direction: column;

button {

padding: 10px;

margin-bottom: 30px;

</style>
</head>

<body>

<div class="flex-container">

<div>

<div id="container"></div>

<img src="photo.jpg" id="newImage"></img>

<h2>Face Detection and Recognition</h2>

<button onclick="capturePhoto();">2# FACE RECOGNITION - CAPTURE PHOTO</button>

</div>

<div>

<img src="test-photo.jpg"></img>

<h2>Face Enrolled - Test Photo</h2>

<button onclick="captureTestPhoto()">1# ENROLL NEW FACE - CAPTURE TEST


PHOTO</button>

</div>

</div>

<div>

<p><b>How to use this ESP32-CAM Face Recognition example:</b></p>

<ol>

<li>Press the "ENROLL NEW FACE - CAPTURE TEST PHOTO" button and refresh the page</li>

<li>Press the "FACE RECOGNITION - CAPTURE PHOTO" button</li>

<li>Refresh the page. The face recognition code runs automatically, so you have to wait 5 to
40 seconds for an alert with the face recognition result.</li>

</ol>

<p><b>IMPORTANT:</b> if you don't see a popup with your Face Recognition result, refresh
the web page and wait a few seconds. I only recommend testing this web server on a
laptop/desktop computer with Google Chrome web browser.</p>

<p>You can only do face recognition for one subject - your TEST PHOTO should only have one
face.</p>

</div>

</body>

<script>

function capturePhoto() {
var xhr = new XMLHttpRequest();

xhr.open('GET', "/capture-photo", true);

xhr.send();

function captureTestPhoto(){

var xhr = new XMLHttpRequest();

xhr.open('GET', "/capture-test-photo", true);

xhr.send();

var ShowImage = document.getElementById('newImage');

const modelPath = 'https://ruisantosdotme.github.io/face-api.js/weights/';

let currentStream;

let displaySize = { width:320, height: 400 }

let convas;

let faceDetection;

Promise.all([

faceapi.nets.faceRecognitionNet.loadFromUri(modelPath),

faceapi.nets.faceLandmark68Net.loadFromUri(modelPath),

faceapi.nets.ssdMobilenetv1.loadFromUri(modelPath)

]).then(start());

async function start() {

const container = document.createElement('div')

container.style.position = 'relative'

document.body.append(container)

const labeledFaceDescriptors = await loadLabeledImages()

const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, 0.6)

if( document.getElementsByTagName("canvas").length == 0 ) {

canvas = faceapi.createCanvasFromMedia(ShowImage)

document.getElementById('container').append(canvas)

const displaySize = { width: ShowImage.width, height: ShowImage.height }


faceapi.matchDimensions(canvas, displaySize)

const detections = await


faceapi.detectAllFaces(ShowImage).withFaceLandmarks().withFaceDescriptors()

const resizedDetections = faceapi.resizeResults(detections, displaySize)

const results = resizedDetections.map(d => faceMatcher.findBestMatch(d.descriptor))

results.forEach((result, i) => {

const box = resizedDetections[i].detection.box

const drawBox = new faceapi.draw.DrawBox(box, { label: result.toString() })

drawBox.draw(canvas)

if( result.toString().indexOf("unknown") == -1) {

var xhr = new XMLHttpRequest();

xhr.open('GET', "/trigger", true);

xhr.send();

})

alert("DONE!");

function loadLabeledImages() {

const labels = ['SARA SANTOS']

return Promise.all(

labels.map(async label => {

const descriptions = []

const img = await faceapi.fetchImage(window.location.href+"test-photo.jpg")

const detections = await


faceapi.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor()

descriptions.push(detections.descriptor)

return new faceapi.LabeledFaceDescriptors(label, descriptions)

})

</script>

</html>)rawliteral";
void setup() {

// Serial port for debugging purposes

Serial.begin(115200);

// Connect to Wi-Fi

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(1000);

Serial.println("Connecting to WiFi...");

if (!SPIFFS.begin(true)) {

Serial.println("An Error has occurred while mounting SPIFFS");

ESP.restart();

else {

delay(500);

Serial.println("SPIFFS mounted successfully");

// Print ESP32 Local IP Address

Serial.print("IP Address: http://");

Serial.println(WiFi.localIP());

// Turn-off the 'brownout detector'

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

// OV2640 camera module

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;

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;

// Camera init

esp_err_t err = esp_camera_init(&config);


if (err != ESP_OK) {

Serial.printf("Camera init failed with error 0x%x", err);

ESP.restart();

// Route for root / web page

server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {

request->send_P(200, "text/html", index_html);

});

server.on("/capture-photo", HTTP_GET, [](AsyncWebServerRequest * request) {

takeNewPhoto = true;

request->send_P(200, "text/plain", "Taking Photo");

});

server.on("/trigger", HTTP_GET, [](AsyncWebServerRequest * request) {

Serial.println("Trigger action");

request->send_P(200, "text/plain", "Trigger");

});

server.on("/capture-test-photo", HTTP_GET, [](AsyncWebServerRequest * request) {

takeNewPhoto2 = true;

request->send_P(200, "text/plain", "Taking Photo");

});

server.on("/photo.jpg", HTTP_GET, [](AsyncWebServerRequest * request) {

request->send(SPIFFS, FILE_PHOTO.c_str(), "image/jpg", false);

});

server.on("/test-photo.jpg", HTTP_GET, [](AsyncWebServerRequest * request) {

request->send(SPIFFS, FILE_PHOTO_2.c_str(), "image/jpg", false);


});

// Start server

server.begin();

void loop() {

if (takeNewPhoto) {

takeNewPhoto = capturePhotoSaveSpiffs(FILE_PHOTO.c_str());

if (takeNewPhoto2) {

takeNewPhoto2 = capturePhotoSaveSpiffs(FILE_PHOTO_2.c_str());

delay(1);

// Check if photo capture was successful

bool checkPhoto( fs::FS &fs , const char* photoName) {

File f_pic = fs.open( photoName );

unsigned int pic_sz = f_pic.size();

return ( pic_sz > 100 );

// Capture Photo and Save it to SPIFFS

bool capturePhotoSaveSpiffs( const char* photoName ) {

camera_fb_t * fb = NULL; // pointer

bool ok = 0; // Boolean indicating if the picture has been taken correctly

do {

// Take a photo with the camera

Serial.println("Taking a photo...");
fb = esp_camera_fb_get();

if (!fb) {

Serial.println("Camera capture failed");

return true;

// Photo file name

Serial.printf("Picture file name: %s\n", photoName);

File file = SPIFFS.open(photoName, FILE_WRITE);

// Insert the data in the photo file

if (!file) {

Serial.println("Failed to open file in writing mode");

else {

file.write(fb->buf, fb->len); // payload (image), payload length

Serial.print("The picture has been saved in ");

Serial.print(photoName);

Serial.print(" - Size: ");

Serial.print(file.size());

Serial.println(" bytes");

// Close the file

file.close();

esp_camera_fb_return(fb);

// check if file has been correctly saved in SPIFFS

ok = checkPhoto(SPIFFS, photoName);

} while ( !ok );

return false;

}
Hasil :

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy