private void OnGUI() { ScrollPos = GUILayout.BeginScrollView(ScrollPos); ShowSection_Forward = EditorGUILayout.Foldout(ShowSection_Forward, "Forward DFT"); if (ShowSection_Forward) { if (GUILayout.Button("Load Source Image")) { string path = EditorUtility.OpenFilePanelWithFilters( "Choose the image file", Application.dataPath, new string[] { "PNG", "png", "JPEG", "jpg", "JPEG", "jpeg" }); if (path.Length > 0) { InitDisplayTex(ref ForwardDFT_Src); ForwardDFT_Src.LoadImage(File.ReadAllBytes(path)); ForwardDFT_Src.Apply(false, false); } } if (ForwardDFT_Src != null) { var texPos = GUILayoutUtility.GetRect(Math.Min(512, ForwardDFT_Src.width), Math.Min(512, ForwardDFT_Src.height)); GUI.DrawTexture(texPos, ForwardDFT_Src, ScaleMode.ScaleToFit); GUILayout.Space(15.0f); if (GUILayout.Button("Run Forward DFT")) { var samples = Algo2D.ToSamples(ForwardDFT_Src); //var dftResults = Algo2D.Forward(samples); var dftResults = new Complex[samples.GetLength(0), samples.GetLength(1)]; DFT_GPU.Forward((uint)samples.GetLength(0), (uint)samples.GetLength(1), (x, y) => samples[x, y], (x, y, c) => dftResults[x, y] = c); InitDisplayTex(ref ForwardDFT_Dest); Algo2D.ToTex(dftResults, ForwardDFT_Dest); } if (ForwardDFT_Dest != null) { texPos = GUILayoutUtility.GetRect(Math.Min(256, ForwardDFT_Dest.width), Math.Min(256, ForwardDFT_Dest.height)); GUI.DrawTexture(texPos, ForwardDFT_Dest, ScaleMode.ScaleToFit); GUILayout.BeginHorizontal(); if (GUILayout.Button("Shift")) { ForwardDFT_Dest.Filter( (x, y, c, pixels) => { x = (x + (ForwardDFT_Dest.width / 2)) % ForwardDFT_Dest.width; y = (y + (ForwardDFT_Dest.height / 2)) % ForwardDFT_Dest.height; return(pixels[x + (y * ForwardDFT_Dest.width)]); }); } if (GUILayout.Button("Map to [0, 1]")) { //A continuous 1:1 mapping from (-inf, +inf) to (0, 1) is: // 1/(1+e^(-x)) ForwardDFT_Dest.Filter(f => (1.0f / (1.0f + Mathf.Exp(-f)))); } if (GUILayout.Button("Map to [-inf, +inf]")) { //The inverse of the above mapping is: // ln(-x/(x-1)) ForwardDFT_Dest.Filter(f => Mathf.Log(-f / (f - 1))); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); ScaleVal = EditorGUILayout.FloatField("Log Scale: ", ScaleVal); if (GUILayout.Button("Forward")) { ForwardDFT_Dest.Filter(f => (ScaleVal * Mathf.Log(f + 1))); } if (GUILayout.Button("Invert")) { //Use the inverse of the "forward" scale. ForwardDFT_Dest.Filter(f => (Mathf.Exp(f / ScaleVal) - 1.0f)); } GUILayout.EndHorizontal(); } GUILayout.Space(15.0f); if (ForwardDFT_Dest != null) { if (GUILayout.Button("Save Forward DFT")) { string path = EditorUtility.SaveFilePanel("Choose the location", Application.dataPath, "DFT", "png"); if (path.Length > 0) { File.WriteAllBytes(path, ForwardDFT_Dest.EncodeToPNG()); } } } } } GUILayout.Space(30.0f); ShowSection_Inverse = EditorGUILayout.Foldout(ShowSection_Inverse, "Inverse DFT"); if (ShowSection_Inverse) { GUILayout.BeginHorizontal(); if (GUILayout.Button("Load DFT Img")) { string path = EditorUtility.OpenFilePanelWithFilters( "Choose the DFT image file", Application.dataPath, new string[] { "JPEG", "jpeg", "JPEG", "jpg", "PNG", "png" }); if (path.Length > 0) { InitDisplayTex(ref InverseDFT_Src); InverseDFT_Src.LoadImage(File.ReadAllBytes(path)); InverseDFT_Src.Apply(false, false); } } if (ForwardDFT_Dest != null && GUILayout.Button("Copy DFT Img")) { InitDisplayTex(ref InverseDFT_Src); ForwardDFT_Dest.CopyTo(InverseDFT_Src); } GUILayout.EndHorizontal(); if (InverseDFT_Src != null) { var texPos = GUILayoutUtility.GetRect(Math.Min(256, InverseDFT_Src.width), Math.Min(256, InverseDFT_Src.height)); GUI.DrawTexture(texPos, InverseDFT_Src, ScaleMode.ScaleToFit); GUILayout.BeginHorizontal(); if (GUILayout.Button("Map to [0, 1]")) { //A continuous 1:1 mapping from (-inf, +inf) to (0, 1) is: // 1/(1+e^(-x)) InverseDFT_Src.Filter(f => (1.0f / (1.0f + Mathf.Exp(-f)))); } if (GUILayout.Button("Map to [-inf, +inf]")) { //The inverse of the above mapping is: // ln(-x/(x-1)) InverseDFT_Src.Filter(f => Mathf.Log(-f / (f - 1))); } GUILayout.EndHorizontal(); GUILayout.Space(15.0f); if (GUILayout.Button("Run Inverse DFT")) { var samples = Algo2D.ToSamples(InverseDFT_Src); var results = Algo2D.Inverse(samples); InitDisplayTex(ref InverseDFT_Dest); Algo2D.ToTex(results, InverseDFT_Dest); } if (InverseDFT_Dest != null) { texPos = GUILayoutUtility.GetRect(Math.Min(512, InverseDFT_Dest.width), Math.Min(512, InverseDFT_Dest.height)); GUI.DrawTexture(texPos, InverseDFT_Dest, ScaleMode.ScaleToFit); } GUILayout.Space(15.0f); if (InverseDFT_Dest != null) { if (GUILayout.Button("Save Inverse DFT")) { string path = EditorUtility.SaveFilePanel("Choose the location", Application.dataPath, "DFT", "png"); if (path.Length > 0) { File.WriteAllBytes(path, InverseDFT_Dest.EncodeToPNG()); } } } } } GUILayout.EndScrollView(); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); var script = (DFTTestScript)target; GUILayout.Space(20.0f); //Button to sample from time signal. GUILayout.BeginHorizontal(); NSamples = EditorGUILayout.IntField(NSamples); if (NSamples < 2) { NSamples = 2; } if (GUILayout.Button("Sample " + NSamples.ToString() + " points")) { timeSamples = DFTTestScript.GetDiscreteTimeSignal(script.TimeSignal, NSamples); var newKeys = new Keyframe[timeSamples.Length]; float timeIncrement = 1.0f / (timeSamples.Length - 1); for (int sampleI = 0; sampleI < timeSamples.Length; ++sampleI) { newKeys[sampleI] = new Keyframe(sampleI * timeIncrement, timeSamples[sampleI]); } script.SampledTimeSignal.keys = newKeys; script.CloneCurve(ref script.SampledTimeSignal); Repaint(); } GUILayout.EndHorizontal(); useGPU = GUILayout.Toggle(useGPU, "Use GPU"); //Button to perform forward DFT. if (GUILayout.Button("Perform Forward DFT")) { if (useGPU) { dftResults = new Complex[timeSamples.Length]; string errMsg = DFT_GPU.Forward((uint)timeSamples.Length, 1, (x, y) => timeSamples[x], (x, y, c) => dftResults[x] = c); if (errMsg.Length > 0) { Debug.LogError(errMsg); } } else { Complex[,] _timeSamples = new Complex[timeSamples.Length, 1]; for (int i = 0; i < timeSamples.Length; ++i) { _timeSamples[i, 0] = new Complex(timeSamples[i], 0.0f); } var _dftResults = Algo2D.Forward(_timeSamples); dftResults = new Complex[timeSamples.Length]; for (int i = 0; i < timeSamples.Length; ++i) { dftResults[i] = _dftResults[i, 0]; } //dftResults = Algo1D.Forward(timeSamples.Select(f => new Complex(f, 0.0f)).ToArray()); } var newKeys_Cosine = new Keyframe[dftResults.Length]; var newKeys_Sine = new Keyframe[dftResults.Length]; for (int sampleI = 0; sampleI < dftResults.Length; ++sampleI) { newKeys_Cosine[sampleI] = new Keyframe(sampleI, dftResults[sampleI].R); newKeys_Sine[sampleI] = new Keyframe(sampleI, dftResults[sampleI].I); } script.CosFrequencySignal.keys = newKeys_Cosine; script.SinFrequencySignal.keys = newKeys_Sine; script.CloneCurve(ref script.CosFrequencySignal); script.CloneCurve(ref script.SinFrequencySignal); } //Button to perform inverse DFT. if (GUILayout.Button("Perform inverse DFT")) { float[] results = null; if (useGPU) { results = new float[dftResults.Length]; string errMsg = DFT_GPU.Inverse((uint)results.Length, 1, (x, y) => dftResults[x], (x, y, c) => results[x] = c); if (errMsg.Length > 0) { Debug.LogError(errMsg); } } else { Complex[,] _dftResults = new Complex[dftResults.Length, 1]; for (int i = 0; i < dftResults.Length; ++i) { _dftResults[i, 0] = dftResults[i]; } var _results = Algo2D.Inverse(_dftResults); results = new float[dftResults.Length]; for (int i = 0; i < results.Length; ++i) { results[i] = _results[i, 0].R; } //results = Algo1D.Inverse(dftResults).Select(c => c.R).ToArray(); } var newKeys = new Keyframe[results.Length]; float timeIncrement = 1.0f / (results.Length - 1); for (int sampleI = 0; sampleI < results.Length; ++sampleI) { newKeys[sampleI] = new Keyframe(sampleI * timeIncrement, results[sampleI]); } script.ReconstructedTimeSignal.keys = newKeys; script.CloneCurve(ref script.ReconstructedTimeSignal); } }