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 |