commited flask_org

parent 86fada0c
/OrgiCheck_Flask/input
\ No newline at end of file
/flask_orgiC/input
\ No newline at end of file
......@@ -48,7 +48,7 @@
</div>
</div>
</nav>
<br>
<!-- Showcase -->
<section
class="bg-dark text-light p-5 p-lg-0 pt-lg-5 text-center text-sm-start"
......@@ -74,7 +74,7 @@
</div>
<img
class="img-fluid w-50 d-none d-sm-block"
src="/img/gopro.png"
src="public/img/gopro.png"
alt=""
/>
</div>
......@@ -97,6 +97,41 @@
</div>
</section>
<!-- Check Sections -->
<section id="cam" class="p-5 bg-dark text-light">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md">
<img id="stream" src="http://192.168.8.103/saved-photo" class="img-fluid" alt=""/>
<!-- <script>
const img = document.querySelector('#stream');
const WS_URL = 'ws:///192.168.8.105:8888';
const ws = new WebSocket(WS_URL);
let urlObject;
ws.onopen = () => console.log(`Connected to ${WS_URL}`);
ws.onmessage = message => {
const arrayBuffer = message.data;
if(urlObject){
URL.revokeObjectURL(urlObject);
}
urlObject = URL.createObjectURL(new Blob([arrayBuffer]));
img.src = urlObject;
}
</script> -->
</div>
<div class="col-md p-5">
<h2>Device Connection</h2>
<p>
Please connect your <span class="text-warning"> OrgiCheck&trade; Smart</span> with the same network
</p>
<a href="http://192.168.8.103" class="btn btn-light mt-3">
<i class="bi bi-camera"></i> Retake Image
</a>
</div>
</div>
</div>
</section>
<!-- Boxes -->
<section id="check" class="p-5">
<div class="container">
......@@ -108,8 +143,18 @@
<i class="bi bi-bookmark-heart"></i>
</div>
<h3 class="card-title mb-3">Organicness</h3>
<form action="/">
<input class="btn btn-primary" type="file" id="img" name="img" accept="image/*">
<br>
<br>
<button data-bs-toggle="modal"
data-bs-target="#organic" class="btn btn-warning">Check with choosed image</button>
</form>
or
<br>
<button data-bs-toggle="modal"
data-bs-target="#organic" class="btn btn-success">Check</button>
data-bs-target="#organic" class="btn btn-success">Check with captured image</button>
</div>
</div>
</div>
......@@ -120,8 +165,19 @@
<i class="bi bi-bug"></i>
</div>
<h3 class="card-title mb-3">Diseases</h3>
<form action="/">
<input class="btn btn-primary" type="file" id="img" name="img" accept="image/*">
<br>
<br>
<button data-bs-toggle="modal"
data-bs-target="#diseases" class="btn btn-warning">Check with choosed image</button>
</form>
or
<br>
<button data-bs-toggle="modal"
data-bs-target="#diseases" class="btn btn-success">Check</button>
data-bs-target="#diseases" class="btn btn-success">Check with captured image</button>
</div>
</div>
</div>
......@@ -132,9 +188,22 @@
<i class="bi bi-hand-thumbs-up"></i>
</div>
<h3 class="card-title mb-3">Quality</h3>
<form action="/">
<input class="btn btn-primary" type="file" id="img" name="img" accept="image/*">
<br>
<br>
<button data-bs-toggle="modal"
data-bs-target="#quality" class="btn btn-warning">Check with choosed image</button>
</form>
or
<br>
<button data-bs-toggle="modal"
data-bs-target="#quality" class="btn btn-success">Check</button>
data-bs-target="#quality" class="btn btn-success">Check with captured image</button>
</div>
</div>
</div>
<div class="col-md">
......@@ -144,45 +213,22 @@
<i class="bi bi-cash"></i>
</div>
<h3 class="card-title mb-3">Price</h3>
<form action="/">
<input class="btn btn-primary" type="file" id="img" name="img" accept="image/*">
<br>
<br>
<button data-bs-toggle="modal"
data-bs-target="#price" class="btn btn-warning">Check with choosed image</button>
</form>
or
<br>
<button data-bs-toggle="modal"
data-bs-target="#price" class="btn btn-success">Check</button>
</div>
</div>
</div>
</div>
</div>
</section>
data-bs-target="#price" class="btn btn-success">Check with captured image</button>
</div>
<!-- Check Sections -->
<section id="cam" class="p-5 bg-dark text-light">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md">
<img id="stream" src="http://192.168.8.107/saved-photo" class="img-fluid" alt=""/>
<!-- <script>
const img = document.querySelector('#stream');
const WS_URL = 'ws:///192.168.8.105:8888';
const ws = new WebSocket(WS_URL);
let urlObject;
ws.onopen = () => console.log(`Connected to ${WS_URL}`);
ws.onmessage = message => {
const arrayBuffer = message.data;
if(urlObject){
URL.revokeObjectURL(urlObject);
}
urlObject = URL.createObjectURL(new Blob([arrayBuffer]));
img.src = urlObject;
}
</script> -->
</div>
<div class="col-md p-5">
<h2>Device Connection</h2>
<p>
Please connect your <span class="text-warning"> OrgiCheck&trade; Smart</span> with the same network
</p>
<a href="#" class="btn btn-light mt-3">
<i class="bi bi-chevron-right"></i> Learn More
</a>
</div>
</div>
</div>
</div>
......
# ML-MODEL-DEPLOYMENT-USING-FLASK
\ No newline at end of file
Sepal_Length,Sepal_Width,Petal_Length,Petal_Width,Class
5.1,3.5,1.4,0.2,Setosa
4.9,3,1.4,0.2,Setosa
4.7,3.2,1.3,0.2,Setosa
4.6,3.1,1.5,0.2,Setosa
5,3.6,1.4,0.2,Setosa
5.4,3.9,1.7,0.4,Setosa
4.6,3.4,1.4,0.3,Setosa
5,3.4,1.5,0.2,Setosa
4.4,2.9,1.4,0.2,Setosa
4.9,3.1,1.5,0.1,Setosa
5.4,3.7,1.5,0.2,Setosa
4.8,3.4,1.6,0.2,Setosa
4.8,3,1.4,0.1,Setosa
4.3,3,1.1,0.1,Setosa
5.8,4,1.2,0.2,Setosa
5.7,4.4,1.5,0.4,Setosa
5.4,3.9,1.3,0.4,Setosa
5.1,3.5,1.4,0.3,Setosa
5.7,3.8,1.7,0.3,Setosa
5.1,3.8,1.5,0.3,Setosa
5.4,3.4,1.7,0.2,Setosa
5.1,3.7,1.5,0.4,Setosa
4.6,3.6,1,0.2,Setosa
5.1,3.3,1.7,0.5,Setosa
4.8,3.4,1.9,0.2,Setosa
5,3,1.6,0.2,Setosa
5,3.4,1.6,0.4,Setosa
5.2,3.5,1.5,0.2,Setosa
5.2,3.4,1.4,0.2,Setosa
4.7,3.2,1.6,0.2,Setosa
4.8,3.1,1.6,0.2,Setosa
5.4,3.4,1.5,0.4,Setosa
5.2,4.1,1.5,0.1,Setosa
5.5,4.2,1.4,0.2,Setosa
4.9,3.1,1.5,0.2,Setosa
5,3.2,1.2,0.2,Setosa
5.5,3.5,1.3,0.2,Setosa
4.9,3.6,1.4,0.1,Setosa
4.4,3,1.3,0.2,Setosa
5.1,3.4,1.5,0.2,Setosa
5,3.5,1.3,0.3,Setosa
4.5,2.3,1.3,0.3,Setosa
4.4,3.2,1.3,0.2,Setosa
5,3.5,1.6,0.6,Setosa
5.1,3.8,1.9,0.4,Setosa
4.8,3,1.4,0.3,Setosa
5.1,3.8,1.6,0.2,Setosa
4.6,3.2,1.4,0.2,Setosa
5.3,3.7,1.5,0.2,Setosa
5,3.3,1.4,0.2,Setosa
7,3.2,4.7,1.4,Versicolor
6.4,3.2,4.5,1.5,Versicolor
6.9,3.1,4.9,1.5,Versicolor
5.5,2.3,4,1.3,Versicolor
6.5,2.8,4.6,1.5,Versicolor
5.7,2.8,4.5,1.3,Versicolor
6.3,3.3,4.7,1.6,Versicolor
4.9,2.4,3.3,1,Versicolor
6.6,2.9,4.6,1.3,Versicolor
5.2,2.7,3.9,1.4,Versicolor
5,2,3.5,1,Versicolor
5.9,3,4.2,1.5,Versicolor
6,2.2,4,1,Versicolor
6.1,2.9,4.7,1.4,Versicolor
5.6,2.9,3.6,1.3,Versicolor
6.7,3.1,4.4,1.4,Versicolor
5.6,3,4.5,1.5,Versicolor
5.8,2.7,4.1,1,Versicolor
6.2,2.2,4.5,1.5,Versicolor
5.6,2.5,3.9,1.1,Versicolor
5.9,3.2,4.8,1.8,Versicolor
6.1,2.8,4,1.3,Versicolor
6.3,2.5,4.9,1.5,Versicolor
6.1,2.8,4.7,1.2,Versicolor
6.4,2.9,4.3,1.3,Versicolor
6.6,3,4.4,1.4,Versicolor
6.8,2.8,4.8,1.4,Versicolor
6.7,3,5,1.7,Versicolor
6,2.9,4.5,1.5,Versicolor
5.7,2.6,3.5,1,Versicolor
5.5,2.4,3.8,1.1,Versicolor
5.5,2.4,3.7,1,Versicolor
5.8,2.7,3.9,1.2,Versicolor
6,2.7,5.1,1.6,Versicolor
5.4,3,4.5,1.5,Versicolor
6,3.4,4.5,1.6,Versicolor
6.7,3.1,4.7,1.5,Versicolor
6.3,2.3,4.4,1.3,Versicolor
5.6,3,4.1,1.3,Versicolor
5.5,2.5,4,1.3,Versicolor
5.5,2.6,4.4,1.2,Versicolor
6.1,3,4.6,1.4,Versicolor
5.8,2.6,4,1.2,Versicolor
5,2.3,3.3,1,Versicolor
5.6,2.7,4.2,1.3,Versicolor
5.7,3,4.2,1.2,Versicolor
5.7,2.9,4.2,1.3,Versicolor
6.2,2.9,4.3,1.3,Versicolor
5.1,2.5,3,1.1,Versicolor
5.7,2.8,4.1,1.3,Versicolor
6.3,3.3,6,2.5,Virginica
5.8,2.7,5.1,1.9,Virginica
7.1,3,5.9,2.1,Virginica
6.3,2.9,5.6,1.8,Virginica
6.5,3,5.8,2.2,Virginica
7.6,3,6.6,2.1,Virginica
4.9,2.5,4.5,1.7,Virginica
7.3,2.9,6.3,1.8,Virginica
6.7,2.5,5.8,1.8,Virginica
7.2,3.6,6.1,2.5,Virginica
6.5,3.2,5.1,2,Virginica
6.4,2.7,5.3,1.9,Virginica
6.8,3,5.5,2.1,Virginica
5.7,2.5,5,2,Virginica
5.8,2.8,5.1,2.4,Virginica
6.4,3.2,5.3,2.3,Virginica
6.5,3,5.5,1.8,Virginica
7.7,3.8,6.7,2.2,Virginica
7.7,2.6,6.9,2.3,Virginica
6,2.2,5,1.5,Virginica
6.9,3.2,5.7,2.3,Virginica
5.6,2.8,4.9,2,Virginica
7.7,2.8,6.7,2,Virginica
6.3,2.7,4.9,1.8,Virginica
6.7,3.3,5.7,2.1,Virginica
7.2,3.2,6,1.8,Virginica
6.2,2.8,4.8,1.8,Virginica
6.1,3,4.9,1.8,Virginica
6.4,2.8,5.6,2.1,Virginica
7.2,3,5.8,1.6,Virginica
7.4,2.8,6.1,1.9,Virginica
7.9,3.8,6.4,2,Virginica
6.4,2.8,5.6,2.2,Virginica
6.3,2.8,5.1,1.5,Virginica
6.1,2.6,5.6,1.4,Virginica
7.7,3,6.1,2.3,Virginica
6.3,3.4,5.6,2.4,Virginica
6.4,3.1,5.5,1.8,Virginica
6,3,4.8,1.8,Virginica
6.9,3.1,5.4,2.1,Virginica
6.7,3.1,5.6,2.4,Virginica
6.9,3.1,5.1,2.3,Virginica
5.8,2.7,5.1,1.9,Virginica
6.8,3.2,5.9,2.3,Virginica
6.7,3.3,5.7,2.5,Virginica
6.7,3,5.2,2.3,Virginica
6.3,2.5,5,1.9,Virginica
6.5,3,5.2,2,Virginica
6.2,3.4,5.4,2.3,Virginica
5.9,3,5.1,1.8,Virginica
import numpy as np
from flask import Flask, request, jsonify, render_template
from PIL import Image
from urllib import request
from io import BytesIO
from keras_preprocessing import image
import urllib.request
import pickle
from keras.models import load_model
# Create flask app
flask_app = Flask(__name__)
model = pickle.load(open("model.pkl", "rb"))
model1 = load_model('imgClassification.h5')
@flask_app.route("/")
def Home():
return render_template("index.html")
return render_template("predi.html")
@flask_app.route("/predict", methods = ["POST"])
def predict():
float_features = [float(x) for x in request.form.values()]
float_features = [float(x) for x in urllib.request.form.values()]
features = [np.array(float_features)]
prediction = model.predict(features)
return render_template("index.html", prediction_text = "The flower species is {}".format(prediction))
@flask_app.route("/classify", methods = ["POST"])
def classify():
image_path = "http://192.168.8.103/saved-photo"
class_names = ['banana', 'cabbage', 'cucumber', 'mango', 'orange', 'tomato']
img = Image.open(BytesIO(request.urlopen(image_path).read())).resize((224, 224))
# img = image.load_img(request.urlopen(image_path), target_size=(224,224,3))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
pred = model1.predict(images, batch_size=32)
label = np.argmax(pred, axis=1)
out = class_names[np.argmax(pred)]
return render_template("predi.html", prediction_text_class = "The flower species is {}".format(out))
if __name__ == "__main__":
flask_app.run(debug=True)
\ No newline at end of file
import os
from PIL import Image
import numpy as np
import tensorflow as tf
import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout
from tensorflow.keras.callbacks import EarlyStopping
from cv2 import cv2
import matplotlib.pyplot as plt
from keras.layers.normalization import BatchNormalization
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import SGD
val_path="./input/fruit-and-vegetable-image-recognition/validation"
train_path="./input/fruit-and-vegetable-image-recognition/train"
train_dataset = tf.keras.preprocessing.image_dataset_from_directory(train_path,
seed=2509,
image_size=(224, 224),
batch_size=32)
val_dataset = tf.keras.preprocessing.image_dataset_from_directory(val_path,
seed=2509,
image_size=(224, 224),
shuffle=False,
batch_size=32)
class_names = train_dataset.class_names
print(class_names)
print(len(class_names))
model = Sequential()
model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', input_shape=(224,224,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(96, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(32, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
#model.add(Dropout(0.3))
model.add(Dense(len(class_names),activation='softmax'))
model.compile(
loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.summary()
history = model.fit(x=train_dataset,
epochs= 20,
validation_data=val_dataset)
model.save('imgClassification.h5')
\ No newline at end of file
......@@ -2,7 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Orgicheck_flask.iml" filepath="$PROJECT_DIR$/.idea/Orgicheck_flask.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/flask_orgiC.iml" filepath="$PROJECT_DIR$/.idea/flask_orgiC.iml" />
</modules>
</component>
</project>
\ No newline at end of file
import random
import numpy as np
from flask import Flask, request, jsonify, render_template
from PIL import Image
from urllib import request
from io import BytesIO
from keras_preprocessing import image
import urllib.request
from keras.models import load_model
import csv
# Create flask app
flask_app = Flask(__name__)
print("worr")
model1 = load_model('imgClassification.h5')
print("wk")
wt = random.randint(380, 490)
@flask_app.route("/")
def Home():
return render_template("predi.html")
@flask_app.route("/classify", methods = ["POST"])
def classify():
image_path = "http://192.168.8.103/saved-photo"
print("working.1")
class_names = ['banana', 'cabbage', 'cucumber', 'mango', 'orange', 'tomato']
print("working....2")
img = Image.open(BytesIO(request.urlopen(image_path).read())).resize((224, 224))
print("working....3")
# img = image.load_img(request.urlopen(image_path), target_size=(224,224,3))
x = image.img_to_array(img)
print("working....4")
x = np.expand_dims(x, axis=0)
print("working....5")
images = np.vstack([x])
print("working....6")
pred = model1.predict(images, batch_size=6)
print("working....")
label = np.argmax(pred, axis=1)
out = class_names[np.argmax(pred)]
print(out)
print("workig")
return render_template("predi.html", prediction_text_class = "The flower species is {}".format(out))
@flask_app.route("/price", methods = ["POST"])
def price():
vegi = 'banana'
dt = '18/10/2021'
with open('data/Predict_vegetable_2021_SL.csv', encoding="utf8") as f:
csv_reader = csv.DictReader(f)
next(csv_reader)
for line in csv_reader:
if line['date'] == dt and line['item'] == vegi:
para = line['price']
print(line['price'])
listM = [vegi, dt, para]
return render_template("predi.html", vegita = vegi, dte = dt, pr = para)
# return render_template("predi.html", prediction_text_class_price="The price is {}".format(para))
if __name__ == "__main__":
flask_app.run(debug=True)
\ No newline at end of file
import os
from PIL import Image
import numpy as np
import tensorflow as tf
import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout
from tensorflow.keras.callbacks import EarlyStopping
from cv2 import cv2
import matplotlib.pyplot as plt
from keras.layers.normalization import BatchNormalization
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import SGD
import joblib
val_path="./input/fruit-and-vegetable-image-recognition/validation"
train_path="./input/fruit-and-vegetable-image-recognition/train"
train_dataset = tf.keras.preprocessing.image_dataset_from_directory(train_path,
seed=2509,
image_size=(224, 224),
batch_size=32)
val_dataset = tf.keras.preprocessing.image_dataset_from_directory(val_path,
seed=2509,
image_size=(224, 224),
shuffle=False,
batch_size=32)
class_names = train_dataset.class_names
print(class_names)
print(len(class_names))
model = Sequential()
model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', input_shape=(224,224,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(96, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(32, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
#model.add(Dropout(0.3))
model.add(Dense(len(class_names),activation='softmax'))
model.compile(
loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.summary()
history = model.fit(x=train_dataset,
epochs= 20,
validation_data=val_dataset)
model.save('imgClassification.h5')
joblib.dump(model, "imgClassmodel.joblib")
\ No newline at end of file
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{{ url_for('classify')}}"method="post">
<button type="submit" class="btn btn-primary btn-block btn-large">Predict</button>
</form>
<form action="{{ url_for('price')}}"method="post">
<button type="submit" class="btn btn-primary btn-block btn-large">Pre55</button>
</form>
<br>
<br>
{{ prediction_text_class }}
{{ vegita }}
{{ dte }}
{{ pr }}
</body>
</html>
\ No newline at end of file
body::before {
display: block;
content: '';
height: 60px;
}
#map {
width: 100%;
height: 100%;
border-radius: 10px;
}
@media (min-width: 768px) {
.news-input {
width: 50%;
}
}
#include "WiFi.h"
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour 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 = "Dialog 4G";
const char* password = "MNQ009A0L83";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
boolean takeNewPhoto = false;
// Photo File Name to save in SPIFFS
#define FILE_PHOTO "/photo.jpg"
// OV2640 camera module pins (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>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { text-align:center; }
.vert { margin-bottom: 10%; }
.hori{ margin-bottom: 0%; }
</style>
</head>
<body>
<div id="container">
<h2>ESP32-CAM Last Photo</h2>
<p>It might take more than 5 seconds to capture a photo.</p>
<p>
<button onclick="rotatePhoto();">ROTATE</button>
<button onclick="capturePhoto()">CAPTURE PHOTO</button>
<button onclick="location.reload();">REFRESH PAGE</button>
</p>
</div>
<div><img src="saved-photo" id="photo" width="70%"></div>
</body>
<script>
var deg = 0;
function capturePhoto() {
var xhr = new XMLHttpRequest();
xhr.open('GET', "/capture", true);
xhr.send();
}
function rotatePhoto() {
var img = document.getElementById("photo");
deg += 90;
if(isOdd(deg/90)){ document.getElementById("container").className = "vert"; }
else{ document.getElementById("container").className = "hori"; }
img.style.transform = "rotate(" + deg + "deg)";
}
function isOdd(n) { return Math.abs(n % 2) == 1; }
</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", HTTP_GET, [](AsyncWebServerRequest * request) {
takeNewPhoto = true;
request->send_P(200, "text/plain", "Taking Photo");
});
server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
});
// Start server
server.begin();
}
void loop() {
if (takeNewPhoto) {
capturePhotoSaveSpiffs();
takeNewPhoto = false;
}
delay(1);
}
// Check if photo capture was successful
bool checkPhoto( fs::FS &fs ) {
File f_pic = fs.open( FILE_PHOTO );
unsigned int pic_sz = f_pic.size();
return ( pic_sz > 100 );
}
// Capture Photo and Save it to SPIFFS
void capturePhotoSaveSpiffs( void ) {
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;
}
// Photo file name
Serial.printf("Picture file name: %s\n", FILE_PHOTO);
File file = SPIFFS.open(FILE_PHOTO, 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(FILE_PHOTO);
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);
} while ( !ok );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment