该CvInvoke.FindChessboardCorners
方法具有此签名1:
public static bool FindChessboardCorners(
IInputArray image,
Size patternSize,
IOutputArray corners,
CalibCbType flags = CalibCbType.Default|CalibCbType.AdaptiveThresh|CalibCbType.NormalizeImage
)
第三个参数是类型2。我不明白他们为什么要引入这些由不能互换使用的各种类实现的超通用输入/输出接口。IOutputArray
您是对的,Matrix
该类确实实现了该接口(通过 super class CvArray
),因此您的代码可以编译。但是,CvInvoke.FindChessboardCorners
应该返回几个点(取决于模式的大小)。我搜索了实现IOutputArray
并找到了VectorOfPoints
. 这对我来说很有意义,比使用Matrix
.
我编写了一个用于校准的小控制台应用程序,该应用程序从目录中读取所有图像文件并检测其中的角点,因为对我来说,预先捕获图像更有意义。
这应该给你一个起点:
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();
}
}
由于某种原因,我无法CvInvoke.DrawChessboardCorners
执行。它没有在合理的时间内完成函数的执行。这就是为什么我将结果打印到Console
,这对我来说是这样的:

我在图像编辑器中直观地验证了一些,它们似乎是正确的。
tl;博士
选择一个合适的类型,它可以表示一个点列表并实现IOutputArray
类似VectorOfPoints
的例子。
1有人说返回类型不包含在签名中,因此将上述称为签名可能完全是胡说八道,但是当我说“签名”时,您仍然会明白。
2现在这是一些有用的文档!