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) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/797505.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Hadoop+python的物品租赁系统(带1w+文档)

基于SpringBootHadooppython的物品租赁系统(带1w文档) 基于SpringBootHadooppython的物品租赁系统(带1w文档) 物品租赁系统是电子、信息技术相结合,是一种必然的发展趋势。以互联网为基础,以服务于广大用户为目的,发展整体优势,扩…

Flutter实现局部刷新的几种方式

目录 前言 1.局部刷新的重要性 1.概念 2.重要性 2.局部刷新实现的几种方式 1.使用setState方法进行局部刷新 2.使用StatefulWidget和InheritedWidget局部刷新UI 3.ValueNotifier和ValueListenableBuilder 4.StreamBuilder 5.Provider 6.GetX 7.使用GlobalKey 前言 …

游戏三倍补帧工具 Lossless Scaling v2.9.0

运行时请将游戏窗口化或全屏 比如你的显示器是144hz 把游戏限制帧率到48帧后开启三倍补帧 允许撕裂和垂直同步一起来延迟更低 72,48,36,分别对应1/2,1/3,1/4,性能够的话(补帧后满144fps)就优先锁72fps&a…

自动驾驶中的人机互相接管问题讨论

一、背景 人机接管(human takeover)是指在自动驾驶过程中,当系统遇到超出其处理能力或预设安全阈值的情况时,将控制权交还给驾驶员的过程。这一环节的设计直接关系到自动驾驶技术的实用性与安全性,是目前研究和实践中…

深入解析双向链表与单向链表的区别:示例详解

文章目录 一、单向链表与双向链表的定义及结构二、单向链表与双向链表的区别示例插入操作删除操作 三、完整示例四、总结 链表是一种灵活的数据结构,它通过指针连接一系列节点,实现了动态数组的特性。在众多链表类型中,单向链表和双向链表是最…

vue2学习笔记2-老规矩,从Hello World开始,了解Vue实例和模板

想要实现的效果&#xff1a;在页面上展示“Hello&#xff0c;World”字符串 1、准备一个【容器】div 想要把“Hello&#xff0c;World”放置在页面上&#xff0c;首先需要准备一个HTML的块级元素div&#xff0c;来承接内容。所以&#xff0c;我们先在<body>中定义<di…

Android12 MultiMedia框架之GenericSource extractor

前面两节学习到了各种Source的创建和extractor service的启动&#xff0c;本节将以本地播放为例记录下GenericSource是如何创建一个extractor的。extractor是在PrepareAsync()方法中被创建出来的&#xff0c;为了不过多赘述&#xff0c;我们直接从GenericSource的onPrepareAsyn…

《昇思25天学习打卡营第17天|K近邻算法实现红酒聚类》

K近邻算法原理介绍 K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;最初由 Cover和Hart于1968年提出是机器学习最基础的算法之一。它正是基于以上思想&#xff1a;要确定一个样本的类别&#xff0c;可以计算它与所…

springboot在线教育平台-计算机毕业设计源码68562

摘要 在数字化时代&#xff0c;随着信息技术的飞速发展&#xff0c;在线教育已成为教育领域的重要趋势。为了满足广大学习者对于灵活、高效学习方式的需求&#xff0c;基于Spring Boot的在线教育平台应运而生。Spring Boot以其快速开发、简便部署以及良好的可扩展性&#xff0c…

TypeError: Rule.__init__() got an unexpected keyword argument ‘method‘报错的解法

报错如图&#xff1a; 原代码&#xff1a; app.route(/query,method[get,post]) 解决办法很简单&#xff0c;method后加s​​​​​​​ app.route(/query,methods[get,post]) 重新执行代码&#xff0c;不报错了

C++ QT开发 学习笔记(1)

C QT开发 学习笔记(1) 考试系统 创建项目 新建Qt桌面应用程序&#xff0c;项目名&#xff1a;ExamSys。 类信息&#xff1a;类名LoginDialog继承自QDialog &#xff08;1&#xff09; ExamSys.pro 工程文件&#xff0c;包含当前工程的相关信息。 QDialog 是 Qt 框架中用…

大数据基础:Hadoop之MapReduce重点架构原理

文章目录 Hadoop之MapReduce重点架构原理 一、MapReduce概念 二、MapReduce 编程思想 2.1、Map阶段 2.2、Reduce阶段 三、MapReduce处理数据流程 四、MapReduce Shuffle 五、MapReduce注意点 六、MapReduce的三次排序 Hadoop之MapReduce重点架构原理 一、MapReduce概…

JavaScript中的面向对象编程

OPP在JavaScript的表现方式&#xff1a;原型 传统的OPP&#xff1a;类 ● 对象&#xff08;实例&#xff09;由类实例化&#xff0c;类的功能类似于蓝图&#xff0c;通过蓝图来实现建筑&#xff08;实例&#xff09; ● 行为&#xff08;方法&#xff09;从类复制到所有实例 …

【2-1:RPC设计】

RPC 1. 基础1.1 定义&特点1.2 具体实现框架1.3 应用场景2. RPC的关键技术点&一次调用rpc流程2.1 RPC流程流程两个网络模块如何连接的呢?其它特性RPC优势2.2 序列化技术序列化方式PRC如何选择序列化框架考虑因素2.3 应用层的通信协议-http2.3.1 基础概念大多数RPC大多自…

并查集——AcWing 239. 奇偶游戏

目录 并查集 定义 运用情况 注意事项 解题思路 AcWing 239. 奇偶游戏 题目描述 运行代码 代码思路 改进思路 并查集 定义 并查集&#xff08;Disjoint Set Union&#xff0c;简称DSU&#xff09;&#xff0c;是一种树形的数据结构&#xff0c;常用于处理一些不交集…

jvm 07 GC算法,内存池

01 垃圾判断算法 1.1引用计数算法 最简单的垃圾判断算法。在对象中添加一个属性用于标记对象被引用的次数&#xff0c;每多一个其他对象引用&#xff0c;计数1&#xff0c; 当引用失效时&#xff0c;计数-1&#xff0c;如果计数0&#xff0c;表示没有其他对象引用&#xff0c;…

一文详解DDL同步及其应用场景

目录 一、什么是DDL&#xff1f; 二、什么是DDL同步&#xff1f; 三、DDL同步的痛点 1、缺少自动DDL同步机制 2、缺少DDL变更监测预警 四、解决方案 五、应用场景及案例 案例一 案例二 案例三 在现代数据管理中&#xff0c;数据库的结构变更频繁且不可避免&#xff0c;特别是在…

计算机视觉之Vision Transformer图像分类

Vision Transformer&#xff08;ViT&#xff09;简介 自注意结构模型的发展&#xff0c;特别是Transformer模型的出现&#xff0c;极大推动了自然语言处理模型的发展。Transformers的计算效率和可扩展性使其能够训练具有超过100B参数的规模空前的模型。ViT是自然语言处理和计算…

卑微的LDAR第三方检测公司该如何应对政府强制使用LDAR系统

最近两年各个地方环保局和园区都再上LDAR管理系统&#xff0c;本来上系统是好事&#xff0c;监管企业和第三方检测公司规范开展检测业务&#xff0c;但是部分系统给第三方检测企业增加了大量的工作量&#xff0c;有的甚至由于系统不稳定&#xff0c;造成企业无法开展工作&#…

各种Attention|即插即用|适用于YoloV5、V7、V8、V9、V10(一)

摘要 本文总结了各种注意力&#xff0c;即插即用&#xff0c;方便大家将注意力加到自己的论文中。 SE import torch from torch import nn class SEAttention(nn.Module): """ SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;中的注意力…