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

news2024/9/24 7:19:10

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) 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

心电信号降噪前处理(MATLAB R2018)

心电信号降噪方法分析 (1)基线漂移的常用滤除法是拟合基线抵消法,此法先估计或提取信号基线,然后进行减法运算去掉信号中漂移成分,达到滤波的目的。抑制基线漂移的另一种方法是采用线性相位滤波器,因为基线…

什么是 GC Roots??一文带你看懂!!

什么是 GC Roots ? JVM 是如何判断哪些对象应该回收,哪些应该保留呢?GC Roots 堆是一个巨大的对象集合,其中包含许多对象实例。 这些对象在堆中有不同的引用层次。一些接口会被频繁调用,每秒生成大量对象。这些对象之间…

【网络安全】实验七(ISA防火墙的规则设置)

一、实验目的 二、配置环境 1、打开两台虚拟机,并参照下图,搭建网络拓扑环境,要求两台虚拟机的IP地址要按照图中的标识进行设置,并根据搭建完成情况,勾选对应选项。注:此处的学号本人学号的最后两位数字&a…

MVC之 Controller 》》 ModelState ValidationMessageFor ValidationSummary

ModelState是Controller的一个属性,可以被继承自System.Web.Mvc.Controller的那些类访问。它表示在一次POST提交中被提交到服务器的 键值对集合,每个记录到ModelState内的值都有一个错误信息集。尽管ModelState的名字中含有“Model”,但它只有…

Monorepo仓库管理策略之 Lerna

这里写目录标题 前言:一、简介二、新建项目使用安装生成结构 三、复用现有项目执行命令查看包 四、配置package相互引用导入现有的包 五、发布包确定项目版本发布项目添加项目到到git发布包到NPM包发布出错解决方案 五、实例代码 前言: 将大型代码仓库分…

中国光储充一体化行业:有望成为全球能源转型的重要驱动力

光储充一体化系统,又称微电网解决方案,系一种整合分布式光伏能源、用电负载管理、配电设施以及监控与保护设备的自给型能源供应体系。该系统核心组件包括光伏发电系统、储能装置及充电站,其工作原理为:光伏发电系统捕获太阳能并转…

Floyd判圈算法——寻找重复数(C++)

287. 寻找重复数 - 力扣(LeetCode) 题目描述 给定一个包含 n 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 ,返…

系统分析师-基础知识

基础知识 一、计算机组成与结构1、计算机系统基础知识1.1 计算机硬件组成1.2 中央处理单元(CPU)1.3 数据表示1.3.1 R进制转十进制:1.3.2 十进制转R进制: 1.4 校验码(3种校验码)1.4.1 基本知识1.4.2 奇偶校验…

Security认证要点速记

登录校验流程 springSecurity已经为我们默认实现了一个用不着的登录功能,我们需要自己实现个符合我们需求的登录功能,所以我们需要去了解默认登录功能的流程,对其中的部分进行替换 SpringSecurity底层就是过滤器链,包含实现了各种…

滑动变阻器在实际应用中需要注意哪些安全事项?

滑动变阻器在实际应用中,为了确保其正常运作及保护电路安全,需要注意以下安全事项: 一、了解并遵守规格参数 最大电阻值和允许通过的最大电流值:使用前,必须清楚滑动变阻器的最大电阻值和允许通过的最大电流值&#x…

RISC-V异常处理流程概述(2):异常处理机制

RISC-V异常处理流程概述(2):异常处理机制 一、异常处理流程和异常委托1.1 异常处理流程1.2 异常委托二、RISC-V异常处理中软件相关内容2.1 异常处理准备工作2.2 异常处理函数2.3 Opensbi系统调用的注册一、异常处理流程和异常委托 1.1 异常处理流程 发生异常时,首先需要执…

软件工程(下)

目录 需求工程 概述 需求获取 分层 获取方法 项目管理维度 需求开发---需求分析 UML(统一建模语言):平台无关、语言无关 UML 41视图 需求的定义、验证、跟踪、变更 需求定义 需求验证 需求跟踪 需求变更管理 软件系统建模 软件…

.NET周刊【7月第1期 2024-07-07】

国内文章 学习.NET 8 MiniApis入门 https://www.cnblogs.com/hejiale010426/p/18280441 MiniApis是ASP.NET Core中的轻量级框架,用最少的代码和配置创建HTTP API。其特点包括简洁明了、性能卓越、灵活多变、易于学习使用,并与ASP.NET Core生态系统完美…

深入了解java锁升级可以应对各种疑难问题

对于java锁升级,很多人都停留在比较浅层的表面理解,一定程度下也许够用,但如果学习其中的细节,我们更好地理解多线程并发时各种疑难问题的应对方式! 因此我将锁升级过程中可能涉及的大部分细节或者疑问都整合成了一篇…

01MFC建立单个文件类型——画线

文章目录 选择模式初始化文件作用解析各初始化文件解析类导向创建鼠标按键按下抬起操作函数添加一个变量记录起始位置注意事项代码实现效果图虚实/颜色线选择模式 初始化文件作用解析 运行: 各初始化文件解析 MFC(Microsoft Foundation Classes)是一个C++类库,用于在Win…

fm足球经理Football Manager 2022 for mac 下载安装包

《Football Manager 2022》(足球经理2022)是一款由Sports Interactive开发并由SEGA发行的足球管理模拟游戏。这款游戏让玩家扮演足球俱乐部的 manager(经理),负责球队的所有管理工作,包括战术制定、球员转会…

美业收银系统怎么选?哪些功能实用?美业门店管理系统|拓客系统

选择美业会员系统时,你可以考虑以下几个方面的功能来确定哪些对你最实用: 1.会员管理: 系统应该能够轻松管理会员资料、积分、消费记录等信息,以便更好地了解客户需求并提供个性化服务。 2.促销与营销工具: 包括发…

RS NGP804 直流电源

直流电源 R&S NGP804 -借助四核功率提升效率- R&SNGP800 直流电源系列共有五种不同型号,功率为 400 W 或 800 W,可在多种操作条件下提供最大功率。该电源系列具有两个或四个 200 W 输出通道,每通道的输出电压和电流可达 64 V 及 …

C++入门基础篇(下)

目录 6.引用 6.1 引用的特性 6.2 const引用 7.指针和引用的关系 8.内联函数 9.nullptr 6.引用 引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间, 它和它引⽤的变量共⽤同⼀块内存空间。比如&a…

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序 SSM 图书管理系统小程序 功能介绍 用户 登录 注册 首页 图片轮播 图书信息推荐 图书详情 赞 踩 评论 收藏 系统公告 公告详情 用户信息修改 我的待还 图书归还 催还提醒 我的收藏管理 意见反馈 管理员 登录 个人中心…