DepthImage.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. Int16 maxDepth = getMaxDepth();
  64. for (int x = 0; x < width; ++x)
  65. {
  66. for (int y = 0; y < height; ++y)
  67. {
  68. Int16 depth = getDepth(x, y);
  69. if (depth <= thresholdDepth)
  70. setDepth(x, y, 0);
  71. else if (depth != maxDepth)
  72. setDepth(x, y, (short) (maxDepth / 2));
  73. }
  74. }
  75. }
  76. public int[] getSmoothedHistogram()
  77. {
  78. Int16 minDepth = getMinDepth();
  79. Int16 maxDepth = getMaxDepth();
  80. histogram = new int[maxDepth - minDepth];
  81. for (int x = 0; x < width; ++x)
  82. {
  83. for (int y = 0; y < height; ++y)
  84. {
  85. int depth = getDepth(x, y);
  86. if (depth != maxDepth)
  87. histogram[depth - minDepth]++;
  88. }
  89. }
  90. smoothHistogram();
  91. return histogram;
  92. }
  93. private void smoothHistogram()
  94. {
  95. histogram[0] = (histogram[0] + histogram[1]) / 2;
  96. histogram[histogram.Length - 1] = (histogram[histogram.Length - 2] + histogram[histogram.Length - 1]) / 2;
  97. for (int i = 1; i < histogram.Length - 1; ++i)
  98. {
  99. histogram[i] = (histogram[i - 1] + histogram[i] + histogram[i + 1]) / 3;
  100. }
  101. }
  102. public Int16[] getSegmentationDepth()
  103. {
  104. //get first peak
  105. Int16 firstMaxIndex = 0;
  106. for (Int16 i = 0; i < histogram.Length; i++) {
  107. if (histogram[i] > histogram[firstMaxIndex]) {
  108. firstMaxIndex = i;
  109. }
  110. }
  111. // get second peak
  112. Int16 minDistance = 20; // mm
  113. Int16 secondMaxIndex = 0;
  114. for (Int16 i = 0; i < histogram.Length; i++) {
  115. if (Math.Abs(firstMaxIndex - i) > minDistance && histogram[i] > histogram[secondMaxIndex]) {
  116. secondMaxIndex = i;
  117. }
  118. }
  119. if (secondMaxIndex < firstMaxIndex) {
  120. Int16 dummy = firstMaxIndex;
  121. firstMaxIndex = secondMaxIndex;
  122. secondMaxIndex = dummy;
  123. }
  124. // get min in between
  125. Int16 minIndex = firstMaxIndex;
  126. for (Int16 i = firstMaxIndex; i < secondMaxIndex; i++) {
  127. if (histogram[i] < histogram[minIndex]) {
  128. minIndex = i;
  129. }
  130. }
  131. Int16 minDepth = getMinDepth();
  132. Int16[] result = new Int16[3];
  133. result[0] = firstMaxIndex;
  134. result[1] = minIndex;
  135. result[2] = secondMaxIndex;
  136. return result;
  137. }
  138. public Int16 getPeakDepth()
  139. {
  140. Int16 minDepth = getMinDepth();
  141. Int16 peak = -1;
  142. int maxValue = 0;
  143. for (int i = 0; i < histogram.Length; ++i)
  144. {
  145. if (histogram[i] > maxValue)
  146. {
  147. maxValue = histogram[i];
  148. peak = (Int16) (i + minDepth);
  149. }
  150. }
  151. return peak;
  152. }
  153. public Int16 getMinDepth()
  154. {
  155. Int16 minDepth = Int16.MaxValue;
  156. for (int x = 0; x < width; ++x)
  157. {
  158. for (int y = 0; y < height; ++y)
  159. {
  160. Int16 depth = getDepth(x, y);
  161. if (depth < minDepth)
  162. minDepth = depth;
  163. }
  164. }
  165. return minDepth;
  166. }
  167. public Int16 getMaxDepth()
  168. {
  169. Int16 maxDepth = Int16.MinValue;
  170. for (int x = 0; x < width; ++x)
  171. {
  172. for (int y = 0; y < height; ++y)
  173. {
  174. Int16 depth = getDepth(x, y);
  175. if (depth > maxDepth)
  176. maxDepth = depth;
  177. }
  178. }
  179. return maxDepth;
  180. }
  181. public void floodFill(int x, int y, int val)
  182. {
  183. Image<Gray, Byte> tmp = image.Convert<Byte>(delegate(short s) { return (byte) ((int) s * Byte.MaxValue / 2000); });
  184. Emgu.CV.Structure.MCvConnectedComp comp = new MCvConnectedComp();
  185. Emgu.CV.CvInvoke.cvFloodFill(tmp.Ptr, new Point(x, y), new MCvScalar(val), new MCvScalar(30), new MCvScalar(30), out comp, 0, IntPtr.Zero);
  186. for (int i = 0; i < width; ++i)
  187. {
  188. for (int j = 0; j < height; ++j)
  189. {
  190. if (tmp.Data[j, i, 0] == 255)
  191. setDepth(i, j, 2000);
  192. else
  193. setDepth(i, j, 0);
  194. }
  195. }
  196. }
  197. }
  198. }