如何使用FindChessboardCorners [英] How to use FindChessboardCorners

查看:223
本文介绍了如何使用FindChessboardCorners的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用新的EmguCV 3.0.0 alpha来检测带有网络摄像头的棋盘,并且对角矩阵有了解的问题.

  Size patternSize = new Size(5,4);矩阵< float>corners = new Matrix< float>(1,2);bool find = CvInvoke.FindChessboardCorners(grayFrame,patternSize,corners,CalibCbType.AdaptiveThresh | CalibCbType.FilterQuads);CvInvoke.DrawChessboardCorners(grayFrame,patternSize,corners,find);如果(找到){Console.Write(corners.Size);} 

将检测到棋盘并显示正确!

但是,拐角矩阵的大小必须为多大,我如何提取拐角位置?

我在互联网上找到的所有样本都使用了较旧版本的EmguCV,并且现在有一个完全不同的语法.我会使用较旧的版本,但较新的Alpha版速度更快,并且计时是我应用程序中的大问题.

解决方案

我在图像编辑器中目视验证了一些,似乎是正确的.

tl; dr

选择一个合适的类型,该类型可以表示点的列表,并实现 IOutputArray ,例如 VectorOfPoints .


1 有人说签名中不包含返回类型,因此在上面签名称为签名完全是胡说八道,但是当我说"签名".

2 现在这是一些有用的文档!

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.

解决方案

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!

这篇关于如何使用FindChessboardCorners的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆