Lambang commited on
Commit
364ca9d
1 Parent(s): 6caf9b5
crud.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ from flask import Flask, request, jsonify
4
+ from werkzeug.utils import secure_filename
5
+
6
+ #-----------------------------------------------------
7
+ # Tempat setting server
8
+ UPLOAD_FOLDER = './upload'
9
+ UPLOAD_MODEL = './models'
10
+ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg','zip','h5'}
11
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
12
+ app.config['UPLOAD_MODEL'] = UPLOAD_MODEL
13
+ app.config['MAX_CONTENT_LENGTH'] = 500 * 1024 * 1024 # 500 MB
14
+ #-----------------------------------------------------
15
+
16
+
17
+ class FaceDetectionApp:
18
+ def __init__(self, upload_folder="./static", public_url="/"):
19
+ self.app = Flask(__name__)
20
+ self.app.config['UPLOAD_FOLDER'] = upload_folder
21
+ self.app.config['UPLOAD_MODEL'] = os.path.join(upload_folder, "model")
22
+ self.public_url = public_url
23
+
24
+ def delete_img():
25
+ for i in range (0,4):
26
+ if os.path.exists(f"./static/result_upload{i}.jpg"):
27
+ os.remove(f"./static/result_upload{i}.jpg")
28
+ print("File terhapus")
29
+ return jsonify({'message': 'Berhasil di hapus'}), 400
30
+ else:
31
+ print("File tidak ditemukan.")
32
+ return jsonify({'message': 'No file selected for uploading'}), 400
33
+
34
+ def upload_file():
35
+ if 'file' not in request.files:
36
+ return jsonify({'message': 'No file part in the request'}), 400
37
+
38
+ file = request.files['file']
39
+
40
+ if file.filename == '':
41
+ return jsonify({'message': 'No file selected for uploading'}), 400
42
+
43
+ filename = secure_filename(file.filename)
44
+ filepath = os.path.join(self.app.config['UPLOAD_FOLDER'], filename)
45
+ file.save(filepath)
46
+ img = cv2.imread(filepath)
47
+ # Detect Face
48
+ try:
49
+ self.preprocessing(img)
50
+ return jsonify({'message': 'File successfully uploaded'})
51
+ except:
52
+ path = "empty_image.png"
53
+ return jsonify({'message': 'File failed to uploaded'})
54
+
55
+ def upload_data():
56
+ if 'file' not in request.files:
57
+ return jsonify({'message': 'No file part in the request'}), 400
58
+
59
+ file = request.files['file']
60
+
61
+ if file.filename == '':
62
+ return jsonify({'message': 'No file selected for uploading'}), 400
63
+
64
+ if file and self.allowed_file(file.filename):
65
+ filename = secure_filename(file.filename)
66
+ filepath = os.path.join(self.app.config['UPLOAD_FOLDER'], filename)
67
+ file.save(filepath)
68
+
69
+ self.extract_zip(filepath)
70
+ return jsonify({'message': 'File successfully uploaded'})
71
+
72
+ return jsonify({'message': 'File failed to uploaded'})
73
+
74
+
75
+ def upload_model():
76
+ if 'file' not in request.files:
77
+ return jsonify({'message': 'No file part in the request'}), 400
78
+
79
+ file = request.files['file']
80
+
81
+ if file.filename == '':
82
+ return jsonify({'message': 'No file selected for uploading'}), 400
83
+
84
+ if file and self.allowed_file(file.filename):
85
+ filename = secure_filename(file.filename)
86
+ filepath = os.path.join(self.app.config['UPLOAD_MODEL'], filename)
87
+ file.save(filepath)
88
+
89
+ return jsonify({'message': 'File successfully uploaded'})
90
+
91
+ return jsonify({'message': 'File failed to uploaded'})
92
+
93
+ def get_total_files():
94
+ training_counts = self.get_training_file_counts()
95
+ testing_counts = self.get_testing_file_counts()
96
+ result = {}
97
+ result['training'] = training_counts.json
98
+ result['testing'] = testing_counts.json
99
+ return jsonify(result)
data_preprocess.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import numpy as np
4
+ import mediapipe as mp
5
+ from deepface import DeepFace
6
+
7
+ class DataProcessing:
8
+ def __init__(self):
9
+ self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_alt2.xml')
10
+ self.mp_face_mesh = mp.solutions.face_mesh
11
+ self.mp_drawing = mp.solutions.drawing_utils
12
+
13
+ def enhance_contrast_histeq(self, image):
14
+ img = image.copy()
15
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
16
+ resized_gray = cv2.resize(gray, (250, 190))
17
+ enhanced_image = cv2.equalizeHist(resized_gray)
18
+
19
+ cv2.imwrite("./static/result_upload2.jpg", enhanced_image)
20
+ cv2.imwrite("./static/temporary/result_upload2.jpg", enhanced_image)
21
+
22
+ return enhanced_image
23
+
24
+ def face_cropping_pred(self, img):
25
+ for i in range(0, 4):
26
+ if os.path.exists(f"./static/result_upload{i}.jpg"):
27
+ os.remove(f"./static/result_upload{i}.jpg")
28
+ print("File terhapus")
29
+ else:
30
+ print("File tidak ditemukan.")
31
+
32
+ # img = cv2.imread(filepath)
33
+ cv2.imwrite("./static/result_upload0.jpg", img)
34
+ cv2.imwrite('./static/temporary/result_upload0.jpg', img)
35
+ try:
36
+ DeepFace.extract_faces("./static/result_upload0.jpg")
37
+ offset = 40
38
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
39
+ faces = self.face_cascade.detectMultiScale(gray, 1.1, 5)
40
+
41
+ for (x, y, w, h) in faces:
42
+ offset = 80
43
+ y_offset = 20
44
+ y1 = max(0, y - offset + y_offset)
45
+ y2 = min(y + h + offset + y_offset, img.shape[0])
46
+ x1 = max(0, x - offset)
47
+ x2 = min(x + w + offset, img.shape[1])
48
+
49
+ # Mengambil area sekitar wajah
50
+ faces = img[y1:y2, x1:x2]
51
+
52
+ cv2.imwrite("./static/result_upload1.jpg", faces)
53
+ cv2.imwrite('./static/temporary/result_upload1.jpg', faces)
54
+
55
+ return faces
56
+ except:
57
+ print("error")
58
+
59
+ def detect_landmark(self, img):
60
+ print("test")
61
+ image1 = img.copy()
62
+ image2 = img.copy()
63
+
64
+ with self.mp_face_mesh.FaceMesh(min_detection_confidence=0.1, min_tracking_confidence=0.6) as face_mesh:
65
+ image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)
66
+ image2.flags.writeable = False
67
+ results = face_mesh.process(image2)
68
+ image2.flags.writeable = True
69
+ image2 = cv2.cvtColor(image2, cv2.COLOR_RGB2BGR)
70
+
71
+ if results.multi_face_landmarks:
72
+ for face_landmarks in results.multi_face_landmarks:
73
+ self.mp_drawing.draw_landmarks(
74
+ image=image2,
75
+ landmark_list=face_landmarks,
76
+ connections=self.mp_face_mesh.FACEMESH_TESSELATION,
77
+ landmark_drawing_spec=self.mp_drawing.DrawingSpec(color=(0, 0, 0), thickness=0, circle_radius=0),
78
+ connection_drawing_spec=self.mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=1, circle_radius=0))
79
+
80
+ cv2.imwrite('./static/result_upload2.jpg', image2)
81
+ cv2.imwrite('./static/temporary/result_upload2.jpg', image2)
82
+
83
+ subtracted_img = np.zeros(image1.shape, np.uint8)
84
+
85
+ for i in range(image1.shape[0]):
86
+ for j in range(image1.shape[1]):
87
+ subtracted_img[i, j] = abs(int(image1[i, j][0]) - int(image2[i, j][0]))
88
+
89
+ cv2.imwrite('./static/result_upload3.jpg', subtracted_img)
90
+ cv2.imwrite('./static/temporary/result_upload3.jpg', subtracted_img)
91
+
92
+ def annotate_face_mesh(self, image):
93
+ with self.mp_face_mesh.FaceMesh(min_detection_confidence=0.1, min_tracking_confidence=0.6) as face_mesh:
94
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
95
+ image.flags.writeable = False
96
+ results = face_mesh.process(image)
97
+ image.flags.writeable = True
98
+ image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
99
+
100
+ if results.multi_face_landmarks:
101
+ for face_landmarks in results.multi_face_landmarks:
102
+ self.mp_drawing.draw_landmarks(
103
+ image=image,
104
+ landmark_list=face_landmarks,
105
+ connections=self.mp_face_mesh.FACEMESH_TESSELATION,
106
+ landmark_drawing_spec=self.mp_drawing.DrawingSpec(color=(0, 0, 0), thickness=0, circle_radius=0),
107
+ connection_drawing_spec=self.mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=1, circle_radius=0))
108
+ return image
109
+
110
+
file_processing.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import zipfile
2
+
3
+ class FileProcess:
4
+ ALLOWED_EXTENSIONS = {'zip'}
5
+
6
+ @staticmethod
7
+ def allowed_file(filename):
8
+ return '.' in filename and \
9
+ filename.rsplit('.', 1)[1].lower() in FileProcess.ALLOWED_EXTENSIONS
10
+
11
+ @staticmethod
12
+ def extract_zip(filepath):
13
+ path_ke_folder = './static/dataset/'
14
+ with zipfile.ZipFile(filepath, 'r') as zip_ref:
15
+ zip_ref.extractall(path_ke_folder)
get_load_data.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import random
3
+ import pandas as pd
4
+ from pathlib import Path
5
+ from flask import jsonify
6
+
7
+ list_class = ['Diamond','Oblong','Oval','Round','Square','Triangle']
8
+
9
+ # public_url = "https://yamanaka1.pagekite.me"
10
+
11
+ class GetLoadData:
12
+ @staticmethod
13
+ def get_training_file_counts():
14
+ path = "./static/dataset/Face Shape"
15
+ training_file_counts = []
16
+
17
+ # Loop melalui folder Training
18
+ for sub_folder in ["Diamond", "Oblong", "Oval", "Round", "Square", "Triangle"]:
19
+ # Tentukan path ke folder sub_folder dalam folder Training
20
+ sub_path = os.path.join(path, "Training", sub_folder)
21
+
22
+ # Gunakan fungsi listdir untuk membaca semua file dalam folder sub_folder
23
+ num_files = len([f for f in os.listdir(sub_path) if os.path.isfile(os.path.join(sub_path, f))])
24
+
25
+ # Tambahkan jumlah file ke dalam array training_file_counts
26
+ training_file_counts.append(num_files)
27
+
28
+ total_file = sum(training_file_counts)
29
+ training_file_counts.append(total_file)
30
+
31
+ # Return hasil dalam bentuk JSON
32
+ return jsonify(training_file_counts)
33
+
34
+ @staticmethod
35
+ def get_testing_file_counts():
36
+ path = "./static/dataset/Face Shape"
37
+ testing_file_counts = []
38
+
39
+ # Loop melalui folder Testing
40
+ for sub_folder in ["Diamond", "Oblong", "Oval", "Round", "Square", "Triangle"]:
41
+ # Tentukan path ke folder sub_folder dalam folder Testing
42
+ sub_path = os.path.join(path, "Testing", sub_folder)
43
+
44
+ # Gunakan fungsi listdir untuk membaca semua file dalam folder sub_folder
45
+ num_files = len([f for f in os.listdir(sub_path) if os.path.isfile(os.path.join(sub_path, f))])
46
+
47
+ # Tambahkan jumlah file ke dalam array testing_file_counts
48
+ testing_file_counts.append(num_files)
49
+
50
+ total_file = sum(testing_file_counts)
51
+ testing_file_counts.append(total_file)
52
+
53
+ # Return hasil dalam bentuk JSON
54
+ return jsonify(testing_file_counts)
55
+
56
+ @staticmethod
57
+ def folder_maker(preprocessing_name):
58
+ folder_path = f'./static/dataset/{preprocessing_name}'
59
+ training_path = f'./static/dataset/{preprocessing_name}/Training'
60
+ testing_path = f'./static/dataset/{preprocessing_name}/Testing'
61
+
62
+ # Membuat folder dataset/Landmark Face Shape jika belum ada
63
+ if not os.path.exists(folder_path):
64
+ os.makedirs(folder_path)
65
+
66
+ # Membuat folder dataset/Landmark Face Shape/Training jika belum ada
67
+ if not os.path.exists(training_path):
68
+ os.makedirs(training_path)
69
+ for i in range(0, len(list_class)):
70
+ os.mkdir(f'{training_path}/{list_class[i]}')
71
+
72
+ # Membuat folder dataset/Landmark Face Shape/Testing jika belum ada
73
+ if not os.path.exists(testing_path):
74
+ os.makedirs(testing_path)
75
+ for i in range(0, len(list_class)):
76
+ os.mkdir(f'{testing_path}/{list_class[i]}')
77
+
78
+ @staticmethod
79
+ def load_image_data(image_dir):
80
+ # Get file paths for all images in the directory
81
+ jpeg = list(image_dir.glob(r'**/*.jpeg'))
82
+ JPG = list(image_dir.glob(r'**/*.JPG'))
83
+ jpg = list(image_dir.glob(r'**/*.jpg'))
84
+ PNG = list(image_dir.glob(r'**/*.PNG'))
85
+ png = list(image_dir.glob(r'**/*.png'))
86
+ filepaths_ori = jpeg + JPG + jpg + PNG + png
87
+
88
+ # Get labels for each image
89
+ labels = list(map(lambda x: os.path.split(os.path.split(x)[0])[1], filepaths_ori))
90
+
91
+ # Convert filepaths and labels to Pandas series
92
+ filepaths_ori = pd.Series(filepaths_ori, name='Filepath').astype(str)
93
+ labels = pd.Series(labels, name='Label')
94
+
95
+ return filepaths_ori, labels
96
+
97
+ @staticmethod
98
+ def get_random_images(tahap, public_url):
99
+ root_path = f'./static/dataset/{tahap}/Training/'
100
+ num_images = 1
101
+ random_images = []
102
+ folder_count = 1
103
+
104
+ # Iterasi melalui folder di dalam folder "training"
105
+ for folder_name in os.listdir(root_path):
106
+ folder_path = os.path.join(root_path, folder_name)
107
+
108
+ print(folder_path)
109
+
110
+ # Jika folder_name bukan folder, skip
111
+ if not os.path.isdir(folder_path):
112
+ continue
113
+
114
+ # Mengambil daftar file di dalam folder dan mengacaknya
115
+ file_names = os.listdir(folder_path)
116
+ random.shuffle(file_names)
117
+
118
+ # Memilih 1 file pertama setelah diacak
119
+ for i in range(len(file_names)):
120
+ if i < num_images:
121
+ url = f'{public_url}/static/dataset/{tahap}/Training/{folder_name}'
122
+ print(url)
123
+ random_images.append(os.path.join(url, file_names[i]))
124
+ print(random_images)
125
+
126
+ # Hentikan loop setelah mengambil 5 gambar dari folder ke-5
127
+ if folder_count == 5:
128
+ break
129
+
130
+ folder_count += 1
131
+
132
+ # Mengirimkan daftar file acak sebagai respons ke Flutter
133
+ print(random_images)
134
+ return random_images
135
+
136
+ @staticmethod
137
+ def load_image_dataset(train_dataset_path, test_dataset_path):
138
+ list_data_path = [train_dataset_path, test_dataset_path]
139
+
140
+ # Get filepaths and labels
141
+ image_dir_train = Path(list_data_path[0])
142
+ filepaths_train, labels_train = GetLoadData.load_image_data(image_dir_train)
143
+
144
+ # Concatenate filepaths and labels
145
+ train_image_df = pd.concat([filepaths_train, labels_train], axis=1)
146
+
147
+ # Get filepaths and labels
148
+ image_dir_test = Path(list_data_path[1])
149
+ filepaths_test, labels_test = GetLoadData.load_image_data(image_dir_test)
150
+
151
+ # Concatenate filepaths and labels
152
+ test_image_df = pd.concat([filepaths_test, labels_test], axis=1)
153
+
154
+ # Return filepaths and labels
155
+ return train_image_df, test_image_df
haarcascade_frontalface_alt2.xml ADDED
The diff for this file is too large to render. See raw diff
 
train_pred.py ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+ import matplotlib.pyplot as plt
4
+ import tensorflow as tf
5
+ from tensorflow.keras.preprocessing.image import load_img, img_to_array
6
+ from sklearn.metrics import confusion_matrix
7
+ import os
8
+ import cv2
9
+ import numpy as np
10
+ from tqdm import tqdm
11
+ from flask import jsonify, flash, redirect, url_for
12
+ from pathlib import Path
13
+
14
+ from get_load_data import GetLoadData
15
+ from data_preprocess import DataProcessing
16
+
17
+
18
+ list_folder = ['Training', 'Testing']
19
+
20
+ class TrainPred:
21
+
22
+ def __init__(self, batch_size=32):
23
+ self.batch_size = batch_size
24
+ self.list_class = ['Diamond', 'Oblong', 'Oval', 'Round', 'Square', 'Triangle']
25
+ self.face_crop_img = True
26
+ self.face_landmark_img = True
27
+ self.landmark_extraction_img = True
28
+
29
+ self.prepro_img = 0
30
+ self.prepro_img2 = 0
31
+ self.name = ""
32
+ self.progres = 0
33
+
34
+ self.data_processor = DataProcessing()
35
+
36
+ def train_model(self, model, train_generator, test_generator, epoch):
37
+ model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
38
+ history = model.fit(train_generator, epochs=epoch, validation_data=test_generator)
39
+ return history
40
+
41
+ def prediction(self, model):
42
+ # img_width, img_height = 200, 200
43
+ # img = load_img("./static/result_upload2.jpg", target_size=(img_width, img_height))
44
+ img = load_img("./static/result_upload2.jpg")
45
+
46
+ img = img_to_array(img)
47
+ img = img/255.0
48
+ img = np.expand_dims(img, axis=0)
49
+ pred = model.predict(img)
50
+ pred_2 = model.predict_on_batch(img)
51
+ print(f"Pred :{pred}")
52
+ print(f"Pred 2 : {pred_2}")
53
+
54
+ # menghitung softmax
55
+ softmax_pred = np.exp(pred) / np.sum(np.exp(pred), axis=1, keepdims=True)
56
+
57
+ max_value = int(round(np.max(softmax_pred * 100)))
58
+ pred = np.argmax(pred, axis=1)
59
+
60
+ # Map the label
61
+ pred = [self.list_class[k] for k in pred]
62
+
63
+ return pred, max_value
64
+
65
+ def plot_accuracy(self, result, epoch):
66
+ train_acc_gr = result.history['accuracy']
67
+ val_acc_gr = result.history['val_accuracy']
68
+ epochs = range(1, epoch+1)
69
+
70
+ # Plot training accuracy
71
+ plt.plot(epochs, train_acc_gr, label='Training Accuracy')
72
+ plt.plot(epochs, val_acc_gr, label='Testing Accuracy')
73
+
74
+ # Set plot title and labels
75
+ plt.title('Model Accuracy')
76
+ plt.xlabel('Epoch')
77
+ plt.ylabel('Accuracy')
78
+ plt.legend(loc='best')
79
+
80
+ # Save plot as image file
81
+ plt.savefig('./static/accuracy_plot.png')
82
+
83
+ def plot_loss(self, result, epoch):
84
+ train_loss_gr = result.history['loss']
85
+ val_loss_gr = result.history['val_loss']
86
+ epochs = range(1, epoch+1)
87
+
88
+ # Plot training accuracy
89
+ plt.plot(epochs, train_loss_gr, label='Training Loss')
90
+ plt.plot(epochs, val_loss_gr, label='Testing Loss')
91
+
92
+ # Set plot title and labels
93
+ plt.title('Model Loss')
94
+ plt.xlabel('Epoch')
95
+ plt.ylabel('Loss')
96
+ plt.legend(loc='best')
97
+
98
+ # Save plot as image file
99
+ plt.savefig('./static/loss_plot.png')
100
+
101
+ def plot_confusion_matrix(self, model, test_generator):
102
+ # Get the predictions from the model
103
+ predictions = model.predict(test_generator, steps=len(test_generator), verbose=1)
104
+ y_pred = np.argmax(predictions, axis=1)
105
+ y_true = test_generator.classes
106
+
107
+ # Generate confusion matrix
108
+ cm = confusion_matrix(y_true, y_pred)
109
+
110
+ # Plot the confusion matrix
111
+ fig, ax = plt.subplots(figsize=(8, 8))
112
+ ax.imshow(cm, cmap='Blues')
113
+ ax.set_title('Confusion Matrix')
114
+ ax.set_xlabel('Predicted Labels')
115
+ ax.set_ylabel('True Labels')
116
+ ax.set_xticks(range(len(test_generator.class_indices)))
117
+ ax.set_xticklabels(test_generator.class_indices.keys(), rotation=90)
118
+ ax.set_yticks(range(len(test_generator.class_indices)))
119
+ ax.set_yticklabels(test_generator.class_indices.keys())
120
+ for i in range(len(test_generator.class_indices)):
121
+ for j in range(len(test_generator.class_indices)):
122
+ ax.text(j, i, str(cm[i, j]), ha='center', va='center', color='white')
123
+ fig.tight_layout()
124
+
125
+ filename = './static/confusion_matrix.png'
126
+ # Save the confusion matrix as an image file
127
+ fig.savefig(filename)
128
+
129
+ return filename
130
+
131
+ def data_configuration(self, train_image_df, test_image_df):
132
+ train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
133
+ test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
134
+
135
+ train_generator = train_datagen.flow_from_dataframe(
136
+ dataframe=train_image_df,
137
+ x_col='Filepath',
138
+ y_col='Label',
139
+ target_size=(220, 280),
140
+ color_mode='rgb',
141
+ class_mode='categorical',
142
+ batch_size=self.batch_size,
143
+ subset='training'
144
+ )
145
+
146
+ test_generator = test_datagen.flow_from_dataframe(
147
+ dataframe=test_image_df,
148
+ x_col='Filepath',
149
+ y_col='Label',
150
+ target_size=(220, 280),
151
+ color_mode='rgb',
152
+ class_mode='categorical',
153
+ batch_size=self.batch_size,
154
+ subset='training'
155
+ )
156
+
157
+ return train_generator, test_generator
158
+
159
+ def model_architecture(self):
160
+ model = tf.keras.models.Sequential()
161
+
162
+ # layers from the previous code
163
+ model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(220, 280, 3)))
164
+ model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))
165
+ model.add(tf.keras.layers.MaxPooling2D((2, 2)))
166
+ model.add(tf.keras.layers.Conv2D(128, (3, 3), activation='relu'))
167
+ model.add(tf.keras.layers.Conv2D(128, (3, 3), activation='relu'))
168
+ model.add(tf.keras.layers.MaxPooling2D((2, 2)))
169
+ model.add(tf.keras.layers.Conv2D(256, (3, 3), activation='relu'))
170
+ model.add(tf.keras.layers.Conv2D(256, (3, 3), activation='relu'))
171
+ model.add(tf.keras.layers.MaxPooling2D((2, 2)))
172
+
173
+ model.add(tf.keras.layers.Flatten())
174
+ model.add(tf.keras.layers.Dense(6, activation='softmax'))
175
+
176
+ model.summary()
177
+
178
+ return model
179
+
180
+ # @staticmethod
181
+ def do_pre1(self,test):
182
+ global prepro_img
183
+ global face_landmark_img, landmark_extraction_img
184
+ self.prepro_img = 0
185
+ try:
186
+ if (self.face_landmark_img == True):
187
+ GetLoadData.folder_maker("Face Landmark")
188
+
189
+ for i in tqdm(range(0, len(list_folder)), desc=f"Processing {list_folder} images"):
190
+ for j in range(0, len(self.list_class)):
191
+ dataset = f"./static/dataset/Face Shape/{list_folder[i]}/{self.list_class[j]}"
192
+ len_dataset = os.listdir(f"./static/dataset/Face Shape/{list_folder[i]}/{self.list_class[j]}")
193
+ image_dir = Path(dataset)
194
+ for k in (range(0, len(len_dataset))):
195
+ filepaths, labels = GetLoadData.load_image_data(image_dir)
196
+ img = cv2.imread(filepaths[k])
197
+ img = self.data_processor.annotate_face_mesh(image=img)
198
+ # print("./static/dataset/Face Landmark/" + f"{list_folder[i]}/" + f"{list_class[j]}/" + f"{len_dataset[k]}")
199
+ cv2.imwrite(
200
+ "./static/dataset/Face Landmark/" + f"{list_folder[i]}/" + f"{self.list_class[j]}/" + f"{len_dataset[k]}",
201
+ img)
202
+ self.prepro_img += 1
203
+
204
+ return jsonify({'message': 'Preprocessing 1 sukses'}), 200
205
+
206
+ except Exception as e:
207
+ flash('Terjadi error: {}'.format(str(e)))
208
+
209
+ return redirect(url_for('index'))
210
+
211
+ def do_pre2(self,test):
212
+ global prepro_img2
213
+ global face_landmark_img, landmark_extraction_img
214
+ self.prepro_img2 = 0
215
+ try:
216
+ if (self.landmark_extraction_img == True):
217
+ GetLoadData.folder_maker("Landmark Extraction")
218
+ for i2 in tqdm(range(0, len(list_folder)), desc=f"Processing {list_folder} images"):
219
+ for j2 in range(0, len(self.list_class)):
220
+ new_dataset = f"./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}"
221
+ len_new_dataset = os.listdir(
222
+ f"./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}")
223
+
224
+ image_dir = Path(new_dataset)
225
+ for k in (range(0, len(len_new_dataset))):
226
+ filepaths, labels = GetLoadData.load_image_data(image_dir)
227
+ img = cv2.imread(filepaths[k])
228
+
229
+ subtracted_img = np.zeros(img.shape, np.uint8)
230
+
231
+ # ----------------------------------------------------------------------
232
+ img1 = cv2.imread(
233
+ f'./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}/{len_new_dataset[k]}')
234
+ img2 = cv2.imread(
235
+ f'./static/dataset/Face Shape/{list_folder[i2]}/{self.list_class[j2]}/{len_new_dataset[k]}')
236
+
237
+ # Lakukan perhitungan pengurangan pixel secara manual
238
+ for l in range(img1.shape[0]):
239
+ for m in range(img1.shape[1]):
240
+ subtracted_img[l, m] = abs(int(img1[l, m][0]) - int(img2[l, m][0]))
241
+
242
+ # ----------------------------------------------------------------------
243
+ cv2.imwrite(
244
+ "./static/dataset/Landmark Extraction/" + f"{list_folder[i2]}/" + f"{self.list_class[j2]}/" + f"{len_new_dataset[k]}",
245
+ subtracted_img)
246
+ self.prepro_img2 += 1
247
+
248
+ # requests.get(url_for('get_progress_1', _external=True), params={'progress': prepro_img2})
249
+
250
+ # prepro_img = 0
251
+ # code preprocessing
252
+ return jsonify({'message': 'Preprocessing sukses'}), 200
253
+ except Exception as e:
254
+ flash('Terjadi error: {}'.format(str(e)))
255
+ return redirect(url_for('index'))
256
+
257
+ def get_progress_1(self):
258
+
259
+ if self.prepro_img > 0:
260
+ self.name = "Face Landmark"
261
+ self.progres = self.prepro_img
262
+ print(self.progres)
263
+
264
+ if self.prepro_img2 > 0:
265
+ self.name = "Landmark Extraction"
266
+ self.progres = self.prepro_img2
267
+ print(self.progres)
268
+
269
+ return self.progres, self.name