我目前正在编写一个在 python 上运行的代码,该代码的想法是准确测量物体的高度和宽度,无论相机与物体的距离如何,这意味着如果物体的高度和宽度为 5 厘米5 厘米,无论距离进一步或接近,相机仍应显示该测量结果。
下面是我尝试过的代码,谷歌搜索和浏览论坛都说需要一些公式,但我似乎无法理解这个想法。
import cv2
import numpy as np
def get_object_dimensions(contour, reference_width, reference_distance):
# Calculate the bounding box around the contour
x, y, w, h = cv2.boundingRect(contour)
# Assuming the camera calibration is done, convert pixel dimensions to centimeters
pixel_width = w
pixel_height = h
# You may need to calibrate these conversion factors based on your camera and setup
width_cm = pixel_width * pixel_to_cm_width
height_cm = pixel_height * pixel_to_cm_height
# Calculate the current distance based on the reference width and current measured width
current_distance = (reference_width * reference_distance) / width_cm
return width_cm, height_cm, current_distance
# Camera setup
cap = cv2.VideoCapture(0) # Use 0 for the default camera
# Calibration factors for converting pixel dimensions to centimeters
pixel_to_cm_width = 0.1 # Adjust based on your calibration
pixel_to_cm_height = 0.1 # Adjust based on your calibration
# Initial reference distance (distance at which the width measurement is accurate)
initial_reference_distance = 50.0 # Adjust based on your setup
reference_width = 10.0 # Adjust based on your setup
while True:
# Capture a frame
ret, frame = cap.read()
# Convert the frame to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Apply Gaussian blur to reduce noise and improve edge detection
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Perform edge detection using Canny
edges = cv2.Canny(blurred, 50, 150)
# Find contours in the edged image
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Iterate over detected contours
for contour in contours:
# Ignore small contours
if cv2.contourArea(contour) > 1000:
# Draw a bounding box around the contour
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Get object dimensions and current distance in centimeters
width_cm, height_cm, current_distance = get_object_dimensions(contour, reference_width, initial_reference_distance)
# Display the dimensions and current distance
cv2.putText(frame, f'Width: {width_cm:.2f} cm', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.putText(frame, f'Height: {height_cm:.2f} cm', (x, y + h + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.putText(frame, f'Distance: {current_distance:.2f} cm', (x, y + h + 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# Display the frame
cv2.imshow('Object Detection and Measurement', frame)
# Break the loop when 'q' is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release the camera and close all windows
cap.release()
cv2.destroyAllWindows()
结果如下图
如结果所示,即使距离发生变化,高度和宽度也会发生变化,任何帮助或建议都将受到赞赏!谢谢你。
你所要求的是不可能的。您要么需要知道距离才能根据物体的角度大小正确获取物体的尺寸,要么需要事先知道尺寸才能知道距物体的距离。 例如,太阳和月亮在天空中看起来大小相同,尽管太阳比月亮大几个数量级,但它恰好距离地球远几个数量级,这意味着它最终会具有相同的角度大小。
如果您不相信我,请拍一张某物的照片并使用您想要的任何方法手动计算其尺寸。
角距离的公式是众所周知的,你可以在网上找到它们