2021电子设计竞赛飞控视觉之openmv寻找方格中心

2023-05-16

写在前面

这是我在电赛飞控备赛期间写的一个小函数,功能是寻找目标点所在方格的中心。这样四旋翼在方格地图上移动一定距离之后就可以使用openmv将四旋翼辅助定位至目前所在方格的中心。今年G题刚出来的时候本来以为能用上这个函数进行辅助定位,但是后面补充说明中方格的线太细,无法使用,就没能用上这个方案,把这个分享给大家。
在这里插入图片描述

详述

整体思路是先使用openmv中寻找直线的函数,找到所有横线和竖线,并筛选出离目标点最近的两条横线和竖线,从而锁定方格中心。
寻找直线的函数如下
在这里插入图片描述
该函数使用霍夫变换返回所有直线对象,我们调用该函数,通过限制寻找直线的角度来找到图像中所有的横线和竖线

min_degree = 80
max_degree = 100
for l in img.find_lines(roi=(50,30,220,180),threshold = 900, theta_margin = 25, rho_margin = 25):
        if (min_degree <= l.theta()) and (l.theta() <= max_degree):
            img.draw_line(l.line(), color = (255, 0, 0))
            heng.append(l)
 for l in img.find_lines(roi=(50,30,220,180),threshold = 1000,theta_margin = 35, rho_margin = 25):
        if (30 >= l.theta()) or (l.theta() >= 150):
            img.draw_line(l.line(), color = (255, 0, 0))
            shu.append(l)

对于找到的每条直线,我们可以获得其角度theta值和视野左上角到直线的垂直距离rho值,示意图如下,对于openmv来说,图中的原点就是openmv视野的左上角。
在这里插入图片描述
由于我们寻找的都是横线和竖线,可以把rho值近似认为是横线的纵坐标值和竖线的横坐标值,并以此筛选出离目标点最近的两条横线和两条竖线。

if len(heng)>=2:
        heng1 = heng[0]



        for l in heng:
            if abs(l.rho()-my_place[0])<abs(heng1.rho()-my_place[0]):
                heng1 = l

        heng.pop(heng.index(heng1))
        #print(heng)
        heng2 = heng[0]
        for l in heng:
            if abs(l.rho()-my_place[0])<abs(heng2.rho()-my_place[0]):
                heng2 = l
        count.append(1)
if len(shu)>=2:
        shu1 = shu[0]



        for l in shu:
            if abs(abs(l.rho())-my_place[1])<abs(abs(shu1.rho())-my_place[1]):
                shu1 = l

        shu.pop(shu.index(shu1))
       # print(shu)
        shu2 = shu[0]
        for l in shu:
            if abs(abs(l.rho())-my_place[1])<abs(abs(shu2.rho())-my_place[1]):
                shu2 = l
        count.append(1)

找到离目标最近的两条横线和竖线之后,我首先想到的是将两条横线的rho值取平均作为方格中心的纵坐标,将两条竖线的rho值取平均作为方格中心的横坐标。但经过验证,即使在倾斜的角度很小的情况下,直接使用rho取平均的做法也会让最后的结果产生较大的误差。因此我最后采用了另一种思路,我们得到四根直线(两根离目标最近的横线和两根离目标最近的竖线)的角度theta值和rho值之后就可以写出这四根直线的方程,将横线的方程与竖线的方程两两组合联立,即可解出方格对角两个点的坐标,再用这两个对角的横纵坐标分别取平均就能得到方格中心的坐标。

 if  len(count)==2:
        center_y_1=(math.cos(shu1.theta()/180*3.14159)*heng1.rho()-math.cos(heng1.theta()/180*3.14159)*shu1.rho())/(math.sin(heng1.theta()/180*3.14159)*math.cos(shu1.theta()/180*3.14159)-math.sin(shu1.theta()/180*3.14159)*math.cos(heng1.theta()/180*3.14159))
        center_x_1=(math.sin(shu1.theta()/180*3.14159)*heng1.rho()-math.sin(heng1.theta()/180*3.14159)*shu1.rho())/(math.cos(heng1.theta()/180*3.14159)*math.sin(shu1.theta()/180*3.14159)-math.cos(shu1.theta()/180*3.14159)*math.sin(heng1.theta()/180*3.14159))
        center_y_2=(math.cos(shu2.theta()/180*3.14159)*heng2.rho()-math.cos(heng2.theta()/180*3.14159)*shu2.rho())/(math.sin(heng2.theta()/180*3.14159)*math.cos(shu2.theta()/180*3.14159)-math.sin(shu2.theta()/180*3.14159)*math.cos(heng2.theta()/180*3.14159))
        center_x_2=(math.sin(shu2.theta()/180*3.14159)*heng2.rho()-math.sin(heng2.theta()/180*3.14159)*shu2.rho())/(math.cos(heng2.theta()/180*3.14159)*math.sin(shu2.theta()/180*3.14159)-math.cos(shu2.theta()/180*3.14159)*math.sin(heng2.theta()/180*3.14159))
        center_x=(abs(center_x_1)+abs(center_x_2))/2
        center_y=(abs(center_y_1)+abs(center_y_2))/2

这个地方要注意直线对象返回的角度值theta和进行sin,cos运算的函数输入的角度一个是弧度制一个是角度值,需要进行一次转换。经验证,该方案效果较好。

最后

该函数其实不只可以在全方格的地图可以使用,在一些简单的方格迷宫中同样可以进行定位。
在这里插入图片描述

例如这样的一个方格迷宫,我们只需要调整好寻找直线函数的参数,就可以在这样只有三条边甚至两条边的“伪方格”中寻找方格中心,从而进行辅助定位。

整个函数如下:

def find_center(img):
    my_place=[120,160]
    heng=[]
    shu=[]
    center = []
    min_degree = 80
    max_degree = 100
    count=[]
###################找最靠近飞机坐标点的两条横线从而得出方框中心点纵坐标
    for l in img.find_lines(roi=(50,30,220,180),threshold = 900, theta_margin = 25, rho_margin = 25):
        if (min_degree <= l.theta()) and (l.theta() <= max_degree):
            img.draw_line(l.line(), color = (255, 0, 0))
            heng.append(l)
   # print("横线p值"heng.rho())
    if len(heng)>=2:
        heng1 = heng[0]
        for l in heng:
            if abs(l.rho()-my_place[0])<abs(heng1.rho()-my_place[0]):
                heng1 = l
        heng.pop(heng.index(heng1))
        #print(heng)
        heng2 = heng[0]
        for l in heng:
            if abs(l.rho()-my_place[0])<abs(heng2.rho()-my_place[0]):
                heng2 = l
        count.append(1)
        #center_y = (heng1.rho()+heng2.rho())/2
        #center.append(center_y)
        #print(heng1,heng2,center_y)
##########################找中心横坐标
    for l in img.find_lines(roi=(50,30,220,180),threshold = 1000,theta_margin = 35, rho_margin = 25):
        if (30 >= l.theta()) or (l.theta() >= 150):
            img.draw_line(l.line(), color = (255, 0, 0))
            shu.append(l)
    #print("竖线坐标"shu)
    if len(shu)>=2:
        shu1 = shu[0]
        for l in shu:
            if abs(abs(l.rho())-my_place[1])<abs(abs(shu1.rho())-my_place[1]):
                shu1 = l
        shu.pop(shu.index(shu1))
       # print(shu)
        shu2 = shu[0]
        for l in shu:
            if abs(abs(l.rho())-my_place[1])<abs(abs(shu2.rho())-my_place[1]):
                shu2 = l
        count.append(1)
    if  len(count)==2:
 
        center_y_1=(math.cos(shu1.theta()/180*3.14159)*heng1.rho()-math.cos(heng1.theta()/180*3.14159)*shu1.rho())/(math.sin(heng1.theta()/180*3.14159)*math.cos(shu1.theta()/180*3.14159)-math.sin(shu1.theta()/180*3.14159)*math.cos(heng1.theta()/180*3.14159))
        center_x_1=(math.sin(shu1.theta()/180*3.14159)*heng1.rho()-math.sin(heng1.theta()/180*3.14159)*shu1.rho())/(math.cos(heng1.theta()/180*3.14159)*math.sin(shu1.theta()/180*3.14159)-math.cos(shu1.theta()/180*3.14159)*math.sin(heng1.theta()/180*3.14159))
        center_y_2=(math.cos(shu2.theta()/180*3.14159)*heng2.rho()-math.cos(heng2.theta()/180*3.14159)*shu2.rho())/(math.sin(heng2.theta()/180*3.14159)*math.cos(shu2.theta()/180*3.14159)-math.sin(shu2.theta()/180*3.14159)*math.cos(heng2.theta()/180*3.14159))
        center_x_2=(math.sin(shu2.theta()/180*3.14159)*heng2.rho()-math.sin(heng2.theta()/180*3.14159)*shu2.rho())/(math.cos(heng2.theta()/180*3.14159)*math.sin(shu2.theta()/180*3.14159)-math.cos(shu2.theta()/180*3.14159)*math.sin(heng2.theta()/180*3.14159))
        center_x=(abs(center_x_1)+abs(center_x_2))/2
        center_y=(abs(center_y_1)+abs(center_y_2))/2
        print("中心x",center_x_1,center_x_2)
        print("中心y",center_y_1,center_y_2)
		return int(center_x), int(center_y)
        img.draw_cross(my_place[1], my_place[0], size=3,color=(0))
        img.draw_cross(int(center_x), int(center_y), size=5,color=(0))
        img.draw_arrow(my_place[1],  my_place[0], int(center_x), int(center_y), color = (0), size = 10, thickness = 2)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021电子设计竞赛飞控视觉之openmv寻找方格中心 的相关文章

  • 2016年小结 2017年展望

    转载请标明出处 xff1a http blog csdn net junzaivip article details 54231935 xff0c 本文出自 junzaivip博客 每个人的世界里有的不止是光鲜 xff0c 其实还有更多别人
  • 如何将本地已有的项目加入git版本管理

    本文地址 xff1a https blog csdn net junzaivip article details 82626584 如果自己已经新建的一个项目 xff0c 暂时没有加入项目管理 xff0c 且名称不变 xff0c 如何加入
  • 基于github搭建自己的个人博客

    今天一时兴起 xff0c 看见别人使用的github io搭建了属于自己的个人博客 xff0c 我也使用github搭建一个自己的博客系统 xff1b 步骤一 xff1a 创建一个自己的github账号 xff1b xff08 略 xff0
  • 将C++ 看作多种语言的联合体

    起初 xff0c C 43 43 仅仅是增补了面向对象特性的 C 语言 甚至 C 43 43 原始的名称都叫做 使用类的 C 语言 xff0c 这可以很明显地反映出这一继承关系 随着 C 43 43 逐渐成熟 xff0c 它变得更加丰富多彩
  • ES6基本用法

    ES6基本用法 字符串的基本用法 let junzai 61 34 史慧君 34 let blog 61 34 淘宝多的是 xff0c 都是正版 xff0c 放心买 学习字符串 34 let blog 61 96 淘宝多的是 xff0c 都
  • Node升级到最新版本

    检查目前的版本 xff1a localhost shihuijun node v v8 9 3 清除node js的cache 不确定有没有必要 localhost shihuijun sudo npm cache clean f Pass
  • APM飞控添加自定义参数

    原文链接 xff1a http www nufeichuiyun com p 61 283
  • APM(pixhawk)飞控疑难杂症解决方法汇总(持续更新)

    原文链接 xff1a http www nufeichuiyun com p 61 28
  • 我设计了一款开源飞控,性能远超Pixhawk,运行APM固件-怒飞垂云

    从2009年到现在 xff0c 我从事无人机研发将近11年了 xff0c 中途设计过很多飞控 xff0c 有闭源的无人飞艇飞控 大型固定翼无人机飞控 xff0c 也有在开源飞控Pixhawk基础上修改的飞控 xff0c 如今 xff0c 基
  • MissionPlanner使用说明(持续更新)

    MissionPlanner有些功能需要自己摸索 xff0c 我把一些比较难找的功能使用方法列举如下 xff1a 原文链接 xff1a http www nufeichuiyun com p 61 67
  • 怒飞垂云视频教程 一、建立编译环境

    本文讲述如何建立APM飞控固件的编译环境 原文链接 xff1a http www nufeichuiyun com p 61 237
  • Android Automotive(七) VehicleService

    Android Automotive xff08 七 xff09 VehicleService VehicleService 是Android Automotive在硬件抽象层的一个核心native服务 处理和车辆相关功能 xff0c 为系
  • ardupilot之添加mavlink消息

    本文是这篇文章的复现 xff1a http www sohu com a 213599378 175233 一 mavlink分析 Mavlink 的全称是Micro Air Vehicle link xff0c pixhawk把它作为与地
  • Linux中断机制:硬件处理,初始化和中断处理

    来源 CSDN phenix lord的专栏 硬件处理 最近解决一个关于Linux中断的问题 xff0c 把相关机制整理了一遍 xff0c 记录在此 不同的外部设备 不同的体系结构 不同的OS其中断实现机制都有差别 xff0c 本文对应的O
  • 跟我一起复制一款基于ESP-Drone无人机控制板

    1 ESP Drone 无人机项目简介 ESP 无人机是基于ESPRESIF ESP32 ESP32 S2 Wi Fi芯片的开源解决方案 xff0c 可通过Wi Fi连接到手机应用程序或游戏控制台 ESP无人机具有简单的硬件 清晰和可扩展的
  • linux安装llvm

    先装cmake xff0c 可以用sudo apt get install cmake或者去官网下载源码编译安装 下载llvm git clone https github com llvm llvm project git 3 Build
  • Makefile中的MAKECMDGOALS

    make 在执行时会设置一个特殊变量 xff1a 34 MAKECMDGOALS 34 xff0c 该变量记录了命令行参数指定的终极目标列表 xff0c 没有通过参数指定终极目标时此变量为空 该变量仅限于用在特殊场合 比如判断 xff0c
  • Docker切换存放目录踩坑

    因为 var 目录下的磁盘空间不足 xff0c 故把docker的存放目录切换到 data 下面 xff0c 具体步骤 xff1a 1 编辑docker配置文件 etc docker daemon json xff0c 修改data roo
  • 关于Modelsim SE-64 2020.4取消优化后不显示波形问题

    Modelsim取消优化后报错 Error suppressible vsim 12110 All optimizations are disabled because the novopt option is in effect This
  • 关于串口调试助手XCOM点击发送后卡住问题

    未成功安装CH340驱动 USB串口驱动 安装前先重启电脑 xff0c 再点击安装 串口选择错误 打开设备管理器 xff0c 查看USB连接的端口 xff08 COM xff09 号 xff0c 选择正确的端口 xff08 COM xff0

随机推荐

  • Makefile中Linux转Windows执行知识点

    makefile 是一个自动化编译工具 xff0c 可以简化编译过程 xff0c 自动化处理依赖关系和编译顺序 xff0c 提高了代码的可维护性 makefile 通常由一些规则和命令组成 xff0c 规则由目标 依赖和命令构成 xff0c
  • darknet2ncnn编译中 libopencv 库文件找不到

    问题描述 没有直接从 github 上下载 darknet2ncnn 包 xff0c 用的是他人提供的包 xff0c 包已经编译好 解压已经有 convert verify 文件 执行该文件 xff0c 问题描述如下 xff1a root
  • linux usb设备如何和u盘对应

    已知 usb 的 pid vid 如何对加载的u盘进行管理 思路 xff0c 找到 U盘的厂商信息中的pid和 vid 对应关系 xff0c 然后控制 U盘的加载 但是 U盘信息中没有pid 和 vid root 64 li PC sys
  • CV面试题(持续更新!!!)

    CV面试题 1 反卷积 反卷积又叫做转置卷积 xff0c 在计算机中计算的时候 xff0c 转置卷积先将卷积核转为稀疏矩阵C的形式 xff0c 然后计算的时候正向传播的时候左乘这个稀疏矩阵C的转置 xff0c 反向传播的时候左乘这个稀疏矩阵
  • 程序运行时数据保存位置

    程序运行时 xff0c 内存中有六个地方可以保存数据 1 寄存器 这是最快的保存区域 xff0c 寄存器位于处理器内部 然而寄存器的数量很有限 xff0c 所以寄存器是根据需要由编译器的分配的 我们对此没有直接的控制权限 也不可能在我们的程
  • ESP-Drone无人机控制板设计的第一个任务---绘制ESP32-S2-WROVER模块及周边电路

    第1步 xff0c 查看官方ESP Drone无人机ESP32 S2 WROVER模块的参考设计原理图 第二步 xff0c 用KiCAD绘制ESP32 S2 WROVER模块及周边电路 1 如图2 1所示 xff0c 从KiCAD的原理图符
  • ROS学习——读取摄像头数据image

    在ROS工作空间的src文件夹下创建read camera功能包 xff0c 并在包内创建include launch src cfg四个文件夹 在cfg文件夹中创建param yaml文件 xff0c 并写入以下内容 xff1a imag
  • ROS学习——控制小车转向

    给定一个旋转的角度 xff0c 让小车进行顺时针或逆时针旋转 span class token macro property span class token directive keyword include span span clas
  • PID参数设定

    在电机的控制领域 xff0c 不同的电机有不同的驱动方式 xff0c 其中应用最广泛的就是PID proportion integration differentiation 控制 P I和D分别指比例控制 xff0c 积分控制和微分控制
  • 系统编程__2__父子进程的创建和回收

    系统编程 这里写的是对于小白来说更多的了解系统编程的文章 xff0c 有写的不对的地方还恳请各位大佬指出错误 xff0c 小编一定会多多采纳 手动多谢 那么 xff0c 上一次我们稍微了解了一下关于系统编程的一些主要内容 没有看到的童鞋还请
  • php解决跨域访问

    php跨域问题解决判断 参考文章 xff1a php跨域 xff1a https blog csdn net ouxiaoxian article details 89332027 预检请求是什么 xff1a https www jians
  • 动态库与静态库的区别是什么

    区别 xff1a 1 静态库的扩展名一般为 a 或 lib xff1b 动态库的扩展名一般为 so 或 dll 2 静态库在编译时会直接整合到目标程序中 xff0c 编译成功的可执行文件可独立运行 xff1b 动态库在编译时不会放到连接的目
  • Ubuntu 使用 du 查看某个文件夹大小

    在 Ubuntu 系统中 xff0c 你可以使用 du 命令来查看文件夹的大小 例如 xff0c 如果你想查看文件夹 var log 的大小 xff0c 你可以使用如下的命令 xff1a du sh var log 其中 xff0c s 选
  • 无人机六旋翼数学建模[matlab-simulink]

    写在前面 xff0c 这篇文章是借鉴Drexel University 的Senior Design project的matlab simulink四旋翼模型 xff0c 在此基础上针对六旋翼进行的基本改进 xff0c 这里只对 43 型模
  • stm32连接DHT11温湿度传感器

    目录 1 DHT11简介 1 1 连接电路 1 2 串行接口 单线双向 2 cubeMX设置 3 代码开发 3 1 实现定时函数 3 2 打开串口调试 3 4 测试代码实现 4 运行效果 1 DHT11简介 1 1 连接电路 信息如下 xf
  • STM32CubeMX 真的不要太好用

    STM32CubeMX 真的不要太好用 由于工作内容的变动 xff0c 我已经很久没有正经的玩过单片机了 xff0c 近期又要用它做个小玩意了 xff0c 还是选 stm32 吧 xff0c 外设库开发不要太方便 xff0c 哈哈哈 先去
  • ESP-Drone控制板设计的第二个任务-绘制USB-TTL串口下载电路和ESP32-S2芯片内置USB接口电路

    1 摘要 ESP32系列处理器一般会需要采用串口来下载代码 xff0c 因此在其设计中都会保留一个USB TTL串口电路 xff0c 查看乐鑫官网的参考设计 xff0c 基本上是采用CP2102这颗USB转TTL串口芯片 xff0c 但在本
  • Airflow ETL任务调度工具 介绍

    Airflow 是 Apache 基金会的一套用于创建 管理和监控工作流程的开源平台 xff0c 是一套非常优秀的任务调度工具 截至2022年7月 xff0c 在GitHub上已经拥有近27k的star 本文主要介绍一下Airflow 2
  • Data_web(八)mysql增量同步到mongodb

    1 mongdb连接 连接方式如下 xff08 重要 xff01 xff01 xff01 xff01 xff0c 账号密码必须建立在db下面 xff0c 如果默认再admin下面 xff0c 导致无法切换库 xff0c 连接报错 xff09
  • 2021电子设计竞赛飞控视觉之openmv寻找方格中心

    写在前面 这是我在电赛飞控备赛期间写的一个小函数 xff0c 功能是寻找目标点所在方格的中心 这样四旋翼在方格地图上移动一定距离之后就可以使用openmv将四旋翼辅助定位至目前所在方格的中心 今年G题刚出来的时候本来以为能用上这个函数进行辅