Spaces:
Runtime error
Runtime error
import os | |
# Set a writable Matplotlib configuration directory to avoid permission errors. | |
os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib" | |
from flask import Flask, render_template, Response, jsonify | |
import cv2 | |
import time | |
import numpy as np | |
import threading | |
import requests | |
from twilio.rest import Client | |
from datetime import datetime | |
from inference_sdk import InferenceHTTPClient | |
import pygame # Ensure pygame is installed | |
app = Flask(__name__) | |
# Attempt to initialize the webcam. | |
# Note: In many Hugging Face Spaces, a physical camera may not be available. | |
camera = cv2.VideoCapture(0) | |
if not camera.isOpened(): | |
print("Warning: Camera not available. Video processing will be disabled or use a fallback image.") | |
# Initialize the Roboflow Inference Client | |
CLIENT = InferenceHTTPClient( | |
api_url="https://detect.roboflow.com", | |
api_key="IkQtIl5NGRTc0llwyIMo" | |
) | |
# Detection settings | |
ALERT_INTERVAL = 300 # seconds between alerts | |
last_alert_time = 0 | |
# Define the classes for this project | |
PROJECT_CLASSES = [ | |
"Balls", "Bird", "Cat", "Dog", "Elephant", "Pig", "Tikus", | |
"apple", "bean", "bunny", "cattle", "cute", "leopard", "lion", | |
"rat", "standpig", "tiger" | |
] | |
# Set your location (address or a Google Maps URL) | |
SITE_LOCATION = "1234 Main St, City, Country" | |
def make_call(): | |
"""Initiate a call using Twilio.""" | |
try: | |
account_sid = "AC3988de38b87b0de231ee7704d9e6dafb" | |
auth_token = "2a282eeb0a72c2a2bec9a1331d3cc803" | |
client = Client(account_sid, auth_token) | |
call = client.calls.create( | |
url="http://demo.twilio.com/docs/voice.xml", | |
to="+918999094929", | |
from_="+19046820459" | |
) | |
print("Call initiated. Call SID:", call.sid) | |
except Exception as e: | |
print("Error making call:", str(e)) | |
def send_telegram_message(image, caption): | |
"""Send an alert image with caption via Telegram.""" | |
try: | |
TOKEN = "7289300782:AAF0qzc38BQ1S5a4kyXj7F02kUjIswb1YDY" | |
CHAT_ID = "6186075118" | |
send_photo_url = f"https://api.telegram.org/bot{TOKEN}/sendPhoto" | |
ret, buffer = cv2.imencode('.jpg', image) | |
if not ret: | |
print("Failed to encode image.") | |
return | |
files = {"photo": ("alert.jpg", buffer.tobytes(), "image/jpeg")} | |
data = {"chat_id": CHAT_ID, "caption": caption} | |
response = requests.post(send_photo_url, data=data, files=files) | |
if response.status_code == 200: | |
print("Telegram alert sent.") | |
else: | |
print("Failed to send Telegram alert. Status code:", response.status_code) | |
except Exception as e: | |
print("Error sending Telegram message:", str(e)) | |
def play_siren(): | |
"""Play a siren sound alert using pygame.""" | |
try: | |
pygame.mixer.init() | |
pygame.mixer.music.load("alarm_tune.mp3") | |
pygame.mixer.music.play() | |
except Exception as e: | |
print("Error playing siren:", str(e)) | |
def gen_frames(): | |
"""Generate video frames with object detection overlays.""" | |
global last_alert_time | |
while True: | |
success, frame = camera.read() | |
if not success: | |
print("Error: Unable to read from camera.") | |
break | |
# Save frame for inference | |
image_path = "temp_frame.jpg" | |
cv2.imwrite(image_path, frame) | |
# Perform object detection using Roboflow | |
result = CLIENT.infer(image_path, model_id="animal-detection-yolov8/1") | |
predictions = result.get('predictions', []) | |
# Check for objects in our project classes | |
detected_object = any(obj['class'] in PROJECT_CLASSES for obj in predictions) | |
# Draw detections on the frame | |
for obj in predictions: | |
x, y, w, h = int(obj['x']), int(obj['y']), int(obj['width']), int(obj['height']) | |
cv2.rectangle(frame, (x - w // 2, y - h // 2), (x + w // 2, y + h // 2), (0, 255, 0), 2) | |
cv2.putText(frame, obj['class'], (x, y - 10), | |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) | |
# Trigger alert if an object is detected and sufficient time has passed | |
current_time = time.time() | |
if detected_object and (current_time - last_alert_time >= ALERT_INTERVAL): | |
detected_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
detected_labels = {obj['class'] for obj in predictions if obj['class'] in PROJECT_CLASSES} | |
caption = ( | |
f"Alert! Detected: {', '.join(detected_labels)}\n" | |
f"Time: {detected_time}\n" | |
f"Location: {SITE_LOCATION}" | |
) | |
threading.Thread(target=make_call).start() | |
threading.Thread(target=send_telegram_message, args=(frame.copy(), caption)).start() | |
threading.Thread(target=play_siren).start() | |
last_alert_time = current_time | |
ret, buffer = cv2.imencode('.jpg', frame) | |
if not ret: | |
continue | |
yield (b'--frame\r\n' | |
b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n') | |
def index(): | |
return render_template('index.html') | |
def video_feed(): | |
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame') | |
if __name__ == '__main__': | |
# Run on all interfaces to be accessible outside the container | |
app.run(debug=True, host='0.0.0.0') | |