opencv 中如何通过欧式距离估算实际距离(厘米)

1:这个方法个人测试觉得是正确的,误差较小,目前满足我当前的需求,如果方法不对,请大家评论,完善。

2:确保拍摄的参照物是垂直的,如果不垂直,就会有误差,不垂直的角度越大,误差越大。

实际中主要是利用无人机拍摄的俯视图,计算边缘到特定点的距离。

3:使用棋盘格作为物理参照物,如下

4:代码

import cv2
import numpy as np
import glob
def get_K_and_D(checkerboard, imgsPath):

    CHECKERBOARD = checkerboard
    subpix_criteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 0.01)
    calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_CHECK_COND+cv2.fisheye.CALIB_FIX_SKEW
    objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
    objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)*50
    
    _img_shape = None
    #print(objp)
    #objp+=200
    objpoints = []
    imgpoints = []
    images = glob.glob(imgsPath + '/*.jpg')
    for fname in images:
        img = cv2.imread(fname)
        
        if _img_shape == None:
            _img_shape = img.shape[:2]
        else:
            assert _img_shape == img.shape[:2], "All images must share the same size."

        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD,cv2.CALIB_CB_ADAPTIVE_THRESH) #+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)
        if ret == True:
            objpoints.append(objp)
            cv2.cornerSubPix(gray,corners,(5,5),(-1,-1),subpix_criteria)
            imgpoints.append(corners)
            #print(images)
    N_OK = len(objpoints)
    #print(objpoints)
    K = np.zeros((3, 3))
    D = np.zeros((4, 1))
    rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
    tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
    rms, _, _, _, _ = cv2.fisheye.calibrate(
        objpoints,
        imgpoints,
        gray.shape[::-1],
        K,
        D,
        rvecs,
        tvecs,
        calibration_flags,
        (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6)
    )



            
    DIM = _img_shape[::-1]
    print("Found " + str(N_OK) + " valid images for calibration")
    print("DIM=" + str(_img_shape[::-1]))
    print("K=np.array(" + str(K.tolist()) + ")")
    print("D=np.array(" + str(D.tolist()) + ")")
    print("rms",rms)
    return DIM, K, D,corners



if __name__ == '__main__':
    
    BORAD_HEIGHT=3
    BORAD_WIDTH=3
    radius = 1
    color = (0, 0, 255)  # BGR格式,红色
    thickness = 2

    DIM, K, D,corners = get_K_and_D((BORAD_HEIGHT, BORAD_WIDTH), './distance')   
    dst_img=cv2.imread("./distance/img_dst_distance.jpg")
    
    cnt=0
    print(corners)
    for index in range(len(corners)): 
        x, y = corners[index][0]
        color = (0, 0, 255)  # BGR格式,红色
        cv2.putText(dst_img, str(cnt), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1,color, thickness)
        color = (0, 255, 255)  # BGR格式,红色
        cv2.circle(dst_img,(int(x),int(y)), radius, color, thickness)
        cnt+=1

    dist_total=0
    for i in range(BORAD_HEIGHT):
        print(i * BORAD_WIDTH,(i+1) * BORAD_WIDTH-1)
        print(corners[i * BORAD_WIDTH,:])
        dist = cv2.norm(corners[i * BORAD_WIDTH,:], corners[(i+1) * BORAD_WIDTH-1,:], cv2.NORM_L2)
        dist_total += dist / (BORAD_WIDTH - 1)

   
    dist_square = dist_total / BORAD_HEIGHT
    print("dst_img.shape:",dst_img.shape)
    print("dist_square:",dist_square)
    realy_board_length=13.5/2 #厘米,13.5是从尺子测量出来2个正方形边长的长度,所以单个要除以2
    realy_H=dst_img.shape[0]*realy_board_length/dist_square
    realy_W=dst_img.shape[1]*realy_board_length/dist_square
    print("realy_H",realy_H)
    print("realy_W",realy_W)
    ret=1
    cv2.drawChessboardCorners(dst_img, (BORAD_HEIGHT,BORAD_WIDTH), corners, ret)
    cv2.imshow("org_img", dst_img)
    cv2.waitKey(0) 

相关推荐

  1. 如何实现单片机与手机的远距离通信

    2024-07-11 05:26:05       33 阅读
  2. 如何利用单声道音频进行说话人距离估计

    2024-07-11 05:26:05       30 阅读
  3. OpenCV构建交互式图像距离测量工具

    2024-07-11 05:26:05       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 05:26:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 05:26:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 05:26:05       58 阅读
  4. Python语言-面向对象

    2024-07-11 05:26:05       69 阅读

热门阅读

  1. 从像素角度出发使用OpenCV检测图像是否为彩色

    2024-07-11 05:26:05       28 阅读
  2. ES索引模板

    2024-07-11 05:26:05       21 阅读
  3. ”极大似然估计“和”贝叶斯估计“思想对比

    2024-07-11 05:26:05       24 阅读
  4. 理解Gunicorn:Python WSGI服务器的基石

    2024-07-11 05:26:05       24 阅读
  5. C++函数模板学习

    2024-07-11 05:26:05       19 阅读
  6. 探索Perl的自动清洁工:垃圾收集机制全解析

    2024-07-11 05:26:05       21 阅读
  7. Kruskal

    2024-07-11 05:26:05       23 阅读
  8. C++入门

    C++入门

    2024-07-11 05:26:05      21 阅读
  9. Spring框架配置进阶_自动装配(XML和注解)

    2024-07-11 05:26:05       21 阅读
  10. xml CDATA

    2024-07-11 05:26:05       23 阅读
  11. XML Schema 杂项数据类型

    2024-07-11 05:26:05       24 阅读
  12. 我的前端实习之旅

    2024-07-11 05:26:05       22 阅读