File size: 6,803 Bytes
de236dc
37b0940
de236dc
58574bf
de236dc
ae58e6e
58574bf
86a3f51
8157937
c2ed860
1e53150
8140af8
615bf6c
8140af8
347e5c4
462c66a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
de236dc
c43aee1
58574bf
 
16e29fd
8157937
37b0940
615bf6c
ae58e6e
1e53150
27b0f1b
 
8157937
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8140af8
8157937
 
 
 
 
 
 
615bf6c
1e53150
8140af8
1e53150
8157937
c2ed860
 
 
137bfc1
8157937
1e53150
8140af8
 
 
 
 
1e53150
8157937
 
 
 
8140af8
 
8157937
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2ed860
8157937
 
 
 
 
86a3f51
8157937
 
 
 
 
 
 
 
 
 
 
462c66a
 
 
 
8157937
 
 
86a3f51
8157937
 
 
86a3f51
8157937
 
1e53150
 
8157937
 
 
 
 
 
 
 
1e53150
8157937
 
 
 
8140af8
8157937
 
1e53150
8157937
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import cv2
import numpy as np
import requests
import tempfile
import mediapipe as mp
import os
import pickle
import io
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from PIL import Image

from simple_salesforce import Salesforce
from datetime import datetime
import uuid

# === SALESFORCE SETUP ===
sf = Salesforce(
    username='suriraja822@agentforce.com',
    password='Sati@1010',
    security_token='B9nS0HEyBE7YmWllqXCyiOJpY',
    domain='login'  # Use 'test' if you're on a sandbox
)

def log_intruder_to_salesforce(frame_id):
    """Logs a detection event to Salesforce."""
    try:
        sf.Hotel_Security_Alert__c.create({
            'Alert_Type__c': 'Intruder',
            'Detection_Timestamp__c': datetime.utcnow().isoformat(),
            'HF_Detection_ID__c': f'intruder_{frame_id}_{uuid.uuid4()}',
            'Confidence_Score__c': 0.90,
            'Description__c': 'Detected unrecognized face from CCTV feed',
            'Status__c': 'Open',
            'Title__c': f'Intruder Detected Frame {frame_id}',
            'Priority__c': 'Medium'
        })
    except Exception as e:
        st.warning(f"⚠️ Failed to log to Salesforce: {e}")



        

# === CONFIGURATION ===
API_KEY = "AIzaSyDojJrpauA0XZtCCDUuo9xeQHZQamYKsC4"
CCTVFEED_IDS = ['1KJRkSf2SKEZ1mXS9_si65IwMBtjs6p4n']
REG_FOLDER_ID = '1qkcR7nQTEtiMH9OFUv2bGxVn08E3dKjF'
INTRUDER_FOLDER_ID = '1PPAUWU-wMx7fek73p-hqPqYQypYtG8Ob'
FRAME_SKIP = st.sidebar.slider("⏩ Frame Skip", 1, 15, 5)

# === SETUP ===
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils
face_detector = mp_face_detection.FaceDetection(model_selection=0, min_detection_confidence=0.5)

def mse(img1, img2):
    try:
        if img1.shape != img2.shape:
            img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
        err = np.mean((img1.astype("float") - img2.astype("float")) ** 2)
        return err
    except Exception:
        return float("inf")

def is_duplicate(img, img_list, threshold=200):
    for existing in img_list:
        if mse(img, existing) < threshold:
            return True
    return False

def get_drive_file_links(folder_id, filter_video=False):
    url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
    response = requests.get(url)
    files = response.json().get("files", [])
    links = []
    for f in files:
        mime = f["mimeType"]
        if (not filter_video and mime.startswith("image/")) or (filter_video and mime.startswith("video/")):
            link = f"https://drive.google.com/uc?id={f['id']}&export=download"
            links.append((f["name"], link))
    return links

def download_file(link, suffix):
    response = requests.get(link, stream=True)
    temp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
    for chunk in response.iter_content(1024 * 1024):
        temp.write(chunk)
    temp.close()
    return temp.name

def detect_faces(image):
    rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = face_detector.process(rgb)
    faces = []
    if results.detections:
        for det in results.detections:
            bbox = det.location_data.relative_bounding_box
            h, w, _ = image.shape
            x, y, bw, bh = int(bbox.xmin * w), int(bbox.ymin * h), int(bbox.width * w), int(bbox.height * h)
            crop = image[max(0, y):y+bh, max(0, x):x+bw]
            if crop.size > 0:
                faces.append(crop)
    return faces

def upload_to_drive(image_np, filename):
    creds = None
    if os.path.exists("token.pickle"):
        with open("token.pickle", "rb") as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
    service = build('drive', 'v3', credentials=creds)
    image_pil = Image.fromarray(cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB))
    buf = io.BytesIO()
    image_pil.save(buf, format="JPEG")
    buf.seek(0)
    with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as tmp:
        tmp.write(buf.read())
        tmp.flush()
        file_metadata = {'name': filename, 'parents': [INTRUDER_FOLDER_ID]}
        media = MediaFileUpload(tmp.name, mimetype='image/jpeg')
        service.files().create(body=file_metadata, media_body=media, fields='id').execute()
        os.remove(tmp.name)

def detect_faces_from_video(video_path, registered_faces):
    cap = cv2.VideoCapture(video_path)
    detected = []
    unique = []
    frame_id = 0

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        frame_id += 1
        if frame_id % FRAME_SKIP != 0:
            continue
        faces = detect_faces(frame)
        for f in faces:
            if not any(mse(f, reg) < 200 for reg in registered_faces) and not is_duplicate(f, unique):
                unique.append(f)
                filename = f"intruder_{frame_id}.jpg"
upload_to_drive(f, filename)
log_intruder_to_salesforce(frame_id)
                
        detected.extend(faces)
    cap.release()
    return detected, unique

# === STREAMLIT UI ===
st.title("πŸ” Intruder Detection")
st.write("Streams from Google Drive and detects intruders using MediaPipe.")

st.sidebar.header("πŸ“ Registered Faces")
reg_faces_raw = get_drive_file_links(REG_FOLDER_ID, filter_video=False)
registered_faces = []

for name, link in reg_faces_raw:
    img_path = download_file(link, ".jpg")
    img = cv2.imread(img_path)
    faces = detect_faces(img)
    for f in faces:
        registered_faces.append(f)
        st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=name, width=100)
    os.remove(img_path)

st.sidebar.header("πŸ“Έ Detected Intruders")

with st.spinner("Processing videos..."):
    total_uploaded = 0
    for folder_id in CCTVFEED_IDS:
        vids = get_drive_file_links(folder_id, filter_video=True)
        for vname, vlink in vids:
            st.subheader(f"πŸŽ₯ {vname}")
            vfile = download_file(vlink, ".mp4")
            detected_faces, unique_faces = detect_faces_from_video(vfile, registered_faces)
            for i, f in enumerate(unique_faces):
                st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=f"Intruder {i+1}", width=100)
            if unique_faces:
                st.success(f"βœ… Uploaded {len(unique_faces)} intruder(s).")
            else:
                st.info("😎 No new intruders detected.")
            os.remove(vfile)
            total_uploaded += len(unique_faces)

st.info(f"🎯 Completed processing all videos.")