suprimedev commited on
Commit
09cb33c
·
verified ·
1 Parent(s): deb3fac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +292 -155
app.py CHANGED
@@ -2,130 +2,236 @@ import gradio as gr
2
  import numpy as np
3
  from PIL import Image
4
  import cv2
 
5
  import os
6
- import tempfile
7
  import warnings
8
  warnings.filterwarnings('ignore')
9
 
10
  # عنوان برنامه
11
- TITLE = "🔍 سامانه تشخیص هویت چهره"
12
  DESCRIPTION = """
13
- 🎯 سیستم هوشمند تشخیص هویت از طریق تصویر چهره
14
 
15
  ✨ امکانات:
16
- - تشخیص چهره‌های یکسان از زوایای مختلف
17
- - مقاوم در برابر تغییرات نور و آرایش
18
- - دقت بالا در شرایط مختلف
19
- - نمایش نتایج کامل و تحلیلی
20
 
21
  📌 راهنمایی:
22
  1. تصویر اول را آپلود کنید
23
- 2. تصویر دوم را آپلود کنید
24
  3. دقت مورد نظر را انتخاب کنید
25
  4. روی دکمه "تشخیص هویت" کلیک کنید
26
  """
27
 
28
- # توضیحات بیشتر
29
- ARTICLE = """
30
- ### 🔬 نحوه عملکرد سیستم
31
 
32
- این سیستم از الگوریتم‌های پیشرفته یادگیری ماشین استفاده می‌کند:
 
 
 
 
 
 
 
 
 
 
33
 
34
- 1. **تشخیص چهره**: پیدا کردن موقعیت چهره در تصویر
35
- 2. **استخراج ویژگی**: تبدیل چهره به بردار عددی
36
- 3. **مقایسه**: محاسبه فاصله بین بردارهای ویژگی
37
- 4. **تصمیم‌گیری**: مقایسه فاصله با آستانه انتخابی
38
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- # تابع تشخیص چهره با OpenCV
41
- def detect_faces_opencv(image_array):
42
- """تشخیص چهره با استفاده از OpenCV"""
43
  try:
44
- # تبدیل به تصویر سیاه و سفید
45
  gray = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY)
46
-
47
- # استفاده از Haar Cascade برای تشخیص چهره
48
  face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
49
- faces = face_cascade.detectMultiScale(
50
- gray,
51
- scaleFactor=1.1,
52
- minNeighbors=5,
53
- minSize=(30, 30),
54
- flags=cv2.CASCADE_SCALE_IMAGE
55
- )
56
 
57
  if len(faces) == 0:
58
- # تلاش با تنظیمات متفاوت
59
- faces = face_cascade.detectMultiScale(
60
- gray,
61
- scaleFactor=1.05,
62
- minNeighbors=3,
63
- minSize=(20, 20)
64
- )
 
 
 
65
 
66
- return faces
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  except Exception as e:
69
- print(f"خطا در تشخیص چهره OpenCV: {e}")
70
- return []
71
 
72
- # تابع استخراج ویژگی‌های چهره
73
- def extract_face_features(image_array, faces):
74
- """استخراج ویژگی‌های چهره"""
75
- if len(faces) == 0:
76
- return None
77
-
78
- # استفاده از اولین چهره تشخیص داده شده
79
- x, y, w, h = faces[0]
80
- face_region = image_array[y:y+h, x:x+w]
81
-
82
  try:
83
  # تغییر سایز به اندازه ثابت
84
- face_resized = cv2.resize(face_region, (128, 128))
85
-
86
- # نرمال‌سازی
87
- face_normalized = face_resized / 255.0
88
 
89
- # استخراج ویژگی‌های ساده
90
- features = {
91
- 'histogram': cv2.calcHist([face_resized], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256]).flatten(),
92
- 'mean_color': face_normalized.mean(axis=(0, 1)),
93
- 'std_color': face_normalized.std(axis=(0, 1)),
94
- }
95
 
96
- # ترکیب ویژگی‌ها
97
- feature_vector = np.concatenate([
98
- features['histogram'][:64],
99
- features['mean_color'] * 10,
100
- features['std_color'] * 10,
101
- ])
 
 
 
 
 
 
 
102
 
103
- return feature_vector
 
 
104
 
105
  except Exception as e:
106
- print(f"خطا در استخراج ویژگی: {e}")
107
- return None
108
 
109
- # تابع مقایسه ویژگی‌ها
110
- def compare_features(features1, features2):
111
- """مقایسه دو بردار ویژگی"""
112
  if features1 is None or features2 is None:
113
- return None, None
114
 
115
- # محاسبه فاصله اقلیدسی
116
- distance = np.linalg.norm(features1 - features2)
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- # محاسبه شباهت
119
- similarity = 1.0 / (1.0 + distance)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- return distance, similarity
122
 
123
  # تابع اصلی پردازش
124
  def process_faces(image1, image2, precision_level):
125
  """پردازش و مقایسه دو تصویر چهره"""
126
 
127
- # دیباگ: چاپ مقدار دریافتی
128
- print(f"🔍 precision_level دریافت شده: {precision_level} (نوع: {type(precision_level)})")
129
 
130
  # تبدیل تصاویر به آرایه
131
  if isinstance(image1, str):
@@ -138,109 +244,126 @@ def process_faces(image1, image2, precision_level):
138
  else:
139
  image2_array = np.array(image2)
140
 
141
- # تنظیم آستانه بر اساس انتخاب کاربر - **تصحیح شده**
142
  thresholds = {
143
- 'high': 25.0, # دقت بالا
144
- 'medium': 30.0, # دقت متوسط
145
- 'low': 35.0 # دقت پایین
146
  }
147
 
148
- threshold = thresholds.get(precision_level, 30.0) # مقدار پیش‌فرض
149
  print(f"🔧 آستانه انتخاب شده: {threshold}")
150
 
151
- # تشخیص چهره در تصویر اول
152
- faces1 = detect_faces_opencv(image1_array)
153
- if len(faces1) == 0:
154
- return "❌ خطا: هیچ چهره‌ای در تصویر اول یافت نشد!", None, None
155
-
156
- # تشخیص چهره در تصویر دوم
157
- faces2 = detect_faces_opencv(image2_array)
158
- if len(faces2) == 0:
159
- return "❌ خطا: هیچ چهره‌ای در تصویر دوم یافت نشد!", None, None
160
-
161
- # استخراج ویژگی‌ها
162
- features1 = extract_face_features(image1_array, faces1)
163
- features2 = extract_face_features(image2_array, faces2)
 
 
 
 
 
 
164
 
 
165
  if features1 is None:
166
- return "❌ خطا: استخراج ویژگی‌های چهره اول ناموفق!", None, None
167
 
168
  if features2 is None:
169
- return "❌ خطا: استخراج ویژگی‌های چهره دوم ناموفق!", None, None
170
 
171
- # مقایسه ویژگی‌ها
172
- distance, similarity = compare_features(features1, features2)
 
173
 
174
- if distance is None or similarity is None:
175
  return "❌ خطا در مقایسه ویژگی‌ها!", None, None
176
 
177
- # تصمیم‌گیری
178
- is_match = distance <= threshold
179
-
180
- # ایجاد تصاویر با مستطیل دور چهره - **تصحیح شده**
181
- img1_with_faces = image1_array.copy()
182
- img2_with_faces = image2_array.copy()
183
-
184
- for (x, y, w, h) in faces1:
185
- cv2.rectangle(img1_with_faces, (x, y), (x+w, y+h), (0, 255, 0), 3)
186
-
187
- for (x, y, w, h) in faces2:
188
- cv2.rectangle(img2_with_faces, (x, y), (x+w, y+h), (0, 255, 0), 3)
189
 
190
- # تبدیل RGB برای نمایش در Gradio
191
- img1_with_faces = cv2.cvtColor(img1_with_faces, cv2.COLOR_BGR2RGB)
192
- img2_with_faces = cv2.cvtColor(img2_with_faces, cv2.COLOR_BGR2RGB)
193
 
194
- # ایجاد گزارش نتایج
195
  result_text = f"""
196
  🎯 **نتایج تشخیص هویت چهره**
197
 
198
  📊 **آمار فنی:**
199
- - فاصله بردار ویژگی: `{distance:.2f}`
200
- - میزان شباهت: `{similarity:.4f}`
201
  - آستانه انتخابی: `{threshold:.2f}`
202
 
203
  🎭 **نتیجه‌گیری:**
204
  """
205
 
206
  if is_match:
207
- if distance < 20:
208
- confidence = "🔒 تطبیق با اطمینان بسیار بالا"
209
- elif distance < 25:
210
- confidence = "✅ تطبیق با اطمینان بالا"
211
  else:
212
- confidence = "✓ تطبیق با اطمینان متوسط"
213
 
214
  result_text += f"""
215
  {confidence}
 
216
  🟢 **این دو تصویر متعلق به یک شخص هستند**
217
 
218
- تحلیل: فاصله محاسبه‌شده ({distance:.2f}) کمتر از آستانه ({threshold:.2f}) است.
 
 
 
219
  """
220
  else:
221
- if distance > 40:
222
- confidence = "🔒 عدم تطبیق با اطمینان بسیار بالا"
223
  else:
224
- confidence = "❌ عدم تطبیق با اطمینان متوسط"
225
 
226
  result_text += f"""
227
  {confidence}
 
228
  🔴 **این دو تصویر متعلق به اشخاص مختلف هستند**
229
 
230
- تحلیل: فاصله محاسبه‌شده ({distance:.2f}) بیشتر از آستانه ({threshold:.2f}) است.
 
 
 
 
 
 
 
 
231
  """
232
 
 
 
 
 
 
233
  result_text += f"""
 
 
 
234
 
235
- 📈 **راهنمای تفسیر نتایج:**
236
- - فاصله ۰-۲۰: شباهت بسیار زیاد
237
- - فاصله ۲۰-۲۵: شباهت زیاد
238
- - فاصله ۲۵-۳۰: شباهت متوسط
239
- - فاصله ۳۰-۴۰: تفاوت متوسط
240
- - فاصله +۴۰: تفاوت زیاد
241
  """
242
 
243
- return result_text, img1_with_faces, img2_with_faces
244
 
245
  # ایجاد رابط Gradio
246
  with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
@@ -249,7 +372,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
249
  gr.HTML(f"""
250
  <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px;">
251
  <h1 style="font-size: 32px; margin-bottom: 10px;">{TITLE}</h1>
252
- <p style="font-size: 16px; margin: 0;">سامانه هوشمند تشخیص هویت از طریق تصویر چهره</p>
253
  </div>
254
  """)
255
 
@@ -267,14 +390,14 @@ with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
267
  image2_input = gr.Image(label="📸 تصویر چهره دوم", type="pil", height=250)
268
  gr.HTML("<p style='text-align: center; color: gray; font-size: 12px;'>تصویر دوم را انتخاب یا آپلود کنید</p>")
269
 
270
- # بخش تنظیمات - **تصحیح شده**
271
  with gr.Row():
272
  with gr.Column():
273
  precision_input = gr.Radio(
274
  choices=[
275
- ("high", "🟢 دقت بالا (آستانه ۲۵)"),
276
- ("medium", "🟡 دقت متوسط (آستانه ۳۰)"),
277
- ("low", "🔴 دقت پایین (آستانه ۳۵)")
278
  ],
279
  label="🎯 سطح دقت تشخیص",
280
  value='medium',
@@ -283,28 +406,44 @@ with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
283
 
284
  # دکمه پردازش
285
  with gr.Row():
286
- submit_btn = gr.Button("🚀 شروع تشخیص هویت", variant="primary", size="lg")
287
 
288
  # بخش خروجی
289
  with gr.Row():
290
- with gr.Column():
291
  output_text = gr.Markdown(label="📊 نتایج تشخیص")
292
 
293
  with gr.Row():
294
  with gr.Column():
295
- output_image1 = gr.Image(label="تصویر اول - تشخیص چهره", type="numpy", height=200)
296
  with gr.Column():
297
- output_image2 = gr.Image(label="تصویر دوم - تشخیص چهره", type="numpy", height=200)
298
 
299
- # اطلاعات بیشتر
300
  gr.HTML("""
301
  <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; border-left: 4px solid #667eea;">
302
- <h4 style="margin-top: 0;">💡 نکات مهم:</h4>
303
  <ul style="margin-bottom: 0;">
304
- <li>از تصاویر با کیفیت حداقل ۱۰۰x۱۰۰ پیکسل استفاده کنید</li>
305
- <li>چهره باید کامل در تصویر باشد و نور مناسبی داشته باشد</li>
306
- <li>سیستم با زوایای مختلف (تا ۴۵ درجه) کار می‌کند</li>
307
- <li>برای دقت بیشتر از تصاویر روبرو استفاده کنید</li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  </ul>
309
  </div>
310
  """)
@@ -315,8 +454,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
315
  inputs=[image1_input, image2_input, precision_input],
316
  outputs=[output_text, output_image1, output_image2]
317
  )
318
-
319
- # **حذف بخش Examples به دلیل ایجاد خطا**
320
 
321
  # اجرای برنامه
322
  if __name__ == "__main__":
 
2
  import numpy as np
3
  from PIL import Image
4
  import cv2
5
+ import dlib
6
  import os
 
7
  import warnings
8
  warnings.filterwarnings('ignore')
9
 
10
  # عنوان برنامه
11
+ TITLE = "🔍 سامانه پیشرفته تشخیص هویت چهره"
12
  DESCRIPTION = """
13
+ 🎯 سیستم هوشمند تشخیص هویت با استفاده از نقاط کلیدی صورت
14
 
15
  ✨ امکانات:
16
+ - تشخیص ۶۸ نقطه کلیدی روی چهره
17
+ - مقایسه ساختار استخوانی و هندسی صورت
18
+ - مقاوم در برابر تغییرات نور و آرایش
19
+ - دقت بسیار بالا با الگوریتم‌های پیشرفته
20
 
21
  📌 راهنمایی:
22
  1. تصویر اول را آپلود کنید
23
+ 2. تصویر دوم را آپلود کنید
24
  3. دقت مورد نظر را انتخاب کنید
25
  4. روی دکمه "تشخیص هویت" کلیک کنید
26
  """
27
 
28
+ # بارگذاری مدل‌های dlib
29
+ print("🔄 در حال بارگذاری مدل‌های تشخیص چهره...")
 
30
 
31
+ try:
32
+ # تشخیص نقاط کلیدی صورت
33
+ predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
34
+ detector = dlib.get_frontal_face_detector()
35
+ face_rec_model = dlib.face_recognition_model_v1('dlib_face_recognition_resnet_model_v1.dat')
36
+ print("✅ مدل‌ها با موفقیت بارگذاری شدند!")
37
+
38
+ MODELS_LOADED = True
39
+ except Exception as e:
40
+ print(f"⚠️ مدل‌ها یافت نشدند. از روش جایگزین استفاده می‌کنیم... {e}")
41
+ MODELS_LOADED = False
42
 
43
+ # تابع تشخیص چهره و نقاط کلیدی با dlib
44
+ def detect_face_landmarks_dlib(image_array):
45
+ """تشخیص ۶۸ نقطه کلیدی صورت با dlib"""
46
+ if not MODELS_LOADED:
47
+ return None, None, None
48
+
49
+ try:
50
+ # تشخیص چهره
51
+ faces = detector(image_array, 1)
52
+
53
+ if len(faces) == 0:
54
+ return None, None, None
55
+
56
+ # گرفتن اولین چهره
57
+ face = faces[0]
58
+
59
+ # تشخیص نقاط کلیدی
60
+ shape = predictor(image_array, face)
61
+
62
+ # استخراج بردار ویژگی چهره
63
+ face_descriptor = face_rec_model.compute_face_descriptor(image_array, shape)
64
+ face_encoding = np.array(face_descriptor)
65
+
66
+ # استخراج نقاط کلیدی
67
+ landmarks = np.array([[p.x, p.y] for p in shape.parts()])
68
+
69
+ return face, landmarks, face_encoding
70
+
71
+ except Exception as e:
72
+ print(f"خطا در تشخیص نقاط کلیدی: {e}")
73
+ return None, None, None
74
 
75
+ # تابع تشخیص چهره جایگزین با OpenCV
76
+ def detect_face_features_opencv(image_array):
77
+ """تشخیص ویژگی‌های صورت با OpenCV پیشرفته"""
78
  try:
79
+ # تشخیص چهره
80
  gray = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY)
 
 
81
  face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
82
+ faces = face_cascade.detectMultiScale(gray, 1.3, 5)
 
 
 
 
 
 
83
 
84
  if len(faces) == 0:
85
+ return None, None
86
+
87
+ # گرفتن اولین چهره
88
+ x, y, w, h = faces[0]
89
+ face_region = image_array[y:y+h, x:x+w]
90
+
91
+ # استخراج ویژگی‌های پیشرفته
92
+ # ۱. هیستوگرام گرادیان‌ها (HOG)
93
+ gray_face = cv2.cvtColor(face_region, cv2.COLOR_RGB2GRAY)
94
+ gray_face = cv2.resize(gray_face, (64, 128))
95
 
96
+ # محاسبه گرادیان
97
+ gx = cv2.Sobel(gray_face, cv2.CV_32F, 1, 0)
98
+ gy = cv2.Sobel(gray_face, cv2.CV_32F, 0, 1)
99
+
100
+ mag, ang = cv2.cartToPolar(gx, gy)
101
+
102
+ # هیستوگرام گرادیان‌های جهت‌دار
103
+ bins = np.int32(16 * ang / (2 * np.pi))
104
+ bin_cells = bins[:10, :10], bins[10:, :10], bins[:10, 10:], bins[10:, 10:]
105
+ mag_cells = mag[:10, :10], mag[10:, :10], mag[:10, 10:], mag[10:, 10:]
106
+
107
+ hists = [np.bincount(b.ravel(), m.ravel(), 16) for b, m in zip(bin_cells, mag_cells)]
108
+ hist = np.hstack(hists)
109
+
110
+ # ۲. ویژگی‌های رنگ و بافت
111
+ face_resized = cv2.resize(face_region, (64, 64))
112
+
113
+ # هیستوگرام رنگ
114
+ color_hist = cv2.calcHist([face_resized], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256]).flatten()
115
+ color_hist = color_hist[:128] # گرفتن ۱۲۸ مقدار اول
116
+
117
+ # ویژگی‌های آماری
118
+ mean_color = face_resized.mean(axis=(0, 1))
119
+ std_color = face_resized.std(axis=(0, 1))
120
+
121
+ # ۳. ویژگی‌های الگوی محلی (LBP)
122
+ lbp_features = extract_lbp_features(gray_face)[:64]
123
+
124
+ # ترکیب تمام ویژگی‌ها
125
+ features = np.concatenate([
126
+ hist / (hist.sum() + 1e-8), # نرمال‌سازی هیستوگرام
127
+ color_hist / (color_hist.sum() + 1e-8), # نرمال‌سازی هیستوگرام رنگ
128
+ mean_color / 255,
129
+ std_color / 255,
130
+ lbp_features
131
+ ])
132
+
133
+ return faces[0], features
134
 
135
  except Exception as e:
136
+ print(f"خطا در استخراج ویژگی‌های OpenCV: {e}")
137
+ return None, None
138
 
139
+ def extract_lbp_features(gray_image):
140
+ """استخراج ویژگی‌های الگوی محلی باینری (LBP)"""
 
 
 
 
 
 
 
 
141
  try:
142
  # تغییر سایز به اندازه ثابت
143
+ img = cv2.resize(gray_image, (64, 64))
 
 
 
144
 
145
+ # محاسبه LBP
146
+ lbp = np.zeros_like(img, dtype=np.uint8)
 
 
 
 
147
 
148
+ for i in range(1, img.shape[0]-1):
149
+ for j in range(1, img.shape[1]-1):
150
+ center = img[i, j]
151
+ code = 0
152
+ code |= (img[i-1, j-1] >= center) << 7
153
+ code |= (img[i-1, j] >= center) << 6
154
+ code |= (img[i-1, j+1] >= center) << 5
155
+ code |= (img[i, j+1] >= center) << 4
156
+ code |= (img[i+1, j+1] >= center) << 3
157
+ code |= (img[i+1, j] >= center) << 2
158
+ code |= (img[i+1, j-1] >= center) << 1
159
+ code |= (img[i, j-1] >= center) << 0
160
+ lbp[i, j] = code
161
 
162
+ # هیستوگرام LBP
163
+ hist, _ = np.histogram(lbp.ravel(), bins=256, range=(0, 256))
164
+ return hist
165
 
166
  except Exception as e:
167
+ print(f"خطا در استخراج LBP: {e}")
168
+ return np.zeros(256)
169
 
170
+ # تابع مقایسه پیشرفته
171
+ def compare_faces_advanced(features1, features2, threshold):
172
+ """مقایسه پیشرفته دو بردار ویژگی"""
173
  if features1 is None or features2 is None:
174
+ return None, None, "❌ خطا در استخراج ویژگی‌ها"
175
 
176
+ try:
177
+ # محاسبه فاصله اقلیدسی
178
+ distance = np.linalg.norm(features1 - features2)
179
+
180
+ # محاسبه شباهت کسینوسی
181
+ cos_similarity = np.dot(features1, features2) / (np.linalg.norm(features1) * np.linalg.norm(features2) + 1e-10)
182
+
183
+ # محاسبه شباهت کلی
184
+ similarity = 1.0 / (1.0 + distance)
185
+
186
+ # تصمیم‌گیری
187
+ is_match = distance <= threshold
188
+
189
+ return distance, similarity, is_match
190
 
191
+ except Exception as e:
192
+ print(f"خطا در مقایسه: {e}")
193
+ return None, None, None
194
+
195
+ # تابع رسم نقاط کلیدی
196
+ def draw_landmarks_on_image(image_array, landmarks, face_rect):
197
+ """رسم نقاط کلیدی و مستطیل چهره"""
198
+ img_copy = image_array.copy()
199
+
200
+ # رسم مستطیل دور چهره
201
+ if face_rect is not None:
202
+ if hasattr(face_rect, 'left'): # dlib rectangle
203
+ cv2.rectangle(img_copy, (face_rect.left(), face_rect.top()),
204
+ (face_rect.right(), face_rect.bottom()), (0, 255, 0), 3)
205
+ else: # OpenCV rectangle
206
+ x, y, w, h = face_rect
207
+ cv2.rectangle(img_copy, (x, y), (x+w, y+h), (0, 255, 0), 3)
208
+
209
+ # رسم نقاط کلیدی
210
+ if landmarks is not None:
211
+ for i, (x, y) in enumerate(landmarks):
212
+ # رنگ‌های مختلف برای نقاط مختلف صورت
213
+ if i < 17: # خط فک
214
+ color = (255, 0, 0)
215
+ elif i < 22: # ابروی راست
216
+ color = (0, 255, 0)
217
+ elif i < 27: # ابروی چپ
218
+ color = (0, 0, 255)
219
+ elif i < 36: # بینی
220
+ color = (255, 255, 0)
221
+ elif i < 48: # چشم‌ها
222
+ color = (255, 0, 255)
223
+ else: # دهان
224
+ color = (0, 255, 255)
225
+
226
+ cv2.circle(img_copy, (int(x), int(y)), 3, color, -1)
227
 
228
+ return img_copy
229
 
230
  # تابع اصلی پردازش
231
  def process_faces(image1, image2, precision_level):
232
  """پردازش و مقایسه دو تصویر چهره"""
233
 
234
+ print(f"🔍 شروع پردازش با دقت: {precision_level}")
 
235
 
236
  # تبدیل تصاویر به آرایه
237
  if isinstance(image1, str):
 
244
  else:
245
  image2_array = np.array(image2)
246
 
247
+ # تنظیم آستانه
248
  thresholds = {
249
+ 'high': 0.4, # دقت بالا
250
+ 'medium': 0.5, # دقت متوسط
251
+ 'low': 0.6 # دقت پایین
252
  }
253
 
254
+ threshold = thresholds.get(precision_level, 0.5)
255
  print(f"🔧 آستانه انتخاب شده: {threshold}")
256
 
257
+ # پردازش تصویر اول
258
+ print("📸 پردازش تصویر اول...")
259
+ if MODELS_LOADED:
260
+ face1, landmarks1, features1 = detect_face_landmarks_dlib(image1_array)
261
+ if face1 is None:
262
+ features1 = None
263
+ else:
264
+ face1, features1 = detect_face_features_opencv(image1_array)
265
+ landmarks1 = None
266
+
267
+ # پردازش تصویر دوم
268
+ print("📸 پردازش تصویر دوم...")
269
+ if MODELS_LOADED:
270
+ face2, landmarks2, features2 = detect_face_landmarks_dlib(image2_array)
271
+ if face2 is None:
272
+ features2 = None
273
+ else:
274
+ face2, features2 = detect_face_features_opencv(image2_array)
275
+ landmarks2 = None
276
 
277
+ # بررسی خطاها
278
  if features1 is None:
279
+ return "❌ خطا: تشخیص چهره در تصویر اول ناموفق بو��!", None, None
280
 
281
  if features2 is None:
282
+ return "❌ خطا: تشخیص چهره در تصویر دوم ناموفق بود!", None, None
283
 
284
+ # مقایسه چهره‌ها
285
+ print("🔄 در حال مقایسه چهره‌ها...")
286
+ distance, similarity, is_match = compare_faces_advanced(features1, features2, threshold)
287
 
288
+ if distance is None:
289
  return "❌ خطا در مقایسه ویژگی‌ها!", None, None
290
 
291
+ # ایجاد تصاویر با نشانگر
292
+ img1_processed = draw_landmarks_on_image(image1_array, landmarks1, face1)
293
+ img2_processed = draw_landmarks_on_image(image2_array, landmarks2, face2)
 
 
 
 
 
 
 
 
 
294
 
295
+ # تبدیل به RGB
296
+ img1_processed = cv2.cvtColor(img1_processed, cv2.COLOR_BGR2RGB)
297
+ img2_processed = cv2.cvtColor(img2_processed, cv2.COLOR_BGR2RGB)
298
 
299
+ # ایجاد گزارش
300
  result_text = f"""
301
  🎯 **نتایج تشخیص هویت چهره**
302
 
303
  📊 **آمار فنی:**
304
+ - فاصله بردار ویژگی: `{distance:.4f}`
305
+ - میزان شباهت: `{similarity:.4f}`
306
  - آستانه انتخابی: `{threshold:.2f}`
307
 
308
  🎭 **نتیجه‌گیری:**
309
  """
310
 
311
  if is_match:
312
+ if distance < 0.3:
313
+ confidence = "🔒 **تطبیق با اطمینان بسیار بالا**"
314
+ elif distance < 0.4:
315
+ confidence = "✅ **تطبیق با اطمینان بالا**"
316
  else:
317
+ confidence = "✓ **تطبیق با اطمینان متوسط**"
318
 
319
  result_text += f"""
320
  {confidence}
321
+
322
  🟢 **این دو تصویر متعلق به یک شخص هستند**
323
 
324
+ _تحلیل سیستم:_
325
+ - فاصله محاسبه‌شده ({distance:.4f}) کمتر از آستانه ({threshold:.2f}) است
326
+ - ساختار صورت و ویژگی‌های کلیدی بسیار مشابه هستند
327
+ - احتمال اینکه این دو تصویر از یک شخص باشند: **{(1-distance)*100:.1f}%**
328
  """
329
  else:
330
+ if distance > 0.7:
331
+ confidence = "🔒 **عدم تطبیق با اطمینان بسیار بالا**"
332
  else:
333
+ confidence = "❌ **عدم تطبیق با اطمینان متوسط**"
334
 
335
  result_text += f"""
336
  {confidence}
337
+
338
  🔴 **این دو تصویر متعلق به اشخاص مختلف هستند**
339
 
340
+ _تحلیل سیستم:_
341
+ - فاصله محاسبه‌شده ({distance:.4f}) بیشتر از آستانه ({threshold:.2f}) است
342
+ - ساختار صورت و ویژگی‌های کلیدی تفاوت قابل توجهی دارند
343
+ - شباهت: **{(1-distance)*100:.1f}%**
344
+ """
345
+
346
+ result_text += f"""
347
+
348
+ 📈 **جزئیات فنی:**
349
  """
350
 
351
+ if MODELS_LOADED:
352
+ result_text += "- ✅ استفاده از مدل dlib با ۶۸ نقطه کلیدی\n"
353
+ else:
354
+ result_text += "- ⚠️ استفاده از روش OpenCV (دقت کمتر)\n"
355
+
356
  result_text += f"""
357
+ - تعداد ویژگی‌های استخراج‌شده: {len(features1)}
358
+ - روش تشخیص: نقاط کلیدی صورت + ساختار هندسی
359
+ - دامنه فاصله: ۰ (کاملاً مشابه) تا ۱ (کاملاً متفاوت)
360
 
361
+ 🛠️ **توضیح فنی:**
362
+ سیستم از نقاط کلیدی صورت شم‌ها، بینی، دهان، فک) استفاده می‌کند
363
+ و ساختار هندسی صورت را با دقت بالا مقایسه می‌کند.
 
 
 
364
  """
365
 
366
+ return result_text, img1_processed, img2_processed
367
 
368
  # ایجاد رابط Gradio
369
  with gr.Blocks(theme=gr.themes.Soft(), title=TITLE) as demo:
 
372
  gr.HTML(f"""
373
  <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px;">
374
  <h1 style="font-size: 32px; margin-bottom: 10px;">{TITLE}</h1>
375
+ <p style="font-size: 16px; margin: 0;">سامانه هوشمند تشخیص هویت با تحلیل نقاط کلیدی صورت</p>
376
  </div>
377
  """)
378
 
 
390
  image2_input = gr.Image(label="📸 تصویر چهره دوم", type="pil", height=250)
391
  gr.HTML("<p style='text-align: center; color: gray; font-size: 12px;'>تصویر دوم را انتخاب یا آپلود کنید</p>")
392
 
393
+ # بخش تنظیمات
394
  with gr.Row():
395
  with gr.Column():
396
  precision_input = gr.Radio(
397
  choices=[
398
+ ("high", "🟢 دقت بالا (آستانه ۰.۴)"),
399
+ ("medium", "🟡 دقت متوسط (آستانه ۰)"),
400
+ ("low", "🔴 دقت پایین (آستانه ۰.۶)")
401
  ],
402
  label="🎯 سطح دقت تشخیص",
403
  value='medium',
 
406
 
407
  # دکمه پردازش
408
  with gr.Row():
409
+ submit_btn = gr.Button("🚀 شروع تشخیص پیشرفته", variant="primary", size="lg")
410
 
411
  # بخش خروجی
412
  with gr.Row():
413
+ with gr.Column(scale=2):
414
  output_text = gr.Markdown(label="📊 نتایج تشخیص")
415
 
416
  with gr.Row():
417
  with gr.Column():
418
+ output_image1 = gr.Image(label="تصویر اول - نقاط کلیدی", type="numpy", height=250)
419
  with gr.Column():
420
+ output_image2 = gr.Image(label="تصویر دوم - نقاط کلیدی", type="numpy", height=250)
421
 
422
+ # راهنمای رنگ‌ها
423
  gr.HTML("""
424
  <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; border-left: 4px solid #667eea;">
425
+ <h4 style="margin-top: 0;">🎨 راهنمای رنگ نقاط کلیدی:</h4>
426
  <ul style="margin-bottom: 0;">
427
+ <li>🔵 آبی: خط فک و چانه</li>
428
+ <li>🟢 سبز: ابروی راست</li>
429
+ <li>🔴 قرمز: ابروی چپ</li>
430
+ <li>🟡 زرد: بینی</li>
431
+ <li>🟣 بنفش: چشم‌ها</li>
432
+ <li>🟡 زرد-سبز: دهان و لب‌ها</li>
433
+ <li>🟢 مستطیل سبز: محدوده کل چهره</li>
434
+ </ul>
435
+ </div>
436
+ """)
437
+
438
+ # نکات مهم
439
+ gr.HTML("""
440
+ <div style="background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107;">
441
+ <h4 style="margin-top: 0; color: #856404;">⚠️ نکات مهم:</h4>
442
+ <ul style="margin-bottom: 0; color: #856404;">
443
+ <li>برای بهترین نتیجه، از تصاویر با کیفیت بالا و نور مناسب استفا��ه کنید</li>
444
+ <li>چهره باید کامل در تصویر باشد و حداقل ۲۰۰x۲۰۰ پیکسل باشد</li>
445
+ <li>این سیستم از ۶۸ نقطه کلیدی صورت برای تشخیص استفاده می‌کند</li>
446
+ <li>در صورت عدم تشخیص، تصویر را کمی بزرگ‌تر کنید</li>
447
  </ul>
448
  </div>
449
  """)
 
454
  inputs=[image1_input, image2_input, precision_input],
455
  outputs=[output_text, output_image1, output_image2]
456
  )
 
 
457
 
458
  # اجرای برنامه
459
  if __name__ == "__main__":