Open In App

Realtime Distance Estimation Using OpenCV – Python

Last Updated : 03 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Introduction to OpenCV

In this article, we are going to see how to calculate the distance with a webcam using OpenCV in Python. By using it, one can process images and videos to identify objects, faces, or even the handwriting of a human. This article focuses on detecting objects.

We will do object detection in this article using something known as haar cascades.

Haar Cascades

Haar Cascade classifiers are an effective way for object detection. Haar Cascade is a machine learning-based approach where a lot of positive and negative images are used to train the classifier. 

The file can be downloaded from here:  Forrontalface.

Steps for Distance Estimation:

  • Capture Reference Image: Measure the distance from the object(face) to the camera, capture a Reference image and note down the measured distance
  • Measure the object (face) width, make sure that measurement units are kept for reference image and object(face) width. Mine Reference Image

Face Detection:

This function will detect the face and return the face width in the pixels values. This face data function simply takes one argument, which image, returns the face width in the pixels, which is a requirement for the focal length finder and distance finder function. 

Python3




def face_data(image):
  
    face_width = 0  # making face width to zero
  
    # converting color image to gray scale image
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  
    # detecting face in the image
    faces = face_detector.detectMultiScale(gray_image, 1.3, 5)
  
    # looping through the faces detect in the 
    # image getting coordinates x, y ,
    # width and height
    for (x, y, h, w) in faces:
  
        # draw the rectangle on the face
        cv2.rectangle(image, (x, y), (x+w, y+h), GREEN, 2)
  
        # getting face width in the pixels
        face_width = w
  
    # return the face width in pixel
    return face_width


Focal Length Finder:

The Focal Length finder Function Tacks Three Arguments: 

  1. Measured_distance: It is the distance from the camera to object while capturing the Reference image, Known_distance = 72.2 #centimeter
  2. Real_width: Its measure the width of an object in real-world, here we measure the width of the face which is around Known_width =14.3 #centimeter
  3. Width_in_rf_image: It 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. 

Python3




# 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 has three arguments.

  1. Focal length in pixel, which is a return from the Focal length finder function
  2. Real_width measures the width of an object in real-world, here we measure the width of the face  which is around Known_width =14.3 #centimeter
  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 centimeters

Python3




# 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


Below is the full implementation:

Python3




# install opencv "pip install opencv-python"
import cv2
  
# distance from camera to object(face) measured
# centimeter
Known_distance = 76.2
  
# width of face in the real world or Object Plane
# centimeter
Known_width = 14.3
  
# Colors
GREEN = (0, 255, 0)
RED = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
  
# defining the fonts
fonts = cv2.FONT_HERSHEY_COMPLEX
  
# face detector object
face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
  
# focal length finder function
def Focal_Length_Finder(measured_distance, real_width, width_in_rf_image):
  
    # finding the focal length
    focal_length = (width_in_rf_image * measured_distance) / real_width
    return focal_length
  
# 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 the distance
    return distance
  
  
def face_data(image):
  
    face_width = 0  # making face width to zero
  
    # converting color image to gray scale image
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  
    # detecting face in the image
    faces = face_detector.detectMultiScale(gray_image, 1.3, 5)
  
    # looping through the faces detect in the image
    # getting coordinates x, y , width and height
    for (x, y, h, w) in faces:
  
        # draw the rectangle on the face
        cv2.rectangle(image, (x, y), (x+w, y+h), GREEN, 2)
  
        # getting face width in the pixels
        face_width = w
  
    # return the face width in pixel
    return face_width
  
  
# reading reference_image from directory
ref_image = cv2.imread("Ref_image.png")
  
# find the face width(pixels) in the reference_image
ref_image_face_width = face_data(ref_image)
  
# get the focal by calling "Focal_Length_Finder"
# face width in reference(pixels),
# Known_distance(centimeters),
# known_width(centimeters)
Focal_length_found = Focal_Length_Finder(
    Known_distance, Known_width, ref_image_face_width)
  
print(Focal_length_found)
  
# show the reference image
cv2.imshow("ref_image", ref_image)
  
# initialize the camera object so that we
# can get frame from it
cap = cv2.VideoCapture(0)
  
# looping through frame, incoming from 
# camera/video
while True:
  
    # reading the frame from camera
    _, frame = cap.read()
  
    # calling face_data function to find
    # the width of face(pixels) in the frame
    face_width_in_frame = face_data(frame)
  
    # check if the face is zero then not 
    # find the distance
    if face_width_in_frame != 0:
        
        # finding the distance by calling function 
        # Distance finder function need 
        # these arguments the Focal_Length,
        # Known_width(centimeters),
        # and Known_distance(centimeters)
        Distance = Distance_finder(
            Focal_length_found, Known_width, face_width_in_frame)
  
        # draw line as background of text
        cv2.line(frame, (30, 30), (230, 30), RED, 32)
        cv2.line(frame, (30, 30), (230, 30), BLACK, 28)
  
        # Drawing Text on the screen
        cv2.putText(
            frame, f"Distance: {round(Distance,2)} CM", (30, 35), 
          fonts, 0.6, GREEN, 2)
  
    # show the frame on the screen
    cv2.imshow("frame", frame)
  
    # quit the program if you press 'q' on keyboard
    if cv2.waitKey(1) == ord("q"):
        break
  
# closing the camera
cap.release()
  
# closing the windows that are opened
cv2.destroyAllWindows()


Output:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads