使用 OpenCV 进行实时距离估计 – Python
先决条件: OpenCV简介
在本文中,我们将了解如何使用Python的OpenCV 计算网络摄像头的距离。通过使用它,人们可以处理图像和视频以识别物体、面孔,甚至是人类的笔迹。本文重点介绍检测对象。
我们将在本文中使用称为 haar 级联的东西进行对象检测。
哈尔瀑布
Haar Cascade 分类器是一种有效的目标检测方法。 Haar Cascade 是一种基于机器学习的方法,其中使用大量正负图像来训练分类器。
该文件可以从这里下载:Forrontalface。
距离估计步骤:
- 捕捉参考图像:测量物体(人脸)到相机的距离,捕捉参考图像并记下测量的距离
- 测量对象(人脸)宽度,确保保留参考图像和对象(人脸)宽度的测量单位。我的参考图片
人脸检测:
此函数将检测人脸并以像素值返回人脸宽度。这个人脸数据函数只接受一个参数,即哪个图像,返回以像素为单位的人脸宽度,这是焦距查找器和距离查找器函数。
Python3
def face_data(image):
face_width = 0 # making face width to zero
# converting color image ot 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
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
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
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 ot 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 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 the windows that are opened
cv2.destroyAllWindows()
焦距查找器:
焦距查找器函数三个参数:
- Measured_distance:拍摄参考图像时相机到物体的距离, Known_distance = 72.2 #centimeter
- Real_width:它测量的是现实世界中物体的宽度,这里我们测量的是人脸的宽度,大约为Known_width =14.3 #centimeter
- Width_in_rf_image:它是图像/帧中对象的宽度,以像素为单位
此函数将返回焦距,用于查找距离。
蟒蛇3
# 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
测距仪:
这个函数有三个参数。
- 以像素为单位的焦距,这是焦距查找器函数的返回值
- Real_width 测量现实世界中物体的宽度,这里我们测量的是人脸的宽度,大约为known_width =14.3 #centimete r
- Width_in_rf_image 是图像/帧中对象的宽度,以像素为单位
测距仪函数将返回以厘米为单位的距离
蟒蛇3
# 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
下面是完整的实现:
蟒蛇3
# 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 ot 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 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 the windows that are opened
cv2.destroyAllWindows()
输出: