Files
CheckDevice/Check.Main/Common/LogoMatcher.cs
2025-10-20 14:47:17 +08:00

291 lines
8.7 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 HalconDotNet;
//using System;
//using System.Collections.Generic;
//using System.Drawing.Imaging;
//using System.IO;
//namespace HalconTemplateMatch
//{
// public class LogoMatcher
// {
// private List<HTuple> modelHandles = new List<HTuple>();
// /// <summary>
// /// 从文件加载多个模板
// /// </summary>
// public void LoadTemplates(string dir)
// {
// foreach (var file in Directory.GetFiles(dir, "*.shm"))
// {
// HTuple modelID;
// HOperatorSet.ReadShapeModel(file, out modelID);
// modelHandles.Add(modelID);
// Console.WriteLine($"加载模板: {file}");
// }
// }
// /// <summary>
// /// 在测试图像中查找 Logo
// /// </summary>
// /// <returns>true = OKfalse = NG</returns>
// public bool FindLogo(string testImagePath)
// {
// HObject ho_TestImage;
// HOperatorSet.ReadImage(out ho_TestImage, testImagePath);
// HOperatorSet.Rgb1ToGray(ho_TestImage, out ho_TestImage);
// foreach (var modelID in modelHandles)
// {
// HOperatorSet.FindShapeModel(
// ho_TestImage,
// modelID,
// new HTuple(0).TupleRad(),
// new HTuple(360).TupleRad(),
// 0.5, // 最低分数
// 1, // 最大匹配数
// 0.5, // 重叠度
// "least_squares",
// 0,
// 0.9,
// out HTuple row,
// out HTuple col,
// out HTuple angle,
// out HTuple score);
// if (score.Length > 0 && score[0].D > 0.5)
// {
// Console.WriteLine($"找到 Logo: Row={row[0]}, Col={col[0]}, Score={score[0]}");
// return true; // 找到即返回成功
// }
// }
// return false; // 没找到
// }
// /// <summary>
// /// 重载FindLogo函数double返回
// /// </summary>
// /// <param name="bmp"></param>
// /// <returns></returns>
// public double FindLogo(Bitmap bmp)
// {
// // Bitmap 转 HObject
// HObject ho_TestImage;
// Bitmap2HObject(bmp, out ho_TestImage);
// HOperatorSet.Rgb1ToGray(ho_TestImage, out ho_TestImage);
// double bestScore = -1;
// foreach (var modelID in modelHandles)
// {
// HOperatorSet.FindShapeModel(
// ho_TestImage,
// modelID,
// new HTuple(0).TupleRad(),
// new HTuple(360).TupleRad(),
// 0.5, // 最低分数
// 1, // 最大匹配数
// 0.5, // 重叠度
// "least_squares",
// 0,
// 0.9,
// out HTuple row,
// out HTuple col,
// out HTuple angle,
// out HTuple score);
// if (score.Length > 0 && score[0].D > bestScore)
// {
// bestScore = score[0].D;
// }
// }
// ho_TestImage.Dispose();
// return bestScore; // -1 = 没找到
// }
// /// <summary>
// /// Bitmap 转 Halcon HObject
// /// </summary>
// private void Bitmap2HObject(Bitmap bmp, out HObject hobj)
// {
// HOperatorSet.GenEmptyObj(out hobj);
// Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
// BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
// try
// {
// HOperatorSet.GenImageInterleaved(
// out hobj,
// bmpData.Scan0,
// "bgr", // Bitmap 默认是 BGR
// bmp.Width,
// bmp.Height,
// 0,
// "byte",
// bmp.Width,
// bmp.Height,
// 0,
// 0,
// -1,
// 0
// );
// }
// finally
// {
// bmp.UnlockBits(bmpData);
// }
// }
// }
//}
using HalconDotNet;
using NPOI.OpenXmlFormats.Vml;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace HalconTemplateMatch
{
public class LogoMatcher
{
private readonly List<HTuple> modelHandles = new List<HTuple>();
/// <summary>
/// 从指定目录加载所有 .shm 模板文件
/// </summary>
public void LoadTemplates(string dir)
{
try
{
string fullPath = Path.GetFullPath(dir);
if (!Directory.Exists(fullPath))
{
Console.WriteLine($"[警告] 模型目录不存在: {fullPath}");
return;
}
string[] modelFiles = Directory.GetFiles(fullPath, "*.shm", SearchOption.TopDirectoryOnly);
if (modelFiles.Length == 0)
{
Console.WriteLine($"[警告] 模型目录中没有任何 .shm 文件: {fullPath}");
return;
}
foreach (var file in modelFiles)
{
try
{
HTuple modelID;
HOperatorSet.ReadShapeModel(file, out modelID);
modelHandles.Add(modelID);
Console.WriteLine($"[加载成功] 模板: {file}");
}
catch (HOperatorException ex)
{
Console.WriteLine($"[错误] 无法加载模板 {file}: {ex.Message}");
}
}
if (modelHandles.Count == 0)
{
Console.WriteLine($"[警告] 没有成功加载任何模板文件。");
}
}
catch (Exception ex)
{
Console.WriteLine($"[异常] 加载模板目录出错: {ex.Message}");
}
}
/// <summary>
/// 匹配并返回最高得分double返回
/// </summary>
public double FindLogo(Bitmap bmp)
{
if (modelHandles.Count == 0)
{
Console.WriteLine("[警告] 尚未加载任何模板。");
return -1;
}
// Bitmap 转 Halcon 对象
HObject ho_TestImage;
Bitmap2HObject(bmp, out ho_TestImage);
HOperatorSet.Rgb1ToGray(ho_TestImage, out ho_TestImage);
double bestScore = -1;
foreach (var modelID in modelHandles)
{
try
{
HOperatorSet.FindScaledShapeModel(
ho_TestImage,
modelID,
new HTuple(0).TupleRad(),
new HTuple(360).TupleRad(),
0.8, 1.2,
0.5, 1, 0.5,
"least_squares_high",
0, 0.9,
out HTuple row, out HTuple col, out HTuple angle, out HTuple scale, out HTuple score
);
if (score.Length > 0 && score[0].D > bestScore)
bestScore = score[0].D;
}
catch (HOperatorException ex)
{
Console.WriteLine($"[错误] 模板匹配失败: {ex.Message}");
}
}
ho_TestImage.Dispose();
return bestScore;
}
/// <summary>
/// Bitmap 转 Halcon HObject
/// </summary>
private void Bitmap2HObject(Bitmap bmp, out HObject hobj)
{
HOperatorSet.GenEmptyObj(out hobj);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
try
{
HOperatorSet.GenImageInterleaved(
out hobj,
bmpData.Scan0,
"bgr",
bmp.Width,
bmp.Height,
0,
"byte",
bmp.Width,
bmp.Height,
0,
0,
-1,
0);
}
finally
{
bmp.UnlockBits(bmpData);
}
}
}
}