SuriRaja commited on
Commit
86a3f51
Β·
verified Β·
1 Parent(s): 615bf6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -100
app.py CHANGED
@@ -5,138 +5,134 @@ import requests
5
  import tempfile
6
  import mediapipe as mp
7
  import os
8
- import hashlib
9
- import io
10
- from PIL import Image
11
  from googleapiclient.discovery import build
12
  from googleapiclient.http import MediaFileUpload
13
- from google_auth_oauthlib.flow import InstalledAppFlow
14
  from google.auth.transport.requests import Request
15
- import pickle
16
 
17
  # === CONFIGURATION ===
18
  API_KEY = "AIzaSyDojJrpauA0XZtCCDUuo9xeQHZQamYKsC4"
19
  CCTVFEED_IDS = ['1KJRkSf2SKEZ1mXS9_si65IwMBtjs6p4n']
20
  REG_FOLDER_ID = '1qkcR7nQTEtiMH9OFUv2bGxVn08E3dKjF'
21
  INTRUDER_FOLDER_ID = '1PPAUWU-wMx7fek73p-hqPqYQypYtG8Ob'
22
- SCOPES = ['https://www.googleapis.com/auth/drive.file']
23
 
24
  # === SETUP ===
25
  mp_face_detection = mp.solutions.face_detection
26
  mp_drawing = mp.solutions.drawing_utils
27
  face_detector = mp_face_detection.FaceDetection(model_selection=0, min_detection_confidence=0.5)
28
 
29
- # === AUTH FOR UPLOAD ===
30
- def get_drive_service_from_token():
31
- creds = None
32
- if os.path.exists('token.pickle'):
33
- with open('token.pickle', 'rb') as token:
34
- creds = pickle.load(token)
35
- if creds and creds.valid:
36
- return build('drive', 'v3', credentials=creds)
37
- return None
38
 
39
- def upload_to_drive_using_token(file_path, filename, folder_id):
40
- service = get_drive_service_from_token()
41
- if not service:
42
- return False
43
- file_metadata = {
44
- 'name': filename,
45
- 'parents': [folder_id]
46
- }
47
- media = MediaFileUpload(file_path, resumable=True)
48
- service.files().create(body=file_metadata, media_body=media, fields='id').execute()
49
- return True
50
 
51
- # === UTILITIES ===
52
- def get_drive_links(folder_id, mime_prefix="video/"):
53
  api_url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
54
- res = requests.get(api_url).json()
55
- files = res.get("files", [])
56
- return [(f["name"], f["id"]) for f in files if f["mimeType"].startswith(mime_prefix)]
57
-
58
- def get_file_download_url(file_id):
59
- return f"https://drive.google.com/uc?id={file_id}&export=download"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- def download_file(url):
62
- response = requests.get(url, stream=True)
63
  temp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
64
- for chunk in response.iter_content(chunk_size=1024 * 1024):
65
  temp.write(chunk)
66
  temp.close()
67
  return temp.name
68
 
69
- def list_registered_faces():
70
- st.sidebar.markdown("### πŸ§‘β€πŸ’Ό Registered Faces")
71
- images = get_drive_links(REG_FOLDER_ID, mime_prefix="image/")
72
- for name, file_id in images:
73
- img_url = get_file_download_url(file_id)
74
- img = Image.open(requests.get(img_url, stream=True).raw)
75
- st.sidebar.image(img, caption=name, width=120)
76
-
77
- # === FACE DETECTION ===
78
- def detect_faces_from_video(video_path, uploaded_hashes):
79
- cap = cv2.VideoCapture(video_path)
80
- detected = 0
81
- displayed_faces = []
82
-
83
- st.sidebar.markdown("### πŸŽ₯ Faces Detected from Video")
84
-
 
 
 
 
85
  while cap.isOpened():
86
  ret, frame = cap.read()
87
  if not ret:
88
  break
89
-
90
- frame = cv2.resize(frame, (640, 480))
91
  rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
92
  results = face_detector.process(rgb)
93
-
94
  if results.detections:
95
- for det in results.detections:
96
- bbox = det.location_data.relative_bounding_box
97
  ih, iw, _ = frame.shape
98
- x, y, w, h = int(bbox.xmin * iw), int(bbox.ymin * ih), int(bbox.width * iw), int(bbox.height * ih)
99
- x, y = max(x, 0), max(y, 0)
100
- face = frame[y:y + h, x:x + w]
101
- gray = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
102
- resized = cv2.resize(gray, (100, 100))
103
- hsh = hashlib.md5(resized.tobytes()).hexdigest()
104
-
105
- if hsh not in uploaded_hashes:
106
- uploaded_hashes.add(hsh)
107
- tmp_path = os.path.join(tempfile.gettempdir(), f"intruder_{hsh}.jpg")
108
- cv2.imwrite(tmp_path, face)
109
- success = upload_to_drive_using_token(tmp_path, f"intruder_{hsh}.jpg", INTRUDER_FOLDER_ID)
110
- if success:
111
- st.sidebar.image(face, caption="🚨 Intruder", width=120)
112
- else:
113
- st.warning("❌ Upload failed.")
114
- else:
115
- st.sidebar.image(face, caption="β›” Duplicate", width=120)
116
- detected += 1
117
  cap.release()
118
- return detected
119
 
120
  # === STREAMLIT UI ===
121
- st.set_page_config(page_title="CCTV Face Detector", layout="wide")
122
- st.title("πŸ” Intruder Detection from Google Drive CCTV Feed")
123
-
124
- list_registered_faces()
125
- uploaded_hashes = set()
126
-
127
- with st.spinner("Processing videos..."):
128
- total_detected = 0
129
- for folder_id in CCTVFEED_IDS:
130
- videos = get_drive_links(folder_id)
131
- for name, vid_id in videos:
132
- st.subheader(f"🎞️ {name}")
133
- vpath = download_file(get_file_download_url(vid_id))
134
- count = detect_faces_from_video(vpath, uploaded_hashes)
135
- os.remove(vpath)
136
- if count > 0:
137
- st.success(f"βœ… {count} faces detected in {name}")
138
- total_detected += count
139
- else:
140
- st.warning(f"⚠️ No faces found in {name}")
141
-
142
- st.info(f"🎯 Completed processing all videos.")
 
 
 
 
5
  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.transport.requests import Request
 
12
 
13
  # === CONFIGURATION ===
14
  API_KEY = "AIzaSyDojJrpauA0XZtCCDUuo9xeQHZQamYKsC4"
15
  CCTVFEED_IDS = ['1KJRkSf2SKEZ1mXS9_si65IwMBtjs6p4n']
16
  REG_FOLDER_ID = '1qkcR7nQTEtiMH9OFUv2bGxVn08E3dKjF'
17
  INTRUDER_FOLDER_ID = '1PPAUWU-wMx7fek73p-hqPqYQypYtG8Ob'
18
+ MSE_THRESHOLD = 1000
19
 
20
  # === SETUP ===
21
  mp_face_detection = mp.solutions.face_detection
22
  mp_drawing = mp.solutions.drawing_utils
23
  face_detector = mp_face_detection.FaceDetection(model_selection=0, min_detection_confidence=0.5)
24
 
25
+ def mse(img1, img2):
26
+ return np.mean((img1.astype("float") - img2.astype("float")) ** 2)
 
 
 
 
 
 
 
27
 
28
+ def download_image(url):
29
+ resp = requests.get(url, stream=True)
30
+ arr = np.asarray(bytearray(resp.content), dtype=np.uint8)
31
+ return cv2.imdecode(arr, cv2.IMREAD_COLOR)
 
 
 
 
 
 
 
32
 
33
+ def get_faces_from_drive(folder_id):
 
34
  api_url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
35
+ results = requests.get(api_url).json().get("files", [])
36
+ faces = []
37
+ for f in results:
38
+ if f["mimeType"].startswith("image/"):
39
+ url = f"https://drive.google.com/uc?id={f['id']}&export=download"
40
+ image = download_image(url)
41
+ rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
42
+ detections = face_detector.process(rgb)
43
+ if detections.detections:
44
+ for d in detections.detections:
45
+ r = d.location_data.relative_bounding_box
46
+ ih, iw, _ = image.shape
47
+ x, y, w, h = int(r.xmin * iw), int(r.ymin * ih), int(r.width * iw), int(r.height * ih)
48
+ face = image[y:y+h, x:x+w]
49
+ if face.size:
50
+ face = cv2.resize(face, (100, 100))
51
+ faces.append(face)
52
+ return faces
53
+
54
+ def get_video_links(folder_id):
55
+ api_url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents&key={API_KEY}&fields=files(id,name,mimeType)"
56
+ results = requests.get(api_url).json().get("files", [])
57
+ return [(f["name"], f"https://drive.google.com/uc?id={f['id']}&export=download")
58
+ for f in results if f["mimeType"].startswith("video/")]
59
 
60
+ def download_video(link):
61
+ resp = requests.get(link, stream=True)
62
  temp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
63
+ for chunk in resp.iter_content(1024*1024):
64
  temp.write(chunk)
65
  temp.close()
66
  return temp.name
67
 
68
+ def upload_intruder(img):
69
+ creds = None
70
+ if os.path.exists("token.pickle"):
71
+ with open("token.pickle", "rb") as token:
72
+ creds = pickle.load(token)
73
+ if not creds or not creds.valid:
74
+ if creds and creds.expired and creds.refresh_token:
75
+ creds.refresh(Request())
76
+ service = build('drive', 'v3', credentials=creds)
77
+ temp = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
78
+ cv2.imwrite(temp.name, img)
79
+ file_metadata = {'name': os.path.basename(temp.name), 'parents': [INTRUDER_FOLDER_ID]}
80
+ media = MediaFileUpload(temp.name, mimetype='image/jpeg')
81
+ service.files().create(body=file_metadata, media_body=media).execute()
82
+ os.remove(temp.name)
83
+
84
+ def process_video(path, reg_faces, intruder_gallery):
85
+ cap = cv2.VideoCapture(path)
86
+ uploaded_faces = []
87
+ uploaded = 0
88
  while cap.isOpened():
89
  ret, frame = cap.read()
90
  if not ret:
91
  break
 
 
92
  rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
93
  results = face_detector.process(rgb)
 
94
  if results.detections:
95
+ for d in results.detections:
96
+ r = d.location_data.relative_bounding_box
97
  ih, iw, _ = frame.shape
98
+ x, y, w, h = int(r.xmin * iw), int(r.ymin * ih), int(r.width * iw), int(r.height * ih)
99
+ face = frame[y:y+h, x:x+w]
100
+ if face.size:
101
+ face_resized = cv2.resize(face, (100, 100))
102
+ if not any(mse(face_resized, r) < MSE_THRESHOLD for r in reg_faces + uploaded_faces):
103
+ uploaded_faces.append(face_resized)
104
+ intruder_gallery.image(face, caption="πŸ‘€ New Intruder", use_column_width=True)
105
+ try:
106
+ upload_intruder(face)
107
+ uploaded += 1
108
+ except:
109
+ st.warning("Upload failed.")
 
 
 
 
 
 
 
110
  cap.release()
111
+ return uploaded
112
 
113
  # === STREAMLIT UI ===
114
+ st.set_page_config(layout="wide")
115
+ st.title("πŸ” Intruder Detection (MediaPipe + Google Drive)")
116
+ sidebar = st.sidebar
117
+ sidebar.header("🧍 Registered Faces")
118
+ registered_faces = get_faces_from_drive(REG_FOLDER_ID)
119
+ for idx, face in enumerate(registered_faces):
120
+ sidebar.image(cv2.cvtColor(face, cv2.COLOR_BGR2RGB), caption=f"Reg {idx+1}", use_column_width=True)
121
+
122
+ intruder_gallery = st.sidebar.container()
123
+ intruder_gallery.header("🚨 Intruders")
124
+
125
+ total_uploaded = 0
126
+ for folder_id in CCTVFEED_IDS:
127
+ videos = get_video_links(folder_id)
128
+ for vname, link in videos:
129
+ st.subheader(f"πŸŽ₯ {vname}")
130
+ with st.spinner("Downloading video..."):
131
+ video_file = download_video(link)
132
+ with st.spinner("Detecting faces..."):
133
+ uploaded = process_video(video_file, registered_faces, intruder_gallery)
134
+ st.success(f"βœ… Uploaded {uploaded} intruder(s) from {vname}")
135
+ total_uploaded += uploaded
136
+ os.remove(video_file)
137
+
138
+ st.info(f"🎯 Done. Total intruders uploaded: {total_uploaded}")