|
import os |
|
import cv2 |
|
import face_recognition |
|
import numpy as np |
|
from datetime import datetime |
|
import gradio as gr |
|
import pandas as pd |
|
import plotly.express as px |
|
import json |
|
|
|
class FaceRecognitionSystem: |
|
def __init__(self, images_folder='known_faces'): |
|
self.images_folder = images_folder |
|
self.known_face_encodings = [] |
|
self.known_face_names = [] |
|
self.attendance_file = 'attendance.json' |
|
self.load_face_database() |
|
|
|
def load_face_database(self): |
|
self.known_face_encodings = [] |
|
self.known_face_names = [] |
|
os.makedirs(self.images_folder, exist_ok=True) |
|
for filename in os.listdir(self.images_folder): |
|
if filename.endswith((".jpg", ".png", ".jpeg")): |
|
image_path = os.path.join(self.images_folder, filename) |
|
try: |
|
image = face_recognition.load_image_file(image_path) |
|
face_locations = face_recognition.face_locations(image) |
|
if face_locations: |
|
face_encoding = face_recognition.face_encodings(image, face_locations)[0] |
|
self.known_face_encodings.append(face_encoding) |
|
self.known_face_names.append(filename.split('.')[0]) |
|
except Exception as e: |
|
print(f"Hata: {filename} dosyası yüklenirken hata oluştu - {str(e)}") |
|
|
|
def record_attendance(self, name): |
|
current_time = datetime.now() |
|
attendance_data = self.load_attendance_data() |
|
current_date = current_time.strftime("%Y-%m-%d") |
|
current_time_str = current_time.strftime("%H:%M:%S") |
|
if current_date not in attendance_data: |
|
attendance_data[current_date] = {} |
|
if name not in attendance_data[current_date]: |
|
attendance_data[current_date][name] = [] |
|
attendance_data[current_date][name].append(current_time_str) |
|
self.save_attendance_data(attendance_data) |
|
return True |
|
|
|
def load_attendance_data(self): |
|
if os.path.exists(self.attendance_file): |
|
with open(self.attendance_file, 'r') as f: |
|
return json.load(f) |
|
return {} |
|
|
|
def save_attendance_data(self, data): |
|
with open(self.attendance_file, 'w') as f: |
|
json.dump(data, f, indent=4) |
|
|
|
def process_image(self, image): |
|
if image is None: |
|
return None, [] |
|
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) |
|
face_locations = face_recognition.face_locations(rgb_image) |
|
face_encodings = face_recognition.face_encodings(rgb_image, face_locations) |
|
detected_names = [] |
|
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings): |
|
matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding, tolerance=0.6) |
|
name = "Bilinmeyen" |
|
if True in matches: |
|
first_match_index = matches.index(True) |
|
name = self.known_face_names[first_match_index] |
|
self.record_attendance(name) |
|
detected_names.append(name) |
|
cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2) |
|
cv2.rectangle(image, (left, bottom - 35), (right, bottom), (0, 255, 0), cv2.FILLED) |
|
cv2.putText(image, name, (left + 6, bottom - 6), cv2.FONT_HERSHEY_DUPLEX, 0.6, (255, 255, 255), 1) |
|
return image, detected_names |
|
|
|
def get_attendance_stats(self): |
|
attendance_data = self.load_attendance_data() |
|
stats = [] |
|
for date, entries in attendance_data.items(): |
|
for name, times in entries.items(): |
|
stats.append({ |
|
'date': date, |
|
'name': name, |
|
'total_entries': len(times), |
|
'first_entry': min(times), |
|
'last_entry': max(times) |
|
}) |
|
return pd.DataFrame(stats) |
|
|
|
def create_gradio_interface(): |
|
face_system = FaceRecognitionSystem() |
|
|
|
def process_uploaded_image(image): |
|
processed_image, detected_names = face_system.process_image(image) |
|
return processed_image, ", ".join(detected_names) if detected_names else "Kimse tespit edilmedi." |
|
|
|
def upload_face(image, name): |
|
if image is None or name.strip() == "": |
|
return "Lütfen hem resim hem de isim giriniz." |
|
os.makedirs(face_system.images_folder, exist_ok=True) |
|
file_path = os.path.join(face_system.images_folder, f"{name.strip()}.jpg") |
|
cv2.imwrite(file_path, image) |
|
face_system.load_face_database() |
|
return f"{name} başarıyla kaydedildi!" |
|
|
|
def get_attendance_report(): |
|
df = face_system.get_attendance_stats() |
|
if df.empty: |
|
return "Henüz katılım kaydı bulunmamaktadır." |
|
fig = px.bar(df, x='name', y='total_entries', |
|
title='Kişi Bazlı Toplam Katılım', |
|
labels={'name': 'İsim', 'total_entries': 'Toplam Katılım'}) |
|
table_html = df.to_html(classes='table table-striped', index=False) |
|
return f""" |
|
<div style='margin-bottom: 20px;'> |
|
{fig.to_html()} |
|
</div> |
|
<div> |
|
{table_html} |
|
</div> |
|
""" |
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as interface: |
|
gr.Markdown("# 🎥 Yüz Tanıma ve Katılım Takip Sistemi--ERAY COŞKUN") |
|
|
|
with gr.Tabs(): |
|
with gr.Tab("Yüz Tanıma"): |
|
gr.Markdown("## 📷 Resim Yükle ve Tanı") |
|
image_input = gr.Image(type="numpy", label="Resim Yükle") |
|
output_image = gr.Image(label="İşlenmiş Resim") |
|
output_text = gr.Textbox(label="Tespit Edilen Kişiler") |
|
process_button = gr.Button("Resmi İşle") |
|
process_button.click( |
|
process_uploaded_image, |
|
inputs=[image_input], |
|
outputs=[output_image, output_text] |
|
) |
|
|
|
with gr.Tab("Yeni Kişi Kaydı"): |
|
gr.Markdown("## 👤 Yeni Kişi Ekle") |
|
with gr.Row(): |
|
new_image_input = gr.Image(type="numpy", label="Kişi Fotoğrafı") |
|
name_input = gr.Textbox(label="Kişi Adı") |
|
upload_button = gr.Button("Kaydet") |
|
upload_result = gr.Textbox(label="Sonuç") |
|
upload_button.click( |
|
upload_face, |
|
inputs=[new_image_input, name_input], |
|
outputs=[upload_result] |
|
) |
|
|
|
with gr.Tab("Katılım Raporu"): |
|
gr.Markdown("## 📊 Katılım İstatistikleri") |
|
refresh_button = gr.Button("Raporu Yenile") |
|
report_html = gr.HTML() |
|
refresh_button.click( |
|
get_attendance_report, |
|
outputs=[report_html] |
|
) |
|
|
|
return interface |
|
|
|
if __name__ == "__main__": |
|
interface = create_gradio_interface() |
|
interface.launch() |