File size: 5,512 Bytes
5cee8f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc02d66
5cee8f3
2ce1ecb
5cee8f3
1684a48
5cee8f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f76679
5cee8f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644781c
5cee8f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a11c512
5cee8f3
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import streamlit as st
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import cv2
from skimage.feature import local_binary_pattern

# Fungsi untuk validasi path
def validate_path(path):
    if not os.path.exists(path):
        st.error(f"Path {path} does not exist. Please check your dataset directory.")
        return False
    return True

# Fungsi untuk menghitung histogram warna
def calculate_color_histogram(image):
    hist_r = cv2.calcHist([image], [2], None, [256], [0, 256]).flatten()  # Red
    hist_g = cv2.calcHist([image], [1], None, [256], [0, 256]).flatten()  # Green
    hist_b = cv2.calcHist([image], [0], None, [256], [0, 256]).flatten()  # Blue
    return hist_r, hist_g, hist_b

# Fungsi untuk plotting LBP
def calculate_lbp(image, radius, n_points):
    lbp = local_binary_pattern(image, n_points, radius, method='uniform')
    hist, _ = np.histogram(lbp.ravel(), bins=range(0, n_points + 3))
    return hist

# Fungsi utama aplikasi Streamlit
def run():
    st.title("Exploratory Data Analysis of Skin Type")
    st.write("This page contains Exploratory Data Analysis of Skin Type based on the previous model.")
    st.write("---")
    
    st.image('https://i.ytimg.com/vi/vic-EMOivpA/maxresdefault.jpg', caption='What is your skin type?', use_container_width=True)
    st.write('This model is trained based on 3 classes: Normal Type, Dry Type, Oily Type. The model will predict skin type based on features in the uploaded image. The results will be assigned to the class that has the highest probability. Each class has a maximum probability of 33.37%')

    
    # Set dataset path
    main_path = './Oily-Dry-Skin-Types/'
    train_path = os.path.join(main_path, 'train')

    # Validasi path dataset
    if not validate_path(train_path):
        return

    # Ambil daftar kelas dari folder train
    classes = [d for d in os.listdir(train_path) if os.path.isdir(os.path.join(train_path, d))]
    st.write("## Classes in Dataset:", classes)

    # EDA 1: Histogram Warna
    st.write("### EDA 1: Color Histogram Analysis")
    for skin_type in classes:
        path = os.path.join(train_path, skin_type)
        hist_r, hist_g, hist_b = np.zeros(256), np.zeros(256), np.zeros(256)
        for img_name in os.listdir(path):
            img_path = os.path.join(path, img_name)
            img = cv2.imread(img_path)
            if img is not None:
                r, g, b = calculate_color_histogram(img)
                hist_r += r
                hist_g += g
                hist_b += b

        # Plot histogram warna
        plt.figure(figsize=(10, 5))
        plt.plot(hist_r, color='r', label='Red')
        plt.plot(hist_g, color='g', label='Green')
        plt.plot(hist_b, color='b', label='Blue')
        plt.title(f"Color Histogram for {skin_type}")
        plt.legend()
        st.pyplot(plt)
        plt.clf()

    st.write("Insight: From the results of the analysis above, we can conclude that there are no significant differences in the color spectrum that dominates a particular skin type. This could be due to non-standardized image capture so that much of the data is biased due to camera light")

    # EDA 2: Texture Analysis (LBP)
    st.write("### EDA 2: Texture Analysis (LBP)")
    radius = 3
    n_points = 8 * radius

    for skin_type in classes:
        path = os.path.join(train_path, skin_type)
        lbp_histograms = []
        for img_name in os.listdir(path):
            img_path = os.path.join(path, img_name)
            img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
            if img is not None:
                hist = calculate_lbp(img, radius, n_points)
                lbp_histograms.append(hist)

        # Plot rata-rata histogram LBP
        avg_hist = np.mean(lbp_histograms, axis=0)
        plt.bar(range(len(avg_hist)), avg_hist)
        plt.title(f"LBP Histogram for {skin_type}")
        plt.xlabel("LBP Value")
        plt.ylabel("Frequency")
        st.pyplot(plt)
        plt.clf()

    st.write("Insight: From the results of the analysis above, it can be seen that there are almost no striking differences between each skin type. This could be because many of the respondents who were the data source in making this model used make up so that the original facial skin texture was not visible.")

    # EDA 3: Spot/Pores Analysis
    st.write("### EDA 3: Spot and Pores Analysis")
    for skin_type in classes:
        path = os.path.join(train_path, skin_type)
        spot_counts = []
        for img_name in os.listdir(path):
            img_path = os.path.join(path, img_name)
            img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
            if img is not None:
                _, thresh = cv2.threshold(img, 50, 255, cv2.THRESH_BINARY_INV)
                contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
                spot_counts.append(len(contours))

        # Plot distribusi jumlah spot
        plt.hist(spot_counts, bins=20, alpha=0.7, label=f"{skin_type}")
        plt.title(f"Spot Distribution for {skin_type}")
        plt.xlabel("Number of Spots")
        plt.ylabel("Frequency")
        st.pyplot(plt)
        plt.clf()

    st.write("Insight: From the results of the analysis above, it can be concluded that normal skin types tend to have more pores and spots compared to other skin types. The order of skin types that have lots of spots and pores: 1. Normal Skin, 2. Oily Skin, 3. Dry Skin")

if __name__ == "__main__":
    run()