【OPENCV】单目视觉测距

1 解释说明

单目相机测距常用的方法就是相似三角形法。

注意:1in = 25.4mm

举个例子,假设在离相机距离 D = 45cm = (450/25.4=17.7in)的地方放一张标准的8.27in x 11.69英寸W = 11.69(23cm*16cm)的A4纸并且拍下一张照片。测量出照片中A4纸的像素宽度为 P = 874 像素。因此焦距 F 是:

                                                F = (874px x 17.7in) /11.69in = 1323

当相机移动靠近或者离远物体或者目标时,可以用相似三角形来计算出物体离相机的距离:

                                                           D’ = (W x F) / P

文字说明参考:单目摄像机测距(python+opencv)_花落知多少的博客-CSDN博客_单目相机测距        我的论文方向目前是使用单目摄像头实现机器人对人的跟随,首先单目摄像头与kinect等深度摄像头最大的区别是无法有效获取深度信息,那就首先从这方面入手,尝试通过图像获取摄像头与人的距离。        在网上看了几天关于摄像头标定和摄像头焦距等原理的文章,然后通过这篇文章真正启发了我:用python和opencv来测量目标到相机的距离  主要的测距的原理是利用相似三角形计算物体到相机...https://blog.csdn.net/m0_37811342/article/details/80394935

2 代码

import numpy as np
import cv2

KNOWN_DISTANCE = 17.7
KNOWN_WIDTH = 11.69
KNOWN_HEIGHT = 8.27

# 定义目标函数
def find_marker(image):
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 将彩色图转化为灰度图
    gray_img = cv2.GaussianBlur(gray_img, (5, 5), 0)    # 高斯平滑去噪
    edged_img = cv2.Canny(gray_img, 35, 125)     # Canny算子阈值化
    # 获取纸张的轮廓数据
    img, countours, hierarchy = cv2.findContours(edged_img.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    # print(len(countours))
    # 获取最大面积对应的点集
    c = max(countours, key=cv2.contourArea)    
    # 最小外接矩形
    rect = cv2.minAreaRect(c)      
    return rect


# 定义距离函数
def distance_to_camera(knownWidth, focalLength, perWidth):
    return (knownWidth * focalLength) / perWidth


# 计算摄像头的焦距(内参)
def calculate_focalDistance(img_path):
    first_image = cv2.imread(img_path)     
    # cv2.imshow('first image', first_image)
    # 获取矩形的中心点坐标,长度,宽度和旋转角度
    marker = find_marker(first_image)       
    print("org图片中A4纸的宽度:f%", marker[1][0])
    focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH  
    print('焦距 = ', focalLength)        
    return focalLength


# 计算摄像头到物体的距离
def calculate_Distance(image_path, focalLength_value):
    image = cv2.imread(image_path)
    # 获取矩形的中心点坐标,长度,宽度和旋转角度, marke[1][0]代表宽度
    marker = find_marker(image)     
    distance_inches = distance_to_camera(KNOWN_WIDTH, focalLength_value, marker[1][0])
    box = cv2.boxPoints(marker)
    # print("Box = ", box)
    box = np.int0(box)
    # print("Box = ", box)
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.drawContours(image, [box], -1, (0, 255, 0), 2)
    cv2.putText(image, "%.2fcm" % (distance_inches * 2.54), (image.shape[1] - 1000, image.shape[0] - 100),
                cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 255, 0), 3)
    cv2.imshow("img", image)


if __name__ == "__main__":
    img_path = "org.jpg"
    focalLength = calculate_focalDistance(img_path)
    calculate_Distance("test.jpg", focalLength)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    pass

org.jpg

test.jpg

结果图:

猜你喜欢

转载自blog.csdn.net/wss794/article/details/121021759
今日推荐