File size: 6,682 Bytes
29bcdf2
 
 
 
 
bf836f1
 
 
33f7f53
435eb8d
0623da1
 
 
 
 
435eb8d
29bcdf2
 
 
 
 
 
 
435eb8d
29bcdf2
 
 
 
 
 
 
 
 
aed03ad
 
 
d71712b
aed03ad
 
 
 
 
 
 
 
 
0623da1
 
 
 
 
 
29bcdf2
 
 
0623da1
 
 
 
 
 
 
435eb8d
0623da1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435eb8d
0623da1
 
aed03ad
29bcdf2
 
 
0623da1
33f7f53
 
 
 
 
0623da1
435eb8d
aed03ad
 
0623da1
 
 
29bcdf2
0623da1
29bcdf2
 
 
0623da1
29bcdf2
435eb8d
 
 
0623da1
 
435eb8d
33f7f53
435eb8d
0623da1
1f2f1b7
435eb8d
0623da1
435eb8d
 
0623da1
29bcdf2
 
435eb8d
 
 
 
 
 
 
 
 
 
 
 
0623da1
435eb8d
 
0623da1
435eb8d
 
 
0623da1
435eb8d
 
 
 
 
 
 
 
0623da1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435eb8d
29bcdf2
435eb8d
0623da1
29bcdf2
 
 
 
 
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import streamlit as st
import tensorflow as tf
import numpy as np
import cv2
from PIL import Image
from tensorflow.keras import layers, models
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.applications.efficientnet import preprocess_input
import joblib
import io
import os
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.oauth2 import service_account

# Set page config
st.set_page_config(
    page_title="Stone Classification",
    page_icon="🪨",
    layout="wide"
)

# Custom CSS with improved styling
st.markdown("""
    <style>
    .main {
        padding: 2rem;
    }
    .stButton>button {
        width: 100%;
        margin-top: 1rem;
    }
    .prediction-card {
        padding: 2rem;
        border-radius: 0.5rem;
        background-color: #d7d7d9;
        margin: 1rem 0;
    }
    .top-predictions {
        margin-top: 2rem;
        padding: 1rem;
        background-color: white;
        border-radius: 0.5rem;
        box-shadow: 0 1px 3px rgba(0,0,0,0.12);
    }
    .survey-card {
        padding: 1rem;
        background-color: #f0f2f6;
        border-radius: 0.5rem;
        margin-top: 1rem;
    }
    </style>
    """, unsafe_allow_html=True)

from mega import Mega

# Đăng nhập vào tài khoản Mega
def upload_to_mega(file_path, folder_name):
    """
    Upload file to a specific folder on Mega.nz
    """
    try:
        # Đăng nhập vào tài khoản Mega
        mega = Mega()
        m = mega.login(os.getenv('EMAIL'), os.getenv('PASSWORD'))

        # Tìm thư mục đích
        folder = m.find(folder_name)

        if not folder:
            # Nếu thư mục không tồn tại, hiển thị thông báo lỗi
            return f"Thư mục '{folder_name}' không tồn tại!"

        # Tải tệp lên thư mục
        file = m.upload(file_path, folder[0])
        return f"Upload thành công! Link: {m.get_upload_link(file)}"

    except Exception as e:
        return f"Lỗi khi tải lên Mega: {str(e)}"


def main():
    st.title("🪨 Stone Classification")
    st.write("Upload an image of a stone to classify its type")

    # Load model and scaler
    model, scaler = load_model_and_scaler()
    if model is None or scaler is None:
        st.error("Failed to load model or scaler. Please ensure both files exist.")
        return

    # Initialize session state
    if 'predictions' not in st.session_state:
        st.session_state.predictions = None
    if 'uploaded_image' not in st.session_state:
        st.session_state.uploaded_image = None

    col1, col2 = st.columns(2)

    with col1:
        st.subheader("Upload Image")
        uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])

        if uploaded_file is not None:
            try:
                image = Image.open(uploaded_file)
                st.image(image, caption="Uploaded Image", use_column_width=True)
                st.session_state.uploaded_image = image

                with st.spinner('Analyzing image...'):
                    processed_image = preprocess_image(image, scaler)
                    prediction = model.predict(processed_image, verbose=0)

                    class_names = ['10', '6.5', '7', '7.5', '8', '8.5', '9', '9.2', '9.5', '9.7']
                    st.session_state.predictions = get_top_predictions(prediction, class_names)

            except Exception as e:
                st.error(f"Error processing image: {str(e)}")

    with col2:
        st.subheader("Prediction Results")
        if st.session_state.predictions:
            # Display main prediction
            top_class, top_confidence = st.session_state.predictions[0]
            st.markdown(
                f"""
                <div class='prediction-card'>
                    <h3>Primary Prediction: Grade {top_class}</h3>
                    <h3>Confidence: {top_confidence:.2f}%</h3>
                </div>
                """,
                unsafe_allow_html=True
            )

            # Display confidence bar
            st.progress(top_confidence / 100)

            # Display top 5 predictions
            st.markdown("### Top 5 Predictions")
            st.markdown("<div class='top-predictions'>", unsafe_allow_html=True)

            for class_name, confidence in st.session_state.predictions:
                cols = st.columns([2, 6, 2])
                with cols[0]:
                    st.write(f"Grade {class_name}")
                with cols[1]:
                    st.progress(confidence / 100)
                with cols[2]:
                    st.write(f"{confidence:.2f}%")

            st.markdown("</div>", unsafe_allow_html=True)

            # User Survey
            st.markdown("<div class='survey-card'>", unsafe_allow_html=True)
            st.markdown("### Model Accuracy Survey")
            st.write("Mô hình có dự đoán chính xác màu sắc của đá trong ảnh này không?")

            # Accuracy Confirmation
            accuracy = st.radio(
                "Đánh giá độ chính xác",
                ["Chọn", "Chính xác", "Không chính xác"],
                index=0
            )

            if accuracy == "Không chính xác":
              # Color input for incorrect prediction
              correct_color = st.text_input(
                  "Vui lòng nhập màu sắc chính xác của đá:",
                  help="Ví dụ: 10, 9.7, 9.5, 9.2, v.v."
              )

              if st.button("Gửi phản hồi và tải ảnh"):
                  if correct_color and st.session_state.uploaded_image:
                      # Save the image temporarily
                      temp_image_path = f"temp_image_{hash(uploaded_file.name)}.png"
                      st.session_state.uploaded_image.save(temp_image_path)

                      # Upload to Mega.nz
                      upload_result = upload_to_mega(temp_image_path, correct_color)
                      if "Upload thành công" in upload_result:
                          st.success(upload_result)
                      else:
                          st.error(upload_result)

                      # Clean up temporary file
                      os.remove(temp_image_path)
                  else:
                      st.warning("Vui lòng nhập màu sắc chính xác")

            st.markdown("</div>", unsafe_allow_html=True)
        else:
            st.info("Upload an image to see the predictions")

    st.markdown("---")
    st.markdown("Made with ❤️ using Streamlit")

if __name__ == "__main__":
    main()