import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import tensorflow as tf from tensorflow.keras.preprocessing.image import load_img, img_to_array from sklearn.metrics import confusion_matrix import os import cv2 import numpy as np from tqdm import tqdm from flask import jsonify, flash, redirect, url_for from pathlib import Path from get_load_data import GetLoadData from data_preprocess import DataProcessing list_folder = ['Training', 'Testing'] class TrainPred: def __init__(self, batch_size=32): self.batch_size = batch_size self.list_class = ['Diamond', 'Oblong', 'Oval', 'Round', 'Square', 'Triangle'] self.face_crop_img = True self.face_landmark_img = True self.landmark_extraction_img = True self.prepro_img = 0 self.prepro_img2 = 0 self.name = "" self.progres = 0 self.data_processor = DataProcessing() def train_model(self, model, train_generator, test_generator, epoch): model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) history = model.fit(train_generator, epochs=epoch, validation_data=test_generator) return history def prediction(self, model): img_width, img_height = 200, 200 img = load_img("./static/result_upload2.jpg", target_size=(img_width, img_height)) # img = load_img("./static/result_upload2.jpg") img = img_to_array(img) img = img/255.0 img = np.expand_dims(img, axis=0) pred = model.predict(img) pred_2 = model.predict_on_batch(img) print(f"Pred :{pred}") print(f"Pred 2 : {pred_2}") # menghitung softmax softmax_pred = np.exp(pred) / np.sum(np.exp(pred), axis=1, keepdims=True) max_value = int(round(np.max(softmax_pred * 100))) pred = np.argmax(pred, axis=1) # Map the label pred = [self.list_class[k] for k in pred] return pred, max_value def plot_accuracy(self, result, epoch): train_acc_gr = result.history['accuracy'] val_acc_gr = result.history['val_accuracy'] epochs = range(1, epoch+1) # Plot training accuracy plt.plot(epochs, train_acc_gr, label='Training Accuracy') plt.plot(epochs, val_acc_gr, label='Testing Accuracy') # Set plot title and labels plt.title('Model Accuracy') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.legend(loc='best') # Save plot as image file plt.savefig('./static/accuracy_plot.png') def plot_loss(self, result, epoch): train_loss_gr = result.history['loss'] val_loss_gr = result.history['val_loss'] epochs = range(1, epoch+1) # Plot training accuracy plt.plot(epochs, train_loss_gr, label='Training Loss') plt.plot(epochs, val_loss_gr, label='Testing Loss') # Set plot title and labels plt.title('Model Loss') plt.xlabel('Epoch') plt.ylabel('Loss') plt.legend(loc='best') # Save plot as image file plt.savefig('./static/loss_plot.png') def plot_confusion_matrix(self, model, test_generator): # Get the predictions from the model predictions = model.predict(test_generator, steps=len(test_generator), verbose=1) y_pred = np.argmax(predictions, axis=1) y_true = test_generator.classes # Generate confusion matrix cm = confusion_matrix(y_true, y_pred) # Plot the confusion matrix fig, ax = plt.subplots(figsize=(8, 8)) ax.imshow(cm, cmap='Blues') ax.set_title('Confusion Matrix') ax.set_xlabel('Predicted Labels') ax.set_ylabel('True Labels') ax.set_xticks(range(len(test_generator.class_indices))) ax.set_xticklabels(test_generator.class_indices.keys(), rotation=90) ax.set_yticks(range(len(test_generator.class_indices))) ax.set_yticklabels(test_generator.class_indices.keys()) for i in range(len(test_generator.class_indices)): for j in range(len(test_generator.class_indices)): ax.text(j, i, str(cm[i, j]), ha='center', va='center', color='white') fig.tight_layout() filename = './static/confusion_matrix.png' # Save the confusion matrix as an image file fig.savefig(filename) return filename def data_configuration(self, train_image_df, test_image_df): train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255) test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_dataframe( dataframe=train_image_df, x_col='Filepath', y_col='Label', target_size=(220, 280), color_mode='rgb', class_mode='categorical', batch_size=self.batch_size, subset='training' ) test_generator = test_datagen.flow_from_dataframe( dataframe=test_image_df, x_col='Filepath', y_col='Label', target_size=(220, 280), color_mode='rgb', class_mode='categorical', batch_size=self.batch_size, subset='training' ) return train_generator, test_generator def model_architecture(self): model = tf.keras.models.Sequential() # layers from the previous code model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(220, 280, 3))) model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu')) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Conv2D(128, (3, 3), activation='relu')) model.add(tf.keras.layers.Conv2D(128, (3, 3), activation='relu')) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Conv2D(256, (3, 3), activation='relu')) model.add(tf.keras.layers.Conv2D(256, (3, 3), activation='relu')) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Flatten()) model.add(tf.keras.layers.Dense(6, activation='softmax')) model.summary() return model # @staticmethod def do_pre1(self,test): global prepro_img global face_landmark_img, landmark_extraction_img self.prepro_img = 0 try: if (self.face_landmark_img == True): GetLoadData.folder_maker("Face Landmark") for i in tqdm(range(0, len(list_folder)), desc=f"Processing {list_folder} images"): for j in range(0, len(self.list_class)): dataset = f"./static/dataset/Face Shape/{list_folder[i]}/{self.list_class[j]}" len_dataset = os.listdir(f"./static/dataset/Face Shape/{list_folder[i]}/{self.list_class[j]}") image_dir = Path(dataset) for k in (range(0, len(len_dataset))): filepaths, labels = GetLoadData.load_image_data(image_dir) img = cv2.imread(filepaths[k]) img = self.data_processor.annotate_face_mesh(image=img) # print("./static/dataset/Face Landmark/" + f"{list_folder[i]}/" + f"{list_class[j]}/" + f"{len_dataset[k]}") cv2.imwrite( "./static/dataset/Face Landmark/" + f"{list_folder[i]}/" + f"{self.list_class[j]}/" + f"{len_dataset[k]}", img) self.prepro_img += 1 return jsonify({'message': 'Preprocessing 1 sukses'}), 200 except Exception as e: flash('Terjadi error: {}'.format(str(e))) return redirect(url_for('index')) def do_pre2(self,test): global prepro_img2 global face_landmark_img, landmark_extraction_img self.prepro_img2 = 0 try: if (self.landmark_extraction_img == True): GetLoadData.folder_maker("Landmark Extraction") for i2 in tqdm(range(0, len(list_folder)), desc=f"Processing {list_folder} images"): for j2 in range(0, len(self.list_class)): new_dataset = f"./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}" len_new_dataset = os.listdir( f"./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}") image_dir = Path(new_dataset) for k in (range(0, len(len_new_dataset))): filepaths, labels = GetLoadData.load_image_data(image_dir) img = cv2.imread(filepaths[k]) subtracted_img = np.zeros(img.shape, np.uint8) # ---------------------------------------------------------------------- img1 = cv2.imread( f'./static/dataset/Face Landmark/{list_folder[i2]}/{self.list_class[j2]}/{len_new_dataset[k]}') img2 = cv2.imread( f'./static/dataset/Face Shape/{list_folder[i2]}/{self.list_class[j2]}/{len_new_dataset[k]}') # Lakukan perhitungan pengurangan pixel secara manual for l in range(img1.shape[0]): for m in range(img1.shape[1]): subtracted_img[l, m] = abs(int(img1[l, m][0]) - int(img2[l, m][0])) # ---------------------------------------------------------------------- cv2.imwrite( "./static/dataset/Landmark Extraction/" + f"{list_folder[i2]}/" + f"{self.list_class[j2]}/" + f"{len_new_dataset[k]}", subtracted_img) self.prepro_img2 += 1 # requests.get(url_for('get_progress_1', _external=True), params={'progress': prepro_img2}) # prepro_img = 0 # code preprocessing return jsonify({'message': 'Preprocessing sukses'}), 200 except Exception as e: flash('Terjadi error: {}'.format(str(e))) return redirect(url_for('index')) def get_progress_1(self): if self.prepro_img > 0: self.name = "Face Landmark" self.progres = self.prepro_img print(self.progres) if self.prepro_img2 > 0: self.name = "Landmark Extraction" self.progres = self.prepro_img2 print(self.progres) return self.progres, self.name