291 lines
8.7 KiB
C#
291 lines
8.7 KiB
C#
//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 = OK,false = 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);
|
||
}
|
||
}
|
||
}
|
||
}
|