87 lines
3.8 KiB
C#
87 lines
3.8 KiB
C#
// ============================================================================
|
|
// 文件� AngleMeasurementProcessor.cs
|
|
// æ��è¿°: 角度测é‡�ç®—å� â€?共端点的两æ�¡ç›´çº¿å¤¹è§’
|
|
// 功能:
|
|
// - 用户定义三个点:端点(顶点)�射�终点�射�终点
|
|
// - 计算两�射线之间的夹角(0°~180°�
|
|
// - 在图åƒ�上绘制两æ�¡å°„线ã€�è§’åº¦å¼§çº¿å’Œæ ‡æ³¨
|
|
// ============================================================================
|
|
|
|
using Emgu.CV;
|
|
using Emgu.CV.Structure;
|
|
using Serilog;
|
|
using System.Drawing;
|
|
using XP.ImageProcessing.Core;
|
|
|
|
namespace XP.ImageProcessing.Processors;
|
|
|
|
public class AngleMeasurementProcessor : ImageProcessorBase
|
|
{
|
|
private static readonly ILogger _logger = Log.ForContext<AngleMeasurementProcessor>();
|
|
|
|
public AngleMeasurementProcessor()
|
|
{
|
|
Name = LocalizationHelper.GetString("AngleMeasurementProcessor_Name");
|
|
Description = LocalizationHelper.GetString("AngleMeasurementProcessor_Description");
|
|
}
|
|
|
|
protected override void InitializeParameters()
|
|
{
|
|
// 三个点å��æ ‡ï¼ˆç”±äº¤äº’æŽ§ä»¶æ³¨å…¥ï¼Œä½¿ç”¨ double é�¿å…�å�–整误差ï¼?
|
|
Parameters.Add("VX", new ProcessorParameter("VX", "VX", typeof(double), 250.0, null, null, "") { IsVisible = false });
|
|
Parameters.Add("VY", new ProcessorParameter("VY", "VY", typeof(double), 250.0, null, null, "") { IsVisible = false });
|
|
Parameters.Add("AX", new ProcessorParameter("AX", "AX", typeof(double), 100.0, null, null, "") { IsVisible = false });
|
|
Parameters.Add("AY", new ProcessorParameter("AY", "AY", typeof(double), 250.0, null, null, "") { IsVisible = false });
|
|
Parameters.Add("BX", new ProcessorParameter("BX", "BX", typeof(double), 250.0, null, null, "") { IsVisible = false });
|
|
Parameters.Add("BY", new ProcessorParameter("BY", "BY", typeof(double), 100.0, null, null, "") { IsVisible = false });
|
|
}
|
|
|
|
public override Image<Gray, byte> Process(Image<Gray, byte> inputImage)
|
|
{
|
|
double vx = GetParameter<double>("VX"), vy = GetParameter<double>("VY");
|
|
double ax = GetParameter<double>("AX"), ay = GetParameter<double>("AY");
|
|
double bx = GetParameter<double>("BX"), by = GetParameter<double>("BY");
|
|
|
|
OutputData.Clear();
|
|
|
|
// �� VA �VB
|
|
double vax = ax - vx, vay = ay - vy;
|
|
double vbx = bx - vx, vby = by - vy;
|
|
|
|
double lenA = Math.Sqrt(vax * vax + vay * vay);
|
|
double lenB = Math.Sqrt(vbx * vbx + vby * vby);
|
|
|
|
double angleDeg = 0;
|
|
if (lenA > 0.001 && lenB > 0.001)
|
|
{
|
|
double dot = vax * vbx + vay * vby;
|
|
double cosAngle = Math.Clamp(dot / (lenA * lenB), -1.0, 1.0);
|
|
angleDeg = Math.Acos(cosAngle) * 180.0 / Math.PI;
|
|
}
|
|
|
|
// 计算角度弧的起始角和扫过角(用于绘制弧线�
|
|
double angleA = Math.Atan2(vay, vax) * 180.0 / Math.PI;
|
|
double angleB = Math.Atan2(vby, vbx) * 180.0 / Math.PI;
|
|
|
|
// 确��angleA �angleB 的扫过方�是较�的夹�
|
|
double sweep = angleB - angleA;
|
|
if (sweep > 180) sweep -= 360;
|
|
if (sweep < -180) sweep += 360;
|
|
|
|
string angleText = $"{angleDeg:F2} deg";
|
|
|
|
OutputData["AngleMeasurementResult"] = true;
|
|
OutputData["Vertex"] = new Point((int)Math.Round(vx), (int)Math.Round(vy));
|
|
OutputData["PointA"] = new Point((int)Math.Round(ax), (int)Math.Round(ay));
|
|
OutputData["PointB"] = new Point((int)Math.Round(bx), (int)Math.Round(by));
|
|
OutputData["AngleDeg"] = angleDeg;
|
|
OutputData["ArcStartAngle"] = angleA;
|
|
OutputData["ArcSweepAngle"] = sweep;
|
|
OutputData["AngleText"] = angleText;
|
|
|
|
_logger.Information("AngleMeasurement: Angle={Angle}, V=({VX},{VY}), A=({AX},{AY}), B=({BX},{BY})",
|
|
angleText, vx, vy, ax, ay, bx, by);
|
|
|
|
return inputImage.Clone();
|
|
}
|
|
} |