mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-10 00:44:10 +08:00
add YOLOv8 test trigger
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<PackageReference Include="GlobalHotkeys" Version="1.0.0.6" />
|
||||
<PackageReference Include="H.InputSimulator" Version="1.4.0" />
|
||||
<PackageReference Include="H.InputSimulator" Version="1.4.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
@@ -34,9 +34,10 @@
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.RichTextBox.Wpf" Version="1.1.0" />
|
||||
<PackageReference Include="Vanara.PInvoke.SHCore" Version="3.4.16" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="3.4.16" />
|
||||
<PackageReference Include="Vanara.PInvoke.SHCore" Version="3.4.17" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="3.4.17" />
|
||||
<PackageReference Include="WPF-UI" Version="3.0.0-preview.7" />
|
||||
<PackageReference Include="YoloV8" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
41
BetterGenshinImpact/Core/Recognition/ONNX/YOLO/Predictor.cs
Normal file
41
BetterGenshinImpact/Core/Recognition/ONNX/YOLO/Predictor.cs
Normal file
@@ -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<string[]>(json) ?? throw new Exception("label.json deserialize failed");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||

|
||||
@@ -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<RectDrawable>
|
||||
{
|
||||
("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);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
|
||||
@@ -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<RectDrawable>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -8,54 +8,58 @@ public class DrawContent
|
||||
/// <summary>
|
||||
/// 在遮罩窗口上绘制的矩形
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, RectDrawable> RectList { get; set; } = new();
|
||||
public ConcurrentDictionary<string, List<RectDrawable>> RectList { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 在遮罩窗口上绘制的文本
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, TextDrawable> TextList { get; set; } = new();
|
||||
public ConcurrentDictionary<string, List<TextDrawable>> 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<RectDrawable> { newRect };
|
||||
MaskWindow.Instance().Refresh();
|
||||
}
|
||||
|
||||
public void PutOrRemoveRectList(List<(string, RectDrawable)> list)
|
||||
public void PutOrRemoveRectList(string key, List<RectDrawable>? 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有绘制内容
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
Reference in New Issue
Block a user