FingerDetector.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Drawing;
  7. using Emgu.CV;
  8. using Emgu.CV.Structure;
  9. using bbiwarg.Images;
  10. using bbiwarg.Utility;
  11. namespace bbiwarg.Detectors.Fingers
  12. {
  13. class FingerDetector
  14. {
  15. private DepthImage depthImage;
  16. private EdgeImage edgeImage;
  17. private FingerImage fingerImage;
  18. private List<Finger> possibleFingers;
  19. private List<Finger> fingers;
  20. public FingerDetector(DepthImage depthImage, EdgeImage edgeImage, FingerImage fingerImage) {
  21. this.depthImage = depthImage;
  22. this.edgeImage = edgeImage;
  23. this.fingerImage = fingerImage;
  24. findPossibleFingerPoints();
  25. findPossibleFingers();
  26. setFingers();
  27. setFingerPoints();
  28. }
  29. public List<Finger> getFingers() {
  30. return fingers;
  31. }
  32. private void findPossibleFingerPoints()
  33. {
  34. int width = depthImage.getWidth();
  35. int height = depthImage.getHeight();
  36. int maxFingerSize = 30;
  37. int minFingerSize = 10;
  38. for (int y = 0; y < height; y++) {
  39. for (int x = 0; x < width; x++) {
  40. if (edgeImage.isEdgeAt(x,y)) {
  41. //search horizontal
  42. bool edgeRightFound = false;
  43. int edgeRightX = x + minFingerSize;
  44. while (!edgeRightFound && edgeRightX < width) {
  45. if (edgeImage.isEdgeAt(edgeRightX,y))
  46. edgeRightFound = true;
  47. else
  48. edgeRightX++;
  49. }
  50. if (edgeRightFound){
  51. int midX = (edgeRightX + x) / 2;
  52. Int16 depthLeft = depthImage.getDepthAt(x, y);
  53. Int16 depthMid = depthImage.getDepthAt(midX, y);
  54. Int16 depthRight = depthImage.getDepthAt(edgeRightX, y);
  55. if ((edgeRightX - x) < maxFingerSize && depthLeft > depthMid && depthMid < depthRight) {
  56. fingerImage.setFingerAt(midX, y, FingerImageState.possibleFinger);
  57. }
  58. }
  59. //search vertical
  60. bool edgeBottomFound = false;
  61. int edgeBottomY = y + minFingerSize;
  62. while (!edgeBottomFound && edgeBottomY < height) {
  63. if (edgeImage.isEdgeAt(x, edgeBottomY))
  64. edgeBottomFound = true;
  65. else
  66. edgeBottomY++;
  67. }
  68. if (edgeBottomFound) {
  69. int midY = (edgeBottomY + y) / 2;
  70. Int16 depthTop = depthImage.getDepthAt(x, y);
  71. Int16 depthMid = depthImage.getDepthAt(x, midY);
  72. Int16 depthBottom = depthImage.getDepthAt(x, edgeBottomY);
  73. if ((edgeBottomY - y) < maxFingerSize && depthTop > depthMid && depthMid < depthBottom) {
  74. fingerImage.setFingerAt(x, midY, FingerImageState.possibleFinger);
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. private void findPossibleFingers()
  82. {
  83. int width = depthImage.getWidth();
  84. int height = depthImage.getHeight();
  85. float maxDistanceTogether = 5.0f;
  86. possibleFingers = new List<Finger>();
  87. for (int y = 0; y < height; y++)
  88. {
  89. for (int x = 0; x < width; x++)
  90. {
  91. if (fingerImage.getStateAt(x,y) == FingerImageState.possibleFinger)
  92. {
  93. Int16 depth = depthImage.getDepthAt(x, y);
  94. Vector<int> fingerPoint = new Vector<int>(new int[3]{x,y,depth});
  95. float minDistanceValue = float.MaxValue;
  96. int minDistanceIndex = 0;
  97. for (int i = 0; i < possibleFingers.Count; i++)
  98. {
  99. float distance = possibleFingers[i].getMinDistance(fingerPoint);
  100. if (distance < minDistanceValue)
  101. {
  102. minDistanceValue = distance;
  103. minDistanceIndex = i;
  104. }
  105. }
  106. if (minDistanceValue < maxDistanceTogether)
  107. {
  108. possibleFingers[minDistanceIndex].addFingerPoint(fingerPoint);
  109. }
  110. else
  111. {
  112. possibleFingers.Add(new Finger(fingerPoint));
  113. }
  114. }
  115. }
  116. }
  117. }
  118. private void setFingers()
  119. {
  120. int width = depthImage.getWidth();
  121. int height = depthImage.getHeight();
  122. float minFingerLength = 20.0f;
  123. fingers = new List<Finger>();
  124. foreach (Finger finger in possibleFingers)
  125. {
  126. float length = finger.getLength();
  127. if (length > minFingerLength)
  128. {
  129. fingers.Add(finger);
  130. }
  131. }
  132. }
  133. private void setFingerPoints() {
  134. int width = depthImage.getWidth();
  135. int height = depthImage.getHeight();
  136. foreach (Finger finger in fingers) {
  137. Vector<float> lineEndPoint1 = finger.getLineEndPoint1();
  138. Vector<float> lineEndPoint2 = finger.getLineEndPoint2();
  139. fingerImage.drawLine(lineEndPoint1, lineEndPoint2, FingerImageState.fingerDetected);
  140. }
  141. }
  142. }
  143. }