115 lines
4.9 KiB
C#
115 lines
4.9 KiB
C#
// ============================================================================
|
|
// Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved.
|
|
// 文件� PointToLineProcessor.cs
|
|
// æ��è¿°: 点到直线è·�离测é‡�ç®—å�
|
|
// 功能:
|
|
// - 用户定义一�直线(两个端点)和一个测�点
|
|
// - 计算测�点到直线的垂直��
|
|
// - 支æŒ�åƒ�ç´ å°ºå¯¸æ ‡å®šè¾“å‡ºç‰©ç�†è·�离
|
|
// - 在图åƒ�上绘制直线ã€�测é‡�点ã€�垂足和è·�ç¦»æ ‡æ³¨
|
|
// 算法: 点到直线�离公�
|
|
// 作� �伟 wei.lw.li@hexagon.com
|
|
// ============================================================================
|
|
|
|
using Emgu.CV;
|
|
using Emgu.CV.Structure;
|
|
using Serilog;
|
|
using System.Drawing;
|
|
using XP.ImageProcessing.Core;
|
|
|
|
namespace XP.ImageProcessing.Processors;
|
|
|
|
public class PointToLineProcessor : ImageProcessorBase
|
|
{
|
|
private static readonly ILogger _logger = Log.ForContext<PointToLineProcessor>();
|
|
|
|
public PointToLineProcessor()
|
|
{
|
|
Name = LocalizationHelper.GetString("PointToLineProcessor_Name");
|
|
Description = LocalizationHelper.GetString("PointToLineProcessor_Description");
|
|
}
|
|
|
|
protected override void InitializeParameters()
|
|
{
|
|
// 直线两端�+ 测�点(由交互控件注入)
|
|
Parameters.Add("L1X", new ProcessorParameter("L1X", "L1X", typeof(int), 100, null, null, "") { IsVisible = false });
|
|
Parameters.Add("L1Y", new ProcessorParameter("L1Y", "L1Y", typeof(int), 200, null, null, "") { IsVisible = false });
|
|
Parameters.Add("L2X", new ProcessorParameter("L2X", "L2X", typeof(int), 400, null, null, "") { IsVisible = false });
|
|
Parameters.Add("L2Y", new ProcessorParameter("L2Y", "L2Y", typeof(int), 200, null, null, "") { IsVisible = false });
|
|
Parameters.Add("PX", new ProcessorParameter("PX", "PX", typeof(int), 250, null, null, "") { IsVisible = false });
|
|
Parameters.Add("PY", new ProcessorParameter("PY", "PY", typeof(int), 100, null, null, "") { IsVisible = false });
|
|
|
|
Parameters.Add("PixelSize", new ProcessorParameter(
|
|
"PixelSize",
|
|
LocalizationHelper.GetString("PointToLineProcessor_PixelSize"),
|
|
typeof(double), 1.0, null, null,
|
|
LocalizationHelper.GetString("PointToLineProcessor_PixelSize_Desc")));
|
|
|
|
Parameters.Add("Unit", new ProcessorParameter(
|
|
"Unit",
|
|
LocalizationHelper.GetString("PointToLineProcessor_Unit"),
|
|
typeof(string), "px", null, null,
|
|
LocalizationHelper.GetString("PointToLineProcessor_Unit_Desc"),
|
|
new string[] { "px", "mm", "μm", "cm" }));
|
|
|
|
Parameters.Add("Thickness", new ProcessorParameter(
|
|
"Thickness",
|
|
LocalizationHelper.GetString("PointToLineProcessor_Thickness"),
|
|
typeof(int), 2, 1, 10,
|
|
LocalizationHelper.GetString("PointToLineProcessor_Thickness_Desc")));
|
|
}
|
|
|
|
public override Image<Gray, byte> Process(Image<Gray, byte> inputImage)
|
|
{
|
|
int l1x = GetParameter<int>("L1X"), l1y = GetParameter<int>("L1Y");
|
|
int l2x = GetParameter<int>("L2X"), l2y = GetParameter<int>("L2Y");
|
|
int px = GetParameter<int>("PX"), py = GetParameter<int>("PY");
|
|
double pixelSize = GetParameter<double>("PixelSize");
|
|
string unit = GetParameter<string>("Unit");
|
|
int thickness = GetParameter<int>("Thickness");
|
|
|
|
OutputData.Clear();
|
|
|
|
// 点到直线�离公�: |AB × AP| / |AB|
|
|
double abx = l2x - l1x, aby = l2y - l1y;
|
|
double abLen = Math.Sqrt(abx * abx + aby * aby);
|
|
|
|
double pixelDistance = 0;
|
|
int footX = px, footY = py;
|
|
|
|
if (abLen > 0.001)
|
|
{
|
|
// �积求��
|
|
double cross = Math.Abs(abx * (l1y - py) - aby * (l1x - px));
|
|
pixelDistance = cross / abLen;
|
|
|
|
// 垂足: 投影�数 t = AP·AB / |AB|²
|
|
double apx = px - l1x, apy = py - l1y;
|
|
double t = (apx * abx + apy * aby) / (abLen * abLen);
|
|
footX = (int)(l1x + t * abx);
|
|
footY = (int)(l1y + t * aby);
|
|
OutputData["ProjectionT"] = t;
|
|
}
|
|
|
|
double actualDistance = pixelDistance * pixelSize;
|
|
|
|
string distanceText = unit == "px"
|
|
? $"{pixelDistance:F2} px"
|
|
: $"{actualDistance:F4} {unit} ({pixelDistance:F2} px)";
|
|
|
|
OutputData["PointToLineResult"] = true;
|
|
OutputData["Line1"] = new Point(l1x, l1y);
|
|
OutputData["Line2"] = new Point(l2x, l2y);
|
|
OutputData["MeasurePoint"] = new Point(px, py);
|
|
OutputData["FootPoint"] = new Point(footX, footY);
|
|
OutputData["PixelDistance"] = pixelDistance;
|
|
OutputData["ActualDistance"] = actualDistance;
|
|
OutputData["Unit"] = unit;
|
|
OutputData["Thickness"] = thickness;
|
|
OutputData["DistanceText"] = distanceText;
|
|
|
|
_logger.Information("PointToLine: Distance={Dist}, Foot=({FX},{FY})", distanceText, footX, footY);
|
|
|
|
return inputImage.Clone();
|
|
}
|
|
} |