Projection2DTo2D.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using Emgu.CV;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Text;
  6. namespace BBIWARG.Utility
  7. {
  8. /// <summary>
  9. /// Computes and stores a homography matrix and provides functions to export it and project points.
  10. /// </summary>
  11. internal class Projection2DTo2D
  12. {
  13. /// <summary>
  14. /// calibration points in the first image (match points in calibrationPointsB)
  15. /// </summary>
  16. private List<PointF> calibrationPointsA;
  17. /// <summary>
  18. /// calibration points in the second image (match points in calibrationPointsA)
  19. /// </summary>
  20. private List<PointF> calibrationPointsB;
  21. /// <summary>
  22. /// homography matrix used to compute the projected points
  23. /// </summary>
  24. private HomographyMatrix homography;
  25. /// <summary>
  26. /// number of points used for the calibration
  27. /// </summary>
  28. private int numPointsForCalibration;
  29. /// <summary>
  30. /// size of the image the original points are in
  31. /// </summary>
  32. private ImageSize sizeA;
  33. /// <summary>
  34. /// size of the image the projected points are in
  35. /// </summary>
  36. private ImageSize sizeB;
  37. /// <summary>
  38. /// true iff the calibration is finished
  39. /// </summary>
  40. public bool IsCalibrated { get; private set; }
  41. /// <summary>
  42. /// Constructs a Projection2DTo2D.
  43. /// </summary>
  44. /// <param name="sizeA">size of the image the original points are in</param>
  45. /// <param name="sizeB">size of the image the projected points are in</param>
  46. /// <param name="numPointsForCalibration">number of points used for the calibration</param>
  47. public Projection2DTo2D(ImageSize sizeA, ImageSize sizeB, int numPointsForCalibration = 4)
  48. {
  49. this.sizeA = sizeA;
  50. this.sizeB = sizeB;
  51. this.numPointsForCalibration = numPointsForCalibration;
  52. reset();
  53. }
  54. /// <summary>
  55. /// Adds a pair of calibration points.
  56. /// </summary>
  57. /// <param name="pointA">point in the first image</param>
  58. /// <param name="pointB">point in the second image</param>
  59. public void addCalibrationPoints(Vector2D pointA, Vector2D pointB)
  60. {
  61. calibrationPointsA.Add(sizeA.getRelativePoint(pointA));
  62. calibrationPointsB.Add(sizeB.getRelativePoint(pointB));
  63. if (calibrationPointsA.Count == numPointsForCalibration)
  64. calibrate();
  65. }
  66. /// <summary>
  67. /// Projects a point.
  68. /// </summary>
  69. /// <param name="pointA">the point to project</param>
  70. /// <returns>projected point</returns>
  71. public Vector2D projectPoint(Vector2D pointA)
  72. {
  73. PointF[] pointfsB = new PointF[1] { sizeA.getRelativePoint(pointA) };
  74. homography.ProjectPoints(pointfsB);
  75. return sizeB.getAbsolutePoint(new Vector2D(pointfsB[0]));
  76. }
  77. /// <summary>
  78. /// Resets the calibration.
  79. /// </summary>
  80. public void reset()
  81. {
  82. homography = null;
  83. IsCalibrated = false;
  84. calibrationPointsA = new List<PointF>();
  85. calibrationPointsB = new List<PointF>();
  86. }
  87. /// <summary>
  88. /// Computes the homography from the lists of calibration points.
  89. /// </summary>
  90. private void calibrate()
  91. {
  92. homography = CameraCalibration.FindHomography(calibrationPointsA.ToArray(), calibrationPointsB.ToArray(), Emgu.CV.CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 0.995);
  93. calibrationPointsA.Clear();
  94. calibrationPointsB.Clear();
  95. IsCalibrated = true;
  96. exportHomography();
  97. }
  98. /// <summary>
  99. /// Writes the homography to a file.
  100. /// </summary>
  101. private void exportHomography()
  102. {
  103. String[] fileData = new String[homography.Size.Height];
  104. StringBuilder sb = new StringBuilder();
  105. for (int r = 0; r < homography.Size.Height; r++)
  106. {
  107. for (int c = 0; c < homography.Size.Width; c++)
  108. {
  109. sb.Append(homography.Data[r, c]);
  110. sb.Append(" ");
  111. }
  112. fileData[r] = sb.ToString();
  113. sb.Clear();
  114. }
  115. System.IO.File.WriteAllLines(Parameters.HomographyFileName, fileData);
  116. }
  117. }
  118. }