first commit
|
@ -0,0 +1,192 @@
|
||||||
|
from flask import Flask, render_template, request, redirect, url_for, session, flash
|
||||||
|
from flask import Flask, render_template, request, session, jsonify
|
||||||
|
from flask_mysqldb import MySQL
|
||||||
|
from keras.preprocessing import image as keras_image
|
||||||
|
from tensorflow.keras.applications.efficientnet import preprocess_input as efficientnet_preprocess_input
|
||||||
|
import tensorflow as tf
|
||||||
|
import bcrypt
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import base64
|
||||||
|
import cv2
|
||||||
|
from flask import jsonify
|
||||||
|
from keras.models import load_model
|
||||||
|
from keras.preprocessing import image
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.secret_key = "webarab"
|
||||||
|
|
||||||
|
mysql = MySQL(app)
|
||||||
|
|
||||||
|
# load
|
||||||
|
model = load_model('model70epoch2.h5')
|
||||||
|
|
||||||
|
# memeriksa ekstensi file
|
||||||
|
def allowed_file(filename):
|
||||||
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
UPLOAD_FOLDER = 'static/upload/'
|
||||||
|
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||||
|
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'tiff', 'webp', 'jfif'}
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return redirect(url_for('start'))
|
||||||
|
|
||||||
|
@app.route('/start')
|
||||||
|
def start():
|
||||||
|
return render_template('start.html')
|
||||||
|
|
||||||
|
@app.route('/dashboard')
|
||||||
|
def dashboard():
|
||||||
|
return render_template('dashboard.html')
|
||||||
|
|
||||||
|
@app.route('/materi')
|
||||||
|
def materi():
|
||||||
|
return render_template('materi.html')
|
||||||
|
|
||||||
|
@app.route('/pilihmateri')
|
||||||
|
def pilihmateri():
|
||||||
|
return render_template('pilihmateri.html')
|
||||||
|
|
||||||
|
@app.route('/materi1')
|
||||||
|
def materi1():
|
||||||
|
return render_template('materi1.html')
|
||||||
|
|
||||||
|
@app.route('/materi2')
|
||||||
|
def materi2():
|
||||||
|
return render_template('materi2.html')
|
||||||
|
|
||||||
|
@app.route('/materi3')
|
||||||
|
def materi3():
|
||||||
|
return render_template('materi3.html')
|
||||||
|
|
||||||
|
@app.route('/nextpage1')
|
||||||
|
def nextpage1():
|
||||||
|
return render_template('nextpage1.html')
|
||||||
|
|
||||||
|
@app.route('/nextpage2')
|
||||||
|
def nextpage2():
|
||||||
|
return render_template('nextpage2.html')
|
||||||
|
|
||||||
|
@app.route('/nextpage3')
|
||||||
|
def nextpage3():
|
||||||
|
return render_template('nextpage3.html')
|
||||||
|
|
||||||
|
@app.route('/nextpagee1')
|
||||||
|
def nextpagee1():
|
||||||
|
return render_template('nextpagee1.html')
|
||||||
|
|
||||||
|
@app.route('/nextpagee2')
|
||||||
|
def nextpagee2():
|
||||||
|
return render_template('nextpagee2.html')
|
||||||
|
|
||||||
|
@app.route('/nextpagee3')
|
||||||
|
def nextpagee3():
|
||||||
|
return render_template('nextpagee3.html')
|
||||||
|
|
||||||
|
@app.route('/nextpageee3')
|
||||||
|
def nextpageee3():
|
||||||
|
return render_template('nextpageee3.html')
|
||||||
|
|
||||||
|
@app.route('/quizz')
|
||||||
|
def quizz():
|
||||||
|
return render_template('quizz.html')
|
||||||
|
|
||||||
|
@app.route('/quizz2')
|
||||||
|
def quizz2():
|
||||||
|
return render_template('quizz2.html')
|
||||||
|
|
||||||
|
@app.route('/quizz3')
|
||||||
|
def quizz3():
|
||||||
|
return render_template('quizz3.html')
|
||||||
|
|
||||||
|
@app.route('/quizz4')
|
||||||
|
def quizz4():
|
||||||
|
return render_template('quizz4.html')
|
||||||
|
|
||||||
|
@app.route('/menupindai')
|
||||||
|
def menupindai():
|
||||||
|
return render_template('menupindai.html')
|
||||||
|
|
||||||
|
@app.route('/materipindai')
|
||||||
|
def materipindai():
|
||||||
|
return render_template('materipindai.html')
|
||||||
|
|
||||||
|
@app.route('/materipindai2')
|
||||||
|
def materipindai2():
|
||||||
|
return render_template('materipindai2.html')
|
||||||
|
|
||||||
|
@app.route('/materipindai3')
|
||||||
|
def materipindai3():
|
||||||
|
return render_template('materipindai3.html')
|
||||||
|
|
||||||
|
@app.route('/pindai', methods=['GET', 'POST'])
|
||||||
|
def pindai():
|
||||||
|
return render_template('pindai.html', judul='Pindai')
|
||||||
|
|
||||||
|
#untuk mengirimkan dan memproses gambar
|
||||||
|
@app.route('/submit', methods=['POST', 'GET'])
|
||||||
|
def predict():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return redirect(url_for('pindai'))
|
||||||
|
|
||||||
|
if 'file' not in request.files:
|
||||||
|
flash('Tidak ada gambar dalam permintaan', 'error')
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
|
file = request.files['file']
|
||||||
|
if file.filename == '':
|
||||||
|
flash('Tidak ada file yang dipilih', 'error')
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
filename = secure_filename(file.filename)
|
||||||
|
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
|
file.save(file_path)
|
||||||
|
|
||||||
|
img = Image.open(file_path).convert('RGB')
|
||||||
|
|
||||||
|
#preprocessing
|
||||||
|
img = keras_image.load_img(file_path, target_size=(224, 224))
|
||||||
|
x = keras_image.img_to_array(img) #mengubah ke array
|
||||||
|
x = np.expand_dims(x, axis=0) #dimensi tambahan di sumbu pertama untuk mempersiapkan gambar sebagai input batch untuk model
|
||||||
|
x = efficientnet_preprocess_input(x) #khusus efficient
|
||||||
|
|
||||||
|
# menyimpan gambar
|
||||||
|
processed_image_path = os.path.join(app.config['UPLOAD_FOLDER'], 'processed_image.png')
|
||||||
|
img.save(processed_image_path)
|
||||||
|
|
||||||
|
# mempersiapkan gambar ini untuk penggunaan dalam prediksi model
|
||||||
|
img = keras_image.load_img(processed_image_path, target_size=(224, 224))
|
||||||
|
x = keras_image.img_to_array(img)
|
||||||
|
x = np.expand_dims(x, axis=0)
|
||||||
|
images = np.vstack([x])
|
||||||
|
|
||||||
|
# prediksi kelas yang telah diproses
|
||||||
|
prediction_arab = model.predict(images)
|
||||||
|
|
||||||
|
# mapping class
|
||||||
|
class_names = ['الساعة', 'السباحة', 'حديقة', 'حذاء', 'سور', 'قلم',
|
||||||
|
'قَاعَة', 'كرة سلة', 'مصنع', 'ملابس', 'ملعب', 'مَكْتَبُ المُدَرِّسِيْن', 'مِرْحَاض', 'مِسْطَرَة', 'مِنْضَدَة']
|
||||||
|
predicted_class_index = np.argmax(prediction_arab)
|
||||||
|
predicted_class_name = class_names[predicted_class_index]
|
||||||
|
|
||||||
|
# Return the prediction result to the web page
|
||||||
|
return render_template("pindai.html", img_path=file_path,
|
||||||
|
predictionarab=predicted_class_name,
|
||||||
|
confidencearab='{:.2%}'.format(np.max(prediction_arab)))
|
||||||
|
|
||||||
|
else:
|
||||||
|
flash('Format file tidak diizinkan', 'error')
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
|
@app.route('/refresh', methods=['GET', 'POST'])
|
||||||
|
def refresh():
|
||||||
|
return redirect(url_for('pindai'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 350 KiB |
After Width: | Height: | Size: 457 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,66 @@
|
||||||
|
/* Navbar */
|
||||||
|
.navbar-float {
|
||||||
|
background-color: #333; /* Warna latar belakang */
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-text-active {
|
||||||
|
color: #fff; /* Warna teks */
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-text-active:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #333; /* Warna latar belakang dropdown */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
color: #fff; /* Warna teks dropdown */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:hover {
|
||||||
|
background-color: #555; /* Warna latar belakang saat hover dropdown */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button */
|
||||||
|
.btn {
|
||||||
|
background-color: #808080; /* Warna latar belakang */
|
||||||
|
border-color: #808080; /* Warna border */
|
||||||
|
color: #fff; /* Warna teks */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #999; /* Warna latar belakang saat hover */
|
||||||
|
border-color: #999; /* Warna border saat hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 10px 20px; /* Padding tombol */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Container */
|
||||||
|
.container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Full Screen Button */
|
||||||
|
.col-md-4 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh; /* Mengisi tinggi viewport */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Background Body */
|
||||||
|
.bg-light {
|
||||||
|
background-color: #f2f2f2; /* Warna latar belakang body */
|
||||||
|
}
|
||||||
|
|
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 581 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 49 KiB |