void ShowParticles(OpticalFlowWorker.AsyncResult r) { var dt = r.currTime - r.prevTime; var height = r.imageHeight; var dx = 1f / r.imageWidth; var dy = 1f / height; var offset = new Vector3(-0.5f, -0.5f, -0.1f); for (var i = 0; i < r.nCorners; i++) { if (r.opticalFlowStatus[i] != 1 || r.trackErrors[i] > opticalFlowErrorThreshold) { continue; } var c0 = r.corners0[i]; var c1 = r.corners1[i]; var pos0 = new Vector3(c0.X * dx, (height - c0.Y) * dy, 0) + offset; var pos1 = new Vector3(c1.X * dx, (height - c1.Y) * dy, 0) + offset; pos0 = target.transform.TransformPoint(pos0); pos1 = target.transform.TransformPoint(pos1); var velocity = (pos1 - pos0) / (dt + 1e-9f); if (velocity.sqrMagnitude < (particleVelocityThreshold * particleVelocityThreshold)) { continue; } particleSys.Emit(pos1 + (Vector3)Random.insideUnitCircle * particelRadius, velocity, particleSys.startSize, particleSys.startLifetime, particleSys.startColor); } }
public void ShowCrosshair(OpticalFlowWorker.AsyncResult r) { GL.PushMatrix(); var m = camera.worldToCameraMatrix * target.transform.localToWorldMatrix; GL.LoadIdentity(); GL.MultMatrix(m); var height = r.imageHeight; var dx = 1f / r.imageWidth; var dy = 1f / height; var length = Mathf.Max(dx, dy) * 10f; var offset = new Vector3(-0.5f, -0.5f, 0f); lineMat.SetPass(0); GL.Begin(GL.LINES); GL.Color(crossHairColor); for (var i = 0; i < r.nCorners; i++) { var c = r.corners0[i]; var x = c.X; var y = height - c.Y; var center = new Vector3(x * dx, y * dy, 0) + offset; GL.Vertex(center + new Vector3(-length, 0f, 0f)); GL.Vertex(center + new Vector3(length, 0f, 0f)); GL.Vertex(center + new Vector3(0f, -length, 0f)); GL.Vertex(center + new Vector3(0f, length, 0f)); } GL.End(); GL.PopMatrix(); }
void Start() { _of = GetComponent <OpticalFlowWorker>(); _tex = new Texture2D(0, 0, TextureFormat.RGB24, false); target.renderer.sharedMaterial.mainTexture = _tex; _corners0 = FlowUtil.GenGridCorners(_of.width, _of.height, 50f); _prevResult = _result = _of.CalculateOpticalFlow(_corners0); }
public void ShowImage(OpticalFlowWorker.AsyncResult r) { if (_tex.width != r.imageWidth || _tex.height != r.imageHeight) { _tex.Resize(r.imageWidth, r.imageHeight); } _tex.LoadRawTextureData(r.imageData); _tex.Apply(); }
void Start() { _of = GetComponent <OpticalFlowWorker>(); _tex = new Texture2D(0, 0, TextureFormat.RGB24, false); var mf = flow.GetComponent <MeshFilter>(); _mesh = mf.mesh = new Mesh(); background.renderer.sharedMaterial.mainTexture = _tex; _corners0 = FlowUtil.GenGridCorners(_of.width, _of.height, 50f); _result = _of.CalculateOpticalFlow(_corners0); }
public static void CalculateFlowVelocities(OpticalFlowWorker.AsyncResult r, ref CvPoint2D32f[] velocities) { if (velocities == null || velocities.Length != r.nCorners) { velocities = new CvPoint2D32f[r.nCorners]; } var c0s = r.corners0; var c1s = r.corners1; for (var i = 0; i < r.nCorners; i++) { var c0 = c0s[i]; var c1 = c1s[i]; var cv = c1 - c0; velocities[i] = cv; } }
void Update() { if (!_result.completed) { return; } if (_firstTimeUpdate) { _firstTimeUpdate = false; UpdateAspectRatio(_result.imageWidth, _result.imageHeight); } ShowImage(_result); ShowParticles(_result); _prevResult = _result; _result = _of.CalculateOpticalFlow(_corners0); }
void Update() { if (!_result.completed) { return; } if (_firstTimeUpdate) { _firstTimeUpdate = false; UpdateAspectRatio(_result.imageWidth, _result.imageHeight); _velocities = new CvPoint2D32f[_mesh.vertexCount / 2]; } ShowImage(_result); FlowUtil.CalculateFlowVelocities(_result, ref _velocities); FlowUtil.UpdateLineMesh(_result, _mesh, _velocities, limitVelocity); _result = _of.CalculateOpticalFlow(_corners0); }
// Use this for initialization void Start() { _of = GetComponent <OpticalFlowWorker>(); _videoTex = new Texture2D(0, 0, TextureFormat.RGB24, false, false); _flowMesh = new Mesh(); var mf = flow.GetComponent <MeshFilter>(); mf.sharedMesh = _flowMesh; video.renderer.sharedMaterial.mainTexture = _videoTex; _corners0 = FlowUtil.GenGridCorners(_of.width, _of.height, 50f); _cornerBirthTimes = new float[_corners0.Length]; var t = Time.timeSinceLevelLoad; for (var i = 0; i < _cornerBirthTimes.Length; i++) { _cornerBirthTimes[i] = t; } _ofResult = _of.CalculateOpticalFlow(_corners0); }
public static void UpdateLineMesh(OpticalFlowWorker.AsyncResult r, Mesh mesh, CvPoint2D32f[] velocities, float limitVelocity) { var vertices = new Vector3[r.nCorners * 2]; var colors = new Color[vertices.Length]; var indices = new int[vertices.Length]; var limitSqrVelocity = limitVelocity * limitVelocity; var c0s = r.corners0; var rTexelSize = new Vector2(1f / r.imageWidth, 1f / r.imageHeight); for (var i = 0; i < r.nCorners; i++) { var vertexIndex = 2 * i; var c0 = c0s[i]; var v0 = new Vector3(c0.X * rTexelSize.x - 0.5f, -(c0.Y * rTexelSize.y - 0.5f), 0f); var cv = velocities[i]; var v = new Vector3(cv.X * rTexelSize.x, cv.Y * rTexelSize.y, 0f); var rad = Mathf.Atan2(v.y, v.x); if (rad < 0) { rad += 2 * Mathf.PI; } var color = HSBColor.ToColor(new HSBColor(rad * R_TWO_PI, 1f, 1f)); if (limitSqrVelocity < v.sqrMagnitude) { v = Vector3.zero; } vertices[vertexIndex] = v0; vertices[vertexIndex + 1] = v0 + v; colors[vertexIndex] = color; colors[vertexIndex + 1] = color; indices[vertexIndex] = vertexIndex; indices[vertexIndex + 1] = vertexIndex + 1; } mesh.vertices = vertices; mesh.colors = colors; mesh.SetIndices(indices, MeshTopology.Lines, 0); mesh.RecalculateBounds(); }
// Update is called once per frame void Update() { if (!_ofResult.completed) { return; } //Debug.Log(string.Format("Optical Flow elapsed time {0:f}(ms)", _ofResult.elapsedMs)); if (_ofResult.imageWidth != _videoTex.width || _ofResult.imageHeight != _videoTex.height) { _videoTex.Resize(_ofResult.imageWidth, _ofResult.imageHeight); var s = video.transform.localScale; s.x = s.y * _ofResult.imageWidth / _ofResult.imageHeight; video.transform.localScale = s; } _videoTex.LoadRawTextureData(_ofResult.imageData); _videoTex.Apply(); FlowUtil.CalculateFlowVelocities(_ofResult, ref _velocities); FlowUtil.UpdateLineMesh(_ofResult, _flowMesh, _velocities, limitVelocity); _ofResult = _of.CalculateOpticalFlow(_ofResult.corners1); }
public void ShowOpticalFlow(OpticalFlowWorker.AsyncResult r) { GL.PushMatrix(); var m = camera.worldToCameraMatrix * target.transform.localToWorldMatrix; GL.LoadIdentity(); GL.MultMatrix(m); var height = r.imageHeight; var dx = 1f / r.imageWidth; var dy = 1f / height; var offset = new Vector3(-0.5f, -0.5f, 0f); lineMat.SetPass(0); GL.Begin(GL.LINES); GL.Color(flowColor); for (var i = 0; i < r.nCorners; i++) { if (r.opticalFlowStatus[i] != 1) { continue; } if (r.trackErrors[i] > opticalFlowErrorThreshold) { continue; } var c0 = r.corners0[i]; var c1 = r.corners1[i]; var p0 = new Vector3(c0.X * dx, (height - c0.Y) * dy, 0); var p1 = new Vector3(c1.X * dx, (height - c1.Y) * dy, 0); GL.Vertex(offset + p0); GL.Vertex(offset + p1); } GL.End(); GL.PopMatrix(); }