Distance Estimation with single-camera OpenCV python

·

3 min read

So right then, how can we find the distance from the object camera in real-time with the webcam at decent accuracy, without requiring any extra hardware like a stereo camera or depth sensor at all?

This blog post will cover the implementation of a simple algorithm call triangle similarity, for object detection, we will keep that simple by just using face detection of OpenCV.

Codebase

The code will be available on my GitHub Repository, where I am going to explain important code snippets, In case you need help, just leave a comment, I will be happy to help you out 😎

Requirements

Requirements are pretty simple you need Python, OpenCV, and Haar-cascade files for face detection.

Having python installed on your machine, just open the terminal, and following in the terminal and you are done.

pip install opencv-python # on Linux turn pip to pip3

Capture the Reference Image

The reference image, allows us to map the real world(object plane) since we lose the depth of the object when we capture it in 2D space(image), otherwise, we need a special camera, that can capture the depth since we want to use our webcam, the reference image is required, you need to take care of few things, so accuracy won’t drop, you can use mine reference image it won’t affect much, but I will recommend to capture it yourself to get more accuracy.

  • Same Size

  • Recommend using the same camera for distance estimation and for capturing reference images.

  • keep the camera straight as possible while capturing the reference images.

here is a script for capturing a reference image

Measure distance from object camera, note it down, and capture the image,

Measure the width of the object, and note it down as well.

Important Variables

# distance from camera to object(face) measured
KNOWN_DISTANCE = 76.2  # centimeter
# width of face in the real world or Object Plane
KNOWN_WIDTH = 14.3  # centimeter

Object Detection (face)

I am using face detection here, it is implacable to every object detector, just follow the procedure.

face detection using Opencv python, here is the function which detects the face and returns face width, in pixels

# face detector function 
def face_data(image):
    '''
    This function Detect the face 
    :param Takes image as argument.
    :returns face_width in the pixels
    '''

    face_width = 0
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray_image, 1.3, 5)
    for (x, y, h, w) in faces:
        cv2.rectangle(image, (x, y), (x+w, y+h), WHITE, 1)
        face_width = w

    return face_width

Focal Length Finder

The Focal Length finder Function Tacks Three Arguments:

  1. Measured_distance is the distance from the camera to the object while capturing the Reference image, Known_distance = 72.2 # centimetres

  2. Real_width Its the measured width of an object in real-world, here I measure the width of the face which is around Known_width =14.3 # centimeters

  3. Width_in_rf_image is the width of the object in the image/frame it will be in pixels

This function will return the focal length, which is used to find the distance.

# focal length finder function
def FocalLength(measured_distance, real_width, width_in_rf_image):
    focal_length = (width_in_rf_image* measured_distance)/ real_width
    return focal_length

Distance Finder

This Function Tasks Three Arguments,

  1. Focal length in pixel, which is a return from the Focal length finder function

  2. Real_width Its measures the width of an object in real-world, here I measure the width of the face which is around Known_width =14.3 # centimetre

  3. Width_in_rf_image is the width of the object in the image/frame it will be in pixels

The distance finder function will return the distance in the centimetres

# distance estimation function
def Distance_finder(Focal_Length, real_face_width, face_width_in_frame):
    distance = (real_face_width * Focal_Length)/face_width_in_frame
    return distance

You can also create a face following a Robot using Distance Estimation