RajaThor commited on
Commit
a07ca8b
·
verified ·
1 Parent(s): e49c517

Create nightback.py

Browse files
Files changed (1) hide show
  1. nightback.py +458 -0
nightback.py ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import firebase_admin
4
+ from firebase_admin import credentials, db, auth, firestore
5
+ import face_recognition
6
+ from PIL import Image
7
+ import numpy as np
8
+ import cv2
9
+ import dlib
10
+
11
+ # Get the current working directory
12
+ current_directory = os.path.dirname(os.path.abspath(__file__))
13
+ skp_path = os.path.join(current_directory, "projectinsta-s-firebase-adminsdk-y6vlu-9a1345f468.json")
14
+
15
+ # Check if the app is already initialized
16
+ if not firebase_admin._apps:
17
+ # Initialize Firebase Admin SDK
18
+ cred = credentials.Certificate(skp_path)
19
+ firebase_admin.initialize_app(cred, {
20
+ 'databaseURL': 'https://projectinsta-s-default-rtdb.firebaseio.com/',
21
+ 'projectId': 'projectinsta-s'
22
+ })
23
+
24
+ # Reference to the root of your Firebase Realtime Database
25
+ ref = db.reference('/')
26
+
27
+ # Initialize Firestore client
28
+ db_firestore = firestore.client()
29
+
30
+ # Streamlit session state
31
+ if "auth_state" not in st.session_state:
32
+ st.session_state.auth_state = {
33
+ "user": None,
34
+ "signed_in": False,
35
+ }
36
+
37
+ # Add the shape predictor model for face alignment
38
+ shape_predictor_path = "shape_predictor_68_face_landmarks.dat"
39
+ detector = dlib.get_frontal_face_detector()
40
+ shape_predictor = dlib.shape_predictor(shape_predictor_path)
41
+
42
+ # Firebase Authentication
43
+ def authenticate_user(email, password):
44
+ try:
45
+ user = auth.get_user_by_email(email)
46
+ # The user is successfully fetched, meaning the email and password are valid.
47
+ return True, user
48
+ except auth.AuthError as e:
49
+ print(f"Authentication error: {str(e)}")
50
+ return False, None
51
+
52
+ # Sign-up Functionality
53
+ def create_user(email, password):
54
+ try:
55
+ user = auth.create_user(
56
+ email=email,
57
+ password=password
58
+ )
59
+ return True, user.uid
60
+ except Exception as e:
61
+ print(f"User creation error: {str(e)}")
62
+ return False, None
63
+
64
+ # Update load_and_encode function to use the aligned face without normalization
65
+ def load_and_encode(image_path):
66
+ try:
67
+ aligned_face = detect_and_align_faces(image_path)
68
+
69
+ if aligned_face is not None:
70
+ encoding = face_recognition.face_encodings(aligned_face)
71
+
72
+ if encoding:
73
+ return encoding
74
+ else:
75
+ return None
76
+ else:
77
+ return None
78
+ except Exception as e:
79
+ print(f"Error loading and encoding image: {str(e)}")
80
+ return None
81
+
82
+ # Function to detect and align faces in an image with preprocessing
83
+ def detect_and_align_faces(image_path):
84
+ image = face_recognition.load_image_file(image_path)
85
+
86
+ # Resize the image to a fixed width (you can adjust the width as needed)
87
+ target_width = 800
88
+ aspect_ratio = image.shape[1] / image.shape[0]
89
+ target_height = int(target_width / aspect_ratio)
90
+ resized_image = cv2.resize(image, (target_width, target_height))
91
+
92
+ gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
93
+
94
+ # Detect faces using dlib
95
+ faces = detector(gray)
96
+
97
+ if not faces:
98
+ return None
99
+
100
+ # Use the first face found (you can modify this to handle multiple faces)
101
+ face = faces[0]
102
+
103
+ # Use dlib for face alignment
104
+ landmarks = shape_predictor(gray, face)
105
+ aligned_face = dlib.get_face_chip(resized_image, landmarks, size=256) # Adjust the size as needed
106
+
107
+ return aligned_face
108
+
109
+ # Add person to database
110
+ def add_person(name, image_path, instagram_handle):
111
+ try:
112
+ encoding = load_and_encode(image_path)
113
+ if not encoding:
114
+ return "No face found in the provided image."
115
+
116
+ # Convert NumPy arrays to lists for JSON serialization
117
+ encoding = encoding[0].tolist()
118
+
119
+ # Save data to Firebase Realtime Database
120
+ ref.child(name).set({
121
+ "encoding": encoding,
122
+ "info": {
123
+ "instagram_handle": instagram_handle,
124
+ "instagram_link": f"https://www.instagram.com/{instagram_handle}/"
125
+ }
126
+ })
127
+
128
+ return f"Success: {name} added to the database!"
129
+ except Exception as e:
130
+ return f"Failed to add person: {str(e)}"
131
+
132
+ # Recognize face from image
133
+ def recognize_face(image_path):
134
+ if not image_path:
135
+ return "Please upload an image."
136
+
137
+ try:
138
+ unknown_encoding = load_and_encode(image_path)
139
+ if not unknown_encoding:
140
+ return "No face found in the provided image."
141
+
142
+ matches = []
143
+ for name, data in ref.get().items():
144
+ known_encoding = np.array(data["encoding"])
145
+ if face_recognition.compare_faces([known_encoding], unknown_encoding[0])[0]:
146
+ matches.append((name, data["info"]))
147
+
148
+ if matches:
149
+ results = []
150
+ for name, info in matches:
151
+ insta_handle = info["instagram_handle"]
152
+ insta_link = info["instagram_link"]
153
+ insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
154
+ results.append(f"- It's a picture of {name}! Insta handle: {insta_link_html}")
155
+ return "\n".join(results)
156
+ else:
157
+ return "Face not found in the database."
158
+ except Exception as e:
159
+ return f"Failed to recognize face: {str(e)}"
160
+
161
+ # Recognize face from image and return optimal or highest matching ID
162
+ def recognize_face_optimal(image_path):
163
+ if not image_path:
164
+ return "Please upload an image."
165
+
166
+ try:
167
+ unknown_encoding = load_and_encode(image_path)
168
+ if not unknown_encoding:
169
+ return "No face found in the provided image."
170
+
171
+ matches = []
172
+ for name, data in ref.get().items():
173
+ known_encoding = np.array(data["encoding"])
174
+ similarity_score = face_recognition.face_distance([known_encoding], unknown_encoding[0])[0]
175
+ if similarity_score > 0.50: # Only consider matches above 50.00% similarity
176
+ continue
177
+ matches.append((name, similarity_score))
178
+
179
+ if matches:
180
+ best_match = min(matches, key=lambda x: x[1])
181
+ best_name, best_score = best_match
182
+ info = ref.child(best_name).child("info").get()
183
+ insta_handle = info["instagram_handle"]
184
+ insta_link = info["instagram_link"]
185
+ insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
186
+ return f"Best match: {best_name} with a similarity score of {1 - best_score:.2%}. Insta handle: {insta_link_html}"
187
+ else:
188
+ return "Face not found in the database."
189
+ except Exception as e:
190
+ return f"Failed to recognize face: {str(e)}"
191
+
192
+ # Delete person from database
193
+ def delete_person(name):
194
+ try:
195
+ ref.child(name).delete()
196
+ return f"{name} deleted from the database!"
197
+ except Exception as e:
198
+ return f"Failed to delete person: {str(e)}"
199
+
200
+ # Send feedback to Firebase
201
+ def send_feedback(feedback_data):
202
+ try:
203
+ db_firestore.collection('feedback').add(feedback_data)
204
+ except Exception as e:
205
+ st.error(f"Failed to submit feedback: {str(e)}")
206
+
207
+ # Streamlit interface for adding a person
208
+ def add_person_ui():
209
+ st.title("Add Person")
210
+ name = st.text_input("Enter Name", help="Enter the name of the person")
211
+ image_path = st.file_uploader("Upload Image", help="Upload an image containing the person's face")
212
+ instagram_handle = st.text_input("Enter Instagram Handle", help="Enter the person's Instagram handle")
213
+ if st.button("Add Person"):
214
+ if not name or not image_path or not instagram_handle:
215
+ st.error("Please fill all the fields.")
216
+ else:
217
+ result = add_person(name, image_path, instagram_handle)
218
+ st.success(result)
219
+
220
+ # Streamlit interface for recognizing face
221
+ def recognize_face_ui():
222
+ st.title("Recognize Face")
223
+ image_path = st.file_uploader("Upload Image", help="Upload an image for face recognition")
224
+ if st.button("Recognize Face"):
225
+ result = recognize_face(image_path)
226
+ st.write(result, unsafe_allow_html=True)
227
+
228
+ # Streamlit interface for recognizing face with optimal ID
229
+ def recognize_face_optimal_ui():
230
+ st.title("Recognize Face (Optimal)")
231
+ image_path = st.file_uploader("Upload Image", help="Upload an image for optimal face recognition")
232
+ if st.button("Recognize Face (Optimal)"):
233
+ result = recognize_face_optimal(image_path)
234
+ if "not found" in result.lower(): # Check if "not found" is in the result message
235
+ st.error(result)
236
+ else:
237
+ st.write(result, unsafe_allow_html=True)
238
+
239
+ # Streamlit interface for deleting a person
240
+ def delete_person_ui():
241
+ st.title("Delete Person")
242
+ name = st.text_input("Enter Name", help="Enter the name of the person to delete")
243
+ if st.button("Delete Person"):
244
+ if not name:
245
+ st.error("Please enter a name.")
246
+ else:
247
+ result = delete_person(name)
248
+ st.success(result)
249
+
250
+ # Streamlit interface for feedback
251
+ def feedback_ui():
252
+ st.title("Feedback")
253
+ st.write("Your feedback is important to us! Please fill out the form below:")
254
+
255
+ name = st.text_input("Name (optional)")
256
+ email = st.text_input("Email (optional)")
257
+ category = st.selectbox("Category", ["Bug Report", "Feature Request", "General Feedback"])
258
+ message = st.text_area("Feedback Message")
259
+
260
+ if st.button("Submit Feedback"):
261
+ if not message:
262
+ st.error("Please enter your feedback message.")
263
+ else:
264
+ feedback_data = {
265
+ "name": name,
266
+ "email": email,
267
+ "category": category,
268
+ "message": message,
269
+ }
270
+ send_feedback(feedback_data)
271
+ st.success("Feedback submitted successfully! Thank you for your feedback.")
272
+
273
+ #section for messaging
274
+
275
+ # Send a message to the receiver_email from the sender_email
276
+ def send_message(sender_email, receiver_email, message_content):
277
+ try:
278
+ # Add a new document to the 'messages' collection
279
+ db_firestore.collection('messages').add({
280
+ 'sender_email': sender_email,
281
+ 'receiver_email': receiver_email,
282
+ 'message_content': message_content,
283
+ 'timestamp': firestore.SERVER_TIMESTAMP
284
+ })
285
+ return "Message sent successfully!"
286
+ except Exception as e:
287
+ return f"Failed to send message: {str(e)}"
288
+
289
+ # Function to retrieve messages for a user
290
+ def get_messages(user_email):
291
+ try:
292
+ messages = db_firestore.collection('messages').where('receiver_email', '==', user_email).order_by('timestamp', direction=firestore.Query.DESCENDING).stream()
293
+ return messages # Return the Firestore query snapshot
294
+ except Exception as e:
295
+ st.error(f"Failed to retrieve messages: {str(e)}")
296
+ return None
297
+
298
+ # Streamlit interface for sending messages
299
+ def send_message_ui():
300
+ st.title("Send Message")
301
+ sender_email = st.session_state.auth_state["user"].email
302
+ receiver_email = st.text_input("Receiver's Email", help="Enter the receiver's email address")
303
+ message_content = st.text_area("Message Content")
304
+ if st.button("Send Message"):
305
+ result = send_message(sender_email, receiver_email, message_content)
306
+ st.write(result)
307
+
308
+ # Streamlit interface for viewing messages
309
+ def view_messages_ui():
310
+ st.title("Messages")
311
+ user_email = st.session_state.auth_state["user"].email
312
+ messages = get_messages(user_email)
313
+ if messages is not None:
314
+ for message in messages:
315
+ message_dict = message.to_dict() # Convert Firestore document to dictionary
316
+ st.write(f"From: {message_dict['sender_email']}")
317
+ st.write(f"Message: {message_dict['message_content']}")
318
+ st.write("---")
319
+ #end of messaging section
320
+
321
+ def tour_guide_ui():
322
+ st.title("Tour Guide")
323
+ st.markdown("This tour will guide you through the application.")
324
+
325
+ with st.expander("Welcome"):
326
+ st.write("This is a tour guide to help you navigate through the application.")
327
+
328
+ with st.expander("Options Sidebar"):
329
+ st.write("Here you can select different options such as adding a person, recognizing a face, deleting a person, or recognizing a face with optimal identification.")
330
+
331
+ with st.expander("Main Interface"):
332
+ st.write("This is where the main functionality of the application is displayed.")
333
+
334
+ with st.expander("Upload Image"):
335
+ st.write("You can upload an image here for face recognition or adding a person.")
336
+
337
+ with st.expander("Text Input"):
338
+ st.write("Enter text here such as the person's name or Instagram handle.")
339
+
340
+ with st.expander("Buttons"):
341
+ st.write("Click on these buttons to perform actions like adding a person or recognizing a face.")
342
+
343
+ # Streamlit interface for user authentication
344
+ def authenticate_user_ui():
345
+ st.title("Insta's EYE")
346
+ # Display the logo
347
+ logo_path = os.path.join(current_directory, "Explore+.png")
348
+ logo = Image.open(logo_path)
349
+ st.image(logo, width=50)
350
+ st.sidebar.title("Options")
351
+
352
+ if st.session_state.auth_state["signed_in"]:
353
+ st.sidebar.button("Sign Out", on_click=logout)
354
+ st.title("Welcome!")
355
+ main()
356
+ else:
357
+ option = st.sidebar.radio("Select Option", ["Login", "Sign-Up"])
358
+
359
+ email = st.text_input("Enter Email", help="Enter your email address")
360
+ password = st.text_input("Enter Password", type="password", help="Enter your password")
361
+
362
+ if option == "Login":
363
+ if st.button("Login"):
364
+ if not email or not password:
365
+ st.error("Please enter both email and password.")
366
+ else:
367
+ success, user = authenticate_user(email, password)
368
+ if success:
369
+ st.session_state.auth_state["user"] = user
370
+ st.session_state.auth_state["signed_in"] = True
371
+ st.success("Authentication successful! You can now manage your set of images and profiles.")
372
+ main()
373
+ else:
374
+ st.error("Authentication failed. Please check your email and password.")
375
+
376
+ elif option == "Sign-Up":
377
+ confirm_password = st.text_input("Confirm Password", type="password", help="Re-enter your password for confirmation")
378
+ if st.button("Sign-Up"):
379
+ if not email or not password or not confirm_password:
380
+ st.error("Please fill all the fields.")
381
+ elif password != confirm_password:
382
+ st.error("Passwords do not match.")
383
+ else:
384
+ success, uid = create_user(email, password)
385
+ if success:
386
+ st.success(f"User with UID: {uid} created successfully! You can now log in.")
387
+ else:
388
+ st.error("User creation failed. Please try again.")
389
+
390
+ # Log out user
391
+ def logout():
392
+ st.session_state.auth_state["user"] = None
393
+ st.session_state.auth_state["signed_in"] = False
394
+
395
+ # Define tour steps
396
+ steps = [
397
+ {
398
+ "title": "Welcome to Insta's EYE",
399
+ "content": "This is a tour guide to help you navigate through the application.",
400
+ },
401
+ {
402
+ "title": "Options Sidebar",
403
+ "content": "Here you can select different options such as adding a person, recognizing a face, deleting a person, or recognizing a face with optimal identification.",
404
+ },
405
+ {
406
+ "title": "Main Interface",
407
+ "content": "This is where the main functionality of the application is displayed.",
408
+ },
409
+ {
410
+ "title": "Upload Image",
411
+ "content": "You can upload an image here for face recognition or adding a person.",
412
+ },
413
+ {
414
+ "title": "Text Input",
415
+ "content": "Enter text here such as the person's name or Instagram handle.",
416
+ },
417
+ {
418
+ "title": "Buttons",
419
+ "content": "Click on these buttons to perform actions like adding a person or recognizing a face.",
420
+ },
421
+ ]
422
+
423
+ # Function to display tour steps
424
+ def display_tour_steps(steps):
425
+ st.markdown("# Tour Guide")
426
+ st.markdown("This tour will guide you through the application.")
427
+ st.markdown("---")
428
+
429
+ for step in steps:
430
+ st.markdown(f"## {step['title']}")
431
+ st.write(step['content'])
432
+ st.markdown("---")
433
+
434
+ # Update the main function to include the feedback option
435
+ def main():
436
+ st.sidebar.title("Options")
437
+ option = st.sidebar.radio("Select Option", ["Add Person", "Recognize Face", "Delete Person", "Recognize Face (Optimal)", "Tour Guide", "Feedback", "Send Message","Messages"])
438
+
439
+ if option == "Add Person":
440
+ add_person_ui()
441
+ elif option == "Recognize Face":
442
+ recognize_face_ui()
443
+ elif option == "Delete Person":
444
+ delete_person_ui()
445
+ elif option == "Recognize Face (Optimal)":
446
+ recognize_face_optimal_ui()
447
+ elif option == "Tour Guide":
448
+ tour_guide_ui()
449
+ elif option == "Feedback":
450
+ feedback_ui()
451
+ elif option == "Send Message":
452
+ send_message_ui()
453
+ elif option == "Messages":
454
+ view_messages_ui()
455
+
456
+ # Run the tour guide
457
+ if __name__ == "__main__":
458
+ authenticate_user_ui()