如何使用opencv测量距离变化的物体高度和宽度?

问题描述 投票:0回答:1

我目前正在编写一个在 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() 

结果如下图

如结果所示,即使距离发生变化,高度和宽度也会发生变化,任何帮助或建议都将受到赞赏!谢谢你。

python opencv edge-detection
1个回答
0
投票

你所要求的是不可能的。您要么需要知道距离才能根据物体的角度大小正确获取物体的尺寸,要么需要事先知道尺寸才能知道距物体的距离。 例如,太阳和月亮在天空中看起来大小相同,尽管太阳比月亮大几个数量级,但它恰好距离地球远几个数量级,这意味着它最终会具有相同的角度大小。

如果您不相信我,请拍一张某物的照片并使用您想要的任何方法手动计算其尺寸。

角距离的公式是众所周知的,你可以在网上找到它们

© www.soinside.com 2019 - 2024. All rights reserved.