t1 / TFDContents / Assets / KinectScripts / BodySlicer.cs @ 3
이력 | 보기 | 이력해설 | 다운로드 (16.9 KB)
| 1 | 3 | KTH | using UnityEngine; |
|---|---|---|---|
| 2 | //using Windows.Kinect; |
||
| 3 | |||
| 4 | using System.Collections; |
||
| 5 | using System.Collections.Generic; |
||
| 6 | using System.Runtime.InteropServices; |
||
| 7 | using System.Threading; |
||
| 8 | using System; |
||
| 9 | using System.IO; |
||
| 10 | |||
| 11 | public enum BodySlice |
||
| 12 | {
|
||
| 13 | HEIGHT = 0, |
||
| 14 | WIDTH = 1, |
||
| 15 | |||
| 16 | TORSO_1 = 2, |
||
| 17 | TORSO_2 = 3, |
||
| 18 | TORSO_3 = 4, |
||
| 19 | TORSO_4 = 5, |
||
| 20 | |||
| 21 | COUNT = 6 |
||
| 22 | } |
||
| 23 | |||
| 24 | /// <summary> |
||
| 25 | /// Data structure used by the body slicer. |
||
| 26 | /// </summary> |
||
| 27 | public struct BodySliceData |
||
| 28 | {
|
||
| 29 | public bool isSliceValid; |
||
| 30 | |||
| 31 | public float diameter; |
||
| 32 | public int depthPointsLength; |
||
| 33 | public int colorPointsLength; |
||
| 34 | |||
| 35 | // public ushort[] depths; |
||
| 36 | public Vector2 startDepthPoint; |
||
| 37 | public Vector2 endDepthPoint; |
||
| 38 | |||
| 39 | public Vector2 startColorPoint; |
||
| 40 | public Vector2 endColorPoint; |
||
| 41 | |||
| 42 | public Vector3 startKinectPoint; |
||
| 43 | public Vector3 endKinectPoint; |
||
| 44 | } |
||
| 45 | |||
| 46 | |||
| 47 | /// <summary> |
||
| 48 | /// Body slicer is component that estimates the user height, as well as several other body measures, from the depth image data. |
||
| 49 | /// </summary> |
||
| 50 | public class BodySlicer : MonoBehaviour |
||
| 51 | {
|
||
| 52 | [Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
|
||
| 53 | public int playerIndex = 0; |
||
| 54 | |||
| 55 | [Tooltip("Whether the body height should estimated or not.")]
|
||
| 56 | public bool estimateBodyHeight = true; |
||
| 57 | |||
| 58 | [Tooltip("Whether the body width should estimated or not.")]
|
||
| 59 | public bool estimateBodyWidth = false; |
||
| 60 | |||
| 61 | [Tooltip("Whether the body slices should estimated or not.")]
|
||
| 62 | public bool estimateBodySlices = false; |
||
| 63 | |||
| 64 | [Tooltip("Whether the slicing should be done on all updates, or only after the user calibration.")]
|
||
| 65 | public bool continuousSlicing = false; |
||
| 66 | |||
| 67 | [Tooltip("Whether the detected body slices should be displayed on the screen.")]
|
||
| 68 | public bool displayBodySlices = false; |
||
| 69 | |||
| 70 | // // background image texture, if any |
||
| 71 | // public GUITexture bgImage; |
||
| 72 | |||
| 73 | private long calibratedUserId; |
||
| 74 | private byte userBodyIndex; |
||
| 75 | |||
| 76 | |||
| 77 | // The singleton instance of BodySlicer |
||
| 78 | private static BodySlicer instance = null; |
||
| 79 | private KinectManager manager; |
||
| 80 | private KinectInterop.SensorData sensorData; |
||
| 81 | private long lastDepthFrameTime; |
||
| 82 | |||
| 83 | private BodySliceData[] bodySlices = new BodySliceData[(int)BodySlice.COUNT]; |
||
| 84 | private Texture2D depthImage; |
||
| 85 | |||
| 86 | |||
| 87 | /// <summary> |
||
| 88 | /// Gets the singleton BodySlicer instance. |
||
| 89 | /// </summary> |
||
| 90 | /// <value>The singleton BodySlicer instance.</value> |
||
| 91 | public static BodySlicer Instance |
||
| 92 | {
|
||
| 93 | get |
||
| 94 | {
|
||
| 95 | return instance; |
||
| 96 | } |
||
| 97 | } |
||
| 98 | |||
| 99 | |||
| 100 | /// <summary> |
||
| 101 | /// Gets the height of the user. |
||
| 102 | /// </summary> |
||
| 103 | /// <returns>The user height.</returns> |
||
| 104 | public float getUserHeight() |
||
| 105 | {
|
||
| 106 | return getSliceWidth (BodySlice.HEIGHT); |
||
| 107 | } |
||
| 108 | |||
| 109 | |||
| 110 | /// <summary> |
||
| 111 | /// Gets the slice width. |
||
| 112 | /// </summary> |
||
| 113 | /// <returns>The slice width.</returns> |
||
| 114 | /// <param name="slice">Slice.</param> |
||
| 115 | public float getSliceWidth(BodySlice slice) |
||
| 116 | {
|
||
| 117 | int iSlice = (int)slice; |
||
| 118 | |||
| 119 | if (bodySlices[iSlice].isSliceValid) |
||
| 120 | {
|
||
| 121 | return bodySlices[iSlice].diameter; |
||
| 122 | } |
||
| 123 | |||
| 124 | return 0f; |
||
| 125 | } |
||
| 126 | |||
| 127 | |||
| 128 | /// <summary> |
||
| 129 | /// Gets the body slice count. |
||
| 130 | /// </summary> |
||
| 131 | /// <returns>The body slice count.</returns> |
||
| 132 | public int getBodySliceCount() |
||
| 133 | {
|
||
| 134 | return bodySlices != null ? bodySlices.Length : 0; |
||
| 135 | } |
||
| 136 | |||
| 137 | |||
| 138 | /// <summary> |
||
| 139 | /// Gets the body slice data. |
||
| 140 | /// </summary> |
||
| 141 | /// <returns>The body slice data.</returns> |
||
| 142 | /// <param name="slice">Slice.</param> |
||
| 143 | public BodySliceData getBodySliceData(BodySlice slice) |
||
| 144 | {
|
||
| 145 | return bodySlices[(int)slice]; |
||
| 146 | } |
||
| 147 | |||
| 148 | |||
| 149 | /// <summary> |
||
| 150 | /// Gets the calibrated user ID. |
||
| 151 | /// </summary> |
||
| 152 | /// <returns>The calibrated user ID.</returns> |
||
| 153 | public long getCalibratedUserId() |
||
| 154 | {
|
||
| 155 | return calibratedUserId; |
||
| 156 | } |
||
| 157 | |||
| 158 | |||
| 159 | /// <summary> |
||
| 160 | /// Gets the last frame time. |
||
| 161 | /// </summary> |
||
| 162 | /// <returns>The last frame time.</returns> |
||
| 163 | public long getLastFrameTime() |
||
| 164 | {
|
||
| 165 | return lastDepthFrameTime; |
||
| 166 | } |
||
| 167 | |||
| 168 | |||
| 169 | //////////////////////////////////////////////////////////////////////// |
||
| 170 | |||
| 171 | |||
| 172 | void Awake() |
||
| 173 | {
|
||
| 174 | instance = this; |
||
| 175 | } |
||
| 176 | |||
| 177 | void Start() |
||
| 178 | {
|
||
| 179 | manager = KinectManager.Instance; |
||
| 180 | sensorData = manager ? manager.GetSensorData() : null; |
||
| 181 | } |
||
| 182 | |||
| 183 | void Update() |
||
| 184 | {
|
||
| 185 | if(!manager || !manager.IsInitialized()) |
||
| 186 | return; |
||
| 187 | |||
| 188 | // get required player |
||
| 189 | long userId = manager.GetUserIdByIndex (playerIndex); |
||
| 190 | |||
| 191 | if(calibratedUserId == 0) |
||
| 192 | {
|
||
| 193 | if(userId != 0) |
||
| 194 | {
|
||
| 195 | OnCalibrationSuccess(userId); |
||
| 196 | } |
||
| 197 | } |
||
| 198 | else |
||
| 199 | {
|
||
| 200 | if (calibratedUserId != userId) |
||
| 201 | {
|
||
| 202 | OnUserLost(calibratedUserId); |
||
| 203 | } |
||
| 204 | else if(continuousSlicing) |
||
| 205 | {
|
||
| 206 | EstimateBodySlices(calibratedUserId); |
||
| 207 | } |
||
| 208 | } |
||
| 209 | |||
| 210 | // // update color image |
||
| 211 | // if (bgImage && !bgImage.texture) |
||
| 212 | // {
|
||
| 213 | // bgImage.texture = manager.GetUsersClrTex(); |
||
| 214 | // } |
||
| 215 | } |
||
| 216 | |||
| 217 | void OnGUI() |
||
| 218 | {
|
||
| 219 | if(displayBodySlices && depthImage) |
||
| 220 | {
|
||
| 221 | Rect depthImageRect = new Rect(0, Screen.height, 256, -212); |
||
| 222 | GUI.DrawTexture(depthImageRect, depthImage); |
||
| 223 | } |
||
| 224 | } |
||
| 225 | |||
| 226 | public void OnCalibrationSuccess(long userId) |
||
| 227 | {
|
||
| 228 | calibratedUserId = userId; |
||
| 229 | |||
| 230 | // estimate body slices |
||
| 231 | EstimateBodySlices(calibratedUserId); |
||
| 232 | } |
||
| 233 | |||
| 234 | void OnUserLost(long UserId) |
||
| 235 | {
|
||
| 236 | calibratedUserId = 0; |
||
| 237 | } |
||
| 238 | |||
| 239 | public bool EstimateBodySlices(long userId) |
||
| 240 | {
|
||
| 241 | if (userId <= 0) |
||
| 242 | userId = calibratedUserId; |
||
| 243 | |||
| 244 | if(!manager || userId == 0) |
||
| 245 | return false; |
||
| 246 | |||
| 247 | userBodyIndex = (byte)manager.GetBodyIndexByUserId(userId); |
||
| 248 | if (userBodyIndex == 255) |
||
| 249 | return false; |
||
| 250 | |||
| 251 | bool bSliceSuccess = false; |
||
| 252 | |||
| 253 | if (sensorData.bodyIndexImage != null && sensorData.depthImage != null && |
||
| 254 | sensorData.lastDepthFrameTime != lastDepthFrameTime) |
||
| 255 | {
|
||
| 256 | lastDepthFrameTime = sensorData.lastDepthFrameTime; |
||
| 257 | bSliceSuccess = true; |
||
| 258 | |||
| 259 | Vector2 pointSpineBase = manager.MapSpacePointToDepthCoords(manager.GetJointKinectPosition(userId, (int)KinectInterop.JointType.SpineBase)); |
||
| 260 | |||
| 261 | if (estimateBodyHeight) |
||
| 262 | {
|
||
| 263 | bodySlices[(int)BodySlice.HEIGHT] = GetUserHeightParams(pointSpineBase); |
||
| 264 | } |
||
| 265 | |||
| 266 | if (estimateBodyWidth) |
||
| 267 | {
|
||
| 268 | bodySlices[(int)BodySlice.WIDTH] = GetUserWidthParams(pointSpineBase); |
||
| 269 | } |
||
| 270 | |||
| 271 | if(estimateBodySlices && manager.IsJointTracked(userId, (int)KinectInterop.JointType.SpineBase) && manager.IsJointTracked(userId, (int)KinectInterop.JointType.Neck)) |
||
| 272 | {
|
||
| 273 | Vector2 point1 = pointSpineBase; |
||
| 274 | Vector2 point2 = manager.MapSpacePointToDepthCoords(manager.GetJointKinectPosition(userId, (int)KinectInterop.JointType.Neck)); |
||
| 275 | Vector2 sliceDir = (point2 - point1) / 4f; |
||
| 276 | |||
| 277 | Vector2 vSlicePoint = point1; |
||
| 278 | bodySlices[(int)BodySlice.TORSO_1] = GetBodySliceParams(vSlicePoint, true, false, -1); |
||
| 279 | |||
| 280 | vSlicePoint += sliceDir; |
||
| 281 | bodySlices[(int)BodySlice.TORSO_2] = GetBodySliceParams(vSlicePoint, true, false, -1); |
||
| 282 | |||
| 283 | vSlicePoint += sliceDir; |
||
| 284 | bodySlices[(int)BodySlice.TORSO_3] = GetBodySliceParams(vSlicePoint, true, false, -1); |
||
| 285 | |||
| 286 | vSlicePoint += sliceDir; |
||
| 287 | bodySlices[(int)BodySlice.TORSO_4] = GetBodySliceParams(vSlicePoint, true, false, -1); |
||
| 288 | } |
||
| 289 | |||
| 290 | // display body slices |
||
| 291 | if(displayBodySlices) |
||
| 292 | {
|
||
| 293 | depthImage = manager.GetUsersLblTex(); |
||
| 294 | |||
| 295 | if(depthImage) |
||
| 296 | {
|
||
| 297 | depthImage = GameObject.Instantiate(depthImage) as Texture2D; |
||
| 298 | |||
| 299 | DrawBodySlice(bodySlices[(int)BodySlice.HEIGHT]); |
||
| 300 | |||
| 301 | DrawBodySlice(bodySlices[(int)BodySlice.TORSO_1]); |
||
| 302 | DrawBodySlice(bodySlices[(int)BodySlice.TORSO_2]); |
||
| 303 | DrawBodySlice(bodySlices[(int)BodySlice.TORSO_3]); |
||
| 304 | DrawBodySlice(bodySlices[(int)BodySlice.TORSO_4]); |
||
| 305 | |||
| 306 | depthImage.Apply(); |
||
| 307 | } |
||
| 308 | } |
||
| 309 | } |
||
| 310 | |||
| 311 | return bSliceSuccess; |
||
| 312 | } |
||
| 313 | |||
| 314 | |||
| 315 | private void DrawBodySlice(BodySliceData bodySlice) |
||
| 316 | {
|
||
| 317 | if(depthImage && bodySlice.isSliceValid && |
||
| 318 | bodySlice.startDepthPoint != Vector2.zero && bodySlice.endDepthPoint != Vector2.zero) |
||
| 319 | {
|
||
| 320 | KinectInterop.DrawLine(depthImage, (int)bodySlice.startDepthPoint.x, (int)bodySlice.startDepthPoint.y, |
||
| 321 | (int)bodySlice.endDepthPoint.x, (int)bodySlice.endDepthPoint.y, Color.red); |
||
| 322 | } |
||
| 323 | } |
||
| 324 | |||
| 325 | private BodySliceData GetUserHeightParams(Vector2 pointSpineBase) |
||
| 326 | {
|
||
| 327 | int depthLength = sensorData.depthImage.Length; |
||
| 328 | int depthWidth = sensorData.depthImageWidth; |
||
| 329 | int depthHeight = sensorData.depthImageHeight; |
||
| 330 | |||
| 331 | Vector2 posTop = new Vector2 (0, depthHeight); |
||
| 332 | for (int i = 0, x = 0, y = 0; i < depthLength; i++) |
||
| 333 | {
|
||
| 334 | if (sensorData.bodyIndexImage [i] == userBodyIndex) |
||
| 335 | {
|
||
| 336 | //if (posTop.y > y) |
||
| 337 | posTop = new Vector2(x, y); |
||
| 338 | break; |
||
| 339 | } |
||
| 340 | |||
| 341 | x++; |
||
| 342 | if (x >= depthWidth) |
||
| 343 | {
|
||
| 344 | x = 0; |
||
| 345 | y++; |
||
| 346 | } |
||
| 347 | } |
||
| 348 | |||
| 349 | Vector2 posBottom = new Vector2 (0, -1); |
||
| 350 | for (int i = depthLength - 1, x = depthWidth - 1, y = depthHeight - 1; i >= 0; i--) |
||
| 351 | {
|
||
| 352 | if (sensorData.bodyIndexImage [i] == userBodyIndex) |
||
| 353 | {
|
||
| 354 | //if (posBottom.y < y) |
||
| 355 | posBottom = new Vector2(x, y); |
||
| 356 | break; |
||
| 357 | } |
||
| 358 | |||
| 359 | x--; |
||
| 360 | if (x < 0) |
||
| 361 | {
|
||
| 362 | x = depthWidth - 1; |
||
| 363 | y--; |
||
| 364 | } |
||
| 365 | } |
||
| 366 | |||
| 367 | BodySliceData sliceData = new BodySliceData(); |
||
| 368 | sliceData.isSliceValid = false; |
||
| 369 | |||
| 370 | if (posBottom.y >= 0) |
||
| 371 | {
|
||
| 372 | sliceData.startDepthPoint = posTop; |
||
| 373 | sliceData.endDepthPoint = posBottom; |
||
| 374 | sliceData.depthPointsLength = (int)posBottom.y - (int)posTop.y + 1; |
||
| 375 | |||
| 376 | int index1 = (int)posTop.y * depthWidth + (int)posTop.x; |
||
| 377 | ushort depth1 = sensorData.depthImage[index1]; |
||
| 378 | sliceData.startKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.startDepthPoint, depth1, true); |
||
| 379 | |||
| 380 | int index2 = (int)posBottom.y * depthWidth + (int)posBottom.x; |
||
| 381 | ushort depth2 = sensorData.depthImage[index2]; |
||
| 382 | sliceData.endKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.endDepthPoint, depth2, true); |
||
| 383 | |||
| 384 | sliceData.startColorPoint = manager.MapDepthPointToColorCoords(sliceData.startDepthPoint, depth1); |
||
| 385 | sliceData.endColorPoint = manager.MapDepthPointToColorCoords(sliceData.endDepthPoint, depth2); |
||
| 386 | |||
| 387 | if (sliceData.startColorPoint.y < 0) |
||
| 388 | sliceData.startColorPoint.y = 0; |
||
| 389 | if (sliceData.endColorPoint.y >= manager.GetColorImageHeight()) |
||
| 390 | sliceData.endColorPoint.y = manager.GetColorImageHeight() - 1; |
||
| 391 | sliceData.colorPointsLength = (int)sliceData.endColorPoint.y - (int)sliceData.startColorPoint.y + 1; |
||
| 392 | |||
| 393 | // correct x-positions of depth points |
||
| 394 | sliceData.startDepthPoint.x = pointSpineBase.x; |
||
| 395 | sliceData.endDepthPoint.x = pointSpineBase.x; |
||
| 396 | |||
| 397 | sliceData.diameter = (sliceData.endKinectPoint - sliceData.startKinectPoint).magnitude; |
||
| 398 | sliceData.isSliceValid = true; |
||
| 399 | } |
||
| 400 | |||
| 401 | return sliceData; |
||
| 402 | } |
||
| 403 | |||
| 404 | private BodySliceData GetUserWidthParams(Vector2 pointSpineBase) |
||
| 405 | {
|
||
| 406 | int depthLength = sensorData.depthImage.Length; |
||
| 407 | int depthWidth = sensorData.depthImageWidth; |
||
| 408 | //int depthHeight = sensorData.depthImageHeight; |
||
| 409 | |||
| 410 | Vector2 posLeft = new Vector2 (depthWidth, 0); |
||
| 411 | Vector2 posRight = new Vector2 (-1, 0); |
||
| 412 | |||
| 413 | for (int i = 0, x = 0, y = 0; i < depthLength; i++) |
||
| 414 | {
|
||
| 415 | if (sensorData.bodyIndexImage [i] == userBodyIndex) |
||
| 416 | {
|
||
| 417 | if (posLeft.x > x) |
||
| 418 | posLeft = new Vector2(x, y); |
||
| 419 | if (posRight.x < x) |
||
| 420 | posRight = new Vector2(x, y); |
||
| 421 | } |
||
| 422 | |||
| 423 | x++; |
||
| 424 | if (x >= depthWidth) |
||
| 425 | {
|
||
| 426 | x = 0; |
||
| 427 | y++; |
||
| 428 | } |
||
| 429 | } |
||
| 430 | |||
| 431 | BodySliceData sliceData = new BodySliceData(); |
||
| 432 | sliceData.isSliceValid = false; |
||
| 433 | |||
| 434 | if (posRight.x >= 0) |
||
| 435 | {
|
||
| 436 | sliceData.startDepthPoint = posLeft; |
||
| 437 | sliceData.endDepthPoint = posRight; |
||
| 438 | sliceData.depthPointsLength = (int)posRight.x - (int)posLeft.x + 1; |
||
| 439 | |||
| 440 | int index1 = (int)posLeft.y * depthWidth + (int)posLeft.x; |
||
| 441 | ushort depth1 = sensorData.depthImage[index1]; |
||
| 442 | sliceData.startKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.startDepthPoint, depth1, true); |
||
| 443 | |||
| 444 | int index2 = (int)posRight.y * depthWidth + (int)posRight.x; |
||
| 445 | ushort depth2 = sensorData.depthImage[index2]; |
||
| 446 | sliceData.endKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.endDepthPoint, depth2, true); |
||
| 447 | |||
| 448 | sliceData.startColorPoint = manager.MapDepthPointToColorCoords(sliceData.startDepthPoint, depth1); |
||
| 449 | sliceData.endColorPoint = manager.MapDepthPointToColorCoords(sliceData.endDepthPoint, depth2); |
||
| 450 | |||
| 451 | if (sliceData.startColorPoint.x < 0) |
||
| 452 | sliceData.startColorPoint.x = 0; |
||
| 453 | if (sliceData.endColorPoint.x >= manager.GetColorImageWidth()) |
||
| 454 | sliceData.endColorPoint.x = manager.GetColorImageWidth() - 1; |
||
| 455 | sliceData.colorPointsLength = (int)sliceData.endColorPoint.x - (int)sliceData.startColorPoint.x + 1; |
||
| 456 | |||
| 457 | // correct y-positions of depth points |
||
| 458 | sliceData.startDepthPoint.y = pointSpineBase.y; |
||
| 459 | sliceData.endDepthPoint.y = pointSpineBase.y; |
||
| 460 | |||
| 461 | sliceData.diameter = (sliceData.endKinectPoint - sliceData.startKinectPoint).magnitude; |
||
| 462 | sliceData.isSliceValid = true; |
||
| 463 | } |
||
| 464 | |||
| 465 | return sliceData; |
||
| 466 | } |
||
| 467 | |||
| 468 | private BodySliceData GetBodySliceParams(Vector2 middlePoint, bool bSliceOnX, bool bSliceOnY, int maxDepthLength) |
||
| 469 | {
|
||
| 470 | BodySliceData sliceData = new BodySliceData(); |
||
| 471 | sliceData.isSliceValid = false; |
||
| 472 | sliceData.depthPointsLength = 0; |
||
| 473 | |||
| 474 | if(!manager || middlePoint == Vector2.zero) |
||
| 475 | return sliceData; |
||
| 476 | if(!bSliceOnX && !bSliceOnY) |
||
| 477 | return sliceData; |
||
| 478 | |||
| 479 | middlePoint.x = Mathf.FloorToInt(middlePoint.x + 0.5f); |
||
| 480 | middlePoint.y = Mathf.FloorToInt(middlePoint.y + 0.5f); |
||
| 481 | |||
| 482 | int depthWidth = sensorData.depthImageWidth; |
||
| 483 | int depthHeight = sensorData.depthImageHeight; |
||
| 484 | |||
| 485 | int indexMid = (int)middlePoint.y * depthWidth + (int)middlePoint.x; |
||
| 486 | byte userIndex = sensorData.bodyIndexImage[indexMid]; |
||
| 487 | |||
| 488 | if(userIndex != userBodyIndex) |
||
| 489 | return sliceData; |
||
| 490 | |||
| 491 | sliceData.startDepthPoint = middlePoint; |
||
| 492 | sliceData.endDepthPoint = middlePoint; |
||
| 493 | |||
| 494 | int indexDiff1 = 0; |
||
| 495 | int indexDiff2 = 0; |
||
| 496 | |||
| 497 | if(bSliceOnX) |
||
| 498 | {
|
||
| 499 | // min-max |
||
| 500 | int minIndex = (int)middlePoint.y * depthWidth; |
||
| 501 | int maxIndex = (int)(middlePoint.y + 1) * depthWidth; |
||
| 502 | |||
| 503 | // horizontal left |
||
| 504 | int stepIndex = -1; |
||
| 505 | indexDiff1 = TrackSliceInDirection(indexMid, stepIndex, minIndex, maxIndex, userIndex); |
||
| 506 | |||
| 507 | // horizontal right |
||
| 508 | stepIndex = 1; |
||
| 509 | indexDiff2 = TrackSliceInDirection(indexMid, stepIndex, minIndex, maxIndex, userIndex); |
||
| 510 | } |
||
| 511 | else if(bSliceOnY) |
||
| 512 | {
|
||
| 513 | // min-max |
||
| 514 | int minIndex = 0; |
||
| 515 | int maxIndex = depthHeight * depthWidth; |
||
| 516 | |||
| 517 | // vertical up |
||
| 518 | int stepIndex = -depthWidth; |
||
| 519 | indexDiff1 = TrackSliceInDirection(indexMid, stepIndex, minIndex, maxIndex, userIndex); |
||
| 520 | |||
| 521 | // vertical down |
||
| 522 | stepIndex = depthWidth; |
||
| 523 | indexDiff2 = TrackSliceInDirection(indexMid, stepIndex, minIndex, maxIndex, userIndex); |
||
| 524 | } |
||
| 525 | |||
| 526 | // calculate depth length |
||
| 527 | sliceData.depthPointsLength = indexDiff1 + indexDiff2 + 1; |
||
| 528 | |||
| 529 | // check for max length (used by upper legs) |
||
| 530 | if(maxDepthLength > 0 && sliceData.depthPointsLength > maxDepthLength) |
||
| 531 | {
|
||
| 532 | // indexDiff1 = (int)((float)indexDiff1 * maxDepthLength / sliceData.depthsLength); |
||
| 533 | // indexDiff2 = (int)((float)indexDiff2 * maxDepthLength / sliceData.depthsLength); |
||
| 534 | |||
| 535 | if(indexDiff1 > indexDiff2) |
||
| 536 | indexDiff1 = indexDiff2; |
||
| 537 | else |
||
| 538 | indexDiff2 = indexDiff1; |
||
| 539 | |||
| 540 | sliceData.depthPointsLength = indexDiff1 + indexDiff2 + 1; |
||
| 541 | } |
||
| 542 | |||
| 543 | // set start and end depth points |
||
| 544 | if(bSliceOnX) |
||
| 545 | {
|
||
| 546 | sliceData.startDepthPoint.x -= indexDiff1; |
||
| 547 | sliceData.endDepthPoint.x += indexDiff2; |
||
| 548 | } |
||
| 549 | else if(bSliceOnY) |
||
| 550 | {
|
||
| 551 | sliceData.startDepthPoint.y -= indexDiff1; |
||
| 552 | sliceData.endDepthPoint.y += indexDiff2; |
||
| 553 | } |
||
| 554 | |||
| 555 | // start point |
||
| 556 | int index1 = (int)sliceData.startDepthPoint.y * depthWidth + (int)sliceData.startDepthPoint.x; |
||
| 557 | ushort depth1 = sensorData.depthImage[index1]; |
||
| 558 | sliceData.startKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.startDepthPoint, depth1, true); |
||
| 559 | |||
| 560 | // end point |
||
| 561 | int index2 = (int)sliceData.endDepthPoint.y * depthWidth + (int)sliceData.endDepthPoint.x; |
||
| 562 | ushort depth2 = sensorData.depthImage[index2]; |
||
| 563 | sliceData.endKinectPoint = manager.MapDepthPointToSpaceCoords(sliceData.endDepthPoint, depth2, true); |
||
| 564 | |||
| 565 | sliceData.startColorPoint = manager.MapDepthPointToColorCoords(sliceData.startDepthPoint, depth1); |
||
| 566 | sliceData.endColorPoint = manager.MapDepthPointToColorCoords(sliceData.endDepthPoint, depth2); |
||
| 567 | |||
| 568 | if (sliceData.startColorPoint.x < 0) |
||
| 569 | sliceData.startColorPoint.x = 0; |
||
| 570 | if (sliceData.endColorPoint.x >= manager.GetColorImageWidth()) |
||
| 571 | sliceData.endColorPoint.x = manager.GetColorImageWidth() - 1; |
||
| 572 | sliceData.colorPointsLength = (int)sliceData.endColorPoint.x - (int)sliceData.startColorPoint.x + 1; |
||
| 573 | |||
| 574 | // diameter |
||
| 575 | sliceData.diameter = (sliceData.endKinectPoint - sliceData.startKinectPoint).magnitude; |
||
| 576 | sliceData.isSliceValid = true; |
||
| 577 | |||
| 578 | // // get depths |
||
| 579 | // sliceData.depths = new ushort[sliceData.depthsLength]; |
||
| 580 | // int stepDepthIndex = 1; |
||
| 581 | // |
||
| 582 | // if(bSliceOnX) |
||
| 583 | // {
|
||
| 584 | // stepDepthIndex = 1; |
||
| 585 | // } |
||
| 586 | // else if(bSliceOnY) |
||
| 587 | // {
|
||
| 588 | // stepDepthIndex = depthWidth; |
||
| 589 | // } |
||
| 590 | // |
||
| 591 | // for(int i = index1, d = 0; i <= index2; i+= stepDepthIndex, d++) |
||
| 592 | // {
|
||
| 593 | // sliceData.depths[d] = sensorData.depthImage[i]; |
||
| 594 | // } |
||
| 595 | |||
| 596 | return sliceData; |
||
| 597 | } |
||
| 598 | |||
| 599 | private int TrackSliceInDirection(int index, int stepIndex, int minIndex, int maxIndex, byte userIndex) |
||
| 600 | {
|
||
| 601 | int indexDiff = 0; |
||
| 602 | int errCount = 0; |
||
| 603 | |||
| 604 | index += stepIndex; |
||
| 605 | while(index >= minIndex && index < maxIndex) |
||
| 606 | {
|
||
| 607 | if(sensorData.bodyIndexImage[index] != userIndex) |
||
| 608 | {
|
||
| 609 | errCount++; |
||
| 610 | if(errCount > 0) // allow 0 error(s) |
||
| 611 | break; |
||
| 612 | } |
||
| 613 | else |
||
| 614 | {
|
||
| 615 | errCount = 0; |
||
| 616 | } |
||
| 617 | |||
| 618 | index += stepIndex; |
||
| 619 | indexDiff++; |
||
| 620 | } |
||
| 621 | |||
| 622 | return indexDiff; |
||
| 623 | } |
||
| 624 | |||
| 625 | } |