How to use FindChessboardCorners

﹥>﹥吖頭↗ 提交于 2021-02-07 14:55:21

问题


i am using the new EmguCV 3.0.0 alpha to detect a chessboard with webcam and have an understanding problem with the corners matrix.

        Size patternSize = new Size(5, 4);
        Matrix<float> corners = new Matrix<float>(1, 2);

        bool find = CvInvoke.FindChessboardCorners(grayFrame, patternSize, corners, CalibCbType.AdaptiveThresh | CalibCbType.FilterQuads);
        CvInvoke.DrawChessboardCorners(grayFrame, patternSize, corners, find);
        if (find)
        {
            Console.Write(corners.Size);
        }

The chessboard will be detected and shown correct!

But, how big must be the size of the corners matrix and how do i extract the corner positions?

All samples i found on internet are using older versions of EmguCV and there is a complete different syntax now. I would use the older version but the newer alpha is much faster and timing is a big issue in my app.


回答1:


The CvInvoke.FindChessboardCorners Method has this signature1:

public static bool FindChessboardCorners(
    IInputArray image,
    Size patternSize,
    IOutputArray corners,
    CalibCbType flags = CalibCbType.Default|CalibCbType.AdaptiveThresh|CalibCbType.NormalizeImage
)

The third parameter is of type IOutputArray2. I do not understand why they introduced these super generic input/output interfaces that are implemented by various classes that cannot be used interchangeably.

You are right, the Matrix class does implement that interface (via super class CvArray) and thus your code compiles. However, CvInvoke.FindChessboardCorners is supposed to return a few points (depending on the size of the pattern). I googled for classes that implement IOutputArray and found VectorOfPoints. That kind of made sense to me, more so than using a Matrix.

I hacked together a little console app for calibration that reads all image files from a directory and detects the corners in them, because for me it makes more sense to capture the images beforehand.

That should give you a starting point:

public class Calibration
{
    static void Main(string[] args)
    {
        // chessboard pattern size
        Size patternSize = new Size(9, 7);

        // for each image, have one Image object and one VectorOfPoints
        // for many images have a List of each
        List<VectorOfPoint> corners = new List<VectorOfPoint>();
        List<Image<Gray, Byte>> images = new List<Image<Gray, byte>>();

        // get paths to image files
        string[] imageFiles = Directory.GetFiles(@"C:\your\directory", "*.jpg");

        // for every image
        foreach (string imageFile in imageFiles)
        {
            // create new image object from file path
            var image = new Image<Gray, byte>(imageFile);
            images.Add(image);

            // create new list of corner points
            var cornerPoints = new VectorOfPoint();
            corners.Add(cornerPoints);

            // find chessboard corners
            bool result = CvInvoke.FindChessboardCorners(image, patternSize, cornerPoints);

            // some debug output
            Console.WriteLine("=== " + Path.GetFileName(imageFile) + " === " + result);

            if (!result)
            {
                continue;
            }

            // list points
            foreach (Point cornerPoint in cornerPoints.ToArray())
            {
                Console.WriteLine(cornerPoint.X + ", " + cornerPoint.Y);
            }
        }

        Console.ReadLine();
    }
}

For some reason I could not get CvInvoke.DrawChessboardCorners to execute. It did not finish executing the function in a reasonable amount of time. That's why I printed the results to Console, which looks like this for me:

I verified a few visually in an image editor and they seem to be correct.

tl;dr

Pick an appropriate type that can represent a list of points and that implements IOutputArray like VectorOfPoints for example.


1 some say the return type is not included in a signature so calling the above a signature might be total nonsense, but you still get the idea when I say "signature".

2 now that's some useful documentation!



来源:https://stackoverflow.com/questions/29557197/how-to-use-findchessboardcorners

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!