Common Vision Blox 15.1
Loading...
Searching...
No Matches
Foundation/Cvb.Net/Metric3DCalibration

This example program is located in your CVB installation under %CVB%Tutorial/Foundation/Cvb.Net/Metric3DCalibration.

Program.cs:

// Example for **intrinsic and extrinsic calibration** of a laser triangulation system using the AQS12
// target.

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
using System;
namespace Metric3DCalibration
{
using ExtensionMethods;
class Program
{
static void Main(string[] args)
{
Console.Write("Estimation of homography and affine transformation (correcting an inclined laser plane)\n\n");
var piece = GetAQS12Piece();
var segmentor = new AQS12RangeMapSegmentor(SegmentationMethod.KmeansClustering);
var rangeMap = Image.FromFile(@"%CVB%\Tutorial\Metric\Images\RangeMapCalibrationPattern.tif");
Console.Write("Rangemap loaded with size of " + rangeMap.Width.ToString() + " x " + rangeMap.Height.ToString() + " from ");
Console.Write(@"%CVB%\Tutorial\Metric\Images\RangeMapCalibrationPattern.tif" + "\n");
var calibrator = Metric.CalibratorFromAqs12Piece(rangeMap.Planes[0], segmentor, config, out Point3Dd[] residuals);
calibrator.CorrectionOfLaserPlaneInclination.Item1.Value.ShowTransformation();
calibrator.CorrectionOfLaserPlaneInclination.Item2?.ShowTransformation();
Console.Write("Residuals:\n");
residuals.ShowXYZArray();
double desiredAccuracy = 0.05;
if (!residuals.CheckAccuracy(desiredAccuracy))
{
Console.Write("Results do not have desired accuracy. Check face segmentation and extracted AQS12 points...\n");
_ = segmentor.FaceSegmentationFromPiece(rangeMap.Planes[0]);
var pointsAqs12 = segmentor.ExtractProjectedPointsFromPiece(rangeMap.Planes[0]);
Console.Write("Extracted points from range map:\n");
pointsAqs12.ShowXYZArray();
}
else
{
var calibratedCloud = calibrator.CreatePointCloud(rangeMap, PointCloudFlags.Float);
Console.Write("The calibration was sucessful and accuracy is < " + desiredAccuracy.ToString() +
$" mm. :)\nPointCloud has the following DataType: {calibratedCloud.DataType}");
}
}
public static AQS12Piece GetAQS12Piece()
{
var points = new Point3Dd[]
{
new(20.0018, 44.9941, 15.0000),
new(24.0018, 39.9942, 14.9994),
new(23.9994, 24.9972, 15.0001),
new(20.0021, 20.0035, 15.0011),
new(15.9994, 25.0079, 15.0016),
new(16.0000, 39.9919, 15.0010),
new(20.0095, 59.9985, 4.9902),
new(32.0093, 44.9958, 4.9909),
new(32.0052, 19.9925, 4.9920),
new(20.0021, 4.9961, 4.9939),
new( 8.0024, 19.9980, 5.0009),
new( 8.0065, 45.0009, 4.9984)
};
return new AQS12Piece(points, 0);
}
}
namespace ExtensionMethods
{
public static class Extensions
{
public static void ShowTransformation(this AffineMatrix3D trafo)
{
System.Text.StringBuilder sMessage = new System.Text.StringBuilder();
sMessage.Append("Translation:\n");
sMessage.Append(trafo.Translation.ToString());
sMessage.Append("\n\nTransformation matrix:\n");
sMessage.Append(trafo.Matrix.ToString());
sMessage.Append("\n\n");
Console.Write(sMessage.ToString());
}
public static void ShowTransformation(this AffineTransformationParameters trafoPara)
{
System.Text.StringBuilder sMessage = new System.Text.StringBuilder();
sMessage.Append("Rotation angles in [degree] about\n");
sMessage.Append("X: " + trafoPara.RotationAngles[0].ToString("N4") + "\n");
sMessage.Append("Y: " + trafoPara.RotationAngles[1].ToString("N4") + "\n");
sMessage.Append("Z: " + trafoPara.RotationAngles[2].ToString("N4") + "\n\n");
sMessage.Append("Inclination of laser plane in [degree] about\n");
sMessage.Append("X: " + trafoPara.InclinationX.ToString("N4") + "\n");
sMessage.Append("Z: " + trafoPara.InclinationZ.ToString("N4") + "\n\n");
sMessage.Append("Shear\n");
sMessage.Append("Syz: " + trafoPara.Syz.ToString("N5") + "\n");
sMessage.Append("Syx: " + trafoPara.Syx.ToString("N5") + "\n\n");
sMessage.Append("Scale\n");
sMessage.Append("X: " + trafoPara.Scale.X.ToString("N3") + "\n");
sMessage.Append("Y: " + trafoPara.Scale.Y.ToString("N3") + "\n");
sMessage.Append("Z: " + trafoPara.Scale.Z.ToString("N3") + "\n\n");
Console.Write(sMessage.ToString());
}
public static void ShowXYZArray(this Point3Dd[] xyz)
{
System.Text.StringBuilder sMessage = new System.Text.StringBuilder();
sMessage.Append("Point \t X \t Y \t Z \n");
for (int i = 0; i < 12; i++)
sMessage.Append(i + 1 + "\t" + xyz[i].X.ToString("N4") + " " + xyz[i].Y.ToString("N4") + " " + xyz[i].Z.ToString("N4") + "\n");
sMessage.Append("\n");
Console.Write(sMessage.ToString());
}
public static bool CheckAccuracy(this Point3Dd[] residuals, double desiredAccuracy)
{
foreach (Point3Dd residual in residuals)
{
if (residual.X > desiredAccuracy || residual.Y > desiredAccuracy || residual.Z > desiredAccuracy)
return false;
}
return true;
}
}
} // namespace ExtensionMethods
}
static CalibrationConfiguration FromAQS12Piece(AQS12Piece piece)
static LaserPlaneHomographyCalibrator3D CalibratorFromAqs12Piece(ImagePlane rangeMapPlane, AQS12RangeMapSegmentor segmentor, CalibrationConfiguration config, out Point3Dd[] residuals)
Tuple< AffineMatrix3D?, AffineTransformationParameters?> CorrectionOfLaserPlaneInclination
__int3264 Image
readonly override string ToString()
readonly override string ToString()