OutputImage.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 bbiwarg.Utility;
  8. using Emgu.CV;
  9. using Emgu.CV.Structure;
  10. namespace bbiwarg.Output
  11. {
  12. /// <summary>
  13. /// An <see cref="Image"/> which provides additional drawing functions.
  14. /// </summary>
  15. class OutputImage : Image<Rgb, byte>
  16. {
  17. /// <summary>
  18. /// Creates an OutputImage.
  19. /// </summary>
  20. /// <param name="width">image width</param>
  21. /// <param name="height">image height</param>
  22. public OutputImage(int width, int height)
  23. : base(width, height)
  24. {
  25. }
  26. /// <summary>
  27. /// Creates an OutputImage.
  28. /// </summary>
  29. /// <param name="size">image size</param>
  30. public OutputImage(ImageSize size)
  31. : base(size.Width, size.Height)
  32. {
  33. }
  34. /// <summary>
  35. /// Returns the color at a position.
  36. /// </summary>
  37. /// <param name="x">x coordinate of the position</param>
  38. /// <param name="y">y coordinate of the position</param>
  39. /// <returns>color at position (x, y)</returns>
  40. public Color getColorAt(int x, int y)
  41. {
  42. byte red = Data[y, x, 0];
  43. byte green = Data[y, x, 1];
  44. byte blue = Data[y, x, 2];
  45. return Color.FromArgb(red, green, blue);
  46. }
  47. /// <summary>
  48. /// Draws a line segment.
  49. /// </summary>
  50. /// <param name="lineSegment">line segment to draw</param>
  51. /// <param name="color">color used to draw the line segment</param>
  52. /// <param name="thickness">thickness of the line segment</param>
  53. public void drawLineSegment(bbiwarg.Utility.LineSegment2D lineSegment, Color color, int thickness = 1)
  54. {
  55. Draw(new Emgu.CV.Structure.LineSegment2D(lineSegment.P1, lineSegment.P2), new Rgb(color), thickness);
  56. }
  57. /// <summary>
  58. /// Draws a contour.
  59. /// </summary>
  60. /// <param name="contour">contour to draw</param>
  61. /// <param name="color">color used to draw the contour</param>
  62. /// <param name="thickness">thickness of the contour</param>
  63. public void drawContour(Contour<Point> contour, Color color, int thickness = 1)
  64. {
  65. Draw(contour, new Rgb(color), thickness);
  66. }
  67. /// <summary>
  68. /// Colors a pixel.
  69. /// </summary>
  70. /// <param name="position">position of the pixel</param>
  71. /// <param name="color">new color for pixel</param>
  72. public void drawPixel(Point position, Color color)
  73. {
  74. Data[position.Y, position.X, 0] = color.R;
  75. Data[position.Y, position.X, 0] = color.G;
  76. Data[position.Y, position.X, 0] = color.B;
  77. }
  78. /// <summary>
  79. /// Draws a filled circle.
  80. /// </summary>
  81. /// <param name="position">center of the circle</param>
  82. /// <param name="radius">radius of the circle</param>
  83. /// <param name="color">color used to draw the circle</param>
  84. public void fillCircle(Point position, float radius, Color color)
  85. {
  86. Draw(new CircleF(position, radius), new Rgb(color), 0);
  87. }
  88. /// <summary>
  89. /// Draws a filled rectangle.
  90. /// </summary>
  91. /// <param name="rect">the rectangle</param>
  92. /// <param name="color">color used to fill the rectangle</param>
  93. public void fillRectangle(Rectangle rect, Color color)
  94. {
  95. Draw(rect, new Rgb(color), -1);
  96. }
  97. /// <summary>
  98. /// Draws a unfilled rectangle.
  99. /// </summary>
  100. /// <param name="rect">the rectangle</param>
  101. /// <param name="color">color used to raw the rectangle</param>
  102. /// <param name="thichness">thickness of the rectangle</param>
  103. public void drawRectangle(Rectangle rect, Color color, int thichness = 0)
  104. {
  105. Draw(rect, new Rgb(color), thichness);
  106. }
  107. /// <summary>
  108. /// Draws text.
  109. /// </summary>
  110. /// <param name="position">top left corner to draw the text at</param>
  111. /// <param name="text">the text to draw</param>
  112. /// <param name="color">color used to draw the text</param>
  113. public void drawText(Point position, String text, Color color)
  114. {
  115. MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 1, 1);
  116. Draw(text, ref font, position, new Rgb(color));
  117. }
  118. /// <summary>
  119. /// Draws a convexity defect.
  120. /// </summary>
  121. /// <param name="defect">the defect to draw</param>
  122. /// <param name="pointColor">color used to draw the points of the defect</param>
  123. /// <param name="lineColor">color used to draw the lines of the defect</param>
  124. public void drawDefect(ConvexityDefect defect, Color pointColor, Color lineColor)
  125. {
  126. drawLineSegment(new Utility.LineSegment2D(defect.OuterShort, defect.Inner), lineColor);
  127. drawLineSegment(new Utility.LineSegment2D(defect.OuterLong, defect.Inner), lineColor);
  128. fillCircle(defect.Inner, 2, pointColor);
  129. fillCircle(defect.OuterShort, 2, pointColor);
  130. fillCircle(defect.OuterLong, 2, pointColor);
  131. }
  132. /// <summary>
  133. /// Draws a grid into a quadrangle.
  134. /// </summary>
  135. /// <param name="quad">the quadrangle</param>
  136. /// <param name="borderColor">color used to draw the border lines</param>
  137. /// <param name="gridColor">color used to draw the grid</param>
  138. /// <param name="numRows">number of rows in the grid</param>
  139. /// <param name="numCols">number of columns in the grid</param>
  140. public void drawQuadrangleGrid(Quadrangle quad, Color borderColor, Color gridColor, int numRows, int numCols)
  141. {
  142. Vector2D a = quad.TopLeft;
  143. Vector2D b = quad.TopRight;
  144. Vector2D c = quad.BottomRight;
  145. Vector2D d = quad.BottomLeft;
  146. Vector2D relAB = (b - a) / numCols;
  147. Vector2D relDC = (c - d) / numCols;
  148. Vector2D relBC = (c - b) / numRows;
  149. Vector2D relAD = (d - a) / numRows;
  150. for (int i = 1; i < numCols; i++)
  151. {
  152. drawLineSegment(new bbiwarg.Utility.LineSegment2D(a + i * relAB, d + i * relDC), gridColor);
  153. }
  154. for (int i = 1; i < numRows; i++)
  155. {
  156. drawLineSegment(new bbiwarg.Utility.LineSegment2D(a + i * relAD, b + i * relBC), gridColor);
  157. }
  158. drawLineSegment(new bbiwarg.Utility.LineSegment2D(a, b), borderColor);
  159. drawLineSegment(new bbiwarg.Utility.LineSegment2D(b, c), borderColor);
  160. drawLineSegment(new bbiwarg.Utility.LineSegment2D(c, d), borderColor);
  161. drawLineSegment(new bbiwarg.Utility.LineSegment2D(d, a), borderColor);
  162. }
  163. /// <summary>
  164. /// Draws a border around the image.
  165. /// </summary>
  166. /// <param name="color">color used to draw the border</param>
  167. public void drawBorder(Color color)
  168. {
  169. drawRectangle(new Rectangle(0, 0, Width, Height), color);
  170. }
  171. /// <summary>
  172. /// Draws a touch gesture as the current point and a faded line.
  173. /// </summary>
  174. /// <param name="positions">touch positions</param>
  175. /// <param name="scale">scale used to transform given positions into positions in the image</param>
  176. /// <param name="opacity">opacity of the faded lines</param>
  177. public void drawTouchGesture(List<Vector2D> positions, Vector2D scale, float opacity = 1)
  178. {
  179. int numPositions = positions.Count;
  180. Color lineColor = Parameters.TouchEventVisualizerLineColor;
  181. Color pointColor = Parameters.TouchEventVisualizerPointColor;
  182. Color lineColorFaded = Color.FromArgb((int)(opacity * lineColor.R), (int)(opacity * lineColor.G), (int)(opacity * lineColor.B));
  183. Color pointColorFaded = Color.FromArgb((int)(opacity * pointColor.R), (int)(opacity * pointColor.G), (int)(opacity * pointColor.B));
  184. for (int i = 1; i < numPositions; i++)
  185. {
  186. drawLineSegment(new Utility.LineSegment2D(positions[i - 1].scale(scale), positions[i].scale(scale)), lineColorFaded);
  187. }
  188. Vector2D lastPos = positions[numPositions - 1].scale(scale);
  189. fillCircle(lastPos, 3, pointColorFaded);
  190. }
  191. /// <summary>
  192. /// Draws a grayscale image into channels of the image.
  193. /// </summary>
  194. /// <param name="image">the image to draw</param>
  195. /// <param name="color">if a color component is != 0 the corresponding image channel is drawn to and image is scaled by (color component value / 255)</param>
  196. public void drawImage(Image<Gray, byte> image, Color color)
  197. {
  198. if (color.R != 0)
  199. {
  200. if (color.R != byte.MaxValue)
  201. this[0] = this[0].Or(image.Mul((float)color.R / byte.MaxValue));
  202. else
  203. this[0] = this[0].Or(image);
  204. }
  205. if (color.G != 0)
  206. {
  207. if (color.G != byte.MaxValue)
  208. this[1] = this[1].Or(image.Mul((float)color.G / byte.MaxValue));
  209. else
  210. this[1] = this[1].Or(image);
  211. }
  212. if (color.B != 0)
  213. {
  214. if (color.B != byte.MaxValue)
  215. this[2] = this[2].Or(image.Mul((float)color.B / byte.MaxValue));
  216. else
  217. this[2] = this[2].Or(image);
  218. }
  219. }
  220. }
  221. }