首页 文章

如何对找到的棋盘角进行排序?

提问于
浏览
1

我有一个关于从棋盘中找到角落的问题 . 我正在使用OpenCVSharp在C#中执行我的程序 .

我需要对找到的角进行排序,这些角是由X和Y描述的点 . 这是我的代码的一部分:

...
CvPoint2D32f[] corners;
bool found = Cv.FindChessboardCorners(gray, board_sz, out corners, out corner_count,
    ChessboardFlag.NormalizeImage | ChessboardFlag.FilterQuads);
Cv.FindCornerSubPix(gray, corners, corner_count, new CvSize(11,11), new CvSize(-1,-1),
    Cv.TermCriteria(CriteriaType.Epsilon | CriteriaType.Iteration, 30, 0.1));

Cv.DrawChessboardCorners(img1, board_sz, corners, found);
...

之后我在ImageBox中显示找到的角落:

see good order in all pictures

这是我需要的角落的顺序,但是当我旋转棋盘时 - 找到的角落改变如下:

see bad order in all pictures

我需要总是相同的(如图1所示)这些点的顺序所以我决定使用:

var ordered = corners.OrderBy(p => p.Y).ThenBy(p => p.X);
corners = ordered.ToArray();

但它不能像我想的那样工作:

see bad result 1 in all pictures

see bad result 2 in all pictures

重点是我的棋盘不会旋转太多,只是一点角度 . 第二点是必须从电路板左上角的第一个白色方块订购角落 . 我知道,基点(0,0)位于图像的左上角,Y的正值在图像底部的方向上增加,而X的正值在朝向右侧的方向上增加图像

我正在制定程序以获得此订购(这些活动在图片编辑器中编辑):

see example 1 in all pictures

see example 2 in all pictures

谢谢你的帮助 .

1 回答

  • 1

    在拉直点上工作 . 确定图像的斜率,例如通过取右上角和左上角的差值 . 见Rotation (mathematics) . 你也可以采取 -diff.Y (减去因为我们想要向后旋转)和 diff.X 为罪 . 获取这些"wrong"值的效果将导致缩放 .

    现在确定这些拉直点的x和y的最小值和最大值 . 您可以从这些信息中获得两条信息:1)距离坐标原点的偏移量 . 2)板的尺寸 . 现在重新缩放变换点以使它们具有0.0到8.0之间的坐标 . 现在,如果图像是完美的,则所有点的坐标都应该具有整数值 .

    因为它们没有,所以围绕坐标使它们全部为整数 . 将这些整数坐标按y然后按x排序应该可以得到您想要的顺序 . 这是因为同一水平线上的点现在确实具有相同的y值 . 事实并非如此 . 由于它们可能都具有不同的y坐标,因此只有x的第二次排序才有效 .

    为了对原始点进行排序,将已转换的点和原始点放入相同的类或结构(例如元组)中并将它们排序在一起 .

相关问题