DepthImage.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using MathNet.Numerics.LinearAlgebra.Single;
  7. using System.Drawing;
  8. using Emgu.CV;
  9. using Emgu.CV.Structure;
  10. namespace bbiwarg.Images
  11. {
  12. /**
  13. * Represents an depth image where the depth is given in distance to the camera in millimeters.
  14. */
  15. class DepthImage
  16. {
  17. private int width, height;
  18. private Image<Gray, short> image;
  19. private int[] histogram;
  20. public DepthImage(int width, int height, short[] data)
  21. {
  22. this.width = width;
  23. this.height = height;
  24. image = new Image<Gray, short>(width, height);
  25. for (int i = 0; i < data.Length; ++i)
  26. setDepth(i % width, i / width, data[i]);
  27. }
  28. public int getWidth()
  29. {
  30. return width;
  31. }
  32. public int getHeight()
  33. {
  34. return height;
  35. }
  36. public short getDepth(int x, int y)
  37. {
  38. return image.Data[y, x, 0];
  39. }
  40. private void setDepth(int x, int y, short depth)
  41. {
  42. image.Data[y, x, 0] = depth;
  43. }
  44. public void filterMedian(int filterSize)
  45. {
  46. image = image.SmoothMedian(filterSize);
  47. }
  48. public void thresholdDepth(int min, int max)
  49. {
  50. image = image.ThresholdToZero(new Gray(min));
  51. image = image.ThresholdTrunc(new Gray(max));
  52. for (int x = 0; x < width; ++x)
  53. {
  54. for (int y = 0; y < height; ++y)
  55. {
  56. if (getDepth(x, y) == 0)
  57. setDepth(x, y, (short) max);
  58. }
  59. }
  60. }
  61. public void thresholdBinary(Int16 thresholdDepth)
  62. {
  63. image = image.ThresholdBinary(new Gray(thresholdDepth), new Gray(Int16.MaxValue));
  64. }
  65. public int[] getSmoothedHistogram()
  66. {
  67. Int16 minDepth = getMinDepth();
  68. Int16 maxDepth = getMaxDepth();
  69. histogram = new int[maxDepth - minDepth];
  70. for (int x = 0; x < width; ++x)
  71. {
  72. for (int y = 0; y < height; ++y)
  73. {
  74. int depth = getDepth(x, y);
  75. if (depth != maxDepth)
  76. histogram[depth - minDepth]++;
  77. }
  78. }
  79. smoothHistogram();
  80. return histogram;
  81. }
  82. private void smoothHistogram()
  83. {
  84. histogram[0] = (histogram[0] + histogram[1]) / 2;
  85. histogram[histogram.Length - 1] = (histogram[histogram.Length - 2] + histogram[histogram.Length - 1]) / 2;
  86. for (int i = 1; i < histogram.Length - 1; ++i)
  87. {
  88. histogram[i] = (histogram[i - 1] + histogram[i] + histogram[i + 1]) / 3;
  89. }
  90. }
  91. public Int16 getPeakDepth()
  92. {
  93. Int16 minDepth = getMinDepth();
  94. Int16 peak = -1;
  95. int maxValue = 0;
  96. for (int i = 0; i < histogram.Length; ++i)
  97. {
  98. if (histogram[i] > maxValue)
  99. {
  100. maxValue = histogram[i];
  101. peak = (Int16) (i + minDepth);
  102. }
  103. }
  104. return peak;
  105. }
  106. public Int16 getMinDepth()
  107. {
  108. Int16 minDepth = Int16.MaxValue;
  109. for (int x = 0; x < width; ++x)
  110. {
  111. for (int y = 0; y < height; ++y)
  112. {
  113. Int16 depth = getDepth(x, y);
  114. if (depth < minDepth)
  115. minDepth = depth;
  116. }
  117. }
  118. return minDepth;
  119. }
  120. public Int16 getMaxDepth()
  121. {
  122. Int16 maxDepth = Int16.MinValue;
  123. for (int x = 0; x < width; ++x)
  124. {
  125. for (int y = 0; y < height; ++y)
  126. {
  127. Int16 depth = getDepth(x, y);
  128. if (depth > maxDepth)
  129. maxDepth = depth;
  130. }
  131. }
  132. return maxDepth;
  133. }
  134. public void floodFill(int x, int y, int val)
  135. {
  136. Image<Gray, Byte> tmp = image.Convert<Byte>(delegate(short s) { return (byte) ((int) s * Byte.MaxValue / 2000); });
  137. Emgu.CV.Structure.MCvConnectedComp comp = new MCvConnectedComp();
  138. Emgu.CV.CvInvoke.cvFloodFill(tmp.Ptr, new Point(x, y), new MCvScalar(val), new MCvScalar(30), new MCvScalar(30), out comp, 0, IntPtr.Zero);
  139. for (int i = 0; i < width; ++i)
  140. {
  141. for (int j = 0; j < height; ++j)
  142. {
  143. if (tmp.Data[j, i, 0] == 255)
  144. setDepth(i, j, 2000);
  145. else
  146. setDepth(i, j, 0);
  147. }
  148. }
  149. }
  150. }
  151. }