private void LateUpdate() { if (UnityEngine.Input.GetKeyDown(KeyCode.Escape)) { ImageScript.Reset(); } else if (UnityEngine.Input.GetKeyDown(KeyCode.Space)) { ImageGestureImage match = ImageScript.CheckForImageMatch(); if (match != null) { Debug.Log("Found image match: " + match.Name); MatchParticleSystem.Play(); AudioSourceOnMatch.Play(); } else { Debug.Log("No match found!"); } // TODO: Do something with the match // You could get a texture from it: // Texture2D texture = FingersImageAutomationScript.CreateTextureFromImageGestureImage(match); } }
/// <summary> /// Create a texture from an image gesture image /// </summary> /// <param name="image">Image</param> /// <returns>Texture</returns> public static Texture2D CreateTextureFromImageGestureImage(ImageGestureImage image) { Texture2D texture = new Texture2D(ImageGestureRecognizer.ImageColumns, ImageGestureRecognizer.ImageRows, TextureFormat.ARGB32, false, false); texture.filterMode = FilterMode.Point; texture.wrapMode = TextureWrapMode.Clamp; for (int y = 0; y < ImageGestureRecognizer.ImageRows; y++) { for (int x = 0; x < ImageGestureRecognizer.ImageColumns; x++) { // each bit in the row can be checked as well if Pixels is not available // if ((imageGesture.Image.Rows[y] & (ulong)(1 << x)) == 0) if (image.Pixels[x + (y * ImageGestureRecognizer.ImageRows)] == 0) { texture.SetPixel(x, y, Color.clear); } else { texture.SetPixel(x, y, Color.white); } } } texture.Apply(); return(texture); }
public ImageGestureImage CheckForImageMatch() { if (matchedImage == null) { if (MatchText != null) { //MatchText.text = "No match found!"; } } else { if (MatchText != null) { //MatchText.text = "You drew a " + matchedImage.Name; print("1"); if (OnMatchFound != null) { print("1"); OnMatchFound.Invoke(matchedImage.Name); StopAnimation(); // print("2"); } } // image gesture must be manually reset when a shape is recognized Gesture.Reset(); matchedImage = null; // clear out lines with animation BeginAnimateOutLines(); } return(matchedImage); }
private void UpdateImage() { Texture2D t = CreateTextureFromImageGestureImage(ImageGesture.Image); Image.texture = t; LastImage = ImageGesture.Image.Clone(); if (ImageGesture.MatchedGestureImage == null) { MatchLabel.text = "No match"; // no match add a script entry if (ScriptText != null) { ScriptText.text += LastImage.GetCodeForRowsInitialize(ImageNameText == null ? null : ImageNameText.text) + "," + System.Environment.NewLine; if (AutoAddImages && ImageNameText != null && ImageNameText.text.Length != 0) { ImageGesture.GestureImages.Add(LastImage); RecognizableImages[LastImage] = ImageNameText.text; } } } else { MatchLabel.text = "Match: " + RecognizableImages[ImageGesture.MatchedGestureImage]; } MatchLabel.text += " (" + ImageGesture.MatchedGestureCalculationTimeMilliseconds + " ms)"; ImageGesture.Reset(); }
private void LateUpdate() { if (Input.GetKeyDown(KeyCode.Escape)) { ImageScript.Reset(); imageTimer = 0f; } else if (Input.GetKeyDown(KeyCode.Space) || imageTimer >= 1f) { ImageGestureImage match = ImageScript.CheckForImageMatch(); if (match != null) { //Debug.Log("Found image match: " + match.Name); MatchParticleSystem.Play(); AudioSourceOnMatch.Play(); imageTimer = 0f; imageTimer += Time.deltaTime; } else { //Debug.Log("No match found!"); ImageScript.Reset(); imageTimer = 0f; } } // print(imageTimer); }
private void LateUpdate() { if (Input.touchCount > 0) { touch1 = Input.touches[0]; } if (Input.GetKeyDown(KeyCode.Escape)) { ImageScript.Reset(); } else if (ismove > 5 && (Input.GetMouseButtonUp(0) || touch1.phase.ToString() == TouchPhase.Ended.ToString())) { Debug.Log("ismove:" + ismove); ImageGestureImage match = ImageScript.CheckForImageMatch(); if (match != null) { Debug.Log("Found image match: " + match.Name); MatchParticleSystem.Play(); AudioSourceOnMatch.Play(); } else { Debug.Log("No match found!"); } ismove = 0; ImageScript.Reset(); // TODO: Do something with the match // You could get a texture from it: // Texture2D texture = FingersImageAutomationScript.CreateTextureFromImageGestureImage(match); } }
public void BulkImport() { #if UNITY_EDITOR string path = UnityEditor.EditorUtility.OpenFolderPanel("Load png image textures", "", ""); StringBuilder scriptText = new StringBuilder(); foreach (string pngFile in System.IO.Directory.GetFiles(path, "*.png")) { string fileName = System.IO.Path.GetFileNameWithoutExtension(pngFile); int pos = fileName.IndexOf('_'); if (pos >= 0) { fileName = fileName.Substring(0, pos); } Texture2D tex = new Texture2D(1, 1, TextureFormat.ARGB32, false, false); tex.LoadImage(System.IO.File.ReadAllBytes(pngFile)); Texture2D scaled = ScaleTexture(tex, ImageGestureRecognizer.ImageRows, ImageGestureRecognizer.ImageColumns); ImageGestureImage image = CreateImageGestureImageFromTexture(scaled); Destroy(tex); Destroy(scaled); scriptText.Append(image.GetCodeForRowsInitialize(fileName)); scriptText.AppendLine(","); if (AutoAddImages) { ImageGesture.GestureImages.Add(image); RecognizableImages[image] = fileName; } } ScriptText.text = scriptText.ToString(); #endif }
/// <summary> /// Constructor /// </summary> public ImageGestureRecognizer() { MaximumPathCount = 1; ThresholdUnits = 0.4f; DirectionTolerance = 0.3f; SimularityMinimum = 0.8f; MinimumDistanceBetweenPointsUnits = 0.1f; MinimumPointsToRecognize = 2; Image = new ImageGestureImage(); Image.Initialize(new byte[ImageSize], ImageColumns); Reset(); }
/// <summary> /// Reload all gesture images from the GestureImages field /// </summary> public void ReloadGestureImageEntries() { Gesture.GestureImages = new List <ImageGestureImage>(); GestureImagesToKey = new Dictionary <ImageGestureImage, string>(); foreach (ImageGestureRecognizerComponentScriptImageEntry img in GestureImages) { List <ulong> rows = new List <ulong>(); string imageText; if (File.Exists(img.Images)) { imageText = File.ReadAllText(img.Images); } else { imageText = img.Images; } foreach (string ulongs in imageText.Split('\n')) { string trimmed = ulongs.Trim(); try { // trim out scripting code Match nameMatch = Regex.Match(trimmed, "\"(?<name>[^\"]+)\" ?},?$"); string name = (nameMatch.Success ? nameMatch.Groups["name"].Value : img.Key).Replace("\\\\", "\\"); trimmed = Regex.Replace(trimmed, @" *?\{ new ImageGestureImage\(new ulong\[\] *?\{ *?", string.Empty); trimmed = Regex.Replace(trimmed, @" *?\}.+$", string.Empty); if (trimmed.Length != 0) { string[] rowStrings = trimmed.Trim().Split(','); foreach (string rowString in rowStrings) { string _rowString = rowString.Trim(); if (_rowString.StartsWith("0x")) { _rowString = _rowString.Substring(2); } rows.Add(ulong.Parse(_rowString, System.Globalization.NumberStyles.HexNumber)); } ImageGestureImage image = new ImageGestureImage(rows.ToArray(), ImageGestureRecognizer.ImageColumns, img.ScorePadding); image.Name = name; Gesture.GestureImages.Add(image); GestureImagesToKey[image] = img.Key; rows.Clear(); } } catch (System.Exception ex) { Debug.LogFormat("Error parsing image gesture image: {0} - {1}", trimmed, ex); } } } }
protected override void OnEnable() { base.OnEnable(); Gesture.MaximumPathCount = MaximumPathCount; Gesture.DirectionTolerance = DirectionTolerance; Gesture.ThresholdUnits = ThresholdUnits; Gesture.MinimumDistanceBetweenPointsUnits = MinimumDistanceBetweenPointsUnits; Gesture.SimilarityMinimum = SimilarityMinimum; Gesture.MinimumPointsToRecognize = MinimumPointsToRecognize; Gesture.GestureImages = new List <ImageGestureImage>(); GestureImagesToKey = new Dictionary <ImageGestureImage, string>(); foreach (ImageGestureRecognizerComponentScriptImageEntry img in GestureImages) { List <ulong> rows = new List <ulong>(); foreach (string ulongs in img.Images.Split('\n')) { string trimmed = ulongs.Trim(); try { // trim out scripting code Match nameMatch = Regex.Match(trimmed, "\"(?<name>.+?)\" ?},?$"); string name = (nameMatch.Success ? nameMatch.Groups["name"].Value : img.Key).Replace("\\\\", "\\"); trimmed = Regex.Replace(trimmed, @" *?\{ new ImageGestureImage\(new ulong\[\] *?\{ *?", string.Empty); trimmed = Regex.Replace(trimmed, @" *?\}.+$", string.Empty); if (trimmed.Length != 0) { string[] rowStrings = trimmed.Trim().Split(','); foreach (string rowString in rowStrings) { string _rowString = rowString.Trim(); if (_rowString.StartsWith("0x")) { _rowString = _rowString.Substring(2); } rows.Add(ulong.Parse(_rowString, System.Globalization.NumberStyles.HexNumber)); } ImageGestureImage image = new ImageGestureImage(rows.ToArray(), ImageGestureRecognizer.ImageColumns, img.ScorePadding); image.Name = name; Gesture.GestureImages.Add(image); GestureImagesToKey[image] = img.Key; rows.Clear(); } } catch (System.Exception ex) { Debug.LogFormat("Error parsing image gesture image: {0} - {1}", trimmed, ex); } } } }
/// <summary> /// Callback for gesture events /// </summary> /// <param name="gesture">Gesture</param> public void GestureCallback(DigitalRubyShared.GestureRecognizer gesture) { if (gesture.State == GestureRecognizerState.Ended) { // save off the matched image, the gesture may reset if max path count has been reached matchedImage = Gesture.MatchedGestureImage; } else if (gesture.State != GestureRecognizerState.Began && gesture.State != GestureRecognizerState.Executing) { // don't update lines unless executing return; } UpdateLines(); }
private void UpdateImage() { Texture2D t = CreateTextureFromImageGestureImage(ImageGesture.Image); Image.texture = t; LastImage = ImageGesture.Image.Clone(); if (ImageGesture.MatchedGestureImage == null) { MatchLabel.text = "No match"; } else { MatchLabel.text = "Match: " + RecognizableImages[ImageGesture.MatchedGestureImage]; } MatchLabel.text += " (" + ImageGesture.MatchedGestureCalculationTimeMilliseconds + " ms)"; }
/// <summary> /// Calculate how different this image is with another image. Images must be the same size to compare. /// </summary> /// <param name="other">Other image</param> /// <returns>Number of different pixels or -1 if unable to compare</returns> public int Difference(ImageGestureImage other) { if (Rows == null || other == null || other.Rows == null || other.Rows.Length != Rows.Length) { return(-1); } int difference = 0; ulong xor; for (int i = 0; i < Rows.Length; i++) { // compute the difference, masking off bits we don't care about xor = (Rows[i] ^ other.Rows[i]) & ImageGestureRecognizer.RowBitmask; difference += NumberOfBitsSet(xor); } return(difference); }
/// <summary> /// Check for equality /// </summary> /// <param name="obj">Other object</param> /// <returns>True if equal, false if not</returns> public override bool Equals(object obj) { if (Rows == null) { return(base.Equals(obj)); } ImageGestureImage other = obj as ImageGestureImage; if (other == null || Rows.Length != other.Rows.Length) { return(false); } for (int i = 0; i < Rows.Length; i++) { if (Rows[i] != other.Rows[i]) { return(false); } } return(true); }
/// <summary> /// Compute the similarity with another image. Images must be the same size to compare. /// </summary> /// <param name="other">Other image</param> /// <returns>Similarity (0 - 1)</returns> public float Similarity(ImageGestureImage other) { if (Rows == null || other == null || other.Rows == null || other.Rows.Length != Rows.Length) { return(0.0f); } int difference = 0; ulong xor; for (int i = 0; i < Rows.Length; i++) { // compute the difference, masking off bits we don't care about xor = (Rows[i] ^ other.Rows[i]) & ImageGestureRecognizer.RowBitmask; difference += NumberOfBitsSet(xor); } float similarity = (float)difference / (float)Size; similarity = (1.0f - similarity) + SimilarityPadding; return(similarity); }
protected override void Start() { base.Start(); Gesture.MaximumPathCount = MaximumPathCount; Gesture.DirectionTolerance = DirectionTolerance; Gesture.ThresholdUnits = ThresholdUnits; Gesture.MinimumDistanceBetweenPointsUnits = MinimumDistanceBetweenPointsUnits; Gesture.SimilarityMinimum = SimilarityMinimum; Gesture.MinimumPointsToRecognize = MinimumPointsToRecognize; Gesture.GestureImages = new List <ImageGestureImage>(); GestureImagesToKey = new Dictionary <ImageGestureImage, string>(); foreach (ImageGestureRecognizerComponentScriptImageEntry img in GestureImages) { List <ulong> rows = new List <ulong>(); foreach (string ulongs in img.Images.Split('\n')) { string trimmed = ulongs.Trim(); if (trimmed.Length != 0) { string[] rowStrings = ulongs.Trim().Split(','); foreach (string rowString in rowStrings) { string _rowString = rowString.Trim(); if (_rowString.StartsWith("0x")) { _rowString = _rowString.Substring(2); } rows.Add(ulong.Parse(_rowString, System.Globalization.NumberStyles.HexNumber)); } ImageGestureImage image = new ImageGestureImage(rows.ToArray(), ImageGestureRecognizer.ImageColumns, img.ScorePadding); Gesture.GestureImages.Add(image); GestureImagesToKey[image] = img.Key; rows.Clear(); } } } }
private void UpdateImage() { Texture2D t = new Texture2D(ImageGestureRecognizer.ImageColumns, ImageGestureRecognizer.ImageRows, TextureFormat.ARGB32, false, false); t.filterMode = FilterMode.Point; t.wrapMode = TextureWrapMode.Clamp; for (int y = 0; y < ImageGestureRecognizer.ImageRows; y++) { for (int x = 0; x < ImageGestureRecognizer.ImageColumns; x++) { // each bit in the row can be checked as well if Pixels is not available // if ((imageGesture.Image.Rows[y] & (ulong)(1 << x)) == 0) if (ImageGesture.Image.Pixels[x + (y * ImageGestureRecognizer.ImageRows)] == 0) { t.SetPixel(x, y, Color.clear); } else { t.SetPixel(x, y, Color.white); } } } t.Apply(); Image.texture = t; LastImage = ImageGesture.Image.Clone(); if (ImageGesture.MatchedGestureImage == null) { MatchLabel.text = "No match"; } else { MatchLabel.text = "Match: " + RecognizableImages[ImageGesture.MatchedGestureImage]; } MatchLabel.text += " (" + ImageGesture.MatchedGestureCalculationTimeMilliseconds + " ms)"; }
private void LateUpdate() { #if UNITY_INPUT_SYSTEM_V2 if (UnityEngine.InputSystem.Keyboard.current.escapeKey.wasPressedThisFrame) #else if (UnityEngine.Input.GetKeyDown(KeyCode.Escape)) #endif { ImageScript.Reset(); } #if UNITY_INPUT_SYSTEM_V2 if (UnityEngine.InputSystem.Keyboard.current.spaceKey.wasPressedThisFrame) #else if (UnityEngine.Input.GetKeyDown(KeyCode.Space)) #endif { ImageGestureImage match = ImageScript.CheckForImageMatch(); if (match != null) { Debug.Log("Found image match: " + match.Name); MatchParticleSystem.Play(); AudioSourceOnMatch.Play(); } else { Debug.Log("No match found!"); } // TODO: Do something with the match // You could get a texture from it: // Texture2D texture = FingersImageAutomationScript.CreateTextureFromImageGestureImage(match); } }
private void ImageGestureUpdated(DigitalRubyShared.GestureRecognizer imageGesture) { if (imageGesture.State == GestureRecognizerState.Ended) { AddTouches(imageGesture.CurrentTrackedTouches); // note - if you have received an image you care about, you should reset the image gesture, i.e. imageGesture.Reset() // the ImageGestureRecognizer doesn't automaticaly Reset like other gestures when it ends because some images need multiple paths // which requires lifting the mouse or finger and drawing again LastImage = ImageGesture.Image.Clone(); MatchedImage = (ImageGesture.MatchedGestureImage == null ? null : ImageGesture.MatchedGestureImage.Clone()); } else if (imageGesture.State == GestureRecognizerState.Began) { // began currentPointList = new List <Vector2>(); lineSet.Add(currentPointList); AddTouches(imageGesture.CurrentTrackedTouches); } else if (imageGesture.State == GestureRecognizerState.Executing) { // moving AddTouches(imageGesture.CurrentTrackedTouches); } }