private void LoadScanAreas() { this.areas = new ScanAreaDictionary(); this.heroes = new ScanAreaDictionary(); this.opponentHeroes = new ScanAreaDictionary(); this.decks = new ScanAreaDictionary(); this.arenaHeroes = new ScanAreaDictionary(); this.arenaWinsLookup = new ScanAreaDictionary(); this.arenaWinsLookup2 = new ScanAreaImageDictionary(); this.arenaLossesLookup = new ScanAreaDictionary(); this.scanAreaProvider.Load(); this.scanareas = this.scanAreaProvider.GetScanAreas(); foreach (var scanArea in this.scanareas) { var allareas = scanArea.Areas.ToDictionary(x => x.Key, x => x); foreach (var a in allareas) { if (a.Key.StartsWith("hero_")) { this.InitAreas(a.Key, "hero_", scanArea, this.heroes, a); } else if (a.Key.StartsWith("opphero_")) { this.InitAreas(a.Key, "opphero_", scanArea, this.opponentHeroes, a); } else if (a.Key.StartsWith("deck_")) { this.InitAreas(a.Key, "deck_", scanArea, this.decks, a); } //else if (a.Key.StartsWith("arenahero_")) //{ // this.InitAreas(a.Key, "arenahero_", scanArea, this.arenaHeroes, a); //} else if (a.Key.StartsWith("arenawins_")) { this.InitAreas(a.Key, "arenawins_", scanArea, this.arenaWinsLookup, a); this.InitImageAreas(a.Key, "arenawins_", scanArea, this.arenaWinsLookup2, a); } else if (a.Key.StartsWith("arenaloss_")) { this.InitAreas(a.Key, "arenaloss_", scanArea, this.arenaLossesLookup, a); } else if (a.Key.StartsWith("arena_hero_")) { this.InitAreas(a.Key, "arena_hero_", scanArea, this.arenaHeroes, a); } else { this.InitAreas(a.Key, string.Empty, scanArea, this.areas, a); } } } }
//private string DetectBest(ScanAreaDictionary lookup, IDictionary<int, Tuple<ulong, Rectangle>> useArea, string debugkey) //{ // var hashes = new List<ulong>(); // var keys = new List<string>(); // var rect = new Rectangle(); // int theResolution; // foreach (var key in lookup.Keys) // { // var template = lookup[key]; // ulong matchhash; // if (template.ContainsKey(this.lastResolution)) // { // matchhash = template[this.lastResolution].Hash; // } // else if (template.ContainsKey(this.BaseResolution)) // { // matchhash = template[this.BaseResolution].Hash; // } // else // { // Log.Error("No scan data found for requested template: " + debugkey); // return null; // } // hashes.Add(matchhash); // keys.Add(key); // } // if (useArea.ContainsKey(this.lastResolution)) // { // rect = useArea[this.lastResolution].Rect; // theResolution = this.lastResolution; // } // else if (useArea.ContainsKey(this.BaseResolution)) // { // rect = useArea[this.BaseResolution].Rect; // theResolution = this.BaseResolution; // } // else // { // Log.Error("No scan data found for requested template: " + debugkey); // return null; // } // var source = this.image; // using (var roi = source.Clone(ResolutionHelper.CorrectRectangle(source.Size, rect, theResolution), PixelFormat.Format32bppRgb)) // { // var hash = this.imageHasher.Create(roi); // var best = PerceptualHash.FindBest(hash, hashes); // if (best.Distance <= ThreshHold) // { // Log.Diag("Detected best hash: '{0}' Distance: {1}", debugkey, best.Distance); // return keys[best.Index]; // } // } // return null; //} private string DetectBest(ScanAreaDictionary lookup, string debugkey, int?threshold = null) { threshold = threshold ?? ThreshHold; var hashes = new List <ulong>(); var keys = new List <string>(); var rect = new Rectangle(); int theResolution = BaseResolution; foreach (var key in lookup.Keys) { var template = lookup[key]; ulong matchhash; if (template.ContainsKey(this.lastResolution)) { matchhash = template[this.lastResolution].Hash; rect = template[this.lastResolution].Rect; theResolution = this.lastResolution; } else if (template.ContainsKey(this.BaseResolution)) { matchhash = template[this.BaseResolution].Hash; rect = template[this.BaseResolution].Rect; theResolution = this.BaseResolution; } else { Log.Error("No scan data found for requested template: " + debugkey); return(null); } hashes.Add(matchhash); keys.Add(key); } var source = this.image; using (var roi = source.Lock(ResolutionHelper.CorrectRectangle(source.Size, rect, theResolution), PixelFormat.Format32bppRgb)) { var hash = this.imageHasher.Create(roi.Data); var best = PerceptualHash.FindBest(hash, hashes); TraceLog.Log("Detected best hash: '{0}' Distance: {1}", debugkey, best.Distance); if (best.Distance <= threshold) { return(keys[best.Index]); } } return(null); }
private void InitAreas(string arrkey, string prefix, ScanAreas scanArea, ScanAreaDictionary lookup, KeyValuePair <string, ScanArea> a) { var key = arrkey.Substring(prefix.Length); if (!lookup.ContainsKey(key)) { // lookup[key] = new Tuple<ulong, IDictionary<int, Rectangle>>(a.Value.Hash, new Dictionary<int, Rectangle>()); lookup[key] = new Dictionary <int, ScanArea>(); } var tmp = lookup[key]; if (!tmp.ContainsKey(scanArea.BaseResolution)) { tmp[scanArea.BaseResolution] = a.Value; } }
/// <summary>The detect.</summary> /// <param name="lookup">The lookup.</param> /// <param name="key">The key.</param> /// <param name="useArea"></param> /// <param name="i"></param> /// <returns>The <see cref="bool"/>.</returns> private DetectionResult Detect(ScanAreaDictionary lookup, string key, IDictionary <int, ScanArea> useArea = null, int threshold = -1) { threshold = threshold >= 0 ? threshold : ThreshHold; if (!lookup.ContainsKey(key)) { Log.Error("No scan data found for requested template: {0}", key); return(new DetectionResult(false, -1)); } var template = lookup[key]; // var rect = new Rectangle(); int theResolution; // ulong matchhash; ScanArea area = null; if (template.ContainsKey(this.lastResolution)) { // rect = template[this.lastResolution].Rect; // matchhash = template[this.lastResolution].Hash; area = template[this.lastResolution]; theResolution = this.lastResolution; } else if (template.ContainsKey(this.BaseResolution)) { // rect = template[this.BaseResolution].Rect; // matchhash = template[this.BaseResolution].Hash; area = template[this.BaseResolution]; theResolution = this.BaseResolution; } else { Log.Error("No scan data found for requested template: " + key); return(new DetectionResult(false, -1)); } if (useArea != null) { if (useArea.ContainsKey(this.lastResolution)) { // rect = useArea[this.lastResolution].Rect; area = useArea[this.lastResolution]; theResolution = this.lastResolution; } else if (useArea.ContainsKey(this.BaseResolution)) { // rect = useArea[this.BaseResolution].Rect; area = useArea[this.BaseResolution]; theResolution = this.BaseResolution; } else { Log.Error("No scan data found for requested template: " + key); return(new DetectionResult(false, -1)); } } var source = this.image; int distance = -1; DetectionResult result = new DetectionResult(); using (var roi = source.Lock(ResolutionHelper.CorrectRectangle(source.Size, area.Rect, theResolution), source.PixelFormat)) { // var roi = source.Clone(ResolutionHelper.CorrectRectangle(source.Size, area.Rect, theResolution), source.PixelFormat); //Tuple<byte[], DetectionResult> cached = null; //byte[] roiBytes = roi.GetBytes(); //if (hashCache.TryGetValue(key, out cached)) //{ // if (ImageUtils.AreEqual(cached.Item1, roiBytes)) // { // TraceLog.Log("hash cache hit: {0}, hit: {1} distance: {2}", key, cached.Item2.Found, cached.Item2.Distance); // return cached.Item2; // } //} var hash = this.imageHasher.Create(roi.Data); distance = PerceptualHash.HammingDistance(hash, area.Hash); TraceLog.Log("Detecting '{0}'. Distance: {1}", key, distance); if (distance <= threshold) { TraceLog.Log("Detected '{0}'. Distance: {1}", key, distance); Mostly mostly; if (!String.IsNullOrEmpty(area.Mostly) && Enum.TryParse(area.Mostly, out mostly)) { result = new DetectionResult(roi.Data.IsMostly(mostly), distance); } else { result = new DetectionResult(true, distance); } } else { result = new DetectionResult(false, distance); } // hashCache.Set(key, new Tuple<byte[], DetectionResult>(roiBytes, result)); } return(result); }