Distance(webcam) Estimation with single-camera 📷 OpenCV-python

AiPhile
4 min readDec 18, 2021

--

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 called triangle similarity, for object detection, we will keep that simple by just using face detection of OpenCV.

Demo Video for Distance Estimation

Codebase

The code will be available on my GitHub Repository here I am going to explain important code snippets, In case you need help, just leave a comment, and 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 paste the following command in the terminal and you are done, Installation.

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.

You must take care of a few things while capturing the reference image.

  • The resolution of the image (frame) must be the same, as in the reference image I have kept to the defaults of OpenCV which is(640, 480)
  • Keep the camera straight as possible while capturing the reference images.
  • Measure distance(KNOWN_DISTANCE)from the object camera, note it down and capture the image which is set to 76.2 centimetres.
  • Measure the width(KNOWN_WIDTH) of the object, note it down as well, for me, it is 14.3 centimetres.

Important Variables

  • KNOWN_DISTANCE: it is the distance for the object camera 📷 in the real world.
  • KNOWN_WIDTH: It is the measured width of an object in real-world
  • face_width_in_frame: It is the width of the face in an image(frame), which provide by a face detector, measured in pixels
KNOWN_DISTANCE = 76.2  # centimeter
KNOWN_WIDTH = 14.3 # centimeter

Object Detection (face)

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

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

the Face data function takes only one argument which is an image.

def face_data(image):
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 centimetres
  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, it is just a mapping.

here is the code :

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 centimetres
  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

here is the code:

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

That is pretty much it, here is a video tutorial that explains everything in great detail,

here is a more accurate version of this algorithm, here is GitHub Repository

There is another way (Aruco Markers )to find a distance that is more convenient and accurate, with a single camera(ordinary webcam of the laptop), we will take look at them in an upcoming post.

Reference:

--

--