-
Notifications
You must be signed in to change notification settings - Fork 1
Home

JUDUL ESAI
PsyCare: Solusi Cerdas Berbasis Deep Learning untuk Diagnosis Gangguan Psikologis Remaja
Diajukan untuk mengikuti Lomba Esai Psychology competition ( Psycompetition) Badan Pengembangan dan Pengkajian Keilmuan ILMPI Wilayah 3
Disusun oleh:
- Galih Ridho Utomo (4211421036/ Fisika 2021)
- Ana Maulida (4201421016/Pendidikan Fisika 2021)
Remaja menjadi kelompok usia yang rentan terhadap berbagai masalah kesehatan mental (Florensa et al., 2023). Perubahan yang berkaitan dengan perkembangan kejiwaan pada remaja diantaranya meliputi perubahan emosional yang sensitif (Mahmud et al., 2023). Dalam situasi ini, remaja sering menghadapi perilaku seperti kehilangan kontrol emosi, menarik diri dari lingkungan sosial, rasa malu dan bersalah, serta kesulitan berkonsentrasi dalam lingkungan sosial maupun sekolah (Fajaruddin & Sahrul, 2024). Setiap remaja memerlukan kondisi mental yang baik agar dapat berkembang secara sehat, membangun hubungan sosial yang kuat, mampu beradaptasi dengan perubahan, serta bertahan menghadapi tantangan hidup (Sunggung & Jonathan, 2024).
Di tengah tantangan tersebut, perkembangan teknologi memberikan peluang baru untuk mendukung berbagai bidang, termasuk kesehatan mental remaja yang tengah menjadi perhatian utama. Misalnya, sistem pakar berbasis deep learning telah digunakan untuk mendiagnosis gangguan kecemasan menyeluruh secara efektif (Daivan et al., 2024). Teknologi deep learning (DL) mampu mengenali pola kompleks dalam data untuk menghasilkan prediksi yang akurat (Adam et al., 2024). Namun, di tengah peluang tersebut, teknologi juga membawa tantangan, seperti meningkatnya kasus cyberbullying sebagai dampak dari penggunaan media sosial seperti Instagram (IG) yang mengganggu kesehatan mental remaja. Lembaga riset asal Inggris, Ditch The Label, mencatat bahwa IG merupakan platform media sosial dengan tingkat cyberbullying tertinggi (Santoso et al., 2023). Di sisi lain, pengukuran gangguan kejiwaan tetap menjadi tantangan besar karena membutuhkan pendekatan yang akurat dan sistematis. Psikometrika, yang berfokus pada pengukuran atribut psikologis individu, memainkan peran penting dalam mendeteksi gangguan psikologis (Israwan et al., 2024). Penanganan masalah kesehatan mental remaja yang semakin kompleks memerlukan solusi inovatif yang efektif. Deteksi dini gangguan kejiwaan menjadi krusial untuk mencegah dampak serius, terutama pada remaja yang berada dalam fase perkembangan emosional yang labil (Wibowo et al., 2024).
Suatu teknologi DL dibangun dengan berbagai metode diantaranya metode SVM, metode KNN, metode CNN. Dari segi metode tersebut mempunyai kekurangan salah satunya kurangnya adapatasi berbagai bentuk model maupun integrasi berbagai platform. Oleh karena itu, Psycare hadir sebagai solusi cerdas yang mengintegrasikan teknologi dan pendekatan psikologis untuk mendukung deteksi dini serta penanganan gangguan mental remaja secara optimal. Psycare dibangun dengan metode Rule-Based Geometric Analysis (RGBA) yang kami bangun mulai dari perhitungan, dataset, maupun mekanisme sistem tersebut. Hipotesis dari penelitian ini yaitu model dengan metode RGBA dapat mengalisis penyebab, hingga prediksi dari Mental Health (MH) berdasarkan input secara realtime (IG) dan akurasi dari RGBA yaitu mencapai lebih dari 95%.
Gambar 2 (A) Sistem akan melakukan autentikasi dan otomatisasi Aplikasi IG sehingga bisa generate secara realtime konten penyebab perubahan tekstur wajah yang ditunjukan (B) warna merah merupakan generate konten dari sistem secara otomatis sesuai pandangan pengguna (flow eye direction) yang menjadi penyebab perubahan emosi sehingga menampilan (C) tampilan prediksi emosi berdasarkan Rule-Based Geometric Analysis (RBGA) dari prediksi ini bisa diketahui bahwa pengguna mempunyai MH ataupun tidak, Perubahan emosi berdasarkan tekstur wajah yang melihat konten dilakukan secara realtime, apabila perubahan ini secara tiba-tiba maka aplikasi IG akan close dan user akan diberikan saran untuk menghubungi pihak terkait.
1 |
---|
Dimana untuk deteksi landmark wajah
Eye Aspect Ration (EAR) = |
1 |
---|---|
2 |
Deteksi MH dilakukan dengan menganalisis pola emosi. Probalititas tiap emosi dihitung melalui fungsi softmax
4 |
---|
Dimana
Deskripsi Emosional | Batas Parameter | Metode Pengolahan |
---|---|---|
Fatique | EAR < 0.2 θbibir < 0.3 BIR > 0.4 |
Normalisasi varian model (Subathradevi et al., 2024) |
Depression | EAR > 0.6 θbibir < 0.1 |
Formulasi 2 dan formulasi 3 |
Neutral | EAR < 0.1 θbibir < 0.3 BIR > 0.3 |
Koordinat landmark wajah |
Happy/Positif Mood | EAR > 0.5 θbibir > 0.8 BIR < 0.3 |
Koordinat landmark wajah |
Stressed | BIR > 0.3 | Koordinat alis dan mata ([70, 63, 105, 66, 107], [159, 145, 133]) |
Pada sistem yang dibangun, dataset dilakukan secara realtime dan disimpan dalam bentuk file csv untuk diolah dan diambil sebuah keputusan akhir berupa saran dan evaluasi setiap membuka aplikasi. File csv memrepresentasikan bentuk emosi yang terekam oleh sistem yang telah diolah menggunakan formulasi 1 – 3 berdasarkan generate konten dari IG. Total emosi yang terdeteksi selama aplikasi ini yaitu 1250 per menit yang bergantung tingkat emosional pengguna dari 1250 dataset yang dikumpulkan maka diolah dengan perbandingan 70% data latih dan 30% data uji. Untuk standarisasi tingkat prediksi MH berdasarkan emosi dapat ditunjukan oleh Tabel 1
Lokalisasi landmark wajah (Coordinat Landmark) yang penting, seperti sudut mata, hidung dan mulut, di dalam wajah yang terdeteksi adalah tujuan dalam menentukan perubahan lengkungan titik yang signifikan sehingga dapat dijadikan model CNN dalam prediksi tertentu. Tahap ini memberikan informasi spasial yang tepat tentang fitur wajah utama, yang penting untuk memungkinkan tugas analisis wajah tingkat lanjut termasuk penyelarasan wajah, analisis ekspresi, dan estimasi tatapan. CNN lainnya yang telah dilatih terutama untuk pelokalan landmark yang digunakan oleh multi-task cascaded convolutional networks (MTCNN). Coordinat Landmark dapat dibangun dengan menggunakan pemprogaman python diantaranya module CV2, Keras, Mediapipe. Pada sistem yang dibangun kami menggunakan CV2 sebagai camera realtime dalam mendeteksi wajah dan mediapipe sebagai landmark wajah. Dengan sistem yang dibangun menggunakan kode progam berikut
Struktur Algoritma Kode Python menggunakan CV2 dan MediaPipe |
---|
frame = cv2.flip(frame, 1)
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = self.face_mesh.process(rgb_frame)
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
self.mp_drawing.draw_landmarks(
image=frame,
landmark_list=face_landmarks,
connections=self.mp_face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=self.drawing_spec,
connection_drawing_spec=self.drawing_spec)
mental_state = self.analyze_mental_state(face_landmarks, frame.shape)
self. prediction_label.setText(f'Mental State: {mental_state}')
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w, ch = rgb_frame.shape
bytes_per_line = ch * w
Pada struktur yang ditunjukan, kode progam tinggal memanggil function flip (mengubah gambar sejalan atau tidak berkebalikan); draw_landmark (mendeteksi background dan membuat titik sesuai bentuk wajah); dan menghitung jumlah perubahan titik (bytes_per_line). Tabel 2 Korelasi dan Persentase Prediksi berdasarkan formulasi parameter yang ditetapkan
Formulasi | MH | Rentang | Kepercayaan (%) |
---|---|---|---|
Fatigue | < 0.20 | 92.3 | |
Normal | 0.2 - 0.3 | 88.7 | |
Waspada | > 0.35 | 85.1 | |
MR = \frac{y_{distance}{x_{distance}}$ | Depression | < 0.2 | 87.0 |
Neutral | 0.2 - 0.5 | 90.2 | |
Positif | > 0.5 | 85.8 | |
Depression | > 0.30 | 89.4 | |
Anxious | 0.2 - 0.3 | 86.7 | |
Neutral | > 0.25% | 91.2 |
Gambar 3 (A) Hasil Analisis facial recognition untuk kondisi MH Neutral (B) kondisi Fatique dan (C) kondisi Positif Mood Perbandingan dengan Metode lain Tabel 3 Perbandingan Berbagai metode pengolahan Deteksi MH
Metode | SVM | KNN | HCRNN and randomforest | RAGB |
---|---|---|---|---|
Akurasi | 96.2 | 82.3 | 98.89 | 99.58 |
Presisi | 85.2 | 75.8 | 96.52 | 96.56 |
F1-Score | 86.7 | 85.3 | 99 | 99.83 |
ROC | 90.5 | 86.4 | 97.24 | 98.17 |
Recall | 88.2 | 80.8 | 96 | 99.75 |
Grafik perbandingan pada Gambar 4 menunjukkan bahwa metode RBGA memberikan peningkatan signifikan dalam hal nilai Accuracy; F1-score; Precision; Recall; ROC. Nilai tersebut diantaranya ditunjukan pada Tabel 3. Hal ini menunjukkan bahwa metode RBGA yang dibangun dapat beradaptasi dan diimplementasikan ke Aplikasi IG. Adapun hasil output dari sistem yang dihasilkan
> Correct Predictions: 13184
> Accuracy: 99.58%
> Kesimpulan akhir prediksi emosi: Neutral
> Saran: Pertahankan kondisi Anda saat ini dan terus lakukan aktivitas yang positif.
Dari hasil tersebut mengungkapkan bahwa bentuk wajah dapat mengindentifikasi tanda-tanda penyebab MH dan penyebab timbulnya gejala yang terjadi (IG). Hal ini dapat dicegah dengan mengurangi pengunaan aplikasi dan sering bersosialisasi dan konsultasi berdasarkan saran sistem selama menggunakan aplikasi.
Adam, N. T., Tyas, Z. A., & Hardiani, T. (2024). Gesture detection of Indonesian sign language using deep learning method SSD MobileNet V2 FPNLite. Sainteks, 21(2), 129-142. https://doi.org/10.30595/sainteks.v21i2.24006
Daivan, F., Saripurna, D., & Siambaton, M. Z. (2024). E-diagnosis gangguan kecemasan menyeluruh menggunakan fuzzy inference system (FIS) Tsukamoto. Jurnal Teknik Informatika, Fakultas Teknik, Universitas Islam Sumatera Utara.
Diwyarthi, N. D. M. S., Pratama, I. W. A., Habibi, D., Anurogo, D., & Maisharah, S. (2023). Kemajuan dalam psikoterapi dan konseling untuk meningkatkan hasil kesehatan mental. Jurnal Multidisiplin West Science, 2(10), 868-880. https://wnj.westscience-press.com/index.php/jmws
Fajaruddin, M., & Sahrul. (2024). Karakteristik kesehatan mental remaja dalam perilaku self-harm. Cetta: Jurnal Ilmu Pendidikan, 7(4). https://jayapanguspress.penerbit.org/index.php/cetta
Florensa, N., Hidayah, N., Sari, L., Yousrihatin, F., & Litaqia, W. (2023). Gambaran kesehatan mental emosional remaja. Jurnal Kesehatan, 12(1).
Hossain, S., Umer, S., Rout, R. K., & Marzouqi, H. Al. (2024). A Deep Quantum Convolutional Neural Network Based Facial Expression Recognition For MH Analysis. IEEE Transactions on Neural Systems and Rehabilitation Engineering, 32, 1556–1565. https://doi.org/10.1109/TNSRE.2024.3385336
Israwan, L. F., Atina, L., & Sarwati. (2024). Aplikasi sistem pakar tes psikometrik menggunakan metodologi The Minnesota Multiphasic Personality Inventory (MMPI). Jurnal Informatika, 13(2), 37-47. https://doi.org/10.55340/jiu.v13i2.2290
Karisma, N., Rofiah, A., Afifah, S. N., & Manik, Y. M. (2023). Kesehatan mental remaja dan tren bunuh diri: Peran masyarakat mengatasi kasus bullying di Indonesia. Edu Cendikia: Jurnal Ilmiah Kependidikan, 3(3). https://doi.org/10.47709/educendikia.v3i03.3439
Liu, N., Liu, H., & Liu, H. (2021). MH diagnosis of college students based on facial recognition and neural network. Journal of Intelligent and Fuzzy Systems, 40(4), 7061–7072. https://doi.org/10.3233/JIFS-189536
Monferrer, M., García, A. S., Ricarte, J. J., Montes, M. J., Fernández-Caballero, A., & Fernández-Sotos, P. (2023). Facial emotion recognition in patients with depression compared to healthy controls when using human avatars. Scientific Reports 2023 13:1, 13(1), 1–10. https://doi.org/10.1038/s41598-023-31277-5
Purnamasari, Y., Fitri, N., & Mardiana, N. (2023). Faktor-faktor yang memengaruhi gangguan mental emosional remaja SMA. Jurnal Penelitian Perawat Profesional, 5(2), 609. https://jurnal.globalhealthsciencegroup.com/index.php/JPPP
Rahmawaty, F., Silalahiv, R. P., T, B., & Mansyah, B. (2024). Faktor-faktor yang mempengaruhi kesehatan mental pada remaja. Jurnal Sains Medis, 13(2). Diambil dari http://journal.umpalangkaraya.ac.id/index.php/jsm
Santoso, H., Putri, R. A., & Sahbandi. (2023). Cyberbullying comment detection on IG social media using random forest algorithm. Jurnal Manajemen Informatika (JAMIKA), 13(1). https://doi.org/10.34010/jamika.v13i1.9303
Sari, M. K., & Susmiatin, E. A. (2023). Deteksi dini kesehatan mental emosional pada mahasiswa. Jurnal Ilmiah STIKES Yarsi Mataram, 13(1), 10-17. http://journal.stikesyarsimataram.ac.id/index.php/jik
Subathradevi, S., Preethiya, T., Santhi, D., & Hemalakshmi, G. R. (2024). Facial emotion recognition for feature extraction and ensemble learning using hierarchical cascade regression neural networks and random forest. Journal of Circuits, Systems and Computers. https://doi.org/10.1142/s0218126625500112
Wibowo, S., Priambodo, A., Prihanto, J. B., Indriarsa, N., & Dinata, V. C. (2024). Deteksi dini gangguan kejiwaan dan peningkatan kesehatan mental remaja melalui fun games. ABSYARA: Jurnal Pengabdian Pada Masyarakat, 5(1), 94-105. https://doi.org/10.29408/ab.v5i1.25135
Zhao, P., Ming, Y., Meng, X., & Yu, H. (2023). LMFNet: A Lightweight Multiscale Fusion Network With Hierarchical Structure for Low-Quality 3-D Face Recognition. IEEE Transactions on Human-Machine Systems, 53(1), 239–252. https://doi.org/10.1109/THMS.2022.3199777
Materi yang mendukung berupa dataset, hasil pengolahan untuk artikel ini dapat ditemukan secara online di: https://github.com/4211421036/facemind
import sys
import cv2
import numpy as np
import mediapipe as mp
import csv
import datetime
import pandas as pd
import matplotlib.pyplot as plt
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PyQt5.QtWidgets import (QApplication, QLabel, QPushButton, QVBoxLayout,
QWidget, QMainWindow, QLineEdit, QMessageBox, QAction)
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QPixmap, QImage
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, confusion_matrix, roc_curve
import subprocess
import pkg_resources
required = {'opencv-python', 'datetime', 'pandas', 'matplotlib', 'numpy', 'mediapipe', 'selenium', 'PyQt5'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
python = sys.executable
subprocess.check_call([python, '-m', 'pip', 'install', *missing])
# Fungsi untuk menghitung metrik evaluasi
def evaluate_metrics(ground_truth, predictions, prediction_labels):
# Mengonversi label prediksi ke angka untuk perhitungan
label_map = {label: i for i, label in enumerate(prediction_labels)}
y_true = [label_map[label] for label in ground_truth]
y_pred = [label_map[label] for label in predictions]
# Menghitung metrik evaluasi
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, average='weighted', zero_division=1)
recall = recall_score(y_true, y_pred, average='weighted', zero_division=1)
f1 = f1_score(y_true, y_pred, average='weighted')
confusion = confusion_matrix(y_true, y_pred)
# Menghitung True Positive, False Positive, True Negative, False Negative
TP = np.diag(confusion)
FP = confusion.sum(axis=0) - TP
FN = confusion.sum(axis=1) - TP
TN = confusion.sum() - (FP + FN + TP)
# Menghitung ROC dan AUC
if len(np.unique(y_true)) == 2: # ROC hanya relevan untuk kasus biner
fpr, tpr, thresholds = roc_curve(y_true, y_pred)
auc = roc_auc_score(y_true, y_pred)
else:
fpr, tpr, thresholds, auc = None, None, None, None
return {
"accuracy": accuracy,
"precision": precision,
"recall": recall,
"f1_score": f1,
"TP": TP.tolist(),
"FP": FP.tolist(),
"TN": TN.tolist(),
"FN": FN.tolist(),
"confusion_matrix": confusion.tolist(),
"fpr": fpr,
"tpr": tpr,
"thresholds": thresholds,
"auc": auc
}
# Fungsi untuk menampilkan hasil metrik
def display_metrics(metrics):
print("\nEvaluation Metrics:")
print(f"Accuracy: {metrics['accuracy']:.2f}")
print(f"Precision: {metrics['precision']:.2f}")
print(f"Recall: {metrics['recall']:.2f}")
print(f"F1-Score: {metrics['f1_score']:.2f}")
print("Confusion Matrix:")
print(np.array(metrics['confusion_matrix']))
print("True Positives (TP):", metrics['TP'])
print("False Positives (FP):", metrics['FP'])
print("True Negatives (TN):", metrics['TN'])
print("False Negatives (FN):", metrics['FN'])
if metrics['auc'] is not None:
print(f"AUC: {metrics['auc']:.2f}")
# Plot ROC curve jika tersedia
if metrics['fpr'] is not None and metrics['tpr'] is not None:
plt.figure()
plt.plot(metrics['fpr'], metrics['tpr'], label=f"ROC Curve (AUC = {metrics['auc']:.2f})")
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("ROC Curve")
plt.legend()
plt.show()
# Fungsi untuk menyimpan prediksi ke file CSV
def save_to_database(prediction):
filename = "mental_health_predictions.csv"
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(filename, mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([current_time, prediction])
# Fungsi untuk menampilkan grafik monitoring prediksi MH dan menghitung akurasi
def show_graph(date_filter=None):
# Membaca data dari CSV
data = pd.read_csv("mental_health_predictions.csv", names=["Time", "Prediction"])
data["Time"] = pd.to_datetime(data["Time"])
# Misalkan ground truth tersedia (harus diganti dengan data aktual Anda)
ground_truth = ["Neutral", "Fatigue Detected", "Positive Mood", "Stressed/Concerned"] * (len(data) // 4)
# Prediksi dari file CSV
predictions = data["Prediction"].tolist()
prediction_labels = ["Neutral", "Fatigue Detected", "Positive Mood", "Stressed/Concerned"]
# Evaluasi metrik
metrics = evaluate_metrics(ground_truth[:len(predictions)], predictions, prediction_labels)
display_metrics(metrics)
if date_filter:
data = data[data["Time"].dt.date == date_filter]
# Mapping prediksi ke angka untuk grafik
predictions_map = {"Neutral": 0, "Fatigue Detected": 1, "Positive Mood": 2, "Stressed/Concerned": 3}
data["Prediction Value"] = data["Prediction"].map(predictions_map)
# Membuat grafik dengan warna berbeda untuk setiap prediksi
plt.figure(figsize=(12, 8))
colors = {'Neutral': 'blue', 'Fatigue Detected': 'red', 'Positive Mood': 'green', 'Stressed/Concerned': 'orange'}
for prediction, group_data in data.groupby("Prediction"):
plt.plot_date(group_data["Time"], group_data["Prediction Value"], linestyle='solid', marker='o', color=colors[prediction], label=prediction)
plt.xlabel("Time")
plt.ylabel("Prediction")
plt.title("MH Prediction Monitoring")
plt.xticks(rotation=45)
plt.tight_layout()
plt.legend()
# Tampilkan grafik
plt.show()
# Menghitung akurasi prediksi
total_predictions = len(data)
correct_predictions = data["Prediction"].value_counts().max()
accuracy = (correct_predictions / total_predictions) * 100
print(f"Total Predictions: {total_predictions}")
print(f"Correct Predictions: {correct_predictions}")
print(f"Accuracy: {accuracy:.2f}%")
# Kesimpulan akhir prediksi emosi
final_prediction = data["Prediction"].iloc[-1]
print(f"Kesimpulan akhir prediksi emosi: {final_prediction}")
# Saran untuk mengatasi atau mengurangi emosi
suggestions = {
"Neutral": "Pertahankan kondisi Anda saat ini dan terus lakukan aktivitas yang positif.",
"Fatigue Detected": "Istirahat yang cukup, tidur yang berkualitas, dan hindari stres berlebihan.",
"Positive Mood": "Lanjutkan aktivitas yang membuat Anda bahagia dan berbagi kebahagiaan dengan orang lain.",
"Stressed/Concerned": "Lakukan relaksasi, meditasi, atau aktivitas yang menenangkan. Jangan ragu untuk mencari bantuan profesional jika diperlukan."
}
print(f"Saran: {suggestions.get(final_prediction, 'Tidak ada saran yang tersedia.')}")
# Grafik akurasi prediksi
plt.figure(figsize=(12, 8))
plt.plot(data["Time"], data["Prediction Value"], label="Detected Emotion", color='blue', linestyle='solid', marker='o')
plt.plot(data["Time"], data["Prediction Value"].rolling(window=10).mean(), label="Predicted Emotion", color='red', linestyle='dashed')
plt.xlabel("Time")
plt.ylabel("Prediction Value")
plt.title("Detected vs Predicted Emotion")
plt.xticks(rotation=45)
plt.tight_layout()
plt.legend()
plt.show()
class SplashScreen(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Splash Screen")
self.setFixedSize(800, 600)
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
layout = QVBoxLayout()
logo = QLabel()
pixmap = QPixmap(r"C:\Users\asus\Downloads\logofm.png").scaled(400, 136, Qt.KeepAspectRatio, Qt.SmoothTransformation)
logo.setPixmap(pixmap)
logo.setAlignment(Qt.AlignCenter)
label = QLabel("Welcome to MH App")
label.setAlignment(Qt.AlignCenter)
layout.addStretch()
layout.addWidget(logo)
container = QWidget()
container.setObjectName("container")
container.setLayout(layout)
self.setStyleSheet("""
QMainWindow {
border-radius: 20px;
background-color: white;
}
""")
layout.addStretch()
self.setCentralWidget(container)
layout = QVBoxLayout()
logo = QLabel()
pixmap = QPixmap(r"C:\Users\asus\Downloads\logofm.png").scaled(400, 136, Qt.KeepAspectRatio, Qt.SmoothTransformation)
logo.setPixmap(pixmap)
logo.setAlignment(Qt.AlignCenter)
label = QLabel("Welcome to MH App")
label.setAlignment(Qt.AlignCenter)
layout.addStretch()
layout.addWidget(logo)
container = QWidget()
container.setObjectName("container")
container.setLayout(layout)
layout.addStretch()
self.setCentralWidget(container)
def showSplash(self):
self.show()
QTimer.singleShot(3000, self.close)
class LoginWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Login")
self.setFixedSize(800, 600)
self.setStyleSheet("""
QMainWindow {
background-color: #f0f0f0;
}
QLabel {
font-size: 18px;
color: #333;
}
QLineEdit {
font-size: 16px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
QPushButton {
font-size: 16px;
padding: 10px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
}
QPushButton:disabled {
background-color: #cccccc;
}
QPushButton:hover {
background-color: #0056b3;
}
QMenuBar {
background-color: #f0f0f0;
}
QMenuBar::item {
background-color: #f0f0f0;
color: #333;
}
QMenuBar::item:selected {
background-color: #e0e0e0;
color: #333;
}
QMenu {
background-color: #f0f0f0;
color: #333;
}
QMenu::item:selected {
background-color: #e0e0e0;
color: #333;
}
""")
menubar = self.menuBar()
file_menu = menubar.addMenu('File')
help_menu = menubar.addMenu('Help')
about_menu = menubar.addMenu('About')
monitoring_menu = menubar.addMenu('Monitoring')
exit_action = QAction('Exit', self)
exit_action.triggered.connect(QApplication.instance().quit)
file_menu.addAction(exit_action)
help_action = QAction('Help', self)
help_action.triggered.connect(self.show_help)
help_menu.addAction(help_action)
about_action = QAction('About', self)
about_action.triggered.connect(self.show_about)
about_menu.addAction(about_action)
show_graph_action = QAction('Show Monitoring Graph', self)
show_graph_action.triggered.connect(self.show_graph)
monitoring_menu.addAction(show_graph_action)
layout = QVBoxLayout()
logo = QLabel()
pixmap = QPixmap(r"C:\Users\asus\Downloads\layarui.png").scaledToWidth(self.width(), Qt.SmoothTransformation)
logo.setPixmap(pixmap)
logo.setAlignment(Qt.AlignCenter)
layout.addWidget(logo)
label = QLabel("Login to your account")
layout.addWidget(label)
label.setAlignment(Qt.AlignCenter)
self.username_input = QLineEdit()
self.username_input.setPlaceholderText('Username')
self.password_input = QLineEdit()
self.password_input.setPlaceholderText('Password')
self.password_input.setEchoMode(QLineEdit.Password)
self.login_button = QPushButton('Login to IG')
self.login_button.clicked.connect(self.login_IG)
self.start_analysis_button = QPushButton('Start MH Analysis')
self.start_analysis_button.clicked.connect(self.start_analysis)
self.start_analysis_button.setEnabled(False)
self.status_label = QLabel('')
layout.addWidget(self.username_input)
layout.addWidget(self.password_input)
layout.addWidget(self.login_button)
layout.addWidget(self.start_analysis_button)
layout.addWidget(self.status_label)
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
self.driver = None
def show_graph(self):
# Panggil fungsi untuk menampilkan grafik
show_graph()
def show_help(self):
QMessageBox.information(self, "Help", "This is the help section.")
def show_about(self):
QMessageBox.information(self, "About", "MH App v1.0")
def login_IG(self):
self.status_label.setText('Logging in...')
self.driver = webdriver.Chrome()
self.driver.get('https://www.IG.com/accounts/login/')
wait = WebDriverWait(self.driver, 10)
username_field = wait.until(EC.presence_of_element_located((By.NAME, 'username')))
username_field.send_keys(self.username_input.text())
password_field = self.driver.find_element(By.NAME, 'password')
password_field.send_keys(self.password_input.text())
password_field.send_keys(Keys.RETURN)
wait.until(EC.url_contains('IG.com'))
if 'login' not in self.driver.current_url:
self.status_label.setText('Login successful! You can now start the analysis.')
self.start_analysis_button.setEnabled(True)
self.login_button.setEnabled(False)
else:
self.status_label.setText('Login failed. Please check your credentials.')
self.status_label.setText('Login successful! You can now start the analysis.')
self.start_analysis_button.setEnabled(True)
self.login_button.setEnabled(False)
def start_analysis(self):
if self.driver:
self.main_window = MentalHealthPredictor()
self.main_window.show()
self.hide()
self.monitor_IG_posts()
else:
self.status_label.setText('Please login first')
def monitor_IG_posts(self):
# Monitor IG posts and analyze user's emotion
self.timer = QTimer()
self.timer.timeout.connect(self.check_posts)
self.timer.start(1000) # Check every second
def check_posts(self):
self.driver.get('https://www.IG.com/')
wait = WebDriverWait(self.driver, 10)
posts = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'article div div div div a')))
for post in posts:
post.click()
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.C4VMK span')))
self.main_window.update_frame()
self.driver.back()
# Check the latest prediction
latest_prediction = self.main_window.prediction_label.text().split(': ')[-1]
if latest_prediction in ["Fatigue Detected", "Stressed/Concerned"]:
self.driver.quit()
QMessageBox.warning(self, "Warning", "Detected MH issue. IG will be closed.")
break
def closeEvent(self, event):
if self.driver:
self.driver.quit()
event.accept()
class MentalHealthPredictor(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.setupFaceDetection()
self.startVideo()
def setupFaceDetection(self):
self.mp_face_mesh = mp.solutions.face_mesh
self.face_mesh = self.mp_face_mesh.FaceMesh(
max_num_faces=1,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
self.mp_drawing = mp.solutions.drawing_utils
self.drawing_spec = self.mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
self.cap = cv2.VideoCapture(0)
def initUI(self):
self.setWindowTitle('MH Analysis')
self.setMinimumSize(800, 600)
layout = QVBoxLayout()
self.image_label = QLabel()
self.image_label.setAlignment(Qt.AlignCenter)
self.prediction_label = QLabel('Analyzing...')
self.prediction_label.setAlignment(Qt.AlignCenter)
self.back_button = QPushButton('Back to Login')
self.back_button.clicked.connect(self.back_to_login)
layout.addWidget(self.image_label)
layout.addWidget(self.prediction_label)
layout.addWidget(self.back_button)
self.setLayout(layout)
def back_to_login(self):
for widget in QApplication.topLevelWidgets():
if isinstance(widget, LoginWindow):
widget.show()
self.close()
def startVideo(self):
self.timer = QTimer()
self.timer.timeout.connect(self.update_frame)
self.timer.start(30)
def update_frame(self):
ret, frame = self.cap.read()
if ret:
frame = cv2.flip(frame, 1)
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = self.face_mesh.process(rgb_frame)
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
self.mp_drawing.draw_landmarks(
image=frame,
landmark_list=face_landmarks,
connections=self.mp_face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=self.drawing_spec,
connection_drawing_spec=self.drawing_spec)
mental_state = self.analyze_mental_state(face_landmarks, frame.shape)
self.prediction_label.setText(f'Mental State: {mental_state}')
save_to_database(mental_state)
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w, ch = rgb_frame.shape
bytes_per_line = ch * w
qt_image = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
self.image_label.setPixmap(QPixmap.fromImage(qt_image))
def analyze_mental_state(self, landmarks, frame_shape):
height, width = frame_shape[:2]
points = np.array([(lm.x * width, lm.y * height) for lm in landmarks.landmark])
eye_ratio = self.calculate_eye_ratio(points)
mouth_ratio = self.calculate_mouth_ratio(points)
brow_ratio = self.calculate_brow_ratio(points)
if eye_ratio < 0.2:
return "Fatigue Detected"
elif mouth_ratio > 0.5:
return "Positive Mood"
elif brow_ratio > 0.3:
return "Stressed/Concerned"
else:
return "Neutral"
def calculate_eye_ratio(self, points):
left_eye = [33, 160, 158, 133, 153, 144]
right_eye = [362, 385, 387, 263, 373, 380]
left_eye_points = points[left_eye]
right_eye_points = points[right_eye]
def eye_aspect_ratio(eye_points):
vertical_dist = np.linalg.norm(eye_points[1] - eye_points[5]) + \
np.linalg.norm(eye_points[2] - eye_points[4])
horizontal_dist = np.linalg.norm(eye_points[0] - eye_points[3]) * 2
return vertical_dist / horizontal_dist if horizontal_dist != 0 else 0
left_ear = eye_aspect_ratio(left_eye_points)
right_ear = eye_aspect_ratio(right_eye_points)
return (left_ear + right_ear) / 2
def calculate_mouth_ratio(self, points):
mouth_points = [61, 291, 0, 17]
mouth_pts = points[mouth_points]
vertical_dist = np.linalg.norm(mouth_pts[2] - mouth_pts[3])
horizontal_dist = np.linalg.norm(mouth_pts[0] - mouth_pts[1])
return vertical_dist / horizontal_dist if horizontal_dist != 0 else 0
def calculate_brow_ratio(self, points):
left_brow = [70, 63, 105, 66, 107]
left_eye = [159, 145, 133]
brow_points = points[left_brow]
eye_points = points[left_eye]
brow_height = np.mean(brow_points[:, 1])
eye_height = np.mean(eye_points[:, 1])
return (eye_height - brow_height) / (points[152, 1] - points[10, 1])
def closeEvent(self, event):
self.cap.release()
self.face_mesh.close()
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
splash = SplashScreen()
login_window = LoginWindow()
splash.showSplash()
QTimer.singleShot(3000, login_window.show)
sys.exit(app.exec_())