我需要一个脚本来“检查”给定的4个点是形成正方形还是菱形。
我正在使用QR码分段脚本,在其中尝试通过查找按行和列遍历二进制图像的非负值来定位顶点。
在某些情况下,不需要进行检查,如下图所示:
很难看到它,但是顶点被标记为4点,分别是绿色,品红色,青色和黄色。在这种情况下,脚本应该返回相同的输入点,因为不需要修改。
另一方面,在某些情况下,顶点被标记为:
It can be seen that the magenta and cyan labels rely on the top right corner of the image. This is obviously not correct, but it fullfills the specified condition: traverse each row of the image until you find a row satisfying sum(row)>1
(greater than 1 to avoid single, noisy pixels).
How can I locate the misplaced vertex and place it using the remaining vertex coordinates?
EDIT
Solved the problem. I'm posting the code of the function in case someone needs it:
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
From basic geometry about squares:
Use the same logic for BotLeft to other points, etc.
允许您自己输入10-20%的误差幅度,以声明不正确的点。也就是说,如果TopLeft到2个点的距离超出范围(80%; 120%)* x,并且它与第三点的距离超出范围(80%; 120%)* sqrt(2)* x,您可以将点声明为错误放置。
在您的情况下,TopLeft点在所有距离测试中均失败:
只要菱形与正方形非常相似,则将其视为正方形时仍可保持20%的误差范围。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句