using Emgu.CV;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace BBIWARG.Utility
{
///
/// Computes and stores a homography matrix and provides functions to export it and project points.
///
internal class Projection2DTo2D
{
///
/// calibration points in the first image (match points in calibrationPointsB)
///
private List calibrationPointsA;
///
/// calibration points in the second image (match points in calibrationPointsA)
///
private List calibrationPointsB;
///
/// homography matrix used to compute the projected points
///
private HomographyMatrix homography;
///
/// number of points used for the calibration
///
private int numPointsForCalibration;
///
/// size of the image the original points are in
///
private ImageSize sizeA;
///
/// size of the image the projected points are in
///
private ImageSize sizeB;
///
/// true iff the calibration is finished
///
public bool IsCalibrated { get; private set; }
///
/// Constructs a Projection2DTo2D.
///
/// size of the image the original points are in
/// size of the image the projected points are in
/// number of points used for the calibration
public Projection2DTo2D(ImageSize sizeA, ImageSize sizeB, int numPointsForCalibration = 4)
{
this.sizeA = sizeA;
this.sizeB = sizeB;
this.numPointsForCalibration = numPointsForCalibration;
reset();
}
///
/// Adds a pair of calibration points.
///
/// point in the first image
/// point in the second image
public void addCalibrationPoints(Vector2D pointA, Vector2D pointB)
{
calibrationPointsA.Add(sizeA.getRelativePoint(pointA));
calibrationPointsB.Add(sizeB.getRelativePoint(pointB));
if (calibrationPointsA.Count == numPointsForCalibration)
calibrate();
}
///
/// Projects a point.
///
/// the point to project
/// projected point
public Vector2D projectPoint(Vector2D pointA)
{
PointF[] pointfsB = new PointF[1] { sizeA.getRelativePoint(pointA) };
homography.ProjectPoints(pointfsB);
return sizeB.getAbsolutePoint(new Vector2D(pointfsB[0]));
}
///
/// Resets the calibration.
///
public void reset()
{
homography = null;
IsCalibrated = false;
calibrationPointsA = new List();
calibrationPointsB = new List();
}
///
/// Computes the homography from the lists of calibration points.
///
private void calibrate()
{
homography = CameraCalibration.FindHomography(calibrationPointsA.ToArray(), calibrationPointsB.ToArray(), Emgu.CV.CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 0.995);
calibrationPointsA.Clear();
calibrationPointsB.Clear();
IsCalibrated = true;
exportHomography();
}
///
/// Writes the homography to a file.
///
private void exportHomography()
{
String[] fileData = new String[homography.Size.Height];
StringBuilder sb = new StringBuilder();
for (int r = 0; r < homography.Size.Height; r++)
{
for (int c = 0; c < homography.Size.Width; c++)
{
sb.Append(homography.Data[r, c]);
sb.Append(" ");
}
fileData[r] = sb.ToString();
sb.Clear();
}
System.IO.File.WriteAllLines(Parameters.HomographyFileName, fileData);
}
}
}