我有一个关于从棋盘中找到角落的问题 . 我正在使用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 回答
在拉直点上工作 . 确定图像的斜率,例如通过取右上角和左上角的差值 . 见Rotation (mathematics) . 你也可以采取
-diff.Y
(减去因为我们想要向后旋转)和diff.X
为罪 . 获取这些"wrong"值的效果将导致缩放 .现在确定这些拉直点的x和y的最小值和最大值 . 您可以从这些信息中获得两条信息:1)距离坐标原点的偏移量 . 2)板的尺寸 . 现在重新缩放变换点以使它们具有0.0到8.0之间的坐标 . 现在,如果图像是完美的,则所有点的坐标都应该具有整数值 .
因为它们没有,所以围绕坐标使它们全部为整数 . 将这些整数坐标按y然后按x排序应该可以得到您想要的顺序 . 这是因为同一水平线上的点现在确实具有相同的y值 . 事实并非如此 . 由于它们可能都具有不同的y坐标,因此只有x的第二次排序才有效 .
为了对原始点进行排序,将已转换的点和原始点放入相同的类或结构(例如元组)中并将它们排序在一起 .