File size: 5,431 Bytes
4afcbd9
cc5da57
4afcbd9
 
ad67671
 
 
 
 
 
 
 
 
4afcbd9
ad67671
 
 
bc35bbd
 
4afcbd9
bc35bbd
 
ad67671
 
 
 
 
 
 
 
cc5da57
ad67671
 
4afcbd9
ad67671
 
 
 
 
 
cc5da57
 
ad67671
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4afcbd9
ad67671
 
 
 
 
 
 
 
 
 
 
 
 
4afcbd9
ad67671
bc35bbd
ad67671
 
 
bc35bbd
ad67671
 
4afcbd9
ad67671
 
 
4afcbd9
ad67671
 
 
4afcbd9
ad67671
 
4afcbd9
ad67671
 
 
cc5da57
 
ad67671
4afcbd9
ad67671
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc5da57
4afcbd9
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
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')

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/video_feed')
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')