/// <summary> /// Updates the state of the editor. /// </summary> /// <param name="position"></param> public void UpdateState(Vector2 position) { BezierPoint clickedPoint = GetPointWithinRange(position, ClickRange); if (clickedPoint != null) { editorState.SelectedPoint = clickedPoint; IEnumerator <Path> pathsEnumerator = pathsContainer.GetPathsEnumerator(); while (pathsEnumerator.MoveNext()) { if (pathsEnumerator.Current.Contains(clickedPoint)) { editorState.SelectedPath = pathsEnumerator.Current; break; } } editorState.CurrentState = MouseState.PointDragging; } if (projectState.EditorState != ProjectState.ProjectEditorState.Color) { if (editorState.ModifierState == KeyModifierState.ControlDragging) { editorState.CurrentState = GetControlWithinRange(position, ClickRange); } else if (clickedPoint == null) { editorState.SelectedPoint = AddPoint(position); editorState.CurrentState = MouseState.NewPointDragging; } } }
/// <summary> /// Construct paths on interpolated points. /// </summary> void ConstructInterpolatedPaths() { IEnumerator <Path> pathsEnumerator = container.GetPathsEnumerator(); while (pathsEnumerator.MoveNext()) { if (pathsEnumerator.Current.Count < 2) { continue; } Vector3[] positionArray; Vector4[] leftColorArray; Vector4[] rightColorArray; uint[] indices; ConstructInterpolatedPathPoints(pathsEnumerator.Current, out indices, out positionArray, out leftColorArray, out rightColorArray); buffers.ListPathPoints.Add(positionArray); buffers.ListLeftColorPoints.Add(leftColorArray); buffers.ListRightColorPoints.Add(rightColorArray); buffers.ListIndices.Add(indices); } }
/// <summary> /// Interpolates the path using the iterative Lucas-Kanade method for each point in the path as a feature /// </summary> /// <param name="previousPath">The path of the previous frame</param> /// <param name="nextPath">The empty path of the to be interpolated frame</param> /// <param name="previousImage">The previous image</param> /// <param name="nextImage">The next image to interpolate to</param> /// <returns>A value between 0 and 1 indicating the accuracy of the interpolation</returns> protected override double Interpolate(Model.IPathContainer previousPath, Model.IPathContainer nextPath, Image <Bgr, Byte> previousImage, Image <Bgr, Byte> nextImage) { List <PointF> featureList = new List <PointF>(); List <Path> activePaths = new List <Path>(); for (int i = 0; i < previousPath.LayerIndices[previousPath.ActivePathsLayer].Count; i++) { activePaths.Add(previousPath.Paths[previousPath.LayerIndices[previousPath.ActivePathsLayer][i]]); } IEnumerator <Path> pathEnumerator = activePaths.GetEnumerator(); while (pathEnumerator.MoveNext()) { LinkedList <BezierPoint> .Enumerator pointEnumerator = pathEnumerator.Current.GetEnumerator(); while (pointEnumerator.MoveNext()) { featureList.Add(GetImagePoint(pointEnumerator.Current)); } } Image <Gray, Byte> prevGray = previousImage.Convert <Gray, Byte>(); Image <Gray, Byte> nextGray = nextImage.Convert <Gray, Byte>(); PointF[] featureArray = featureList.ToArray(); PointF[] newFeatures; byte[] errors; float[] trackErrors; Emgu.CV.Structure.MCvTermCriteria criteria = new Emgu.CV.Structure.MCvTermCriteria(10); OpticalFlow.PyrLK(prevGray, nextGray, featureArray, new Size(10, 10), 5, criteria, out newFeatures, out errors, out trackErrors); IPathContainer tempPathContainer = previousPath.Clone(); IEnumerator <Path> tempPathEnumerator = tempPathContainer.GetPathsEnumerator(); int index = 0; for (int j = 0; j < previousPath.Count; j++) { if (previousPath.LayerIndices[previousPath.ActivePathsLayer].Contains(j)) { LinkedList <BezierPoint> .Enumerator pointEnumerator = tempPathContainer.Paths[j].GetEnumerator(); while (pointEnumerator.MoveNext()) { Translate(pointEnumerator.Current, featureArray[index], newFeatures[index++]); } } } IEnumerator <Path> nextPathEnumerator = tempPathContainer.GetPathsEnumerator(); while (nextPathEnumerator.MoveNext()) { nextPath.AddPath(nextPathEnumerator.Current); } nextPath.ActivePathsLayer = tempPathContainer.ActivePathsLayer; nextPath.LayerIndices = tempPathContainer.LayerIndices; double error = DetermineError(previousPath, nextPath, errors); return(error); }