/BallOnTiltablePlate2/BallOnTiltablePlate/JanRapp/Input/Input1/Input5/ImageProcessing.cs

# · C# · 451 lines · 265 code · 68 blank · 118 comment · 19 complexity · 77d78b59c639275fe4bc46cb34a164bd MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. namespace BallOnTiltablePlate.JanRapp.Input05
  7. {
  8. static class ImageProcessing
  9. {
  10. public static Vector InvalidVector = new Vector(double.NaN, double.NaN);
  11. public struct Input
  12. {
  13. public Input(
  14. byte[] twoByteDepthBits,
  15. int depthHorizontalResulotion,
  16. Int32Rect clip,
  17. float tolerance,
  18. Requests requests,
  19. int minHightAnormalities
  20. )
  21. {
  22. this.twoByteDepthBits = twoByteDepthBits;
  23. this.depthHorizontalResulotion = depthHorizontalResulotion;
  24. this.clip = clip;
  25. this.tolerance = tolerance;
  26. this.requests = requests;
  27. this.minHightAnormalities = minHightAnormalities;
  28. }
  29. public byte[] twoByteDepthBits;
  30. public int depthHorizontalResulotion;
  31. public Int32Rect clip;
  32. public float tolerance;
  33. public Requests requests;
  34. public int minHightAnormalities;
  35. }
  36. public struct Output
  37. {
  38. public Output(
  39. byte[] regualar,
  40. byte[] depth,
  41. byte[] deltaX,
  42. byte[] deltaY,
  43. byte[] anormalyX,
  44. byte[] anormalyY,
  45. byte[] hightAnormalys,
  46. Vector ballPosition,
  47. Vector averageDelta,
  48. Int32Rect clip
  49. )
  50. {
  51. this.regualar = regualar;
  52. this.depth = depth;
  53. this.deltaX = deltaX;
  54. this.deltaY = deltaY;
  55. this.anormalyX = anormalyX;
  56. this.anormalyY = anormalyY;
  57. this.hightAnormalys = hightAnormalys;
  58. this.ballPosition = ballPosition;
  59. this.averageDelta = averageDelta;
  60. this.clip = clip;
  61. }
  62. public readonly byte[] regualar;
  63. public readonly byte[] depth;
  64. public readonly byte[] deltaX;
  65. public readonly byte[] deltaY;
  66. public readonly byte[] anormalyX;
  67. public readonly byte[] anormalyY;
  68. public readonly byte[] hightAnormalys;
  69. public readonly Vector ballPosition;
  70. public readonly Vector averageDelta;
  71. public readonly Int32Rect clip;
  72. }
  73. [Flags]
  74. public enum Requests
  75. {
  76. None = 0,
  77. Regular = 1 << 0,
  78. DeltaX = 1 << 1,
  79. DeltaY = 1 << 2,
  80. AnormalyX = 1 << 3,
  81. AnormalyY = 1 << 4,
  82. HightAnormalys = 1 << 5,
  83. }
  84. public static Vector Average(byte[] depthData, int depthHorizontalResulotion, Int32Rect clip)
  85. {
  86. ///////////////////////////////////////////////////////////////////////////////////////////
  87. int left = clip.X;
  88. int top = clip.Y;
  89. int width = clip.Width;
  90. int height = clip.Height;
  91. int lenght = width * height;
  92. int widthOfData = depthHorizontalResulotion * 2; //2 bytes per pixel
  93. int topLeftCornerOfResultInDepthData = (left * 2 + top * widthOfData); //2 bytes per pixel
  94. ///////////////////////////////////////////////////////////////////////////////////////////
  95. long averageX = 0;
  96. long averageY = 0;
  97. ///////////////////////////////////////////////////////////////////////////////////////////
  98. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
  99. stopwatch.Start();
  100. int lastdept = 0;
  101. int dept = 0;
  102. int j = topLeftCornerOfResultInDepthData;
  103. for (int y = 0; y < height; y++)
  104. {
  105. lastdept = depthData[j - 2] | depthData[j - 1] << 8; //2 bytes are merged to depth
  106. for (int x = 0; x < width; x++)
  107. {
  108. dept = depthData[j++] | depthData[j++] << 8;
  109. int delta = dept - lastdept;
  110. //////////////////////////////////////////////////////////////////////////////////
  111. averageX += delta;
  112. //////////////////////////////////////////////////////////////////////////////////
  113. lastdept = dept;
  114. }
  115. j += widthOfData - width * 2;//2 bytes per pixel
  116. }
  117. j = topLeftCornerOfResultInDepthData;
  118. for (int x = 0; x < width; x++)
  119. {
  120. lastdept = depthData[j - widthOfData] | depthData[j - widthOfData + 1] << 8;
  121. for (int y = 0; y < height; y++)
  122. {
  123. dept = depthData[j] | depthData[j + 1] << 8;
  124. j += widthOfData;
  125. int delta = dept - lastdept;
  126. //////////////////////////////////////////////////////////////////////////////////
  127. averageY += delta;
  128. //////////////////////////////////////////////////////////////////////////////////
  129. lastdept = dept;
  130. }
  131. j = top * widthOfData + (x + left) * 2; //2 bytes per pixel
  132. }
  133. //System.Diagnostics.Debug.WriteLine("Average over depth took:" + stopwatch.ElapsedMilliseconds);
  134. stopwatch.Restart();
  135. //////////////////////////////////////////////////////////////////////////////////////////
  136. return new Vector((double)averageX / lenght, (double)averageY / lenght);
  137. }
  138. public static Vector BallPositionFast(byte[] depthData, int depthHorizontalResulotion, Vector average, float tolerance, Int32Rect clip, int minHeightAnormalities,
  139. out byte[] deptArr, out byte[] deltaXArr, out byte[] deltaYArr, out byte[] anormalXArr, out byte[] anormalYArr, out byte[] hightAnormaltiesArr, int visibilytyMultiplier
  140. )
  141. {
  142. ////////////////////////////////////////////////////////
  143. hightAnormaltiesArr = new byte[clip.Width * clip.Height]; ////
  144. ////
  145. deptArr = new byte[clip.Width * clip.Height]; ////
  146. deltaXArr = new byte[clip.Width * clip.Height]; ////
  147. deltaYArr = new byte[clip.Width * clip.Height]; ////
  148. anormalXArr = new byte[clip.Width * clip.Height]; ////
  149. anormalYArr = new byte[clip.Width * clip.Height]; ////
  150. ////////////////////////////////////////////////////////
  151. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
  152. stopwatch.Start();
  153. tolerance = tolerance * tolerance;
  154. int left = clip.X;
  155. int top = clip.Y;
  156. int width = clip.Width;
  157. int height = clip.Height;
  158. int length = width * height;
  159. int widthOfData = depthHorizontalResulotion * 2;// two bytes per pixel
  160. float averageX = (float)(average.X);
  161. float averageY = (float)(average.Y);
  162. int topLeftCornerOfResultInDepthData = (left * 2 + top * widthOfData); //2 bytes per pixel
  163. int ballX = 0, ballY = 0, ballPointsCount = 0;
  164. var previousRow = new int[width];//Lets Try ushort later!!!!!!
  165. int j = topLeftCornerOfResultInDepthData - widthOfData; //first previousRow is one above the topLeftCorner
  166. for (int i = 0; i < width; i++)//fill previousRow
  167. {
  168. previousRow[i] = depthData[j++] | depthData[j++] << 8;
  169. }
  170. j = topLeftCornerOfResultInDepthData;
  171. for (int y = 0; y < height; y++)
  172. {
  173. int lastDept = depthData[j - 2] | depthData[j - 1] << 8; //2 bytes are merged to depth
  174. for (int x = 0; x < width; x++)
  175. {
  176. int dept = depthData[j++] | depthData[j++] << 8; //Lets Try creating vars outside loop
  177. int deltaX = dept - lastDept;
  178. int deltaY = dept - previousRow[x];
  179. float anormalX = deltaX - averageX;
  180. float anormalY = deltaY - averageY;
  181. float lenghtOfAnormal = anormalX * anormalX + anormalY * anormalY;
  182. if (lenghtOfAnormal > tolerance && dept > 800 && lastDept > 800 && previousRow[x] > 800)
  183. {
  184. ballX += x;
  185. ballY += y;
  186. ballPointsCount++;
  187. ////////////////////////////////////////
  188. hightAnormaltiesArr[x + y * width] = 255; ////
  189. ////////////////////////////////////////
  190. }
  191. previousRow[x] = dept;
  192. lastDept = dept;
  193. /////////////////////////////////////////////////////////////////////////////////
  194. int index = x + y * width; /////
  195. deptArr[index] = (byte)((dept - 800) / 2); /////
  196. deltaXArr[index] = (byte)Math.Abs(deltaX * visibilytyMultiplier);// + 127); /////
  197. deltaYArr[index] = (byte)Math.Abs(deltaY * visibilytyMultiplier);// + 127); /////
  198. anormalXArr[index] = (byte)Math.Abs(anormalX * visibilytyMultiplier);// + 127); /////
  199. anormalYArr[index] = (byte)Math.Abs(anormalY * visibilytyMultiplier);// + 127); /////
  200. /////////////////////////////////////////////////////////////////////////////////
  201. }
  202. j += widthOfData - width * 2; //still 2 bytes per regular pixel
  203. }
  204. //System.Diagnostics.Debug.WriteLine("BallPositionFast: " + stopwatch.ElapsedMilliseconds);
  205. if (ballPointsCount > minHeightAnormalities)
  206. return new Vector(ballX / ballPointsCount, ballY / ballPointsCount);
  207. else
  208. return ImageProcessing.InvalidVector;
  209. }
  210. public static byte[] PrettyPicture(byte[] depthData)
  211. {
  212. byte[] result = new byte[depthData.Length / 2];
  213. //byte notValid = unchecked((byte)(-800 / 2));
  214. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
  215. stopwatch.Start();
  216. for (int i = 0, j = 0; j < depthData.Length; j += 2, i++)
  217. {
  218. result[i] = (byte)(((depthData[j] | depthData[j + 1] << 8) - 800) / 2);
  219. //if (result[i] == notValid)
  220. // result[i] = 255;
  221. }
  222. //System.Diagnostics.Debug.WriteLine("PrettyPicture: " + stopwatch.ElapsedMilliseconds);
  223. stopwatch.Stop();
  224. return result;
  225. }
  226. //Older Stuff is Below
  227. //public static void DeltaToAverage(Microsoft.Research.Kinect.Nui.PlanarImage frame, Int32Rect clip, double tolerance, out byte[] resultX, out byte[] resultY, out Vector average, out Vector ballPos, out byte[] ballAllPos)
  228. // {
  229. // //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  230. // int left = clip.X;
  231. // int top = clip.Y;
  232. // int width = clip.Width;
  233. // int height = clip.Height;
  234. // int length = width * height;
  235. // byte[] depthData = frame.Bits;
  236. // int widthOfData = frame.Width * 2; //2 bytes per pixel
  237. // int topLeftCornerOfResultInDepthData = (left * 2 + top * widthOfData); //2 bytes per pixel
  238. // //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  239. // resultX = new byte[lenght];
  240. // resultY = new byte[lenght];
  241. // ballAllPos = new byte[lenght];
  242. // average = Average(frame.Bits, frame.Width, clip);
  243. // byte averageX = (byte)average.X;
  244. // byte averageY = (byte)average.Y;
  245. // int ballX = 0, ballY = 0, ballCound = 0;
  246. // //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  247. // System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
  248. // stopwatch.Start();
  249. // int lastdept = 0;
  250. // int dept = 0;
  251. // int j = topLeftCornerOfResultInDepthData;
  252. // for (int y = 0; y < height; y++)
  253. // {
  254. // lastdept = depthData[j - 2] | depthData[j - 1] << 8; //2 bytes are merged to depth
  255. // for (int x = 0; x < width; x++)
  256. // {
  257. // dept = depthData[j++] | depthData[j++] << 8;
  258. // int delta = dept - lastdept;
  259. // //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  260. // int anormaly = delta - averageX;
  261. // if (anormaly > tolerance || anormaly < -tolerance)
  262. // {
  263. // ballX += x;
  264. // ballY += y;
  265. // ballCound++;
  266. // }
  267. // resultX[x + y * width] = (byte)(anormaly + 127);
  268. // //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  269. // lastdept = dept;
  270. // }
  271. // j += widthOfData - width * 2;//2 bytes per pixel
  272. // }
  273. // System.Diagnostics.Debug.WriteLine("DeltaToAverage X:" + stopwatch.ElapsedMilliseconds);
  274. // stopwatch.Restart();
  275. // j = topLeftCornerOfResultInDepthData;
  276. // for (int x = 0; x < width; x++)
  277. // {
  278. // lastdept = depthData[j - widthOfData] | depthData[j - widthOfData + 1] << 8;
  279. // for (int y = 0; y < height; y++)
  280. // {
  281. // dept = depthData[j] | depthData[j + 1] << 8;
  282. // j += widthOfData;
  283. // int delta = dept - lastdept;
  284. // //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  285. // int anormaly = delta - averageY;
  286. // if (anormaly > tolerance || anormaly < - tolerance)
  287. // {
  288. // ballX += x;
  289. // ballY += y;
  290. // ballCound++;
  291. // }
  292. // resultY[x + y * width] = (byte)(anormaly + 127);
  293. // //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  294. // lastdept = dept;
  295. // }
  296. // j = top * widthOfData + (x + left) * 2; //2 bytes per pixel
  297. // }
  298. // System.Diagnostics.Debug.WriteLine("DeltaToAverage Y:" + stopwatch.ElapsedMilliseconds);
  299. // stopwatch.Restart();
  300. // //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  301. // ballX = 0;
  302. // ballY = 0;
  303. // ballCound = 0;
  304. // for (int i = 0; i < lenght; i++)
  305. // {
  306. // int x = resultX[i] - 127;
  307. // int y = resultY[i] - 127;
  308. // double l = Math.Sqrt( x * x + y * y );
  309. // if (l > tolerance)
  310. // {
  311. // ballX += i % width;
  312. // ballY += i / width;
  313. // ballCound++;
  314. // ballAllPos[i] = 255;
  315. // }
  316. // }
  317. // System.Diagnostics.Debug.WriteLine("DeltaToAverage Lenght:" + stopwatch.ElapsedMilliseconds);
  318. // if (ballCound == 0)
  319. // ballPos = new Vector();
  320. // else
  321. // ballPos = new Vector(ballX / ballCound, ballY / ballCound);
  322. // }
  323. public static byte[][] DeltaBytes(byte[] TwoByteDepthRaw, int widthOfData, int xLeft, int yTop, int xRight, int yBottom)
  324. {
  325. var stopwatch = new System.Diagnostics.Stopwatch();
  326. stopwatch.Start();
  327. widthOfData *= 2; //2 bytes per pixel
  328. int width = xRight - xLeft;
  329. int height = yBottom - yTop;
  330. byte[,] resultX = new byte[width, height];
  331. byte[,] resultY = new byte[width, height];
  332. System.Diagnostics.Debug.WriteLine("Creating Arrays:" + stopwatch.ElapsedMilliseconds);
  333. stopwatch.Restart();
  334. int topLeftCornerOfResultInDepthData = (xLeft * 2 + yTop * widthOfData); //2 bytes per pixel
  335. int lastdept = 0;
  336. int dept = 0;
  337. int j = topLeftCornerOfResultInDepthData;
  338. for (int y = 0; y < height; y++)
  339. {
  340. lastdept = TwoByteDepthRaw[j - 2] | TwoByteDepthRaw[j - 1] << 8; //2 bytes are merged to depth
  341. for (int x = 0; x < width; x++)
  342. {
  343. dept = TwoByteDepthRaw[j] | TwoByteDepthRaw[j + 1] << 8;
  344. j += 2;
  345. resultX[x, y] = (byte)((dept - lastdept) * 1 + 127);
  346. lastdept = dept;
  347. }
  348. j = topLeftCornerOfResultInDepthData + y * widthOfData;//2 bytes per pixel
  349. }
  350. j = topLeftCornerOfResultInDepthData;
  351. for (int x = 0; x < width; x++)
  352. {
  353. lastdept = TwoByteDepthRaw[j - widthOfData] | TwoByteDepthRaw[j - widthOfData + 1] << 8;
  354. for (int y = 0; y < height; y++)
  355. {
  356. dept = TwoByteDepthRaw[j] | TwoByteDepthRaw[j + 1] << 8;
  357. j += widthOfData;
  358. resultY[x, y] = (byte)((dept - lastdept) * -1 + 127);
  359. lastdept = dept;
  360. }
  361. j = topLeftCornerOfResultInDepthData + x * 2; //2 bytes per pixel
  362. }
  363. System.Diagnostics.Debug.WriteLine("Differentiate over depth took (Bitmap):" + stopwatch.ElapsedMilliseconds);
  364. stopwatch.Restart();
  365. byte[][] result = new byte[2][];
  366. result[0] = new byte[width * height];
  367. result[1] = new byte[width * height];
  368. int i = 0;
  369. for (int y = 0; y < height; y++)
  370. {
  371. for (int x = 0; x < width; x++)
  372. {
  373. result[0][i] = resultX[x, y];
  374. result[1][i] = resultY[x, y];
  375. i++;
  376. }
  377. }
  378. System.Diagnostics.Debug.WriteLine("Coping data:" + stopwatch.ElapsedMilliseconds);
  379. stopwatch.Restart();
  380. return result;
  381. }
  382. }
  383. }