IOU求重叠面积函数,部分代码不太理解 求助
本帖最后由 benson0308 于 2023-12-7 13:54 编辑源代码:
%%%%%%%%%%%%%%%%%%%%%
%{
*函 数 名:is_overlap
*功能描述: 判断两个库位是否匹配,即是否为同一库位
*输入参数:Slot1 - 全局坐标系下的库位1
* Slot2 - 全局坐标系下的库位1
* threshold - 判断是否重叠的阈值,0-1,值越大代表重叠度越高,1代表完全重叠
*输出参数: ret
0 - Slot1和Slot2不匹配
1 - Slot1和Slot2匹配
%}
function ret=is_overlap(Slot1, Slot2, threshold)
point.x=single(0);
point.y=single(0);
pt_Slot1=repmat(point,4,1);
pt_Slot2=repmat(point,4,1);
Slot1.p0_x = (round(Slot1.p0_x*10000))./10000;
Slot1.p0_y = (round(Slot1.p0_y*10000))./10000;
Slot1.p1_x = (round(Slot1.p1_x*10000))./10000;
Slot1.p1_y = (round(Slot1.p1_y*10000))./10000;
Slot1.p2_x = (round(Slot1.p2_x*10000))./10000;
Slot1.p2_y = (round(Slot1.p2_y*10000))./10000;
Slot1.p3_x = (round(Slot1.p3_x*10000))./10000;
Slot1.p3_y = (round(Slot1.p3_y*10000))./10000;
pt_Slot1(1).x=Slot1.p0_x;pt_Slot1(1).y=Slot1.p0_y;
pt_Slot1(2).x=Slot1.p1_x;pt_Slot1(2).y=Slot1.p1_y;
pt_Slot1(3).x=Slot1.p2_x;pt_Slot1(3).y=Slot1.p2_y;
pt_Slot1(4).x=Slot1.p3_x;pt_Slot1(4).y=Slot1.p3_y;
pt_Slot1_PN = length(pt_Slot1);
Slot2.p0_x = (round(Slot2.p0_x*10000))./10000;
Slot2.p0_y = (round(Slot2.p0_y*10000))./10000;
Slot2.p1_x = (round(Slot2.p1_x*10000))./10000;
Slot2.p1_y = (round(Slot2.p1_y*10000))./10000;
Slot2.p2_x = (round(Slot2.p2_x*10000))./10000;
Slot2.p2_y = (round(Slot2.p2_y*10000))./10000;
Slot2.p3_x = (round(Slot2.p3_x*10000))./10000;
Slot2.p3_y = (round(Slot2.p3_y*10000))./10000;
pt_Slot2(1).x=Slot2.p0_x;pt_Slot2(1).y=Slot2.p0_y;
pt_Slot2(2).x=Slot2.p1_x;pt_Slot2(2).y=Slot2.p1_y;
pt_Slot2(3).x=Slot2.p2_x;pt_Slot2(3).y=Slot2.p2_y;
pt_Slot2(4).x=Slot2.p3_x;pt_Slot2(4).y=Slot2.p3_y;
pt_Slot2_PN = length(pt_Slot2);
p0_sqrt = sqrt((Slot1.p0_x - Slot2.p0_x)^2 + (Slot1.p0_y - Slot2.p0_y)^2);
p1_sqrt = sqrt((Slot1.p1_x - Slot2.p1_x)^2 + (Slot1.p1_y - Slot2.p1_y)^2);
p2_sqrt = sqrt((Slot1.p2_x - Slot2.p2_x)^2 + (Slot1.p2_y - Slot2.p2_y)^2);
p3_sqrt = sqrt((Slot1.p3_x - Slot2.p3_x)^2 + (Slot1.p3_y - Slot2.p3_y)^2);
if ((p0_sqrt < 0.3) && (p1_sqrt < 0.3) && (p2_sqrt < 0.3) && (p3_sqrt < 0.3))
ret = 1;
return;
else
end
%排序
pc1=pointsOrdered(pt_Slot1, pt_Slot1_PN);
pc2=pointsOrdered(pt_Slot2, pt_Slot2_PN);
inter=intersectPolygonSHPC(pc1,pc2);
pc_inter=pointsOrdered2(inter);
if pc_inter.size<=0 || pc1.size<=0
proportion = single(0);
else
proportion = computeArea(pc_inter)/computeArea(pc1);
end
% proportion = polyarea(,)/polyarea(,);
if proportion>threshold
ret=1;
else
ret=0;
end
% plot(,,'b',,,'g',,,'r')
end
function res=intersectPolygonSHPC(Slot1,Slot2)
n=Slot1.size;
point.x=single(0);
point.y=single(0);
res.point=repmat(point,16,1);
% res.size = uint8(0);
res.size = 0;
p1=res;
dir = left_of(Slot2.point(1), Slot2.point(2), Slot2.point(3));
Slot1_temp=res;
Slot2_temp=res;
for k=1:Slot1.size
Slot1_temp.point(k).x=Slot1.point(k).x;
Slot1_temp.point(k).y=Slot1.point(k).y;
Slot1_temp.size=Slot1.size;
end
for k=1:Slot2.size
Slot2_temp.point(k).x=Slot2.point(k).x;
Slot2_temp.point(k).y=Slot2.point(k).y;
Slot2_temp.size=Slot2.size;
end
p2=poly_edge_clip(Slot1_temp,Slot2_temp.point(n), Slot2_temp.point(1), dir);
for i =1:n-1
tmp = p2;
p2 = p1;
p1 = tmp;
p2=poly_edge_clip(p1, Slot2_temp.point(i), Slot2_temp.point(i+1), dir);
end
index=0;
for i =1:p2.size
index=index+1;
res.point(index)=p2.point(i);
res.size = res.size + 1;
end
end
function res=poly_edge_clip(sub,x0,x1,left)
n=sub.size;
point.x=single(0);
point.y=single(0);
res.point=repmat(point,16,1);
res.size = 0;
if n==0
return;
end
v0=sub.point(n);
side0 = left_of(x0, x1, v0);
if side0 ~=-left
res.size=res.size+1;
res.point(res.size).x=v0.x;
res.point(res.size).y=v0.y;
end
for i=1:n
v1 = sub.point(i);
side1 = left_of(x0, x1, v1);
if ((side0 + side1 == 0 )&& side0)
% /* last point and current straddle the edge */
=line_sect(x0, x1, v0, v1);
if (ret)
res.size=res.size+1;
res.point(res.size)=temp;
end
end
if (i == n)
break;
end
if (side1 ~= -left)
res.size=res.size+1;
res.point(res.size).x=v1.x;
res.point(res.size).y=v1.y;
end
v0 = v1;
side0 = side1;
end
end
function =line_sect(x0,x1,y0,y1)
ret = 1;
temp.x = single(0);
temp.y = single(0);
dx=vsub(x1, x0);
dy=vsub(y1, y0);
d=vsub(x0, y0);
dyx = cross(dy, dx);
if (~dyx)
ret= 0;
return;
end
dyx = cross(d, dx) / dyx;
if (dyx <= 0 || dyx >= 1)
ret= 0;
return;
end
temp.x = (y0.x + dyx * dy.x);
temp.y = (y0.y + dyx * dy.y);
ret= 1;
end
function ret=left_of(a,b,c)
ret = 0;
tmp1=vsub(b, a);%向量a->b
tmp2=vsub(c, b);
x = cross(tmp1, tmp2);%叉积
if x < 0
ret=-1;
elseif x == 0
ret=0;
else
ret=1;
end
end
function res=vsub(a,b)
point.x=single(0);
point.y=single(0);
res=point;
res.x = a.x - b.x;
res.y = a.y - b.y;
end
function ret=cross(a,b)
ret= a.x * b.y - a.y * b.x;
end
function pc=pointsOrdered(pt, pt_num)
% n=pt_num;
if( pt_num <= 0)
return;
end
center.x = mean();
center.y = mean();
temp.x=single(0);
temp.y=single(0);
temp.angle=single(0);
pc.point=repmat(temp,16,1);
pc.size = pt_num;
for i = 1:pt_num
pc.point(i).x = pt(i).x;
pc.point(i).y = pt(i).y;
pc.point(i).angle = atan2((pt(i).y - center.y), (pt(i).x - center.x));
end
pc.point=qsort(pc.point, pt_num, 1);%按角度升序排列,直角坐标系X轴为0度 从-pi到pi排列
for i = 1:pt_num
pt(i).x = pc.point(i).x;
pt(i).y = pc.point(i).y;
end
end
function pc=pointsOrdered2(pt)
n=pt.size;
temp.x=single(0);
temp.y=single(0);
temp.angle=single(0);
pc.point=repmat(temp,16,1);
pc.size = n;
if( n <= 0)
return;
end
center.x = single(0);
center.y = single(0);
for ii = 1:n
center.x = center.x + pt.point(ii).x;
center.y = center.y + pt.point(ii).y;
end
center.x = center.x/single(n);
center.y = center.y/single(n);
for i = 1:n
pc.point(i).x = pt.point(i).x;
pc.point(i).y = pt.point(i).y;
pc.point(i).angle = atan2((pt.point(i).y - center.y), (pt.point(i).x - center.x));
end
pc.point=qsort(pc.point, n, 1);
for i = 1:n
pt.point(i).x = pc.point(i).x;
pt.point(i).y = pc.point(i).y;
end
end
%comp_point_with_angle=1 升序,-1 降序
function ret=qsort(pc,n,comp_point_with_angle)
if comp_point_with_angle==1
for i=1:n
for j=i:n
if pc(i).angle>pc(j).angle
temp=pc(i);
pc(i)=pc(j);
pc(j)=temp;
end
end
end
else
for i=1:n
for j=i+n
if pc(i).angle<pc(j).angle
temp=pc(i);
pc(i)=pc(j);
pc(j)=temp;
end
end
end
end
ret=pc;
end
function area0=computeArea(pt)
area0 = single(0);
n=pt.size;
if n <= 0
return;
end
for i=1:n-1
area0 = area0+pt.point(i).x * pt.point(i+1).y;
area0 = area0-pt.point(i).y * pt.point(i+1).x;
end
area0 = area0+pt.point(n).x * pt.point(1).y;
area0 = area0-pt.point(n).y * pt.point(1).x;
area0 = 0.5*abs(area0);
end
%%%%%%%%%%%%%%%%%%%%%
其中line_sect模块什么作用,(dyx <= 0 || dyx > 1)作何筛选? 代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判断这两条线段是否相交,并计算它们的交点坐标。
在给定的函数中,line_sect 接收四个点作为输入,分别代表两条线段的起点和终点。它首先计算两条线段的斜率,然后判断两条线段是否相交。
代码中的 (dyx <= 0 || dyx >= 1) 是用来排除交点位置不在两条线段的端点之间的情况。dyx 是通过计算交点在两条线段上的比例,判断其位置是否在两条线段的范围内。如果交点的比例小于等于 0 或者大于等于 1,意味着交点在延长线上而不在两条线段之间,因此不是线段的交点。
这个判断条件的作用是排除一些特殊情况,避免将不在线段上的点作为交点进行处理,确保得到的交点是有效的且位于两条线段之间的。 学习了,顶楼主 这是啥语言写的? ciker_li 发表于 2023-12-7 19:11
这是啥语言写的?
matlab.m 本帖最后由 benson0308 于 2023-12-8 09:17 编辑
qfxldhw 发表于 2023-12-7 15:32
代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判 ...
感谢楼主,我也找到一部分参考。
https://www.cnblogs.com/zhb2000/p/vector-cross-product-solve-intersection.html#:~:text=%E5%A6%82%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%8C%E6%9C%89%E4%B8%A4%E6%9D%A1%E7%9B%B4%E7%BA%BF%E4%BA%A4%E4%BA%8E%E7%82%B9%20I%20%E3%80%82%20%E6%88%91%E4%BB%AC%E7%94%A8%E7%82%B9%20p%201%20%E5%92%8C%E5%90%91%E9%87%8F%20v qfxldhw 发表于 2023-12-7 15:32
代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判 ...
感谢楼主,我最近也在补相关知识。
代码是先用给矩形角点排序,然后利用叉乘判断矩形角点是否在另一矩形任一条线的同侧,如果异侧使用 line_sect函数求两线段交点。
页:
[1]