SuriRaja commited on
Commit
8157937
Β·
verified Β·
1 Parent(s): 1e53150

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -82
app.py CHANGED
@@ -6,6 +6,7 @@ import tempfile
6
  import mediapipe as mp
7
  import os
8
  import pickle
 
9
  from googleapiclient.discovery import build
10
  from googleapiclient.http import MediaFileUpload
11
  from google_auth_oauthlib.flow import InstalledAppFlow
@@ -17,43 +18,49 @@ API_KEY = "AIzaSyDojJrpauA0XZtCCDUuo9xeQHZQamYKsC4"
17
  CCTVFEED_IDS = ['1KJRkSf2SKEZ1mXS9_si65IwMBtjs6p4n']
18
  REG_FOLDER_ID = '1qkcR7nQTEtiMH9OFUv2bGxVn08E3dKjF'
19
  INTRUDER_FOLDER_ID = '1PPAUWU-wMx7fek73p-hqPqYQypYtG8Ob'
20
- SCOPES = ['https://www.googleapis.com/auth/drive.file']
21
 
22
  # === SETUP ===
23
  mp_face_detection = mp.solutions.face_detection
24
  mp_drawing = mp.solutions.drawing_utils
25
  face_detector = mp_face_detection.FaceDetection(model_selection=0, min_detection_confidence=0.5)
26
 
27
- def authenticate_drive():
28
- creds = None
29
- if os.path.exists('token.pickle'):
30
- with open('token.pickle', 'rb') as token:
31
- creds = pickle.load(token)
32
- if not creds or not creds.valid:
33
- if creds and creds.expired and creds.refresh_token:
34
- creds.refresh(Request())
35
- else:
36
- flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
37
- creds = flow.run_local_server(port=0)
38
- with open('token.pickle', 'wb') as token:
39
- pickle.dump(creds, token)
40
- return build('drive', 'v3', credentials=creds)
41
-
42
- def get_drive_files(folder_id, types):
43
- api_url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
44
- response = requests.get(api_url)
45
  files = response.json().get("files", [])
46
- return [(f["name"], f"https://drive.google.com/uc?id={f['id']}&export=download") for f in files if f["mimeType"] in types]
 
 
 
 
 
 
47
 
48
  def download_file(link, suffix):
49
  response = requests.get(link, stream=True)
50
  temp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
51
- for chunk in response.iter_content(chunk_size=1024*1024):
52
  temp.write(chunk)
53
  temp.close()
54
  return temp.name
55
 
56
- def extract_faces(image):
57
  rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
58
  results = face_detector.process(rgb)
59
  faces = []
@@ -61,74 +68,89 @@ def extract_faces(image):
61
  for det in results.detections:
62
  bbox = det.location_data.relative_bounding_box
63
  h, w, _ = image.shape
64
- x, y, w_, h_ = int(bbox.xmin * w), int(bbox.ymin * h), int(bbox.width * w), int(bbox.height * h)
65
- x, y = max(x, 0), max(y, 0)
66
- cropped = image[y:y+h_, x:x+w_]
67
- if cropped.size:
68
- face = cv2.resize(cropped, (128, 128))
69
- faces.append(face)
70
  return faces
71
 
72
- def mse(img1, img2):
73
- return np.mean((img1.astype("float") - img2.astype("float")) ** 2)
74
-
75
- def is_duplicate(new_face, existing_faces):
76
- return any(mse(new_face, old) < 200 for old in existing_faces)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- def upload_image_to_drive(service, folder_id, image_array, name):
79
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
80
- cv2.imwrite(temp_file.name, image_array)
81
- file_metadata = {'name': name, 'parents': [folder_id]}
82
- media = MediaFileUpload(temp_file.name, mimetype='image/jpeg')
83
- service.files().create(body=file_metadata, media_body=media, fields='id').execute()
84
- os.remove(temp_file.name)
85
 
86
- # === MAIN UI ===
87
- st.set_page_config(layout="wide")
88
- st.title("πŸ” Intruder Detection from CCTV Feed")
89
- st.sidebar.header("πŸ“Έ Face Viewer")
 
 
 
 
 
 
 
 
 
 
 
90
 
91
- drive_service = authenticate_drive()
 
 
92
 
93
- # === Load Registered Faces ===
 
94
  registered_faces = []
95
- with st.spinner("πŸ“‚ Loading registered faces..."):
96
- reg_files = get_drive_files(REG_FOLDER_ID, ["image/jpeg", "image/png"])
97
- for name, link in reg_files:
98
- img_path = download_file(link, ".jpg")
99
- img = cv2.imread(img_path)
100
- faces = extract_faces(img)
101
- for f in faces:
102
- registered_faces.append(f)
103
- st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=f"REG: {name}", width=100)
104
- os.remove(img_path)
105
 
106
- # === Process Videos ===
107
- uploaded_intruders = []
108
- total_detections = 0
 
 
 
 
 
109
 
110
- with st.spinner("πŸ“Ή Processing videos..."):
 
 
 
111
  for folder_id in CCTVFEED_IDS:
112
- videos = get_drive_files(folder_id, ["video/mp4", "video/x-msvideo", "video/avi"])
113
- for vname, vlink in videos:
114
  st.subheader(f"πŸŽ₯ {vname}")
115
- vpath = download_file(vlink, ".mp4")
116
- cap = cv2.VideoCapture(vpath)
117
- frame_id = 0
118
- while cap.isOpened():
119
- ret, frame = cap.read()
120
- if not ret:
121
- break
122
- frame_id += 1
123
- faces = extract_faces(frame)
124
- for idx, f in enumerate(faces):
125
- st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=f"VID Frame {frame_id}", width=100)
126
- if not any(mse(f, reg) < 200 for reg in registered_faces) and not is_duplicate(f, uploaded_intruders):
127
- upload_image_to_drive(drive_service, INTRUDER_FOLDER_ID, f, f"intruder_{vname}_{frame_id}_{idx}.jpg")
128
- st.success(f"⚠️ Intruder detected in frame {frame_id}")
129
- uploaded_intruders.append(f)
130
- total_detections += 1
131
- cap.release()
132
- os.remove(vpath)
133
-
134
- st.info(f"🎯 Completed processing. Total intruders uploaded: {total_detections}")
 
6
  import mediapipe as mp
7
  import os
8
  import pickle
9
+ import io
10
  from googleapiclient.discovery import build
11
  from googleapiclient.http import MediaFileUpload
12
  from google_auth_oauthlib.flow import InstalledAppFlow
 
18
  CCTVFEED_IDS = ['1KJRkSf2SKEZ1mXS9_si65IwMBtjs6p4n']
19
  REG_FOLDER_ID = '1qkcR7nQTEtiMH9OFUv2bGxVn08E3dKjF'
20
  INTRUDER_FOLDER_ID = '1PPAUWU-wMx7fek73p-hqPqYQypYtG8Ob'
21
+ FRAME_SKIP = st.sidebar.slider("⏩ Frame Skip", 1, 15, 5)
22
 
23
  # === SETUP ===
24
  mp_face_detection = mp.solutions.face_detection
25
  mp_drawing = mp.solutions.drawing_utils
26
  face_detector = mp_face_detection.FaceDetection(model_selection=0, min_detection_confidence=0.5)
27
 
28
+ def mse(img1, img2):
29
+ try:
30
+ if img1.shape != img2.shape:
31
+ img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
32
+ err = np.mean((img1.astype("float") - img2.astype("float")) ** 2)
33
+ return err
34
+ except Exception:
35
+ return float("inf")
36
+
37
+ def is_duplicate(img, img_list, threshold=200):
38
+ for existing in img_list:
39
+ if mse(img, existing) < threshold:
40
+ return True
41
+ return False
42
+
43
+ def get_drive_file_links(folder_id, filter_video=False):
44
+ url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
45
+ response = requests.get(url)
46
  files = response.json().get("files", [])
47
+ links = []
48
+ for f in files:
49
+ mime = f["mimeType"]
50
+ if (not filter_video and mime.startswith("image/")) or (filter_video and mime.startswith("video/")):
51
+ link = f"https://drive.google.com/uc?id={f['id']}&export=download"
52
+ links.append((f["name"], link))
53
+ return links
54
 
55
  def download_file(link, suffix):
56
  response = requests.get(link, stream=True)
57
  temp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
58
+ for chunk in response.iter_content(1024 * 1024):
59
  temp.write(chunk)
60
  temp.close()
61
  return temp.name
62
 
63
+ def detect_faces(image):
64
  rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
65
  results = face_detector.process(rgb)
66
  faces = []
 
68
  for det in results.detections:
69
  bbox = det.location_data.relative_bounding_box
70
  h, w, _ = image.shape
71
+ x, y, bw, bh = int(bbox.xmin * w), int(bbox.ymin * h), int(bbox.width * w), int(bbox.height * h)
72
+ crop = image[max(0, y):y+bh, max(0, x):x+bw]
73
+ if crop.size > 0:
74
+ faces.append(crop)
 
 
75
  return faces
76
 
77
+ def upload_to_drive(image_np, filename):
78
+ creds = None
79
+ if os.path.exists("token.pickle"):
80
+ with open("token.pickle", "rb") as token:
81
+ creds = pickle.load(token)
82
+ if not creds or not creds.valid:
83
+ if creds and creds.expired and creds.refresh_token:
84
+ creds.refresh(Request())
85
+ service = build('drive', 'v3', credentials=creds)
86
+ image_pil = Image.fromarray(cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB))
87
+ buf = io.BytesIO()
88
+ image_pil.save(buf, format="JPEG")
89
+ buf.seek(0)
90
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as tmp:
91
+ tmp.write(buf.read())
92
+ tmp.flush()
93
+ file_metadata = {'name': filename, 'parents': [INTRUDER_FOLDER_ID]}
94
+ media = MediaFileUpload(tmp.name, mimetype='image/jpeg')
95
+ service.files().create(body=file_metadata, media_body=media, fields='id').execute()
96
+ os.remove(tmp.name)
97
 
98
+ def detect_faces_from_video(video_path, registered_faces):
99
+ cap = cv2.VideoCapture(video_path)
100
+ detected = []
101
+ unique = []
102
+ frame_id = 0
 
 
103
 
104
+ while cap.isOpened():
105
+ ret, frame = cap.read()
106
+ if not ret:
107
+ break
108
+ frame_id += 1
109
+ if frame_id % FRAME_SKIP != 0:
110
+ continue
111
+ faces = detect_faces(frame)
112
+ for f in faces:
113
+ if not any(mse(f, reg) < 200 for reg in registered_faces) and not is_duplicate(f, unique):
114
+ unique.append(f)
115
+ upload_to_drive(f, f"intruder_{frame_id}.jpg")
116
+ detected.extend(faces)
117
+ cap.release()
118
+ return detected, unique
119
 
120
+ # === STREAMLIT UI ===
121
+ st.title("πŸ” Intruder Detection")
122
+ st.write("Streams from Google Drive and detects intruders using MediaPipe.")
123
 
124
+ st.sidebar.header("πŸ“ Registered Faces")
125
+ reg_faces_raw = get_drive_file_links(REG_FOLDER_ID, filter_video=False)
126
  registered_faces = []
 
 
 
 
 
 
 
 
 
 
127
 
128
+ for name, link in reg_faces_raw:
129
+ img_path = download_file(link, ".jpg")
130
+ img = cv2.imread(img_path)
131
+ faces = detect_faces(img)
132
+ for f in faces:
133
+ registered_faces.append(f)
134
+ st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=name, width=100)
135
+ os.remove(img_path)
136
 
137
+ st.sidebar.header("πŸ“Έ Detected Intruders")
138
+
139
+ with st.spinner("Processing videos..."):
140
+ total_uploaded = 0
141
  for folder_id in CCTVFEED_IDS:
142
+ vids = get_drive_file_links(folder_id, filter_video=True)
143
+ for vname, vlink in vids:
144
  st.subheader(f"πŸŽ₯ {vname}")
145
+ vfile = download_file(vlink, ".mp4")
146
+ detected_faces, unique_faces = detect_faces_from_video(vfile, registered_faces)
147
+ for i, f in enumerate(unique_faces):
148
+ st.sidebar.image(cv2.cvtColor(f, cv2.COLOR_BGR2RGB), caption=f"Intruder {i+1}", width=100)
149
+ if unique_faces:
150
+ st.success(f"βœ… Uploaded {len(unique_faces)} intruder(s).")
151
+ else:
152
+ st.info("😎 No new intruders detected.")
153
+ os.remove(vfile)
154
+ total_uploaded += len(unique_faces)
155
+
156
+ st.info(f"🎯 Completed processing all videos.")