FingerImage.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Emgu.CV;
  8. using Emgu.CV.Structure;
  9. using bbiwarg.Utility;
  10. using bbiwarg.Detectors.Fingers;
  11. namespace bbiwarg.Images
  12. {
  13. public enum FingerImageState {
  14. none = 0,
  15. possibleFingerSlice = 1,
  16. fingerSlice = 2,
  17. fingerDetected = 3,
  18. fingerTracked = 4
  19. }
  20. class FingerImage
  21. {
  22. private Image<Gray, byte> image;
  23. public FingerImage(int width, int height) {
  24. image = new Image<Gray, byte>(width, height);
  25. }
  26. public void setFingerAt(int x, int y, FingerImageState fis) {
  27. image.Data[y, x, 0] = (byte) fis;
  28. }
  29. public FingerImageState getStateAt(int x, int y) {
  30. return (FingerImageState)image.Data[y, x, 0];
  31. }
  32. public void drawFinger(Finger finger, FingerImageState state) {
  33. FingerSliceTrail trail = finger.SliceTrail;
  34. for (int i = 0; i < trail.NumSlices; i++) {
  35. drawLine(trail[i].Line, FingerImageState.fingerSlice);
  36. }
  37. drawLine(finger.Line, state);
  38. }
  39. public void drawLine(Line2D line, FingerImageState state)
  40. {
  41. Vector2D start = line.P1;
  42. Vector2D end = line.P2;
  43. int width = image.Width;
  44. int height = image.Height;
  45. // bresenham from wikipedia
  46. int xstart = (int)start.X, xend = (int)end.X, ystart = (int)start.Y, yend = (int)end.Y;
  47. int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
  48. /* Entfernung in beiden Dimensionen berechnen */
  49. dx = xend - xstart;
  50. dy = yend - ystart;
  51. /* Vorzeichen des Inkrements bestimmen */
  52. incx = dx < 0 ? -1 : 1;
  53. incy = dy < 0 ? -1 : 1;
  54. if (dx < 0) dx = -dx;
  55. if (dy < 0) dy = -dy;
  56. /* feststellen, welche Entfernung größer ist */
  57. if (dx > dy)
  58. {
  59. /* x ist schnelle Richtung */
  60. pdx = incx; pdy = 0; /* pd. ist Parallelschritt */
  61. ddx = incx; ddy = incy; /* dd. ist Diagonalschritt */
  62. es = dy; el = dx; /* Fehlerschritte schnell, langsam */
  63. }
  64. else
  65. {
  66. /* y ist schnelle Richtung */
  67. pdx = 0; pdy = incy; /* pd. ist Parallelschritt */
  68. ddx = incx; ddy = incy; /* dd. ist Diagonalschritt */
  69. es = dx; el = dy; /* Fehlerschritte schnell, langsam */
  70. }
  71. /* Initialisierungen vor Schleifenbeginn */
  72. x = xstart;
  73. y = ystart;
  74. err = el / 2;
  75. setFingerAt(Math.Min(width - 1, Math.Max(0, x)), Math.Min(height - 1, Math.Max(0, y)), state);
  76. /* Pixel berechnen */
  77. for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */
  78. {
  79. /* Aktualisierung Fehlerterm */
  80. err -= es;
  81. if (err < 0)
  82. {
  83. /* Fehlerterm wieder positiv (>=0) machen */
  84. err += el;
  85. /* Schritt in langsame Richtung, Diagonalschritt */
  86. x += ddx;
  87. y += ddy;
  88. }
  89. else
  90. {
  91. /* Schritt in schnelle Richtung, Parallelschritt */
  92. x += pdx;
  93. y += pdy;
  94. }
  95. setFingerAt(Math.Min(width - 1, Math.Max(0, x)), Math.Min(height - 1, Math.Max(0, y)), state);
  96. }
  97. }
  98. }
  99. }