diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 33fb72d4..a9172403 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -21,7 +21,7 @@ - + @@ -34,9 +34,10 @@ - - + + + diff --git a/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/Predictor.cs b/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/Predictor.cs new file mode 100644 index 00000000..bb397365 --- /dev/null +++ b/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/Predictor.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using BetterGenshinImpact.Core.Config; +using Microsoft.ML.OnnxRuntime; +using Microsoft.ML.OnnxRuntime.Tensors; +using OpenCvSharp; + +namespace BetterGenshinImpact.Core.Recognition.ONNX.YOLO; + +public class Predictor +{ + private readonly InferenceSession _session; + private readonly string[] labels; + + public Predictor() + { + var options = new SessionOptions(); + var modelPath = Global.Absolute("Config\\Model\\Fish\\bgi_fish.onnx"); + if (!File.Exists(modelPath)) + { + throw new FileNotFoundException("自动钓鱼模型文件不存在", modelPath); + } + + _session = new InferenceSession(modelPath, options); + + + var wordJsonPath = Global.Absolute("Config\\Model\\Fish\\label.json"); + if (!File.Exists(wordJsonPath)) + { + throw new FileNotFoundException("自动钓鱼模型分类文件不存在", wordJsonPath); + } + + var json = File.ReadAllText(wordJsonPath); + labels = JsonSerializer.Deserialize(json) ?? throw new Exception("label.json deserialize failed"); + } + + +} \ No newline at end of file diff --git a/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/README.md b/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/README.md deleted file mode 100644 index 69fbef4b..00000000 --- a/BetterGenshinImpact/Core/Recognition/ONNX/YOLO/README.md +++ /dev/null @@ -1,2 +0,0 @@ - -![](https://raw.githubusercontent.com/babalae/better-genshin-impact/main/Docs/Assert/zzzl.png) diff --git a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs index 701820f2..fcd87aad 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs @@ -588,16 +588,17 @@ namespace BetterGenshinImpact.GameTask.AutoFishing } } + private readonly Pen _pen = new(Color.Red, 1); + private void PutRects(Rect left, Rect cur, Rect right) { - Pen pen = new(Color.Red, 1); - var list = new List<(string, RectDrawable)> + var list = new List { - ("FishingBarLeft", left.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(pen)), - ("FishingBarCur", cur.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(pen)), - ("FishingBarRight", right.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(pen)) + left.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(_pen), + cur.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(_pen), + right.ToWindowsRectangleOffset(_fishBoxRect.X, _fishBoxRect.Y).ToRectDrawable(_pen) }; - VisionContext.Instance().DrawContent.PutOrRemoveRectList(list); + VisionContext.Instance().DrawContent.PutOrRemoveRectList("FishingBar", list); } ///// diff --git a/BetterGenshinImpact/GameTask/Placeholder/PlaceholderTrigger.cs b/BetterGenshinImpact/GameTask/Placeholder/PlaceholderTrigger.cs index d1438235..16d6404b 100644 --- a/BetterGenshinImpact/GameTask/Placeholder/PlaceholderTrigger.cs +++ b/BetterGenshinImpact/GameTask/Placeholder/PlaceholderTrigger.cs @@ -1,10 +1,18 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; using System.Windows; +using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Recognition; using BetterGenshinImpact.GameTask.AutoFishing.Assets; using BetterGenshinImpact.GameTask.AutoGeniusInvokation; using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets; using BetterGenshinImpact.View.Drawable; +using Compunet.YoloV8; +using Compunet.YoloV8.Data; namespace BetterGenshinImpact.GameTask.Placeholder; @@ -19,8 +27,12 @@ public class TestTrigger : ITaskTrigger public int Priority => 9999; public bool IsExclusive { get; private set; } + private readonly Pen _pen = new(Color.Coral, 1); + //private readonly AutoGeniusInvokationAssets _autoGeniusInvokationAssets; + private YoloV8 _predictor = new(Global.Absolute("Config\\Model\\Fish\\bgi_fish.onnx")); + public TestTrigger() { var info = TaskContext.Instance().SystemInfo; @@ -29,12 +41,15 @@ public class TestTrigger : ITaskTrigger public void Init() { - IsEnabled = false; + IsEnabled = true; IsExclusive = true; } public void OnCapture(CaptureContent content) { + Detect(content); + + //var dictionary = GeniusInvokationControl.FindMultiPicFromOneImage2OneByOne(content.CaptureRectArea.SrcGreyMat, _autoGeniusInvokationAssets.RollPhaseDiceMats, 0.7); //if (dictionary.Count > 0) //{ @@ -66,4 +81,21 @@ public class TestTrigger : ITaskTrigger // Debug.WriteLine("没找到"); //} } + + private void Detect(CaptureContent content) + { + using var memoryStream = new MemoryStream(); + content.CaptureRectArea.SrcBitmap.Save(memoryStream, ImageFormat.Bmp); + memoryStream.Seek(0, SeekOrigin.Begin); + var result = _predictor.Detect(memoryStream); + Debug.WriteLine(result); + var list = new List(); + foreach (var box in result.Boxes) + { + var rect = new Rect(box.Bounds.X, box.Bounds.Y, box.Bounds.Width, box.Bounds.Height); + list.Add(new RectDrawable(rect, _pen)); + } + + VisionContext.Instance().DrawContent.PutOrRemoveRectList("Box", list); + } } \ No newline at end of file diff --git a/BetterGenshinImpact/View/Drawable/DrawContent.cs b/BetterGenshinImpact/View/Drawable/DrawContent.cs index 141af3d7..1addeea2 100644 --- a/BetterGenshinImpact/View/Drawable/DrawContent.cs +++ b/BetterGenshinImpact/View/Drawable/DrawContent.cs @@ -8,54 +8,58 @@ public class DrawContent /// /// 在遮罩窗口上绘制的矩形 /// - public ConcurrentDictionary RectList { get; set; } = new(); + public ConcurrentDictionary> RectList { get; set; } = new(); /// /// 在遮罩窗口上绘制的文本 /// - public ConcurrentDictionary TextList { get; set; } = new(); + public ConcurrentDictionary> TextList { get; set; } = new(); public void PutRect(string key, RectDrawable newRect) { if (RectList.TryGetValue(key, out var prevRect)) { - if (newRect.Equals(prevRect)) + if (prevRect.Count == 0 && newRect.Equals(prevRect[0])) { return; } } - RectList[key] = newRect; + RectList[key] = new List { newRect }; MaskWindow.Instance().Refresh(); } - public void PutOrRemoveRectList(List<(string, RectDrawable)> list) + public void PutOrRemoveRectList(string key, List? list) { bool changed = false; - list.ForEach(item => + + if (RectList.TryGetValue(key, out var prevRect)) { - var newRect = item.Item2; - if (newRect.IsEmpty) + if (list == null) { - if (RectList.TryGetValue(item.Item1, out _)) - { - RectList.TryRemove(item.Item1, out _); - changed = true; - } + RectList.TryRemove(key, out _); + changed = true; + } + else if (prevRect.Count != list.Count) + { + RectList[key] = list; + changed = true; } else { - if (RectList.TryGetValue(item.Item1, out var prevRect)) - { - if (newRect.Equals(prevRect)) - { - return; - } - } - RectList[item.Item1] = newRect; + // 不逐一比较了,使用这个方法的地方,都是在每一帧都会刷新的 changed = true; } - }); + } + else + { + if (list is { Count: > 0 }) + { + RectList[key] = list; + changed = true; + } + } + if (changed) { MaskWindow.Instance().Refresh(); @@ -71,29 +75,6 @@ public class DrawContent } } - public void PutText(string key, TextDrawable newText) - { - if (TextList.TryGetValue(key, out var prevText)) - { - if (newText.Equals(prevText)) - { - return; - } - } - - TextList[key] = newText; - MaskWindow.Instance().Refresh(); - } - - public void RemoveText(string key) - { - if (TextList.TryGetValue(key, out _)) - { - TextList.TryRemove(key, out _); - MaskWindow.Instance().Refresh(); - } - } - /// /// 清理所有绘制内容 diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs index 8920547d..0021d75d 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml.cs +++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs @@ -131,25 +131,29 @@ namespace BetterGenshinImpact.View foreach (var kv in VisionContext.Instance().DrawContent.RectList) { - var drawable = kv.Value; - if (!drawable.IsEmpty) + foreach (var drawable in kv.Value) { - drawingContext.DrawRectangle(Brushes.Transparent, - new Pen(new SolidColorBrush(drawable.Pen.Color.ToWindowsColor()), drawable.Pen.Width), - drawable.Rect); + if (!drawable.IsEmpty) + { + drawingContext.DrawRectangle(Brushes.Transparent, + new Pen(new SolidColorBrush(drawable.Pen.Color.ToWindowsColor()), drawable.Pen.Width), + drawable.Rect); + } } } foreach (var kv in VisionContext.Instance().DrawContent.TextList) { - var drawable = kv.Value; - if (!drawable.IsEmpty) + foreach (var drawable in kv.Value) { - drawingContext.DrawText(new FormattedText(drawable.Text, - CultureInfo.GetCultureInfo("zh-cn"), - FlowDirection.LeftToRight, - MyTypeface, - 36, Brushes.Black, 1), drawable.Point); + if (!drawable.IsEmpty) + { + drawingContext.DrawText(new FormattedText(drawable.Text, + CultureInfo.GetCultureInfo("zh-cn"), + FlowDirection.LeftToRight, + MyTypeface, + 36, Brushes.Black, 1), drawable.Point); + } } } } diff --git a/Docs/Assert/mlyt.png b/Docs/Assert/mlyt.png deleted file mode 100644 index c79493e3..00000000 Binary files a/Docs/Assert/mlyt.png and /dev/null differ diff --git a/Docs/Assert/zzzl.png b/Docs/Assert/zzzl.png deleted file mode 100644 index 261dcef9..00000000 Binary files a/Docs/Assert/zzzl.png and /dev/null differ