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 IOutputArray
2. 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!