常规情况与opencv图像中,计算直线与矩形框的交点

文章目录

  • 1、普通方式
    • 1.1、普通计算过程
    • 1.2、优化方式
  • 2、图像中的情况
    • 2.1、常规处理
    • 2.2、opencv中的处理
      • 2.2.1、cv::clipLine函数
      • 2.2.2、测试代码
      • 2.2.3、测试结果

1、普通方式

已知矩形框左上(x1,y1)、右下(x2,y2)点,直线方程 y = kx+b,求交点。

这个问题转换为:计算直线与矩形框的四条线段的交点,因此最多执行4次。
首先计算直线与线段所在直线交点,若交点的在线段坐标的范围内,那么认为是有交点。

1.1、普通计算过程

这里不考虑直线平行的常规情况,如下
{ a 1 x + b 1 y + c 1 = 0 a 2 x + b 2 y + c 2 = 0 \left\{\begin{matrix} a_1x + b_1y+c_1 = 0 \\ a_2x + b_2y+c_2 = 0 \end{matrix}\right. {a1x+b1y+c1=0a2x+b2y+c2=0
计算得到横坐标
x = b 2 c 1 − b 1 c 2 b 2 a 1 − b 1 a 2 x=\frac{b_2c_1 - b_1c_2}{b_2a_1-b_1a_2} x=b2a1b1a2b2c1b1c2

当其位于某一条线段的横坐标坐标取值范围 x ∈ [ x 1 , x 2 ] x \in [x_1, x_2] x[x1,x2] 时,认为存在交点
{ x = b 2 c 1 − b 1 c 2 b 2 a 1 − b 1 a 2 y = − a 2 x − c 2 b 2 \left\{\begin{matrix} x=\frac{b_2c_1 - b_1c_2}{b_2a_1-b_1a_2} \\ y = \frac{-a_2x-c_2}{b_2} \end{matrix}\right. {x=b2a1b1a2b2c1b1c2y=b2a2xc2

1.2、优化方式

我们分两种情况。直线垂直和水平,以及普通情况。

  • (1)垂直和水平情况
    在这里插入图片描述
    这种方式简单,当垂直时直线 x = m x = m x=m,若 m ∈ [ x 1 , x 2 ] m \in [x_1, x_2] m[x1,x2],那么交点为 ( m , y 1 ) (m,y_1) (m,y1) ( m , y 2 ) (m,y_2) (m,y2);同理,当水平式直线 y = n y = n y=n,若 n ∈ [ y 1 , y 2 ] n \in [y_1, y_2] n[y1,y2],那么交点为 ( x 1 , n ) (x_1,n) (x1,n) ( x 2 , n ) (x_2,n) (x2,n)

  • (2)不相交时
    在下图中我们绘制斜率分别为正、负的情况,且与矩形不相交的示意图,大概有8种情况下,矩形框的4个顶点均在某条直线的一侧。
    在这里插入图片描述
    因此,我们判断直线是否与矩形相交,可以直接判定矩形框四个顶点 ( x 1 , y 1 ) , ( x 2 , y 1 ) , ( x 2 , y 2 ) , ( x 1 , y 2 ) (x_1,y_1),(x_2,y_1),(x_2,y_2),(x_1,y_2) (x1,y1),(x2,y1),(x2,y2),(x1,y2) 以顺时针带入直线方程函数 f ( x , y ) = a x + b y + c f(x,y) = ax+by+c f(x,y)=ax+by+c 的结果是否都同号即可

  • (3)相交时
    在下图中绘制了所有相交的情况,可以看到 在(2)基础上,直线与矩形框线段有交点时,矩形框2个顶点一定在直线的两侧,或者某个端点在直线上
    在这里插入图片描述
    我们顺时针将矩形框框四个顶点 ( x 1 , y 1 ) , ( x 2 , y 1 ) , ( x 2 , y 2 ) , ( x 1 , y 2 ) (x_1,y_1),(x_2,y_1),(x_2,y_2),(x_1,y_2) (x1,y1),(x2,y1),(x2,y2),(x1,y2) 带入直线方程函数 f ( x , y ) = a x + b y + c f(x,y) = ax+by+c f(x,y)=ax+by+c ,若相邻两个点符号不同(不同为正,不同为负;或 +、-、0的组合),认为是有交点的。

图像中矩形看过顶点已知,且边界线为水平线和垂直线,因此计算简单。
直线方程为 y = k x + b y = kx + b y=kx+b,矩形框边界的线按顺时针排列:水平线 y = y 1 y = y_1 y=y1, 垂直线 x = x 2 x = x_2 x=x2,水平线 y = y 2 y=y_2 y=y2, 垂直线 x = x 1 x = x_1 x=x1。 后面计算过程,不做赘述。

2、图像中的情况

这里直线与矩形框的交点,我们考虑并非线段(若直线延长后与矩形框有交点,如果用两个点描述直线必须要求延长后与矩形框有交点),而是延长后的线段作为实际直线。

通常矩形框在画面中,例如下图中黑框灰色区域(宽度w)为画面区域,蓝色矩形框位于其中。绿色为线段,延长后与矩形框相交为棕色点。
在这里插入图片描述

2.1、常规处理

通常我们计算的逻辑,会考虑直线在画面中的多种情况,例如 垂直、水平,以及实际与画面无交集的无效直线等。
可以参考前述计算方式,这里不在赘叙。

2.2、opencv中的处理

我们直接以图像x方向左、右边界作为线段的延长线,得到两点(0, y0)(w, y1),之后使用cv::clipLine()计算交点。

2.2.1、cv::clipLine函数

先给出函数定义

bool clipLine(  // true if any part of line in imgRectcv::Rect imgRect,  // rectangle to clip tocv::Point& pt1,  // first endpoint of line overwrittencv::Point& pt2  // second endpoint of line, overwritten
);
bool clipLine(  // true if any part of line in image sizecv::Size imgSize,  // size of image,implies rectangle at 0,0cv::Point& pt1,  // first endpoint of line,overwrittencv::Point& pt2  // second endpoint of line,overwritten
);

第一种函数的形式使用了cv::Rect,直线和这个矩形比较;第二个函数只有cv::Size,该形式表示矩形的范围是从(0,0)开始的。

只有当喜爱那段完全在指定的矩形范围之外时,函数cv::clipLine()才会返回false

注意,端点是引用,当线段与矩形框相交时,函数返回true,并改写pt1pt2.

2.2.2、测试代码

首先Mat创建一个800x800的画面区域, 之后创建一个 cv::Rect(100, 100, 400, 400) 区域。
我们流程如下:

  1. 直线方程:通过2个点,使用cv::fitLine 拟合出直线的方程
  2. 线段端点:之后以图像左、右边界,确定直线的两个端点
  3. 求解交点: 使用 cv::clipLine 计算矩形区域与线段的交点

完整测试代码如下

   {cv::Mat img(800, 800, CV_8UC3, {255,255,255});cv::Rect rect(100, 100, 400, 400);cv::rectangle(img, rect, {0,0,0}, 3);// ---- 直线拟合 cv::Point temp[2] = {{100, 100}, {50,-100}};cv::Vec4f line_para;cv::fitLine(std::vector<cv::Point>{ temp[0], temp[1]/*{-40,-20},{810,830}*/}, line_para, cv::DIST_L2, 0, 1e-2, 1e-2);// ---- 直线端点cv::Point point0(line_para[2], line_para[3]);//计算直线的端点(y = k(x - x0) + y0)cv::Point point1, point2; if(line_para[1] == 1 || line_para[1] == -1 ) {point1 = cv::Point(line_para[2],0);point2 = cv::Point(line_para[2], img.rows);}else {float k = line_para[1] / line_para[0];point1.x = 0;point1.y = k * (0 - point0.x) + point0.y;point2.x = img.cols;point2.y = k * (point2.x - point0.x) + point0.y;}cv::Point line1[] = {point1,point2};   cv::line(img, line1[0], line1[1], {255,0,0},2);// ----- 直线与矩形框交点if(cv::clipLine(rect, line1[0], line1[1])) {cv::circle(img, line1[0], 3, {0,0,255}, -1);cv::circle(img, line1[1], 3, {0,0,255}, -1);}// -- 绘制cv::circle(img, temp[0], 4, {0,255,0}, 2);cv::circle(img, temp[1], 4, {0,255,0}, 2);cv::imshow("1",img);cv::waitKey(0);return 0;}

2.2.3、测试结果

测试结果如下图。实测任何对与任何直线,以上代码都能适用。

在这里插入图片描述

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

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

相关文章

《后端程序猿 · Java8 Stream》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻一周&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

tinyshop商城学习

1、使用badboy屏幕录制工具&#xff0c;获得服装购物业务的结果&#xff0c;生成.jmx文件 2、在JMeter中新建线程组&#xff0c;导入.jmx文件 3、完成进入商城&#xff0c;登录&#xff0c;服装页面进入&#xff0c;随机选择服装&#xff0c;添加购物车&#xff0c;开始结算&…

Java 容器

Java容器都有哪些&#xff1f; Java容器分为Collection和Map两大类&#xff0c;其下又有很多子类&#xff0c;如下所示Collection: List:ArrayList、LinkedList、Vector、Stack Set:HashSet、LinkedHashSet、TreeSet Map:HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap、…

SpringBoot整合Dubbo的快速使用教程

目录 一、什么是Dubbo? 二、SpringBoot整合Dubbo 1、父工程引入依赖 2、各个Dubbo服务子模块引入依赖 3、服务提供者 &#xff08;1&#xff09;启动类添加注解EnableDubbo &#xff08;2&#xff09;服务类添加注解DubboService &#xff08;3&#xff09;配置文件…

Patch SCN使用说明---惜分飞

软件说明 该软件是惜分飞&#xff08;https://www.xifenfei.com&#xff09;开发&#xff0c;仅用来查看和修改Oracle数据库SCN(System Change Number),主要使用在数据库因为某种原因导致无法正常启动的情况下使用该工具进行解决.特别是Oracle新版本中使用隐含参数,event,orad…

Java核心 - 泛型详解

文章目录 一、概述1、什么是泛型2、用泛型最直接的优点3、分类 二、泛型详解1、泛型类&#xff08;1&#xff09;概述&#xff08;2&#xff09;代码实例 2、泛型派生类&#xff08;1&#xff09;概述&#xff08;2&#xff09;代码实例&#xff08;3&#xff09;扩展&#xff…

jupyter在运行问题处理ModuleNotFoundError: No module named ‘jupyter_server‘

背景&#xff1a; 有段时间没有使用了jupyter了&#xff0c;现在需要使用它数据可视化的功能进行学习一个新的python库。创建ipynb文件后运行出现报错。 问题处理 异常报错&#xff1a;ModuleNotFoundError: No module named ‘jupyter_server’ 没有jupyter_server&#x…

Python文字数字转换利器: word2number库详解

Python文字数字转换利器: word2number库详解 1. word2number简介2. 安装3. 基本使用3.1 基本数字转换3.2 序数转换3.3 小数转换3.4 负数转换 4. 高级用法4.1 处理混合表达4.2 处理大写字母 5. 错误处理6. 实际应用示例6.1 文本数据预处理6.2 简单计算器 7. 局限性8. 总结 在处理…

10元 DIY 一个柔性灯丝氛围灯

之前TikTok上特别火的线性氛围灯Augelight刚出来的时候一度卖到80多美金&#xff0c;国内1688也能到400多人民币。 随着各路国内厂商和DIY创客的跟进&#xff0c;功能变多的同时价格一路下滑&#xff0c;虽然有的质感的确感人&#xff0c;但是便宜啊。 甚至关注的up有把成本搞到…

【24年一博研讨会总结】BJ0705

1.工艺边据PCB边缘 >5mm. 2.IPC-A-600G Pitch < 1.25mm H<0.025mm,小于0.4mm,取消丝印框&#xff0c;防止锡膏不匀虚焊&#xff1b; 3.表面镀金与镍厚度 金厚度 um镍厚度 um0.0192.7830.0213.3610.0453.6640.0314.378 4.多层板&#xff0c;层间距>20mil 可以认…

clsx源码阅读分析

clsx源码 版本 2.1.1 一个处理类名的函数。 地址&#xff1a;https://github.com/lukeed/clsx/blob/master/src/index.js 源码文件index.js 文件 src/index.js //src/index.js function toVal(mix) {var k,y,str "";// 判断参数min类型&#xff0c; 字符串或数…

C++中的左值、右值介绍

C中的左值、右值介绍 在C中&#xff0c;左值&#xff08;lvalue&#xff09;和右值&#xff08;rvalue&#xff09;是非常重要的概念&#xff0c;尤其是在C11及以后的版本中引入的右值引用&#xff08;rvalue reference&#xff09;和移动语义&#xff08;Move Semantics&#…

Ubuntu系统复制文件到共享文件夹出错

1、问题描述 Ubuntu系统复制文件到共享文件夹时&#xff0c;出现拼接文件时出错&#xff1a;输入/输出错误。 使用cp命令&#xff1a; cp -Rf XXX YYY 也是出错&#xff1a; cp: 写入 xxx 出错: 输入/输出错误 2、查看磁盘空间 查看磁盘空间&#xff0c;显示空间还有剩余…

安乃达:看不懂的募资

不好玩啊&#xff0c;高标接连被S&#xff0c;市场激进资金找到了新股作为抱团方向。 首日大涨超100%&#xff0c;两日涨幅133%&#xff0c;今天果不其然被电风扇刮走了&#xff0c;今天我们聊聊新加入A股大本营的公司——安乃达。 首先&#xff0c;安乃达是国内直驱轮毂电机头…

Golang栈空间管理

分段栈 在Go1.3之前&#xff0c;所有goroutine在初始化时都会分配一块固定大小的内存空间。 在固定8KB或者满足其他条件下&#xff0c;会在全局的栈缓存链表中找到空闲的内存块作为新goroutine的栈空间返回其余情况&#xff0c;会在堆上申请一块合适的内存 所有栈空间会以链…

hot100 | 六、矩阵

1-leetcode73. 矩阵置零 注意&#xff1a; 注意第一行和第一列如果检查到了0&#xff0c;直接break也可以使用HashSet方法&#xff0c;直接把0的数字对应的横纵坐标放在两个不同的HashSet当中&#xff0c;最后如果HashSet中Contain了当前数字下标中的一个&#xff0c;就直接给…

Amazon SQS应用场景及Python实现案例

1. SQS简介 Amazon Simple Queue Service (SQS) 是一种完全托管的消息队列服务,可以帮助解耦和扩展微服务、分布式系统和无服务器应用程序。SQS 可以在分布式应用程序组件之间传输任何数量的消息,而无需丢失消息或要求其他服务始终可用。 2. SQS应用场景 SQS 在许多场景中…

零基础学python(一)

1. 匿名函数 常规函数&#xff1a; def fun(x, y):return x y 匿名函数&#xff1a; # lambda 空格后面是函数入参&#xff0c;冒号后面写函数体/函数逻辑 a lambda x,y: x y print(a(2,3)) 匿名函数/lambda函数的最大优点就是快速定义函数&#xff0c;使代码更精简。 …

Redis 的缓存淘汰策略

Redis 作为一个高性能的内存数据库&#xff0c;提供了多种缓存淘汰策略&#xff08;也称为过期策略或驱逐策略&#xff09;&#xff0c;用于管理内存使用。当 Redis 达到其内存限制时&#xff0c;系统会根据配置的策略删除一些数据&#xff0c;以释放内存空间。以下是 Redis 支…

【数据结构】(6.3)堆的应用——堆排序(C语言)

系列文章目录 文章目录 系列文章目录前言1. 堆排序的基础知识2. 堆排序详解2.1 堆排序整体思路2.2 思路详解2.2.1 建堆2.2.2 堆排序完整代码2.2.3 输出数据 3. 时间复杂度分析 前言 1. 堆排序的基础知识 堆排序&#xff08;Heap Sort&#xff09;就是对直接选择排序的一种改进…