从一组线段中得出四边形的算法

原始的需求是使用OpenCV的直线检测算法(例如LSD)之后,得到一组线段。然后需要从这些线段得到类似矩形的四边形,用于检测经过透视变换的矩形物体。这些线段不一定首尾相接,彼此之间可能相交或有一定距离。

以下是需求图:

使用从线段中寻找四边形的算法之后,得到了以下结果:

算法的步骤为:

1、从线段中挑出4条,顺序不同的组合只有3种。

2、对于每一种组合,由于每一条线段都有2个方向,那么就会有8种组合。

3、对于每一个组合,首先检查相邻线段的夹角,排除太小或太大的(相对于90度)。

4、继而检查相邻线段的顶点距离,排除距离太远的。

5、最后,求出四条相邻线段的交点,以这4个交点作为最终透视矩形的四个顶点。

算法代码如下:

/// <summary>
/// 线段组成四边形
/// </summary>
/// <param name="segs">线段列表</param>
/// <param name="maxDistSum">最大距离和</param>
/// <returns>四边形列表</returns>
public static List<PolygonScore> FormQuadrangle(Segment2D[] segs, double maxDistSum)
{int len = segs.Length;List<int[]> combines = new List<int[]>();for (int i = 0; i < len - 3; i++){for (int j = i + 1; j < len - 2; j++){for (int k = j + 1; k < len - 1; k++){for (int l = k + 1; l < len; l++){combines.Add(new int[] { i, j, k, l });combines.Add(new int[] { i, j, l, k });combines.Add(new int[] { i, k, j, l });}}}}List<RectInfo> rects = new List<RectInfo>();for (int i = 0; i < combines.Count; i++){int[] combine = combines[i];var seg1 = segs[combine[0]];var seg2 = segs[combine[1]];var seg3 = segs[combine[2]];var seg4 = segs[combine[3]];double cos1 = CosAngle(seg1.Vec, seg1.Length, seg2.Vec, seg2.Length);if (Math.Abs(cos1) > 0.5){continue;}double cos2 = CosAngle(seg2.Vec, seg2.Length, seg3.Vec, seg3.Length);if (Math.Abs(cos2) > 0.5){continue;}double cos3 = CosAngle(seg3.Vec, seg3.Length, seg4.Vec, seg4.Length);if (Math.Abs(cos3) > 0.5){continue;}double cos4 = CosAngle(seg4.Vec, seg4.Length, seg1.Vec, seg1.Length);if (Math.Abs(cos4) > 0.5){continue;}var doubleSegs = new Segment2D[] { seg1, seg1.Reverse(), seg2, seg2.Reverse(), seg3, seg3.Reverse(), seg4, seg4.Reverse() };bool found = false;for (int i1 = 0; i1 < 2; i1++){for (int i2 = 2; i2 < 4; i2++){double d1 = PointPoint(doubleSegs[i1].P2, doubleSegs[i2].P1);if (d1 > maxDistSum){continue;}for (int i3 = 4; i3 < 6; i3++){double d2 = PointPoint(doubleSegs[i2].P2, doubleSegs[i3].P1) + d1;if (d2 > maxDistSum){continue;}for (int i4 = 6; i4 < 8; i4++){double d3 = PointPoint(doubleSegs[i3].P2, doubleSegs[i4].P1);double d4 = PointPoint(doubleSegs[i4].P2, doubleSegs[i1].P1);double dd = d2 + d3 + d4;if (dd < maxDistSum){rects.Add(new RectInfo(new Segment2D[] { doubleSegs[i1], doubleSegs[i2], doubleSegs[i3], doubleSegs[i4] }, dd));found = true;}if (found){break;}}if (found){break;}}if (found){break;}}if (found){break;}}}rects.Sort();List<PolygonScore> polygons = new List<PolygonScore>();foreach (RectInfo rect in rects){polygons.Add(new PolygonScore(new Point2D[] {Intersect(rect.Segments[0],rect.Segments[1]),Intersect(rect.Segments[1],rect.Segments[2]),Intersect(rect.Segments[2],rect.Segments[3]),Intersect(rect.Segments[3],rect.Segments[0])}, rect.DistSum));}return polygons;
}

使用上面的代码对下图进行简单测试:

得到如下结果:

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

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

相关文章

提示词Prompts(2)

摘要&#xff1a; 本文介绍了langchain.prompts中基础的提示词模板的高级用法&#xff0c;包括利用PipelinePrompt组合Prompt使用&#xff0c;多模态场景、动态占位符的使用等进行了介绍。 文章目录 1. 背景2. PipelinePrompt2.1 组合两个Prompt模板2.2 多模态模板 3. 聊天提示…

服务器代码知识点补充

目录 UdpServer: 观察者模式: remove_if算法 管道补充: 文件的标准输出 ,标准输入,标准错误 UdpServer: 数据接收模块关心Adduser 和Deleuser 两个模块 线程池关心Route模块 将这三个方法注册进服务器 ,但是有临界区问题(线程池与数据接受模块可能同时访问用户管理模块,所…

R语言缓释制剂QBD解决方案之二

药物层优化研究 在药物层工艺中水溶剂蒸发起到重要的作用。湿的环境会使丸子聚集&#xff0c;而干的环境影响药物与MCC的粘合。输入变量如气流量&#xff0c;喷雾速率&#xff0c;雾化压力&#xff0c;和产品温度对MCC沉着和包衣溶剂蒸发的平衡有影响。进行了带3个中心点的24-…

Html实现图片上传/裁剪/马赛克/压缩/旋转/缩放

cropper下载 https://download.csdn.net/download/dongyan3595/90970115 前端代码 <!doctype html> <html lang"en"> <head><base href"/aishop/"><meta name"viewport" content"widthdevice-width, initial…

springboot项目中整合高德地图

一&#xff1a;高德开放平台的使用 高德开放平台 | 高德地图API 注册高德地图账号 认证填写个人信息&#xff1a; 认证方式选择“个人认证开发者”即可&#xff0c;然后完善信息 认证成功之后&#xff0c;再次进入控制台&#xff0c;创建关于地图的应用 创建Key&#xff08;y…

鸿蒙开发-视频学习及实用中的一些小结

1.extend 和 styles extend是在styles基础上进行了升级 使用的时候extend是全局的。 styles不加function 局部 加了就是全局。 2.builder 中要引用comp组件 需要在外层嵌套布局 3.ability之间的跳转 want需要加&#xff1b; 4. as 类型断言 &#xff01;跟在xxx! 表示…

网盘直链解析网页版

不支持百度网盘、阿里网盘。 123&#xff0c;蓝奏云&#xff0c;可道云什么的都可以 源码下载地址&#xff1a;https://www.123865.com/s/X91lVv-3l90v

AXI4-Stream Clock Converter IP

一、参考说明 1.没有专门对AXI4-Stream Clock Converter IP说明的文档&#xff1b; 2.可以参考PG085文档&#xff1b; 3.可以参考PG035文档&#xff1b; 二、IP的作用 1.用于stream数据流再不同的时钟域之间的可靠性传输&#xff1b; 2.支持跨时钟域的场景&#xff1b; 3.内部…

NineData 社区版 V4.2.0 发布!新增MySQL与PostgreSQL互相迁移,SQL管理Milvus,安装更高效

NineData 社区版 V4.2.0 正式发布&#xff01;本次更新通过镜像轻量化部署、新增 3 条迁移链路、新增支持 Milvus 向量数据库等核心升级&#xff0c;轻松实现数据库迁移容灾、实时数据集成分析、AI 向量数据管理等场景需求。社区版支持本地离线部署&#xff0c;严格保障数据隐私…

如何安装使用qmt脚本跟单聚宽策略

登录知识星球&#xff0c;下载获取 解压后&#xff0c;登录大qmt&#xff0c;将策略导入其中&#xff0c; 然后修改参数&#xff1a; 点击免密改参 totalcash&#xff1a;该策略使用资金总量 per&#xff1a;每只股票占比资金额 举例&#xff0c;当前出信号&#xff0c;每只…

什么是MongoDB

目录 主要特点 MongoDB概念解析 完整术语列表 MongoDB安装 MongoDB Shell 安装MongoDB Shell 数据库管理 查看数据库列表 创建数据库 删除数据库 默认数据库 系统内置数据库 集合管理 查看集合 创建集合 更新集合名 删除集合 文档操作 插入文档 查询文档 …

【Docker基础】Docker核心概念:容器(Container)与镜像(Image)的区别与联系

目录 引言 1 Docker镜像&#xff08;Image&#xff09; 1.1 镜像的定义 1.2 镜像的特点 1.3 镜像的创建 1.4 镜像的结构 1.5 镜像结构描述 2 Docker容器&#xff08;Container&#xff09; 2.1 容器的定义 2.2 容器的特点 2.3 容器的创建与运行 2.4 容器的生命周期…

从零到一:构建企业级 Vue.js 3 组件库

前言&#xff1a;为何要构建组件库&#xff1f; 在现代前端工程化体系中&#xff0c;组件库已不再是大型团队的专属。它是一个团队设计规范、开发模式和技术沉淀的核心载体。构建一个组件库&#xff0c;能够带来诸多优势&#xff1a; 提升效率&#xff1a;提供可复用的高质量…

【2025 CVPR-Backbone】Building Vision Models upon Heat Conduction

摘要 利用注意力机制的视觉表示模型在追求大感受野时面临着巨大的计算开销。在本研究中&#xff0c;我们通过引入基于物理热传导原理的热传导算子&#xff08;Heat Conduction Operator, HCO&#xff09;来缓解这一挑战这么高级咩(⊙o⊙)&#xff01;。HCO将图像块视为热源&am…

Rust编写Shop管理系统

Rust编写Shop管理系统 Actix Web 是一个功能强大、实用且速度极快的 Rust Web 框架。编写Shop管理系统 HelloKeny 首先是先编写最简单的例子,类似hello World可以检查环境 Actix Web 是一个功能强大、实用且速度极快的 Rust Web 框架。 命令 cargo new hellokenycd hell…

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…

快速幂算法详解:从暴力到优雅的数学优化

文章目录 一、朴素幂运算的问题二、快速幂的数学原理三、快速幂的递归实现四、快速幂的迭代实现五、模运算下的快速幂六、快速幂的应用场景七、总结 快速幂是一种高效计算幂运算的算法&#xff0c;能够将时间复杂度从朴素的 O (n) 降低到 O (log n)。本文将深入探讨快速幂的原理…

HTML+CSS 动态菜单和登录框

摘要 实现了一个现代化的登录/注册界面&#xff0c;包含导航栏和弹窗表单。 HTML结构采用了响应式设计&#xff0c;包含Logo、导航链接和登录按钮。 CSS样式实现了背景图片、导航栏悬浮效果和表单美化&#xff0c;使用伪元素实现链接下划线动画。 JavaScript实现了弹窗切换…

抖音AI数字人对口型软件LatentSync最新版整合包,音频驱动口型讲话

本次和大家分享一个字节跳动开发的强大的音频驱动口型数字人视频制作软件LatentSync&#xff0c;我以前也分享过不少类似软件了&#xff0c;比如&#xff1a;EchoMimic、VideoReTalking、hallo。字节的推出的这个效果稍微更好一点&#xff0c;我制作了最新版的一键启动整合包。…

深入理解 PyTorch:从基础到高级应用

在深度学习的浪潮中&#xff0c;PyTorch 凭借其简洁易用、动态计算图等特性&#xff0c;迅速成为众多开发者和研究人员的首选框架。本文将深入探讨 PyTorch 的核心概念、基础操作以及高级应用&#xff0c;带你全面了解这一强大的深度学习工具。​ 一、PyTorch 简介​ PyTorch…