Month 3 Box - AI Deep Dive

Lesson 4: Real-Time Object Detection + Triggering Real World Actions

Real-Time Object Detection and Triggering Real-World Actions

Detection is only useful if it makes something happen. This lesson turns your camera into a smart security system: when a person enters a defined area of the frame, the Pi snaps a photo and sends it to your phone through Discord or Telegram. You will learn regions of interest, sending alerts with webhooks, and a debounce that stops false alarms, all built on the detection code you already have.

From seeing to doing

So far the Pi recognizes objects; now it reacts to them. The example is a practical one: a camera that watches a spot, and when a person appears there, it takes a picture and notifies you. Put it on a doorstep and it photographs whoever arrives; put it in a garage and it alerts you to anyone inside. The building blocks are a region of interest, a way to send a message, and logic that decides when an event is real enough to act on.

Regions of interest

A camera usually sees a whole room, but you often care about just one spot: the doorway, the couch, the driveway. A region of interest is a rectangle, defined by pixel coordinates, that you check against. You only act when a detection falls inside that box, so a person walking through a far corner is ignored. The right region depends entirely on where your camera sits and what you want to watch, so you set it by experiment for your own setup.

Webhooks: sending an alert

A webhook is a ready-made URL that lets your program post a message into a chat service. For Discord, you create a channel, open its integrations, add a webhook, and copy the URL. For Telegram, you create a bot to get a bot token and also find your chat ID. You paste these into a config file so your code can read them, then a small notify module has functions to send a text message or an image to whichever service you chose. Testing this connection on its own first, before wiring it into the camera, keeps problems isolated.

Filtering by label

The model detects many classes, person, bicycle, car, boat, and more, but you usually want to act on just one. By checking each detection's label and only reacting when it is person, you build a human alarm. Change the label and the same code counts cars on a street or watches for a bicycle in the garage. The list of what it can recognize comes from the pre-trained model's labels.

Debouncing false alarms

No model is 100 percent accurate, and a stray single-frame detection, a flicker, a moving curtain, can momentarily look like a person. If you alerted on every detection you would be flooded with false messages. The fix is a time threshold: only send an alert if a person stays in the region for at least a second or two. A real person is always there for many frames, so this simple rule filters out the fleeting mistakes while keeping the true events.

Working through it

Create a webhook. For Discord, add a webhook to a channel and copy its URL. For Telegram, make a bot for its token and find your chat ID. Do one or both.

Fill in the config file. Paste your webhook URL, or your bot token and chat ID, into the config file so the notify module can read them.

Test the connection alone. Run the notify script to send a test message and image. Confirm it arrives on your phone before adding the camera, so any issue is isolated to the messaging.

Add the region of interest. In the live detection script, define the region rectangle in pixel coordinates for your camera's view, and only consider detections inside it.

Trigger on a person, with a threshold. Check that the detected label is person and that the person has stayed in the region past your time threshold; then capture the frame and send it through your webhook.

Tune it. Adjust the region, the label, and the threshold. Make the saved filename include a timestamp so each alert keeps its own photo instead of overwriting.

Send a message and a photo via a Discord webhook

import requests

def send_discord_message(webhook_url, text):
    requests.post(webhook_url, data={"content": text})

def send_discord_image(webhook_url, image_path, caption=""):
    with open(image_path, "rb") as f:
        requests.post(webhook_url,
                      data={"content": caption},
                      files={"file": f})

# test it on its own before wiring in the camera
if __name__ == "__main__":
    url = "YOUR_WEBHOOK_URL"  # from the config file
    send_discord_message(url, "Hello from Raspberry Pi")
    send_discord_image(url, "sample.jpg", "test image")

These two functions post text and an image to a Discord channel. Running this file alone confirms the webhook works, so when detection fails to alert you later, you know the messaging is not the problem.