Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何检查一个点是否在一组等值线内

大家好。上面的图像是两幅图像的总和,其中我做了特征匹配,并绘制了所有匹配点。我还在第一个图像中找到了pcb部件的轮廓(半左图像-3个等高线)。问题是,我怎么能只画出第一幅图像中的等高线内的匹配点,而不是这样的蓝色混乱呢?我使用python2.7和opencv 2.4.12。

我在opencv 2.4.12中为绘制匹配函数编写了一个函数,但没有实现任何方法。如果我没有包括一些东西请告诉我。提前谢谢你!

代码语言:javascript
运行
AI代码解释
复制
import numpy as np
import cv2

def drawMatches(img1, kp1, img2, kp2, matches):

    # Create a new output image that concatenates the two images
    # (a.k.a) a montage
    rows1 = img1.shape[0]
    cols1 = img1.shape[1]
    rows2 = img2.shape[0]
    cols2 = img2.shape[1]

    # Create the output image
    # The rows of the output are the largest between the two images
    # and the columns are simply the sum of the two together
    # The intent is to make this a colour image, so make this 3 channels
    out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8')

    # Place the first image to the left
    out[:rows1,:cols1] = np.dstack([img1, img1, img1])

    # Place the next image to the right of it
    out[:rows2,cols1:] = np.dstack([img2, img2, img2])

    # For each pair of points we have between both images
    # draw circles, then connect a line between them
    for mat in matches:

        # Get the matching keypoints for each of the images
        img1_idx = mat.queryIdx
        img2_idx = mat.trainIdx

        # x - columns
        # y - rows
        (x1,y1) = kp1[img1_idx].pt
        (x2,y2) = kp2[img2_idx].pt

        # Draw a small circle at both co-ordinates
        # radius 4
        # colour blue
        # thickness = 1
        cv2.circle(out, (int(x1),int(y1)), 4, (255, 0, 0), 1)
        cv2.circle(out, (int(x2)+cols1,int(y2)), 4, (255, 0, 0), 1)

        # Draw a line in between the two points
        # thickness = 1
        # colour blue
        cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (255,0,0), 1)


    # Show the image
    cv2.imshow('Matched Features', out)
    cv2.imwrite("shift_points.png", out)
    cv2.waitKey(0)
    cv2.destroyWindow('Matched Features')

    # Also return the image if you'd like a copy
    return out


img1 = cv2.imread('pic3.png', 0) # Original image - ensure grayscale
img2 = cv2.imread('pic1.png', 0) # Rotated image - ensure grayscale

sift = cv2.SIFT()

# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)

# Create matcher
bf = cv2.BFMatcher()

# Perform KNN matching
matches = bf.knnMatch(des1, des2, k=2)

# Apply ratio test
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
       # Add first matched keypoint to list
       # if ratio test passes
       good.append(m)

# Show only the top 10 matches - also save a copy for use later
out = drawMatches(img1, kp1, img2, kp2, good)
EN

回答 1

Stack Overflow用户

发布于 2017-11-16 11:19:57

根据你的要求,我假设你的意思是你有某种封闭的轮廓,勾勒出你想要将你的数据点对绑定到的区域。

这是相当简单的多边形等高线和更多的数学是需要更复杂的曲线,但解决办法是一样的。

你画一条从所讨论的点到无穷远的线。大多数人把一条线画成+x无穷大,但是任何方向都是可行的。如果有一个奇数的线交点,点在轮廓内。

参见本文:http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/

对于点对,只有两个点都在等高线内的对才完全在等高线内。对于具有凹面段的复杂轮廓形状,如果还想测试点之间的直线路径不与轮廓交叉,则对两个点之间的线段执行类似的测试,如果存在任何直线交叉点,则点之间在等高线之外交叉。

编辑:

因为你的轮廓是矩形,一个简单的方法就足以确定你的点是否在矩形内。

如果你的矩形是轴对齐的(它们是直的,不是旋转的),那么你可以用你的值来检查上、左、下、右。

让点A=顶,左,点B=下,右,点C=你的测试点。

我假设一个基于图像的坐标系,0,0是图像的左上方,宽度、高度是右下角。(我是用C#写的)

代码语言:javascript
运行
AI代码解释
复制
bool PointIsInside(Point A, Point B, Point C)
{
    if (A.X <= C.X && B.X >= C.X   &&   A.Y <= C.Y && B.Y >= C.Y)
        return true;
    return false;
}

如果矩形未对齐,则可以执行四次半空间测试,以确定您的点是否位于矩形内。

设点A=顶,左,点B=下,右,双W=宽,双H=高,双N=旋转角,C点=测试点。

对于轴对齐的矩形,可以通过取矢量(1,0),乘以宽度,并将该向量添加到顶部,向左,来计算上、右。对于底部,我们取向量(0,1),乘以高度,然后加到顶部,对。

(1, 0 )等于角0处的单位向量(长度为1)。同样,(0,1)是一个90度角的单位向量。这些矢量也可以被认为是直线指向的方向。这也意味着这些相同的向量可以用于从底部,左到下,右,从上,左到下,左以及左。

我们需要使用不同的单位向量,在提供的角度。为此,我们只需取给定角度的余弦和正弦。

设向量X=从上到上,从左到顶,从右到右,向量Y=从上到下,从右到右。

我在这个例子中用角度表示。

代码语言:javascript
运行
AI代码解释
复制
Vector X = new Vector();
Vector Y = new Vector();
X.X = Math.Cos(R);
X.Y = Math.Sin(R);
Y.X = Math.Cos(R+90);
Y.Y = Math.Sin(R+90);

因为我们从Top开始,左边,我们可以找到底部,右边,只需简单地将两个向量添加到Top,左侧

代码语言:javascript
运行
AI代码解释
复制
Point B = new Point();
B = A + X + Y;

我们现在想用点积来做半空间测试。前两个测试将使用测试点,顶部,左边,其他两个将使用测试点,以及底部,右边。

半空间测试本质上是基于方向性的。点是在前面,后面,还是垂直于给定的方向?我们有我们需要的两个方向,但它们是基于矩形的顶部,左点,而不是图像的全部空间,所以我们需要得到一个向量,从上,左,到所讨论的点,另一个从底部,右边,因为这是我们测试的两个点。

这是很简单的计算,因为它只是目的地-起源。

设向量D=顶部,左到测试点C,向量E=底部,右到测试点。

代码语言:javascript
运行
AI代码解释
复制
Vector D = C - A;
Vector E = C - B;

点积是两个向量的x1 * x2 + y1*y2。如果结果是正的,则这两个方向的绝对角度小于90度,或者大致是沿着相同的方向运动,零的结果表示它们是垂直的。在我们的例子中,它意味着测试点直接位于我们要测试的矩形的一侧。小于零意味着一个大于90度的绝对角度,或者它们大致是相反的方向。

如果点位于矩形内,则左上角的点积将为>= 0,而右下角的点积将为<= 0。从本质上说,测试点在从左上角进行测试时更接近右下角,但是当我们已经在右下角时,当我们选择相同的方向时,测试点就会离开,向上,向左。

代码语言:javascript
运行
AI代码解释
复制
double DotProd(Vector V1, Vector V2)
{
    return V1.X * V2.X + V1.Y * V2.Y;
}

所以我们的测试结果是:

代码语言:javascript
运行
AI代码解释
复制
if( DotProd(X, D) >= 0 && DotProd(Y, D) >= 0    &&    DotProd(X, E) <= 0 && DotProd(Y, E) <= 0)

然后点在矩形内。对这两个点执行此操作,如果两者都为真,则这条线位于矩形内。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47337200

复制
相关文章
NaN和Infinity,null和undefined
看到这个标题,大家对这4个变量应该都不陌生,但若说起他们的差别或者是举个小栗子判断结果,估计就有点晕乎乎的了。
jojo
2022/04/01
1.2K0
原 NaN和Infinity,null和u
作者:汪娇娇 日期:2016.10.10 看到这个标题,大家对这4个变量应该都不陌生,但若说起他们的差别或者是举个小栗子判断结果,估计就有点晕乎乎的了。 1、NaN和Infinity 那先来说说JavaScript的数据类型,有Number、字符串、布尔值、对象等等,而NaN和Infinity就属于Number类型。先说说它俩的差别: NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示 Infinity; // Infinity表示无限大,当数值超过了JavaScript的Nu
jojo
2018/05/03
1.1K0
java中double的NAN和INFINITY
在开发中double的处理时会出现NAN(无穷小)和INFINITY(无穷大)的情况,所以我们需要在这种情况时加一下处理
余生大大
2022/10/25
1.2K0
[C] C语言中的nan和inf使用
本文总结nan和inf在C语言当中的含义、产生和判定方法。 C语言当中的nan 表示not a number,等同于 #IND:indeterminate (windows) 产生: 对浮点数进行了未定义的操作;
轻舞飞扬SR
2021/02/24
3.5K0
C语言中switch语句_switch在c语言中
本篇文章帮大家学习c语言switch语句,包含了C语言switch语句使用方法、操作技巧、实例演示和注意事项,有一定的学习价值,大家可以用来参考。
全栈程序员站长
2022/09/27
2.7K0
ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’).
笔者在使用LogisticRegression模型进行预测时,报错 Traceback (most recent call last): File “D:/软件(学习)/Python/MachineLearing/taitannike/train.py”, line 55, in predicted_np = clf.predict(test_np) File “D:\Python\Anaconda\lib\site-packages\sklearn\linear_model\base.py”, line 281, in predict scores = self.decision_function(X) File “D:\Python\Anaconda\lib\site-packages\sklearn\linear_model\base.py”, line 257, in decision_function X = check_array(X, accept_sparse=‘csr’) File “D:\Python\Anaconda\lib\site-packages\sklearn\utils\validation.py”, line 573, in check_array allow_nan=force_all_finite == ‘allow-nan’) File “D:\Python\Anaconda\lib\site-packages\sklearn\utils\validation.py”, line 56, in _assert_all_finite raise ValueError(msg_err.format(type_err, X.dtype)) ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’). Age False
全栈程序员站长
2022/09/03
1.6K0
ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’).
从Ndom语浅谈语言中的进制
这题粗看复杂,其实不然。首先不难看出,abo、an并不是数字,所以不是加法就是乘法。因为abo出现的十分多,所以我们可以简单地假设abo是加法。接下来需要确定进制。我们知道1-10的乘方之间,出现了三个单独的词。不难得出,肯定1个是1,一个是基数的平方。除了这两个,只剩一个单独的词,那么这个词只可能是2^2=4。由此我们可以确定,Ndom语言的数字表达的基数肯定大于4且小于9。因为nif为很多长词的开头,所以nif应该是基数的平方。在题2的等式我们发现meregh乘上sas结尾的词,结果竟然还是以meregh尾!所以很明显sas就是1,于是thonith就是4。接着找,就找到了余下几个小于基数的词(于abo、an之后的较小):ithin、meregh、thef(可能是2、3、5)。剩下的mer、nif、tondor估计就是基数的倍数了,通过观察nif abo tondor abo mer abo thonith,发现nif>tondor>mer。按照推论,mer abo ithin应该是第三小的数字——9,那么mer应该就是基数了。ithin肯定不是1、4,所以排除5、8进制可能。那么就只剩下6、7进制两种可能了。分析得mer an thef abo thonith是第4小的,即16。mer*thef+4=16⇒mer*thef=12。所以只有一种可能:Ndom语言的数字是6进制。所以mer为6,thef为2,nif是mer的平方即36,ithin是9-6=3。排除法得,meregh是5。最后还有一个tondor,通过推断tondor abo mer abo sas≥6*2+6+1=19最近的平方数是25,可以判断tondor是18。至此,我们已经推断完成所有的词。剩下就是一些小小的规则,比如表示72,并不是nif an thef,而是直接nif thef。还有就是大的数字一定会在前。所以我们就能写出:58=36+18+4也就是nif abo tondor abo thonith,而87=36*2+6*2+3即nif thef abo mer an thef abo ithin。参考答案:
KAAAsS
2022/01/13
11.3K0
从Ndom语浅谈语言中的进制
为什么在Go语言中要慎用interface{}
在掘金上看到一篇从java转Go思想上的变化以及对go语言思考的文章,写的很透彻,我也推敲了一遍。这里也分享给大家,或许对将要或者已经学习golang的同学有所帮助。提示:代码块可以左右拖动哦~~
我的小碗汤
2018/08/22
1.4K0
为什么在Go语言中要慎用interface{}
void loop在c语言中什么意思,C语言中的loop是什么意思,在C语言中loop是什么意思?…[通俗易懂]
另附上goto,break, continue和return用法:=========================================== 程序中的语句通常总是按顺序方向, 或按语句功能所定义的方向执行的。
全栈程序员站长
2022/08/30
2.7K0
GCC在C语言中内嵌汇编-转载
在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作。 1、简单的内嵌汇编 例:
战神伽罗
2019/07/24
2.9K0
为什么不带参数的 Math.max() 返回-Infinity
Math.max() 是 JS 内置的方法,可以从传入的参数中,返回最大的一个。例如:
前端小智@大迁世界
2022/06/15
1.1K0
system在c语言中_c语言system返回值
C 库函数 int system(const char *command) 把 command 指定的命令名称或程序名称传给要被命令处理器执行的主机环境,并在命令完成后返回。
全栈程序员站长
2022/09/29
1.9K0
在c语言中,数组 a[i++] 和数组 a[++i] 有区别吗? && 在c语言中,数组 a[0]++; 又是什么意思?
b = a++;    //先计算表达式的值,即先把a赋值给了b;然后a再自加1。 b = ++a;    //先a自加1后;然后把a自加后得到的赋值给b。
黑泽君
2018/10/11
3.4K0
JavaScript面向对象编程指南 第一、二章知识点整理
第一章、 面向对象的JavaScript 面向对象程序设计(OOP,Object -Oriented Programming)中最常用到的概念: 对象:是指"事物"在程序设计语言中的表现形式。 这里的"事物"可以是任何东西。例如,对于猫这种常见对象来说,我们可以看到它们具有某些明确的特征(如颜色、名字、体型等),能执行某些动作(如喵喵叫、睡觉等)。在OOP语义中,这些对象特征都叫做属性,而那些动作则被称为方法。 类:在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称
小胖
2018/06/27
4050
0.1+0.2=0.30000000000000004问题的探究
首先声明这不是bug,原因在与十进制到二进制的转换导致的精度问题!其次这几乎出现在很多的编程语言中:C/C++,Java,Javascript中,准确的说:“使用了IEEE 754浮点数格式”来存储浮点类型(float 32,double 64)的任何编程语言都有这个问题!
mmzhou
2018/08/01
6990
c/c++ -nan(ind) NAN
nan -- 表示 出错,“不是一个数” not a number 的缩写。 按 IEEE 754 国际标准,当运算中出现无效数据时,给出 NaN. 许多情况会出现,例如 0 除 0,负数开平方,...
acoolgiser
2019/01/17
3.5K0
C语学习之 getchar() putchar()
// 使用getchar() 和puchar()演示 #include "stdafx.h" int main(int argc, char* argv[]) { char a,b,c,d,e; printf("请输入5个字符:\n"); a=getchar(); b=getchar(); c=getchar(); d=getchar(); e=getchar(); putchar(a); putchar(b); putchar(c); putchar(d); putchar(e)
明明如月学长
2021/08/27
1.7K0
lodash源码分析之NaN不是NaN
暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面。 ——梁文道《暗恋到偷窥》 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 本篇分析的是 eq 函数。 作用与用法 eq 函数用来比较两个值是否相等。遵循的是 SameValueZero 规范。 var obj1 = {test: 1} var obj2 = {test: 1} var obj3 =
对角另一面
2018/03/30
1.9K0
lodash源码分析之NaN不是NaN
本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
1.8K0
原 三、基本概念
作者:汪娇娇 时间:2017年11月4日 一、语法 1、区分大小写 2、标识符 指变量、函数、属性的名字,采用驼峰大小写格式。 3、注释 单行:// 多行:/*  */ 4、严格模式 "use strict" 5、语句 以一个分号结尾,代码块用{}包起来。 二、关键字和保留字 关键字有指定用途; break do instanceof typeof case else new var catch finally return void continue for switch whil
jojo
2018/05/03
9460

相似问题

C语言中带有NAN、INFINITY和-INFINITY的冒泡排序

113

java NaN和-infinity

215

为什么我的代码返回NAN和Infinity?

16

为什么Math.pow(1,Infinity)返回NaN?

42

禁用Infinity和NaN异常

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档