Files
better-genshin-impact/Test/BetterGenshinImpact.Test/Simple/AllMap/MatchTemplateTest.cs
2025-02-23 22:03:52 +08:00

118 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BetterGenshinImpact.Core.Recognition.OpenCv;
using OpenCvSharp;
namespace BetterGenshinImpact.Test.Simple.AllMap;
public class MatchTemplateTest
{
public static readonly Size TemplateSize = new(240, 135);
// 对无用部分进行裁剪左160上80下96
public static readonly Rect TemplateSizeRoi = new Rect(20, 10, TemplateSize.Width - 20, TemplateSize.Height - 22);
public static void Test()
{
var tar = new Mat(@"E:\HuiTask\更好的原神\地图匹配\比较\叠图\无法匹配.png", ImreadModes.Grayscale);
var sTar = tar.Resize(new Size(240, 135), 0, 0, InterpolationFlags.Cubic);
// sTar = new Mat(sTar, TemplateSizeRoi);
Cv2.ImShow("sTar", sTar);
var src = new Mat(@"E:\HuiTask\更好的原神\地图匹配\combined_image_small.png", ImreadModes.Grayscale);
var src2 = src.Clone();
var p = MatchTemplateWithGaussianBlur(src, sTar, TemplateMatchModes.CCoeffNormed, null, 0.1);
Cv2.Rectangle(src2, new Rect(p.X, p.Y, sTar.Width, sTar.Height), new Scalar(0, 0, 255));
Cv2.ImWrite(@"E:\HuiTask\更好的原神\地图匹配\x1.png", src2);
}
public static void TestTrack()
{
var tar = new Mat(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\blue_task_point_28x.png", ImreadModes.Grayscale);
var src = new Mat(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\202404050232291883.png", ImreadModes.Grayscale);
var src2 = src.Clone();
var p = MatchTemplateHelper.MatchTemplate(src, tar, TemplateMatchModes.CCoeffNormed, null, 0.2);
Cv2.Rectangle(src2, new Rect(p.X, p.Y, tar.Width, tar.Height), new Scalar(0, 0, 255), 1);
Cv2.ImWrite(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\rec_b1.png", src2);
}
public static void TestMenu()
{
var tar = new Mat(@"D:\HuiPrograming\Projects\CSharp\MiHoYo\BetterGenshinImpact\BetterGenshinImpact\GameTask\Common\Element\Assets\1920x1080\paimon_menu.png", ImreadModes.Color);
var src = new Mat(@"E:\HuiTask\更好的原神\地图匹配\比较\菜单\Clip_20240331_155210.png", ImreadModes.Color);
var src2 = src.Clone();
var p = MatchTemplateHelper.MatchTemplate(src, tar, TemplateMatchModes.CCoeffNormed, null, 0.1);
Cv2.Rectangle(src2, new Rect(p.X, p.Y, tar.Width, tar.Height), new Scalar(0, 0, 255), 1);
// 画出小地图的位置
// 此图38x40 小地图210x210 小地图左上角位置 24,-15
Cv2.Rectangle(src2, new Rect(p.X + 24, p.Y - 15, 210, 210), Scalar.Blue, 1);
Cv2.ImWrite(@"E:\HuiTask\更好的原神\地图匹配\比较\菜单\rec2.png", src2);
}
public static void TestTeamAvatar()
{
var tar = new Mat(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\识别头像素材\UI_AvatarIcon_Side_Zhongli_2.png", ImreadModes.Unchanged);
// tar = tar.Resize(new Size(108, 108), 0, 0, InterpolationFlags.Cubic);
var channels = tar.Split();
for (int i = 0; i < 3; i++)
{
channels[i] &= channels[3];
}
Cv2.Merge(channels[..3], tar);
Cv2.ImShow("tar.png", tar);
var src = new Mat(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\1.png", ImreadModes.Color);
var src2 = src.Clone();
var p = MatchTemplateWithGaussianBlur(src, tar, TemplateMatchModes.CCoeffNormed, null, 0.1);
Cv2.Rectangle(src2, new Rect(p.X, p.Y, tar.Width, tar.Height), new Scalar(0, 0, 255), 1);
// Cv2.ImWrite(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\rec_1.png", src2);
Cv2.ImShow("src2", src2);
}
public static Point MatchTemplateWithGaussianBlur(Mat srcMat, Mat dstMat, TemplateMatchModes matchMode, Mat? maskMat = null, double threshold = 0.8)
{
try
{
var result = new Mat();
if (maskMat == null)
{
Cv2.MatchTemplate(srcMat, dstMat, result, matchMode);
}
else
{
Cv2.MatchTemplate(srcMat, dstMat, result, matchMode, maskMat);
}
if (matchMode is TemplateMatchModes.SqDiff or TemplateMatchModes.CCoeff or TemplateMatchModes.CCorr)
{
Cv2.Normalize(result, result, 0, 1, NormTypes.MinMax, -1, null);
}
using var blurResult = new Mat();
Cv2.GaussianBlur(result, blurResult, new Size(1, 1), 0);
Cv2.ImShow("blurResult", blurResult);
Cv2.Subtract(result, blurResult, result);
Cv2.MinMaxLoc(result, out var minValue, out var maxValue, out var minLoc, out var maxLoc);
Cv2.ImShow("result", result);
if (matchMode is TemplateMatchModes.SqDiff or TemplateMatchModes.SqDiffNormed)
{
if (minValue <= 1 - threshold)
{
return minLoc;
}
}
else
{
if (maxValue >= threshold)
{
return maxLoc;
}
}
return new Point();
}
catch (Exception ex)
{
return new Point();
}
}
}