File size: 23,391 Bytes
14ea48a eb0c11e 14ea48a 2da4cc2 8667f95 14ea48a 6166b18 14ea48a 5674e8f 14ea48a 6166b18 14ea48a 6166b18 14ea48a 5674e8f 14ea48a 6166b18 9303e93 14ea48a eb0c11e 14ea48a d78cc8d 14ea48a d78cc8d 14ea48a ab3788f 6354973 b0d8fc8 14ea48a d78cc8d 14ea48a d78cc8d 14ea48a aacb328 e59dbba 14ea48a aacb328 9938593 6166b18 14ea48a 6166b18 14ea48a aacb328 8ec329c aacb328 14ea48a aacb328 71acc83 14ea48a 900d150 14ea48a 900d150 14ea48a 6166b18 354034d 900d150 14ea48a e4a1497 354034d 14ea48a b9f7106 9303e93 14ea48a 9303e93 14ea48a 465ef15 e59dbba 14ea48a 3709805 e59dbba 14ea48a e59dbba aacb328 900d150 3709805 900d150 3709805 7c65743 3709805 7c65743 3709805 7c65743 aacb328 7c65743 14ea48a 7c65743 354034d 14ea48a 7c65743 b9f7106 14ea48a 0f0619b 3709805 a4af76e 3709805 b9f7106 aacb328 14ea48a aacb328 14ea48a aacb328 71acc83 aacb328 14ea48a aacb328 14ea48a aacb328 9303e93 14ea48a 6166b18 b9f7106 9303e93 14ea48a 9303e93 14ea48a 9e3862d 74c4208 9e3862d 74c4208 9e3862d 972ff8d eb0c11e 972ff8d 71acc83 14ea48a 0a0f04e 14ea48a 900d150 354034d 14ea48a 900d150 354034d 14ea48a 900d150 14ea48a 0a0f04e e59dbba 14ea48a e59dbba 0e60c05 14ea48a 0a0f04e 14ea48a aacb328 6166b18 14ea48a 0a0f04e 14ea48a 3b3b006 14ea48a 972ff8d 0a0f04e 972ff8d f17e850 4e809c1 b86ffde 4e809c1 f17e850 b86ffde 4e809c1 f17e850 4e809c1 f17e850 bd2f5df b86ffde f17e850 4d20678 f17e850 b86ffde 75644b0 3f410d8 b86ffde 465ef15 b86ffde 39cb97e ca2325b b86ffde b9f7106 f17e850 b9f7106 9e3862d 74c4208 9e3862d 74c4208 9e3862d 74c4208 9e3862d 6166b18 0a0f04e 2d529a5 f5b9f23 6166b18 9303e93 675d389 13afe98 8565aa1 13afe98 2a006e5 2a41cca 18eac15 2a41cca 18eac15 2a41cca 14ea48a 2a41cca 3ca5746 ff0bc47 3ca5746 2a41cca 14ea48a 6166b18 3b3b006 6166b18 972ff8d aad84d2 18eac15 75644b0 3b3b006 aad84d2 3b3b006 2d529a5 972ff8d 5c6d2e8 75644b0 e42b20b 9e3862d 6166b18 14ea48a eb890af |
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 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
import os
import streamlit as st
import firebase_admin
from firebase_admin import credentials, db, auth, firestore
import face_recognition
from PIL import Image
import numpy as np
import cv2
import dlib
from io import BytesIO
import requests
# Get the current working directory
current_directory = os.path.dirname(os.path.abspath(__file__))
skp_path = os.path.join(current_directory, "projectinsta-s-firebase-adminsdk-y6vlu-9a1345f468.json")
# Check if the app is already initialized
if not firebase_admin._apps:
# Initialize Firebase Admin SDK
cred = credentials.Certificate(skp_path)
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://projectinsta-s-default-rtdb.firebaseio.com/',
'projectId': 'projectinsta-s'
})
# Reference to the root of your Firebase Realtime Database
ref = db.reference('/')
# Initialize Firestore client
db_firestore = firestore.client()
# Streamlit session state
if "auth_state" not in st.session_state:
st.session_state.auth_state = {
"user": None,
"signed_in": False,
}
# Add the shape predictor model for face alignment
shape_predictor_path = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
shape_predictor = dlib.shape_predictor(shape_predictor_path)
# Firebase Authentication
def authenticate_user(email, password):
try:
user = auth.get_user_by_email(email)
# The user is successfully fetched, meaning the email and password are valid.
return True, user
except auth.AuthError as e:
print(f"Authentication error: {str(e)}")
return False, None
# Sign-up Functionality
def create_user(email, password):
try:
user = auth.create_user(
email=email,
password=password
)
return True, user.uid
except Exception as e:
print(f"User creation error: {str(e)}")
return False, None
# Update load_and_encode function to return encodings for all detected faces
def load_and_encode(image_file):
try:
# Read the uploaded file as bytes
image_bytes = image_file.read()
# Convert the bytes to a NumPy array
nparr = np.frombuffer(image_bytes, np.uint8)
# Decode the NumPy array as an image
image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
aligned_faces = detect_and_align_faces(image)
if aligned_faces is not None:
encodings = []
for aligned_face in aligned_faces:
encoding = face_recognition.face_encodings(aligned_face)
if encoding:
encodings.append(encoding[0])
if encodings:
return encodings
else:
return None
else:
return None
except Exception as e:
print(f"Error loading and encoding image: {str(e)}")
return None
# Modify detect_and_align_faces function to detect and align multiple faces
def detect_and_align_faces(image):
# Resize the image to a fixed width (you can adjust the width as needed)
target_width = 800
aspect_ratio = image.shape[1] / image.shape[0]
target_height = int(target_width / aspect_ratio)
resized_image = cv2.resize(image, (target_width, target_height))
gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
# Detect faces using dlib
faces = detector(gray)
if not faces:
return None
aligned_faces = []
for face in faces:
# Use dlib for face alignment
landmarks = shape_predictor(gray, face)
aligned_face = dlib.get_face_chip(resized_image, landmarks, size=256) # Adjust the size as needed
aligned_faces.append(aligned_face)
return aligned_faces
# Add person to database
def add_person(name, image_path, instagram_handle, email=None):
try:
encoding = load_and_encode(image_path)
if not encoding:
return "No face found in the provided image."
# Convert NumPy arrays to lists for JSON serialization
encoding = encoding[0].tolist()
# Save data to Firebase Realtime Database
person_data = {
"encoding": encoding,
"info": {
"instagram_handle": instagram_handle,
"instagram_link": f"https://www.instagram.com/{instagram_handle}/"
},
"added_by": st.session_state.auth_state["user"].email # Added this line
}
if email:
person_data["info"]["email"] = email
ref.child(name).set(person_data)
log_action(st.session_state.auth_state["user"].email, "Added person")
return f"Success: {name} added to the database!"
except Exception as e:
return f"Failed to add person: {str(e)}"
# Update recognize_face function to handle multiple face encodings
def recognize_face(image_path):
if not image_path:
return "Please upload an image."
try:
# Assuming load_and_encode function loads and encodes the image
unknown_encodings = load_and_encode(image_path)
if not unknown_encodings:
return "No face found in the provided image."
matches = []
for unknown_encoding in unknown_encodings:
face_matches = []
for name, data in ref.get().items():
known_encoding = np.array(data["encoding"])
if face_recognition.compare_faces([known_encoding], unknown_encoding)[0]:
info = data["info"]
instagram_handle = info.get("instagram_handle")
email = info.get("email", "Email not provided")
# Fetch additional Instagram data
if instagram_handle:
insta_data = fetch_instagram_data(instagram_handle)
if insta_data:
edge_followed_by = insta_data.get('edge_followed_by', {}).get('count')
edge_follow = insta_data.get('edge_follow', {}).get('count')
full_name = insta_data.get('full_name')
biography = insta_data.get('biography')
is_private = insta_data.get('is_private')
profile_pic_url_hd = insta_data.get('profile_pic_url_hd')
face_matches.append((name, instagram_handle, email, edge_followed_by, edge_follow, full_name, biography, is_private, profile_pic_url_hd))
else:
face_matches.append((name, instagram_handle, email, "N/A", "N/A", "Unknown", "Unknown", "N/A", "N/A"))
else:
face_matches.append((name, "Unknown", email, "N/A", "N/A", "Unknown", "Unknown", "N/A", "N/A"))
if face_matches:
matches.extend(face_matches)
else:
matches.append(("Unknown", "Unknown", "Unknown", "N/A", "N/A", "Unknown", "Unknown", "N/A", "N/A"))
if matches:
results = []
for name, insta_handle, email, edge_followed_by, edge_follow, full_name, biography, is_private, profile_pic_url_hd in matches:
insta_link = f"https://www.instagram.com/{insta_handle}/"
insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
results.append(f"- It's a picture of {name}! Insta handle: {insta_link_html}, Email: {email}, Followers: {edge_followed_by}, Following: {edge_follow}, Full Name: {full_name}, Biography: {biography}, Private: {is_private}, Profile Picture: <img src='{profile_pic_url_hd}' width='50'>")
log_action(st.session_state.auth_state["user"].email, "Recognized face")
return "\n".join(results)
else:
return "Face not found in the database."
except Exception as e:
return f"Failed to recognize face: {str(e)}"
def fetch_instagram_data(instagram_handle):
url = f"https://instagram-scraper-20231.p.rapidapi.com/userinfo/{instagram_handle}"
headers = {
"x-rapidapi-key": "f47a0f4918msha715fc855e591a2p170a28jsnfc038903d424",
"x-rapidapi-host": "instagram-scraper-20231.p.rapidapi.com"
}
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
if data.get('status') == 'success':
return data.get('data', {})
else:
return None
else:
return None
except Exception as e:
print(f"Error fetching Instagram data: {str(e)}")
return None
# Update recognize_face_optimal function to handle multiple face encodings
def recognize_face_optimal(image_path):
if not image_path:
return "Please upload an image."
try:
unknown_encodings = load_and_encode(image_path)
if not unknown_encodings:
return "No face found in the provided image."
matches = []
for unknown_encoding in unknown_encodings:
face_matches = []
for name, data in ref.get().items():
known_encoding = np.array(data["encoding"])
similarity_score = face_recognition.face_distance([known_encoding], unknown_encoding)[0]
if similarity_score > 0.50: # Only consider matches above 50.00% similarity
continue
face_matches.append((name, similarity_score))
if face_matches:
best_match = min(face_matches, key=lambda x: x[1])
best_name, best_score = best_match
info = ref.child(best_name).child("info").get()
insta_handle = info["instagram_handle"]
insta_link = info["instagram_link"]
insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
matches.append(f"Best match: {best_name} with a similarity score of {1 - best_score:.2%}. Insta handle: {insta_link_html}")
else:
matches.append("Face not found in the database.")
return "\n".join(matches)
except Exception as e:
return f"Failed to recognize face: {str(e)}"
# Delete person from database
def delete_person(name):
try:
ref.child(name).delete()
log_action(st.session_state.auth_state["user"].email, "Deleted person")
return f"{name} deleted from the database!"
except Exception as e:
return f"Failed to delete person: {str(e)}"
# Delete user from Firebase Authentication
def delete_user(email, password):
# Authenticate user with provided email and password
try:
user = auth.get_user_by_email(email)
if user:
# Delete user if authentication is successful
auth.delete_user(user.uid)
return "User deleted successfully!"
except Exception as e:
return f"Failed to delete user: {str(e)}"
# Send feedback to Firebase
def send_feedback(feedback_data):
try:
db_firestore.collection('feedback').add(feedback_data)
except Exception as e:
st.error(f"Failed to submit feedback: {str(e)}")
# Streamlit interface for adding a person
def add_person_ui():
st.title("π Add Person")
name = st.text_input("Enter Name", help="Enter the name of the person")
image_path = st.file_uploader("Upload Image", help="Upload an image containing the person's face")
email = st.text_input("Enter Email (Optional)", help="Enter the person's email address (optional)")
instagram_handle = st.text_input("Enter Instagram Handle", help="Enter the person's Instagram handle")
if st.button("Add Person"):
if not name or not image_path or not instagram_handle:
st.error("Please fill all the required fields.")
else:
result = add_person(name, image_path, instagram_handle, email)
st.success(result)
# Streamlit interface for recognizing face
def recognize_face_ui():
st.title("π Recognize Face")
image_path = st.file_uploader("Upload Image", help="Upload an image for face recognition")
if st.button("Recognize Face"):
result = recognize_face(image_path)
st.write(result, unsafe_allow_html=True)
def recognize_face_optimal_ui():
st.title("π Recognize Face (Optimal)")
image_path = st.file_uploader("Upload Image", help="Upload an image for optimal face recognition")
if st.button("Recognize Face (Optimal)"):
result = recognize_face_optimal(image_path)
st.write(result, unsafe_allow_html=True)
# Streamlit interface for deleting a person
def delete_person_ui():
st.title("ποΈ Delete Person")
name = st.text_input("Enter Name", help="Enter the name of the person to delete")
if st.button("Delete Person"):
if not name:
st.error("Please enter a name.")
else:
# Check if the person exists in the database
if name not in ref.get().keys():
st.error("Person not found in the database.")
return
# Check if the person was added by the currently signed-in user
person_data = ref.child(name).get()
if person_data["added_by"] != st.session_state.auth_state["user"].email:
st.error("You can only delete the person added by you.")
return
result = delete_person(name)
st.success(result)
# Streamlit interface for feedback
def feedback_ui():
st.title("βοΈ Feedback")
st.write("Your feedback is important to us! Please fill out the form below:")
name = st.text_input("Name (optional)")
email = st.text_input("Email (optional)")
category = st.selectbox("Category", ["Bug Report", "Feature Request", "General Feedback"])
message = st.text_area("Feedback Message")
if st.button("Submit Feedback"):
if not message:
st.error("Please enter your feedback message.")
else:
feedback_data = {
"name": name,
"email": email,
"category": category,
"message": message,
}
send_feedback(feedback_data)
st.success("Feedback submitted successfully! Thank you for your feedback.")
#section for messaging
# Function to send a message
def send_message(sender_email, receiver_email, message_content):
try:
# Add message to Firestore
db_firestore.collection('messages').add({
'sender_email': sender_email,
'receiver_email': receiver_email,
'message_content': message_content,
'timestamp': firestore.SERVER_TIMESTAMP
})
return "Message sent successfully!"
except Exception as e:
return f"Failed to send message: {str(e)}"
# Function to retrieve messages for a user
def get_messages(user_email):
try:
messages = db_firestore.collection('messages').where('receiver_email', '==', user_email).order_by('timestamp', direction=firestore.Query.DESCENDING).stream()
return messages
except Exception as e:
return None
# Streamlit interface for messaging
def messaging_ui():
st.title("π¬ Messaging")
if st.session_state.auth_state["signed_in"]:
sender_email = st.session_state.auth_state["user"].email
receiver_email = st.text_input("Receiver's Email", help="Enter the receiver's email address")
message_content = st.text_area("Message Content")
if st.button("Send Message"):
result = send_message(sender_email, receiver_email, message_content)
st.write(result)
messages = get_messages(sender_email)
if messages:
st.write("Your messages:")
for message in messages:
message_data = message.to_dict()
st.write(f"From: {message_data['sender_email']}")
st.write(f"Message: {message_data['message_content']}")
st.write("---")
else:
st.write("Please sign in to send and view messages.")
#end of messaging section
# History section
def log_action(user_email, action):
try:
db_firestore.collection('history').add({
'user_email': user_email,
'action': action,
'timestamp': firestore.SERVER_TIMESTAMP
})
except Exception as e:
st.error(f"Failed to log action: {str(e)}")
# Display history of actions taken by the user
def display_history(user_email):
st.title("π History")
st.write("Here is the history of actions taken by you:")
try:
history = db_firestore.collection('history').where('user_email', '==', user_email).order_by('timestamp', direction=firestore.Query.DESCENDING).stream()
for entry in history:
entry_data = entry.to_dict()
action = entry_data['action']
timestamp = entry_data['timestamp']
st.write(f"- {action} at {timestamp}")
except Exception as e:
st.error(f"Failed to retrieve history: {str(e)}")
#End of history section
# Streamlit interface for Deleting user
def delete_user_ui():
st.title("Delete User")
email = st.text_input("Enter User's Email", help="Enter the email of the user to delete")
password = st.text_input("Enter Your Password", type="password", help="Enter your password for confirmation")
if st.button("Delete User"):
if not email or not password:
st.error("Please enter the user's email and your password.")
else:
# Display confirmation pop-up
confirmation = st.checkbox("I confirm that I want to delete this user.")
if confirmation:
result = delete_user(email, password)
st.success(result)
def tour_guide_ui():
st.title("πΊοΈ Tour Guide")
st.markdown("This tour will guide you through the application.")
for step in steps:
with st.expander(step["title"]):
st.write(step["content"])
def authenticate_user_ui():
# Display logo and title
c30, c31, c32 = st.columns([0.2, 0.1, 3])
with c30:
st.caption("")
# Display the logo
logo_path = os.path.join(current_directory, "Explore+.png")
logo = Image.open(logo_path)
st.image(logo, width=60)
with c32:
st.title("Insta's EYE")
st.sidebar.title("Options")
if st.session_state.auth_state["signed_in"]:
st.sidebar.button("Sign Out", on_click=logout)
st.title("Welcome!")
main()
else:
option = st.sidebar.radio("Select Option", ["Login", "Sign-Up"])
email = st.text_input("Enter Email", help="Enter your email address")
password = st.text_input("Enter Password", type="password", help="Enter your password")
if option == "Login":
if st.button("Login"):
if not email or not password:
st.error("Please enter both email and password.")
else:
success, user = authenticate_user(email, password)
if success:
st.session_state.auth_state["user"] = user
st.session_state.auth_state["signed_in"] = True
st.success("Authentication successful! You can now manage your set of images and profiles.")
main()
else:
st.error("Authentication failed. Please check your email and password.")
elif option == "Sign-Up":
confirm_password = st.text_input("Confirm Password", type="password", help="Re-enter your password for confirmation")
if st.button("Sign-Up"):
if not email or not password or not confirm_password:
st.error("Please fill all the fields.")
elif password != confirm_password:
st.error("Passwords do not match.")
else:
success, uid = create_user(email, password)
if success:
st.success(f"User with UID: {uid} created successfully! You can now log in.")
else:
st.error("User creation failed. Please try again.")
# Log out user
def logout():
st.session_state.auth_state["user"] = None
st.session_state.auth_state["signed_in"] = False
# Define tour steps
steps = [
{
"title": "Welcome to Insta's EYE",
"content": "This is a tour guide to help you navigate through the application.",
},
{
"title": "Options Sidebar",
"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.",
},
{
"title": "Recognize face",
"content": "This function will return you Id's for your provided face.",
},
{
"title": "Recognize face(optimal)",
"content": "This function will return you Id's of provided face with more accuracy",
},
{
"title": "Add person",
"content": "Here you can add yourself or someone else too",
},
{
"title": "Delete person",
"content": "Here you can delete the person by entering their name",
},
{
"title": "History",
"content": "Here you can track history of your activities",
},
{
"title": "Upload Image",
"content": "You can upload an image here for face recognition or adding a person.",
},
{
"title": "Text Input",
"content": "Enter text here such as the person's name or Instagram handle.",
},
{
"title": "Buttons",
"content": "Click on these buttons to perform actions like adding a person or recognizing a face.",
},
]
# Function to display tour steps
def display_tour_steps(steps):
st.markdown("# Tour Guide")
st.markdown("This tour will guide you through the application.")
st.markdown("---")
for step in steps:
st.markdown(f"## {step['title']}")
st.write(step['content'])
st.markdown("---")
# Update the main function to include the feedback option
def main():
st.sidebar.title("Options")
option = st.sidebar.radio("Select Option", ["Recognize Face", "Add Person", "Recognize Face (Optimal)", "Delete Person", "Tour Guide", "Feedback", "Messaging", "History", "Delete User"])
if option == "Recognize Face":
recognize_face_ui()
elif option == "Recognize Face (Optimal)":
recognize_face_optimal_ui()
elif option == "Add Person":
add_person_ui()
elif option == "Delete Person":
delete_person_ui()
elif option == "Tour Guide":
tour_guide_ui()
elif option == "Feedback":
feedback_ui()
elif option == "Messaging":
messaging_ui()
elif option == "History":
display_history(st.session_state.auth_state["user"].email)
elif option == "Delete User":
delete_user_ui()
# Run the tour guide
if __name__ == "__main__":
authenticate_user_ui() |