How to sort found chessboard corners?

I have a question about sorting found corners from chessboard. I'm doing my program in C# using OpenCVSharp.

I need to sort found corners which are points described by X and Y. This is the part of my code:

...
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);
...

After that I'm displaying found corners in ImageBox:

see good order in all pictures

and this is the order of corners what I need always, but when I rotate the chessboard a bit - found corners changes like this:

see bad order in all pictures

I need always the same (like in picture 1) order of these points so I decided to use:

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

but it doesn't work like I want:

see bad result 1 in all pictures

see bad result 2 in all pictures

The main point is that my chessboard won't be rotated too much, just for a little angle. The second point is that the corners must be ordered from the first white square on the top left side of the board. I know, that the base point (0,0) is on the left top corner of the image and the positive values of Y are increasing in the direction to the bottom of image and positive values of X are increasing in direction to the right side of image.

I'm working on the program to obtain this ordering (these pistures are edited in picture editor):

see example 1 in all pictures

see example 2 in all pictures

Thanks for any help.

Answers


Work on straightened points. Determine the slope of the image, for instance by taking the difference of the upper right and upper left points. See Rotation (mathematics). Instead of taking the cos you could as well take -diff.Y (the minus because we want to rotate back) and diff.X for the sin. The effect of taking these "wrong" values will result in a scaling.

Now determine the minimum and maximum of x and y of these straightened points. You get two pieces of information from these: 1) an offset from the coordinate origin. 2) The size of the board. Now rescale the transformed point to make them have coordinates between 0.0 and 8.0. Now if the image was perfect all the points’ coordinates should have integer values.

Because they don't, round the coordinates to make them all integers. Sorting these integer coordinates by y and then by x should yield your desired order. This is because the points on the same horizontal line now really have the same y value. This was not the case before. Since they probably all had different y-coordinates, only the second sorting by x had an effect.

In order to sort the original points, put the transformed ones and the original ones into the same class or struct (e.g. a Tuple) and sort them together.


Need Your Help

Android app keeps crashing with tabhost

android android-layout android-tabhost crash

My goal is to have two tabs created, each with a different activity. I want the tabs to always be visible at the top so I can easily switch between the two. I believe to have everything set up to c...