Ensuring the safety of workers is crucial in industrial settings. One effective method to enhance safety is by creating a computer vision system to identify “red zones,” where heavy machinery is passed around, and where workers need to be extremely cautious. 

This tutorial will guide you through the process of building a red zone detection system using computer vision. By the end of the guide, you will have a working model that can identify and highlight hazardous areas in real-time.

0:00
/0:13

Step 1. Build a Model

First, sign up for Roboflow and create an account.

Next, go to workspaces and create a project. Customize the project name and annotation group to your choice. Make sure to make an object detection project. 

Next, add your images. The images I used were found from this Youtube video. You can enter the Youtube URL into Roboflow to create your dataset quickly.


Then, add the classes you want your model to detect.

Next, start annotating your dataset. We recommend getting at least 50 annotated images before training your first model.


Draw the annotations using the bounding box feature in Roboflow. Repeat this step for each image. 


Lastly, generate a dataset version of your labeled images. Each version is unique and associated with a trained model so you can iterate on augmentation and data experiments.


Step 2. Create a Red Zone

Using Roboflows PolygonZone creator, you can create a red zone where workers should be wary of heavy machinery. Save the points in a variable named “zone” for now.

Step 3. Download needed libraries

Now that we’ve finished all the prerequisites of model building, we can start to code the application.

First, download the needed libraries.

!pip install roboflow pillow supervision numpy inference

Step 4. Import libraries

Next, import the libraries.

import supervision as sv
import cv2
from typing import Union, List, Optional
from inference.core.interfaces.camera.entities import VideoFrame
from inference import InferencePipeline
from google.colab.patches import cv2_imshow
from datetime import datetime

Make sure to add the polygon zone code.

import numpy as np
zone = np.array([[661, 1638],[1005, 2142],[1649, 1822],[1281, 1342],[665, 1638]])

Step 5. Add detection code

COLOR_ANNOTATOR = sv.ColorAnnotator()
LABEL_ANNOTATOR = sv.LabelAnnotator()

def on_prediction(
    predictions: Union[dict, List[Optional[dict]]],
    video_frame: Union[VideoFrame, List[Optional[VideoFrame]]],
) -> None:
    global zone
    if not isinstance(predictions, list):
        predictions = [predictions]
        video_frame = [video_frame]
    for prediction, frame in zip(predictions, video_frame):
        if prediction is None:
            continue

        # SOME PROCESSING
        image = frame.image
        detections = sv.Detections.from_inference(prediction)

        annotated_frame = image


        annotated_frame = COLOR_ANNOTATOR.annotate(
              scene = annotated_frame,
              detections = detections
        )
        annotated_frame = LABEL_ANNOTATOR.annotate(
                  scene = annotated_frame,
                  detections = detections,
        )        

        polyzone = sv.PolygonZone(
              polygon=zone,
          )
        
        label = "Clear"

        zone_presence = polyzone.trigger(detections)
        for presence in zone_presence:
            if presence:

                label = "Occupied"
                print("NOT SAFE")

        zone_annotated = sv.PolygonZoneAnnotator(
            zone=polyzone,
            color=sv.Color.RED,
            thickness=5,
        )

        annotated_frame = zone_annotated.annotate(
        scene=annotated_frame,
        label=label
        )

        start_point = (2450, 0)
        end_point = (2900, 300)

        cv2.rectangle(annotated_frame, start_point, end_point, (255, 255, 255), cv2.FILLED)

        text = label
        font = cv2.FONT_HERSHEY_SIMPLEX
        font_scale = 3
        font_color = (0, 0, 255)
        line_type = 5

        center_x = (start_point[0] + end_point[0]) // 2
        center_y = (start_point[1] + end_point[1]) // 2

        # Get the text size
        (text_width, text_height), baseline = cv2.getTextSize(text, font, font_scale, line_type)

        # Calculate the bottom-left corner of the text to center it
        text_x = center_x - text_width // 2
        text_y = center_y + text_height // 2

        # Add the text
        cv2.putText(annotated_frame, text, (text_x, text_y), font, font_scale, font_color, line_type)


        cv2.imshow("frame", annotated_frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

In this code snippet, we:

  • Get the predictions from each frame
  • Add different annotations to each frame using Roboflow Supervision
  • Add the polygon to the image
  • Check to see if any objects (such as the helmet or boots) are inside of the bounding box
  • Edits the top right box if any humans traits are detected within the red zone

Step 6. Piece Everything Together

pipeline = InferencePipeline.init(
 video_reference="VIDEO_PATH",
 model_id="PATH_TO_MODEL",
 max_fps = 30,
 confidence=0.8,
 api_key="YOUR_API_KEY",
 on_prediction=on_prediction,
)
pipeline.start()

Make sure you use the same video you sourced for your model.

Now you are able to detect if a worker is safe or not, depending on their position, as well as if they are in the red zone or not. 

Conclusion

By following these steps, you can create a robust red zone detection model that enhances worker safety by identifying dangerous areas. 

This guide has walked you through the process of setting up a model using Roboflow, defining red zones, and integrating the detection system with real-time video feeds.

For more computer vision projects, check out our other guides and resources.