houssamDev commited on
Commit
fb2ecab
·
verified ·
1 Parent(s): 5c3d8dd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +269 -267
app.py CHANGED
@@ -1,268 +1,270 @@
1
- import streamlit as st
2
- import pandas as pd
3
- from PIL import Image
4
- import cv2
5
- import os
6
- import time
7
- import torch
8
- from joblib import load
9
- import matplotlib.pyplot as plt
10
- from transformers import AutoImageProcessor, AutoModelForImageClassification
11
- from streamlit.components.v1 import html
12
-
13
-
14
-
15
- # عنوان التطبيق
16
- st.title("نظام تحليل الصور وتقدير العمر والجنس")
17
-
18
- # تحميل بيانات CSV
19
- def load_data():
20
- try:
21
- data = pd.read_csv('recom.csv', encoding='utf-8')
22
- return data
23
- except FileNotFoundError:
24
- st.warning("ملف البيانات غير موجود")
25
- return pd.DataFrame()
26
-
27
- data = load_data()
28
-
29
- # تحميل نماذج التنبؤ
30
- @st.cache_resource
31
- def load_models():
32
- try:
33
- # Load the processor and models first
34
- processor = AutoImageProcessor.from_pretrained("dima806/fairface_age_image_detection")
35
- age_model = AutoModelForImageClassification.from_pretrained("dima806/fairface_age_image_detection")
36
- gender_model = AutoModelForImageClassification.from_pretrained("dima806/fairface_gender_image_detection")
37
- return processor, age_model, gender_model
38
- except Exception as e:
39
- st.error(f"حدث خطأ في تحميل النماذج: {e}")
40
- return None, None, None
41
-
42
- processor, age_model, gender_model = load_models()
43
-
44
- # وظيفة للتنبؤ بالعمر والجنس
45
- def predict_image(image):
46
- try:
47
- # Preprocess the image
48
- inputs = processor(images=image, return_tensors="pt")
49
-
50
- # Perform inference
51
- with torch.no_grad():
52
- age_logits = age_model(**inputs).logits
53
- gender_logits = gender_model(**inputs).logits
54
-
55
- # Get predictions
56
- predicted_age_idx = age_logits.argmax(-1).item()
57
- predicted_gender_idx = gender_logits.argmax(-1).item()
58
-
59
- # Decode predictions
60
- predicted_age = age_model.config.id2label[predicted_age_idx]
61
- predicted_gender = gender_model.config.id2label[predicted_gender_idx]
62
-
63
- return predicted_age, predicted_gender
64
- except Exception as e:
65
- st.error(f"حدث خطأ أثناء التنبؤ: {e}")
66
- return None, None
67
-
68
- def cards(recommendations):
69
- # Custom CSS for the cards
70
- css = """
71
- <style>
72
- body {
73
- margin: 0;
74
- padding: 0;
75
-
76
- }
77
- [data-testid="stAppViewContainer"] ,section{
78
- background-color: #3559A0;
79
- }
80
- .flex-container {
81
- display: flex;
82
- flex-wrap: nowrap;
83
- gap: 15px;
84
- justify-content: flex-start;
85
- direction: rtl;
86
- padding: 20px;
87
- background-color: #22305C;
88
- overflow-x: auto;
89
- scrollbar-color: #3559A0 #22305C;
90
- scrollbar-width: thin;
91
- box-shadow: 0 2px 8px rgba(0,0,0,0.07);
92
-
93
-
94
- }
95
- iframe,{
96
- border: 1px solid #3559A0;
97
- border-radius: 20px;
98
- background-color: #22305C;
99
-
100
- }
101
- .card {
102
- background: #f9f9f9;
103
- border-radius: 10px;
104
- box-shadow: 0 2px 8px rgba(0,0,0,0.07);
105
- padding: 16px;
106
- width: 220px;
107
- text-align: right;
108
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
109
- margin-bottom: 15px;
110
- flex: 0 0 auto;
111
- }
112
- .card img {
113
- width: 100%;
114
- height: 160px;
115
- object-fit: cover;
116
- border-radius: 8px;
117
- margin-bottom: 12px;
118
- border: 1px solid #eee;
119
- }
120
- .card h4 {
121
- margin: 8px 0;
122
- color: #333;
123
- font-size: 16px;
124
- }
125
- .card p {
126
- margin: 4px 0;
127
- color: #555;
128
- font-size: 14px;
129
- }
130
- </style>
131
- """
132
-
133
- # Create a complete HTML document
134
- cards_html = f"""
135
- <!DOCTYPE html>
136
- <html>
137
- <head>
138
- {css}
139
- </head>
140
- <body>
141
- <div class="flex-container">
142
- """
143
-
144
- # Build the flex cards
145
- for _, row in recommendations.iterrows():
146
- # Handle missing image case
147
- image_url = row.get('image', '') if pd.notna(row.get('image', '')) else "https://via.placeholder.com/220x160?text=No+Image"
148
-
149
- cards_html += f"""
150
- <div class="card">
151
- <img src="{image_url}" alt="{row.get('name', '')}" onerror="this.src='https://via.placeholder.com/220x160?text=Image+Error'"/>
152
- <h4>{row.get('name', '')}</h4>
153
- <p>{row.get('type', '')} | {row.get('genre', '')}</p>
154
- <p>العمر: {row.get('age_group', '')} | الجنس: {row.get('gender', '')}</p>
155
- </div>
156
- """
157
-
158
- cards_html += """
159
- </div>
160
- </body>
161
- </html>
162
- """
163
-
164
- # Use Streamlit's html component to render the HTML properly
165
- html(cards_html, height=320, scrolling=False)
166
-
167
-
168
- # وظيفة لعرض التوصيات بناءً على العمر والجنس
169
- def show_recommendations(age, gender, data):
170
- if data.empty:
171
- st.warning("لا توجد بيانات توصيات متاحة")
172
- return
173
-
174
- # فلترة البيانات بناءً على العمر والجنس (يمكن تعديل هذا المنطق حسب احتياجاتك)
175
- try:
176
- # تحويل العمر إلى رقم للتصفية
177
-
178
- # تصفية حسب الجنس
179
-
180
- # يمكنك تعديل منطق التوصية هنا حسب عمود العمر في بياناتك
181
- recommendations = data.loc[
182
- (data['gender'] == gender) &
183
- (data['age_group'] ==age)
184
- ]
185
-
186
- st.subheader("التوصيات المقترحة:")
187
-
188
- if not recommendations.empty:
189
- # عرض التوصيات باستخدام بطاقات
190
- cards(recommendations)
191
- else:
192
- st.warning(recommendations)
193
- except Exception as e:
194
- st.error(f"حدث خطأ في عرض التوصيات: {e}")
195
- st.dataframe(data.sample(5))
196
-
197
- # إنشاء قائمة جانبية للاختيارات
198
- option = st.sidebar.selectbox(
199
- "اختر طريقة إدخال الصورة",
200
- ("تحميل من الملف", "التقاط من الكاميرا")
201
- )
202
-
203
- # متغير للصورة
204
- uploaded_image = None
205
- captured_image = None
206
- image_to_predict = None
207
-
208
- if option == "تحميل من الملف":
209
- uploaded_file = st.file_uploader("اختر صورة لتحميلها", type=['jpg', 'png', 'jpeg'])
210
-
211
- if uploaded_file is not None:
212
- # عرض شاشة التحميل
213
- with st.spinner('جاري معالجة الصورة...'):
214
- uploaded_image = Image.open(uploaded_file)
215
- image_to_predict = uploaded_image
216
- st.success("تم تحميل الصورة بنجاح!")
217
-
218
- # عرض الصورة
219
- st.image(uploaded_image, caption="الصورة المرفوعة", use_column_width=True)
220
-
221
- else:
222
- # خيار التقاط صورة من الكاميرا
223
- st.write("اضغط على الزر لتفعيل الكاميرا")
224
-
225
- picture = st.camera_input("التقاط صورة")
226
-
227
- if picture:
228
- with st.spinner('جاري معالجة الصورة...'):
229
- captured_image = Image.open(picture)
230
- image_to_predict = captured_image
231
- st.success("تم التقاط الصورة بنجاح!")
232
-
233
- # زر لمعالجة الصورة واستخراج البيانات
234
- if st.button("تحليل الصورة"):
235
- if image_to_predict is not None and processor is not None and age_model is not None and gender_model is not None:
236
- with st.spinner('جاري تحليل الصورة...'):
237
- predicted_age, predicted_gender = predict_image(image_to_predict)
238
-
239
- if predicted_age is not None and predicted_gender is not None:
240
- # عرض النتائج
241
- st.subheader("نتائج التحليل:")
242
- col1, col2 = st.columns(2)
243
- with col1:
244
- st.metric("العمر المتوقع", predicted_age)
245
- with col2:
246
- st.metric("الجنس المتوقع",predicted_gender)
247
-
248
- # عرض التوصيات
249
- show_recommendations(predicted_age.lower().strip(), predicted_gender.lower().strip(), data)
250
- else:
251
- st.error("فشل في تحليل الصورة")
252
- else:
253
- if image_to_predict is None:
254
- st.warning("الرجاء تحميل أو التقاط صورة أولاً")
255
- else:
256
- st.error("النماذج غير جاهزة للتحليل")
257
-
258
- # قسم لإضافة ملف CSV جديد إذا لزم الأمر
259
- st.sidebar.header("إدارة البيانات")
260
- new_csv = st.sidebar.file_uploader("رفع ملف بيانات جديد (CSV)", type=['csv'])
261
- if new_csv is not None:
262
- try:
263
- new_data = pd.read_csv(new_csv, encoding='utf-8')
264
- new_data.to_csv('data.csv', index=False)
265
- st.sidebar.success("تم تحديث بيانات CSV بنجاح!")
266
- data = load_data() # إعادة تحميل البيانات
267
- except Exception as e:
 
 
268
  st.sidebar.error(f"حدث خطأ: {e}")
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from PIL import Image
4
+ import cv2
5
+ import os
6
+ import time
7
+ import torch
8
+ from joblib import load
9
+ import matplotlib.pyplot as plt
10
+ from transformers import AutoImageProcessor, AutoModelForImageClassification
11
+ from streamlit.components.v1 import html
12
+ import os
13
+ os.environ['TRANSFORMERS_CACHE'] = '/app/cache'
14
+
15
+
16
+
17
+ # عنوان التطبيق
18
+ st.title("نظام تحليل الصور وتقدير العمر والجنس")
19
+
20
+ # تحميل بيانات CSV
21
+ def load_data():
22
+ try:
23
+ data = pd.read_csv('recom.csv', encoding='utf-8')
24
+ return data
25
+ except FileNotFoundError:
26
+ st.warning("ملف البيانات غير موجود")
27
+ return pd.DataFrame()
28
+
29
+ data = load_data()
30
+
31
+ # تحميل نماذج التنبؤ
32
+ @st.cache_resource
33
+ def load_models():
34
+ try:
35
+ # Load the processor and models first
36
+ processor = AutoImageProcessor.from_pretrained("dima806/fairface_age_image_detection")
37
+ age_model = AutoModelForImageClassification.from_pretrained("dima806/fairface_age_image_detection")
38
+ gender_model = AutoModelForImageClassification.from_pretrained("dima806/fairface_gender_image_detection")
39
+ return processor, age_model, gender_model
40
+ except Exception as e:
41
+ st.error(f"حدث خطأ في تحميل النماذج: {e}")
42
+ return None, None, None
43
+
44
+ processor, age_model, gender_model = load_models()
45
+
46
+ # وظيفة للتنبؤ بالعمر والجنس
47
+ def predict_image(image):
48
+ try:
49
+ # Preprocess the image
50
+ inputs = processor(images=image, return_tensors="pt")
51
+
52
+ # Perform inference
53
+ with torch.no_grad():
54
+ age_logits = age_model(**inputs).logits
55
+ gender_logits = gender_model(**inputs).logits
56
+
57
+ # Get predictions
58
+ predicted_age_idx = age_logits.argmax(-1).item()
59
+ predicted_gender_idx = gender_logits.argmax(-1).item()
60
+
61
+ # Decode predictions
62
+ predicted_age = age_model.config.id2label[predicted_age_idx]
63
+ predicted_gender = gender_model.config.id2label[predicted_gender_idx]
64
+
65
+ return predicted_age, predicted_gender
66
+ except Exception as e:
67
+ st.error(f"حدث خطأ أثناء التنبؤ: {e}")
68
+ return None, None
69
+
70
+ def cards(recommendations):
71
+ # Custom CSS for the cards
72
+ css = """
73
+ <style>
74
+ body {
75
+ margin: 0;
76
+ padding: 0;
77
+
78
+ }
79
+ [data-testid="stAppViewContainer"] ,section{
80
+ background-color: #3559A0;
81
+ }
82
+ .flex-container {
83
+ display: flex;
84
+ flex-wrap: nowrap;
85
+ gap: 15px;
86
+ justify-content: flex-start;
87
+ direction: rtl;
88
+ padding: 20px;
89
+ background-color: #22305C;
90
+ overflow-x: auto;
91
+ scrollbar-color: #3559A0 #22305C;
92
+ scrollbar-width: thin;
93
+ box-shadow: 0 2px 8px rgba(0,0,0,0.07);
94
+
95
+
96
+ }
97
+ iframe,{
98
+ border: 1px solid #3559A0;
99
+ border-radius: 20px;
100
+ background-color: #22305C;
101
+
102
+ }
103
+ .card {
104
+ background: #f9f9f9;
105
+ border-radius: 10px;
106
+ box-shadow: 0 2px 8px rgba(0,0,0,0.07);
107
+ padding: 16px;
108
+ width: 220px;
109
+ text-align: right;
110
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
111
+ margin-bottom: 15px;
112
+ flex: 0 0 auto;
113
+ }
114
+ .card img {
115
+ width: 100%;
116
+ height: 160px;
117
+ object-fit: cover;
118
+ border-radius: 8px;
119
+ margin-bottom: 12px;
120
+ border: 1px solid #eee;
121
+ }
122
+ .card h4 {
123
+ margin: 8px 0;
124
+ color: #333;
125
+ font-size: 16px;
126
+ }
127
+ .card p {
128
+ margin: 4px 0;
129
+ color: #555;
130
+ font-size: 14px;
131
+ }
132
+ </style>
133
+ """
134
+
135
+ # Create a complete HTML document
136
+ cards_html = f"""
137
+ <!DOCTYPE html>
138
+ <html>
139
+ <head>
140
+ {css}
141
+ </head>
142
+ <body>
143
+ <div class="flex-container">
144
+ """
145
+
146
+ # Build the flex cards
147
+ for _, row in recommendations.iterrows():
148
+ # Handle missing image case
149
+ image_url = row.get('image', '') if pd.notna(row.get('image', '')) else "https://via.placeholder.com/220x160?text=No+Image"
150
+
151
+ cards_html += f"""
152
+ <div class="card">
153
+ <img src="{image_url}" alt="{row.get('name', '')}" onerror="this.src='https://via.placeholder.com/220x160?text=Image+Error'"/>
154
+ <h4>{row.get('name', '')}</h4>
155
+ <p>{row.get('type', '')} | {row.get('genre', '')}</p>
156
+ <p>العمر: {row.get('age_group', '')} | الجنس: {row.get('gender', '')}</p>
157
+ </div>
158
+ """
159
+
160
+ cards_html += """
161
+ </div>
162
+ </body>
163
+ </html>
164
+ """
165
+
166
+ # Use Streamlit's html component to render the HTML properly
167
+ html(cards_html, height=320, scrolling=False)
168
+
169
+
170
+ # وظيفة لعرض التوصيات بناءً على العمر والجنس
171
+ def show_recommendations(age, gender, data):
172
+ if data.empty:
173
+ st.warning("لا توجد بيانات توصيات متاحة")
174
+ return
175
+
176
+ # فلترة البيانات بناءً على العمر والجنس (يمكن تعديل هذا المنطق حسب احتياجاتك)
177
+ try:
178
+ # تحويل العمر إلى رقم للتصفية
179
+
180
+ # تصفية حسب الجنس
181
+
182
+ # يمكنك تعديل منطق التوصية هنا حسب عمود العمر في بياناتك
183
+ recommendations = data.loc[
184
+ (data['gender'] == gender) &
185
+ (data['age_group'] ==age)
186
+ ]
187
+
188
+ st.subheader("التوصيا�� المقترحة:")
189
+
190
+ if not recommendations.empty:
191
+ # عرض التوصيات باستخدام بطاقات
192
+ cards(recommendations)
193
+ else:
194
+ st.warning(recommendations)
195
+ except Exception as e:
196
+ st.error(f"حدث خطأ في عرض التوصيات: {e}")
197
+ st.dataframe(data.sample(5))
198
+
199
+ # إنشاء قائمة جانبية للاختيارات
200
+ option = st.sidebar.selectbox(
201
+ "اختر طريقة إدخال الصورة",
202
+ ("تحميل من الملف", "التقاط من الكاميرا")
203
+ )
204
+
205
+ # متغير للصورة
206
+ uploaded_image = None
207
+ captured_image = None
208
+ image_to_predict = None
209
+
210
+ if option == "تحميل من الملف":
211
+ uploaded_file = st.file_uploader("اختر صورة لتحميلها", type=['jpg', 'png', 'jpeg'])
212
+
213
+ if uploaded_file is not None:
214
+ # عرض شاشة التحميل
215
+ with st.spinner('جاري معالجة الصورة...'):
216
+ uploaded_image = Image.open(uploaded_file)
217
+ image_to_predict = uploaded_image
218
+ st.success("تم تحميل الصورة بنجاح!")
219
+
220
+ # عرض الصورة
221
+ st.image(uploaded_image, caption="الصورة المرفوعة", use_column_width=True)
222
+
223
+ else:
224
+ # خيار التقاط صورة من الكاميرا
225
+ st.write("اضغط على الزر لتفعيل الكاميرا")
226
+
227
+ picture = st.camera_input("التقاط صورة")
228
+
229
+ if picture:
230
+ with st.spinner('جاري معالجة الصورة...'):
231
+ captured_image = Image.open(picture)
232
+ image_to_predict = captured_image
233
+ st.success("تم التقاط الصورة بنجاح!")
234
+
235
+ # زر لمعالجة الصورة واستخراج البيانات
236
+ if st.button("تحليل الصورة"):
237
+ if image_to_predict is not None and processor is not None and age_model is not None and gender_model is not None:
238
+ with st.spinner('جاري تحليل الصورة...'):
239
+ predicted_age, predicted_gender = predict_image(image_to_predict)
240
+
241
+ if predicted_age is not None and predicted_gender is not None:
242
+ # عرض النتائج
243
+ st.subheader("نتائج التحليل:")
244
+ col1, col2 = st.columns(2)
245
+ with col1:
246
+ st.metric("العمر المتوقع", predicted_age)
247
+ with col2:
248
+ st.metric("الجنس المتوقع",predicted_gender)
249
+
250
+ # عرض التوصيات
251
+ show_recommendations(predicted_age.lower().strip(), predicted_gender.lower().strip(), data)
252
+ else:
253
+ st.error("فشل في تحليل الصورة")
254
+ else:
255
+ if image_to_predict is None:
256
+ st.warning("الرجاء تحميل أو التقاط صورة أولاً")
257
+ else:
258
+ st.error("النماذج غير جاهزة للتحليل")
259
+
260
+ # قسم لإضافة ملف CSV جديد إذا لزم الأمر
261
+ st.sidebar.header("إدارة البيانات")
262
+ new_csv = st.sidebar.file_uploader("رفع ملف بيانات جديد (CSV)", type=['csv'])
263
+ if new_csv is not None:
264
+ try:
265
+ new_data = pd.read_csv(new_csv, encoding='utf-8')
266
+ new_data.to_csv('data.csv', index=False)
267
+ st.sidebar.success("تم تحديث بيانات CSV بنجاح!")
268
+ data = load_data() # إعادة تحميل البيانات
269
+ except Exception as e:
270
  st.sidebar.error(f"حدث خطأ: {e}")