我需要一个"检查"如果4个给定点形成正方形或菱形。
我正在使用QR代码分段脚本,在该脚本中,我尝试通过查找按行和列遍历的二进制图像的非负值来定位顶点。
在某些情况下,检查不是必需的,如下图所示:
有点难以看到,但顶点被标记为绿色,品红色,青色和黄色的4个点。在这种情况下,脚本应该返回相同的输入点,因为不需要修改。
另一方面,有些情况下顶点标记为:
可以看出,品红色和青色标签依赖于图像的右上角。这显然不正确,但它满足指定的条件:遍历图像的每一行,直到找到满足sum(row)>1
的行(大于1以避免单个噪声像素)。
如何找到错位的顶点并使用剩余的顶点坐标放置它?
修改
解决了这个问题。我发布了函数的代码,以防有人需要它:
function correctedCorners = square(corners)
correctedCorners = corners;
X = corners(:,1);
Y = corners(:,2);
sortedX = sort(corners(:,1));
sortedY = sort(corners(:,2));
%% DISTANCES BW POINTS
for i=1:4
for j=1:4
distances(i,j) = sqrt((corners(i,1)-corners(j,1))^2+ (corners(i,2)-corners(j,2))^2);
end
end
%% relationship bw distances
% check corner 1
d11 = distances(1,1);%0
d12 = distances(1,2);%x
d13 = distances(1,3);%sqrt(2)*x
d14 = distances(1,4);%x
bool1 = [(d12*0.8<=d14)&(d12*1.2>=d14) (d12*0.8*sqrt(2)<=d13)& (d12*1.2*sqrt(2)>=d13) (d14*0.8<=d12)&(d14*1.2>=d12) (d14*0.8*sqrt(2)<=d13)&(d14*1.2*sqrt(2)>=d13)];
% check corner 2
d21 = distances(2,1);%x
d22 = distances(2,2);%0
d23 = distances(2,3);%x
d24 = distances(2,4);%sqrt(2)*x
bool2 = [(d21*0.8<=d23)&(d21*1.2>=d23) (d21*0.8*sqrt(2)<=d24)&(d21*1.2*sqrt(2)>=d24) (d23*0.8<=d21)&(d23*1.2>=d21) (d23*0.8*sqrt(2)<=d24)&(d23*1.2*sqrt(2)>=d24)];
% check corner 3
d31 = distances(3,1);%sqrt(2)*x
d32 = distances(3,2);%x
d33 = distances(3,3);%0
d34 = distances(3,4);%x
bool3 = [(d32*0.8<=d34)&(d32*1.2>=d34) (d32*0.8*sqrt(2)<=d31)&(d32*1.2*sqrt(2)>=d31) (d34*0.8<=d32)&(d34*1.2>=d32) (d34*0.8*sqrt(2)<=d31)&(d34*1.2*sqrt(2)>=d31)];
% check corner 4
d41 = distances(4,1);%x
d42 = distances(4,2);%sqrt(2)*x
d43 = distances(4,3);%x
d44 = distances(4,4);%0
bool4 = [(d41*0.8<=d43)&(d41*1.2>=d43) (d41*0.8*sqrt(2)<=d42)&(d41*1.2*sqrt(2)>=d42) (d43*0.8<=d41)&(d43*1.2>=d41) (d43*0.8*sqrt(2)<=d42)&(d43*1.2*sqrt(2)>=d42)];
bool = [bool1; bool2;bool3;bool4];
idx = 0;
for i=1:4
if (sum(bool(i,:))==0)
idx = [idx i];
end
end
if (length(idx)>=2)
for i=2:length(idx)
switch idx(i)
case 1
correctedCorners(1,:) = abs(corners(4,:)-(corners(3,:)-corners(2,:)));
case 2
correctedCorners(2,:) = abs(corners(3,:)-(corners(4,:)-corners(1,:)));
case 3
correctedCorners(3,:) = abs(corners(2,:)+(corners(1,:)-corners(1,:)));
case 4
correctedCorners(4,:) = abs(corners(1,:)+(corners(3,:)-corners(2,:)));
end
end
end
答案 0 :(得分:1)
关于正方形的基本几何:
将BotLeft的相同逻辑用于其他点等。
让自己承担10-20%的误差范围,以宣布错误的观点。也就是说,如果TopLeft距离范围之外的2个点(80%; 120%)* x,并且它到第三个点的距离超出了范围(80%; 120%)* sqrt(2)* x,您可以将该点声明为错误放置。
在您的情况下,TopLeft点在所有距离测试中失败:
只要菱形非常类似于正方形,将其视为正方形时误差为20%仍应有效。