Measuring distance with a normal camera

Reprinted, fixed some minor errors.

In recent years, due to the continuous maturity of technologies such as drones and unmanned vehicles, there are more and more places that need to use real-time ranging, such as positioning, obstacle avoidance, speed measurement, etc. Compared with other ranging methods, monocular Ranging is to use a camera for video shooting and find the object to be measured in the image. This series of actions involves the recognition of objects, the structure of the camera, some knowledge of coordinate transformation, and the acquisition of distance is a very broad topic. Using the camera to measure distance is one of the directions, including monocular distance measurement and binocular measurement. Distance, structured light ranging and other methods.

Here, we mainly use a camera to solve the ranging problem by building a certain model.

1. Installation package

python 3.7 或以上
pip install cvzone
pip install mediapipe

2. Imaging principle

The model of the monocular camera can be approximately considered as a pinhole model, as shown in the figure

  • f: focal length

  • W: The actual width of the target object

  • w: width after imaging

  • d: the actual distance or depth between the object and the camera

The relationship between f, d, w, and W is as follows:

2.1 Camera Calibration

Our goal is to calculate the distance d of the target object, but the premise needs to know the focal length f, the calculation formula of the focal length f is as follows:

We can place an object at a known distance d from the camera, and at the same time we know the width W of the actual object, and the width w after the image, so that the above formula can calculate the focal length f.

2.2 Calculate the distance d of the object

After the camera is calibrated, the value of the focal length f is known, and the distance of the target object can be calculated according to the following formula:

If we know the W of the known object and the w after imaging, we can calculate the distance d of the target object in real time.

3 Case introduction

In this paper, the distance between the two eyes of the human face is used as the W of the target object. Since the distance between the two eyes of men is 64mm and the distance between the two eyes of women is 62mm, we take the average value of 63 as the distance between the eyes of the face. Therefore, to calculate the distance of the face, you only need to know the w after imaging to calculate the distance d between the face and the camera.

3.1 Detecting faces

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector
# 检测人脸
detector=FaceMeshDetector(maxFaces=1)
cap=cv2.VideoCapture(0)
while True:
success,img =cap.read()
img,faces=detector.findFaceMesh(img)
cv2.imshow("Image",img)
cv2.waitKey(1)

There may be errors here

AttributeError: module 'mediapipe.python.solutions.face_mesh' has no attribute 'FACEMESH_CONTOURS', just enter the error file FaceMeshModule.py and change it to FACE_CONNECTIONS

3.2 Calculate the distance between the eyes in the video

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector
# 检测人脸
detector=FaceMeshDetector(maxFaces=1)
cap=cv2.VideoCapture(0)
while True:
success,img =cap.read()
img,faces=detector.findFaceMesh(img)
if faces:
face =faces[0]
pointLeft=face[145]     #左眼中心点坐标
pointRight=face[375]    #右眼中心点坐标
# 绘制人眼中心点并连线
cv2.line(img,pointLeft,pointRight,(0,200,0),3)
cv2.circle(img,pointLeft,5,(255,0,255),cv2.FILLED)
cv2.circle(img,pointRight,5,(255,0,255),cv2.FILLED)
w,_=detector.findDistance(pointLeft,pointRight)
print(w)
cv2.imshow("Image",img)
cv2.waitKey(1)

3.3 Camera Calibration: Calculating Focal Length f

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector
# 检测人脸
detector=FaceMeshDetector(maxFaces=1)
cap=cv2.VideoCapture(0)
while True:
success,img =cap.read()
img,faces=detector.findFaceMesh(img)
if faces:
face =faces[0]
pointLeft=face[145]     #左眼中心点坐标
pointRight=face[375]    #右眼中心点坐标
# 绘制人眼中心点并连线
cv2.line(img,pointLeft,pointRight,(0,200,0),3)
cv2.circle(img,pointLeft,5,(255,0,255),cv2.FILLED)
cv2.circle(img,pointRight,5,(255,0,255),cv2.FILLED)
w,_=detector.findDistance(pointLeft,pointRight)  #保持人脸到摄像头50cm下测量
# Finding the Focal Length
W=6.3 # 真实人脸间距 6.3cm
d= 50 # 保持人脸到摄像头50cm的距离
f=(w*d)/W
print(f)
cv2.imshow("Image",img)
cv2.waitKey(1)

3.4 Calculating the distance from the face to the camera

According to the result of camera calibration in the previous step. Suppose the focal length f of the camera is calculated

f = 560 mm

According to the formula:

The real-time distance from the face to the camera can be calculated.

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector

# 检测人脸
detector=FaceMeshDetector(maxFaces=1)
cap=cv2.VideoCapture(0)

while True:
    success,img =cap.read()
    img,faces=detector.findFaceMesh(img)
    if faces:
        face =faces[0]
        pointLeft=face[145]     #左眼中心点坐标
        pointRight=face[375]    #右眼中心点坐标
        # 绘制人眼中心点并连线
        cv2.line(img,pointLeft,pointRight,(0,200,0),3)
        cv2.circle(img,pointLeft,5,(255,0,255),cv2.FILLED)
        cv2.circle(img,pointRight,5,(255,0,255),cv2.FILLED)
        w,_=detector.findDistance(pointLeft,pointRight)  #保持人脸到摄像头50cm下测量
        W=6.3 # 真实人脸间距 6.3cm
        # Finding the Focal Length
        # d= 50 # 保持人脸到摄像头50cm的距离
        # f=(w*d)/W
        # print(f)

        # Finding distance
        f = 840  # 根据相机标定的结果
        d = (W * f)/w
        print(d)
        cvzone.putTextRect(img,f'Depth:{int(d)}cm',(face[10][0]-100,face[10][1]-50),scale=2)
            
    cv2.imshow("Image",img)
    cv2.waitKey(1)

It can be seen that d gets smaller and smaller when the face is closer to the camera, and d gets smaller and smaller when it is far away from the camera. In this way, the distance between the face and the camera can be roughly judged. Although not as accurate as a depth camera , in some scenes, this calculated distance can be applied with good results

Guess you like

Origin blog.csdn.net/Cretheego/article/details/129109860