Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import io
|
| 3 |
+
import time
|
| 4 |
+
from collections import defaultdict
|
| 5 |
+
import numpy as np
|
| 6 |
+
from PIL import Image
|
| 7 |
+
from deepface import DeepFace
|
| 8 |
+
from google.oauth2 import service_account
|
| 9 |
+
from googleapiclient.discovery import build
|
| 10 |
+
from googleapiclient.http import MediaIoBaseDownload, MediaFileUpload
|
| 11 |
+
from simple_salesforce import Salesforce
|
| 12 |
+
|
| 13 |
+
# Configuration settings
|
| 14 |
+
SCOPES = ['https://www.googleapis.com/auth/drive']
|
| 15 |
+
SERVICE_ACCOUNT_FILE = r'C:\Users\Ajaya\Downloads\vertical-sunset-440402-h4-f3e25263f3a1.json'
|
| 16 |
+
SF_USERNAME = 'navyagrand7890@gmail.com'
|
| 17 |
+
SF_PASSWORD = 'navya@123'
|
| 18 |
+
SF_SECURITY_TOKEN = 'NeAPhh5Puxmc1EsL1IJPcQB5'
|
| 19 |
+
AADHAR_FOLDER_ID = '1Qtb5DYzSFE67Mbb5ZgDIqWUtdJaDD2F4'
|
| 20 |
+
CPHOTOS_FOLDER_ID = '1DGeRqRbCPcfLDdEgP0h5fyX-MF8EQ8AH'
|
| 21 |
+
SUSPECTS_FOLDER_ID = '1N3RMhVD0OygeufLPYod6IYLtqzvlm3Jv'
|
| 22 |
+
THRESHOLD = 0.65
|
| 23 |
+
|
| 24 |
+
# Initialize services
|
| 25 |
+
def initialize_services():
|
| 26 |
+
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
|
| 27 |
+
drive_service = build('drive', 'v3', credentials=credentials)
|
| 28 |
+
sf = Salesforce(username=SF_USERNAME, password=SF_PASSWORD, security_token=SF_SECURITY_TOKEN)
|
| 29 |
+
return drive_service, sf
|
| 30 |
+
|
| 31 |
+
# List files in a folder
|
| 32 |
+
def list_files_in_folder(drive_service, folder_id):
|
| 33 |
+
query = f"'{folder_id}' in parents and trashed=false"
|
| 34 |
+
results = drive_service.files().list(q=query, pageSize=1000, fields="files(id, name)").execute()
|
| 35 |
+
return results.get('files', [])
|
| 36 |
+
|
| 37 |
+
# Download a file from Google Drive
|
| 38 |
+
def download_file(drive_service, file_id, file_name):
|
| 39 |
+
request = drive_service.files().get_media(fileId=file_id)
|
| 40 |
+
file_io = io.BytesIO()
|
| 41 |
+
downloader = MediaIoBaseDownload(file_io, request)
|
| 42 |
+
done = False
|
| 43 |
+
while not done:
|
| 44 |
+
_, done = downloader.next_chunk()
|
| 45 |
+
download_path = os.path.join("downloads", file_name)
|
| 46 |
+
os.makedirs("downloads", exist_ok=True)
|
| 47 |
+
with open(download_path, 'wb') as f:
|
| 48 |
+
f.write(file_io.getvalue())
|
| 49 |
+
return download_path
|
| 50 |
+
|
| 51 |
+
# Group similar images based on DeepFace embeddings
|
| 52 |
+
def group_similar_images(image_paths):
|
| 53 |
+
embeddings = []
|
| 54 |
+
grouped_images = defaultdict(list)
|
| 55 |
+
|
| 56 |
+
# Get embeddings for each image
|
| 57 |
+
for image_path in image_paths:
|
| 58 |
+
embedding = DeepFace.represent(image_path, model_name='ArcFace', enforce_detection=False)[0]['embedding']
|
| 59 |
+
embeddings.append((image_path, embedding))
|
| 60 |
+
|
| 61 |
+
# Cluster images based on similarity
|
| 62 |
+
for i, (image_path_i, embedding_i) in enumerate(embeddings):
|
| 63 |
+
for j, (image_path_j, embedding_j) in enumerate(embeddings):
|
| 64 |
+
if i >= j:
|
| 65 |
+
continue
|
| 66 |
+
similarity = np.dot(embedding_i, embedding_j) / (np.linalg.norm(embedding_i) * np.linalg.norm(embedding_j))
|
| 67 |
+
if similarity > 0.85: # Threshold for grouping similar images
|
| 68 |
+
grouped_images[i].append(image_path_j)
|
| 69 |
+
|
| 70 |
+
# Print the number of images per group
|
| 71 |
+
print(f"[INFO] Grouped similar images into {len(grouped_images)} groups based on similarity.")
|
| 72 |
+
|
| 73 |
+
return grouped_images
|
| 74 |
+
|
| 75 |
+
# Function to pick best match per group
|
| 76 |
+
def pick_best_match_and_clean_up(grouped_images, aadhar_images, threshold, suspects_folder_id, drive_service, sf):
|
| 77 |
+
for group_id, image_paths in grouped_images.items():
|
| 78 |
+
match_found = False
|
| 79 |
+
for cphoto_path in image_paths:
|
| 80 |
+
for aadhar_path in aadhar_images:
|
| 81 |
+
is_match, distance = compare_faces_deepface(aadhar_path, cphoto_path, threshold)
|
| 82 |
+
if is_match:
|
| 83 |
+
match_found = True
|
| 84 |
+
print(f"[INFO] Match found for group {group_id} with image {cphoto_path}")
|
| 85 |
+
break
|
| 86 |
+
if match_found:
|
| 87 |
+
break
|
| 88 |
+
|
| 89 |
+
# Clean up: only keep best-matched image, delete others
|
| 90 |
+
if match_found:
|
| 91 |
+
for extra_path in image_paths:
|
| 92 |
+
if extra_path != cphoto_path:
|
| 93 |
+
os.remove(extra_path)
|
| 94 |
+
print(f"[INFO] Deleted redundant image: {extra_path}")
|
| 95 |
+
else:
|
| 96 |
+
# No match found for the group, mark as suspect
|
| 97 |
+
for cphoto_path in image_paths:
|
| 98 |
+
uploaded_file_id, uploaded_file_url = upload_file(drive_service, cphoto_path, suspects_folder_id)
|
| 99 |
+
create_suspect_record_in_salesforce(sf, uploaded_file_id, os.path.basename(cphoto_path), uploaded_file_url)
|
| 100 |
+
|
| 101 |
+
# Upload file to Google Drive
|
| 102 |
+
def upload_file(drive_service, file_path, folder_id):
|
| 103 |
+
file_metadata = {'name': os.path.basename(file_path), 'parents': [folder_id]}
|
| 104 |
+
media = MediaFileUpload(file_path, resumable=True)
|
| 105 |
+
file = drive_service.files().create(body=file_metadata, media_body=media, fields='id, webViewLink').execute()
|
| 106 |
+
return file.get('id'), file.get('webViewLink')
|
| 107 |
+
|
| 108 |
+
# Salesforce record creation
|
| 109 |
+
def create_suspect_record_in_salesforce(sf, file_id, file_name, file_url):
|
| 110 |
+
record = {'Name': file_name, 'File_ID__c': file_id, 'File_Name__c': file_name, 'File_URL__c': file_url}
|
| 111 |
+
sf.zia__c.create(record)
|
| 112 |
+
print(f"[INFO] Created suspect record in Salesforce for file: {file_name}")
|
| 113 |
+
|
| 114 |
+
# Compare images with DeepFace
|
| 115 |
+
def compare_faces_deepface(img1_path, img2_path, threshold):
|
| 116 |
+
result = DeepFace.verify(img1_path=img1_path, img2_path=img2_path, model_name='ArcFace', enforce_detection=False)
|
| 117 |
+
return result['verified'], result['distance']
|
| 118 |
+
|
| 119 |
+
def main():
|
| 120 |
+
drive_service, sf = initialize_services()
|
| 121 |
+
aadhar_files = list_files_in_folder(drive_service, AADHAR_FOLDER_ID)
|
| 122 |
+
cphotos_files = list_files_in_folder(drive_service, CPHOTOS_FOLDER_ID)
|
| 123 |
+
|
| 124 |
+
# Download Aadhaar images
|
| 125 |
+
aadhar_images = [download_file(drive_service, file['id'], file['name']) for file in aadhar_files]
|
| 126 |
+
|
| 127 |
+
# Download CCTV images and group by similarity
|
| 128 |
+
cphotos_paths = [download_file(drive_service, file['id'], file['name']) for file in cphotos_files]
|
| 129 |
+
grouped_images = group_similar_images(cphotos_paths)
|
| 130 |
+
|
| 131 |
+
# Process each group to find best match and clean up
|
| 132 |
+
pick_best_match_and_clean_up(grouped_images, aadhar_images, THRESHOLD, SUSPECTS_FOLDER_ID, drive_service, sf)
|
| 133 |
+
|
| 134 |
+
if __name__ == "__main__":
|
| 135 |
+
main()
|