using HalconDotNet; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenCvSharp; using System; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; using System.Formats.Asn1; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Windows.Forms.AxHost; namespace LB_VisionControl { public enum RoiType { None, Rectangle2, Circle, Ellipse, Segment }; public class ROI { // 你可以在父类中定义一些公共属性或方法 public string Type = "ROI"; // 类型标识符 public double Z = 0; public double Column = 0; public double X { get { return Column; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; Column = value; } } public double Row = 0; public double Y { get { return Row; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; Row = value; } } public double Phi = 0; public double Angle { get { return Phi * 180 / Math.PI; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; Phi = (value / 180 * Math.PI); } } public double Rotation { get { return Phi; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; Phi = value; } } public object Clone() { return MemberwiseClone(); } } [Serializable] public class HRectangle2 : ROI { public HRectangle2() { Type = "HRectangle2"; } //public HRectangle2(HTuple row, HTuple column, HTuple phi, HTuple length1, HTuple length2) //{ // Type = "HRectangle2"; // this.Row = row.TupleReal(); // this.Column = column.TupleReal(); // this.Phi = phi.TupleReal(); // this.SemiLength1 = length1.TupleReal(); // this.SemiLength2 = length2.TupleReal(); //} // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HRectangle2(double X = 0, double Y = 0, double rotation = 0, double width = 800, double height = 800) { Type = "HRectangle2"; this.X = X; this.Y = Y; Rotation = rotation; Width = width; Height = height; } public HObject GetHObject() { HOperatorSet.GenRectangle2(out HObject hObject, (HTuple)Row, (HTuple)Column, (HTuple)Phi, (HTuple)SemiLength1, (HTuple)SemiLength2); return hObject; } /// /// 矩形宽度的一半 /// public double SemiLength1 = 200; /// /// 矩形宽度 /// public double Width { get { return SemiLength1 * 2; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; SemiLength1 = (value / 2.0); } } /// /// 矩形高度的一半 /// public double SemiLength2 = 200; public double Height { get { return SemiLength2 * 2; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; SemiLength2 = (value / 2.0); } } public HPoint[] Corners { get { // 计算未旋转矩形的角点相对于中心的坐标 var corners = new HPoint[] { new HPoint(-Width / 2, -Height / 2), // 左上角 new HPoint(Width / 2, -Height / 2), // 右上角 new HPoint(Width / 2, Height / 2), // 右下角 new HPoint(-Width / 2, Height / 2) // 左下角 }; // 旋转矩形的角点 for (int i = 0; i < corners.Length; i++) { double x = corners[i].X; double y = corners[i].Y; // 旋转矩阵应用 double rotatedX = x * Math.Cos(Rotation) - y * Math.Sin(Rotation); double rotatedY = x * Math.Sin(Rotation) + y * Math.Cos(Rotation); // 移动到实际位置 corners[i] = new HPoint(rotatedX + X, rotatedY + Y); } return corners; } } } [Serializable] public class HCircle : ROI { public HCircle() { Type = "HCircle"; } //public HCircle(HTuple row, HTuple column, HTuple radius) //{ // Type = "HCircle"; // this.Row = row.TupleReal(); // this.Column = column.TupleReal(); // this.Radius = radius.TupleReal(); //} // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HCircle(double X = 0, double Y = 0, double radius = 100) { Type = "HCircle"; this.X = X; this.Y = Y; Radius = radius; } public double Radius = 100; public double Diameter { get { return Radius * 2; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; Radius = value / 2.0; } } } public class HEllipse : ROI { public HEllipse() { Type = "HEllipse"; } // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HEllipse(double x, double y, double phi, double radius1, double radius2, double start_angle = 0, double end_angle = Math.PI) { Type = "HEllipse"; this.X = x; this.Y = y; this.Phi = phi; Radius1 = radius1; Radius2 = radius2; StartAngle = start_angle; EndAngle = end_angle; } public double Radius1 = 100; public double Radius2 = 100; public double StartAngle = 0; public double EndAngle = Math.PI; } [Serializable] public class HSegment : ROI { public HSegment() { Type = "HSegment"; } // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HSegment(double startX = 0, double startY = 0, double endX = 0, double endY = 0) { Type = "HSegment"; StartX = startX; StartY = startY; EndX = endX; EndY = endY; } public HSegment(HPoint startPoint, HPoint endPoint) { Type = "HSegment"; BeginRow = startPoint.Row; BeginColumn = startPoint.Column; EndRow = endPoint.Row; EndColumn = endPoint.Column; } public HObject GetHObject() { HOperatorSet.GenRegionLine(out HObject hObject, (HTuple)BeginRow, (HTuple)BeginColumn, (HTuple)EndRow, (HTuple)EndColumn); return hObject; } public HPoint StartPoint { get { return new HPoint(BeginColumn, BeginRow); } set { BeginRow = value.Row; BeginColumn = value.Column; } } public HPoint EndPoint { get { return new HPoint(EndColumn, EndRow); } set { EndRow = value.Row; EndColumn = value.Column; } } public double BeginColumn = 0; public double StartX { get { return BeginColumn; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; BeginColumn = value; } } public double BeginRow = 0; public double StartY { get { return BeginRow; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; BeginRow = value; } } public double EndColumn = 100; public double EndX { get { return EndColumn; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; EndColumn = value; } } public double EndRow = 100; public double EndY { get { return EndRow; } set { double result = 0; value = double.TryParse(value.ToString(), out result) ? result : 0; EndRow = value; } } public double MidX { get { return (StartX + EndX) / 2; } } public double MidY { get { return (StartY + EndY) / 2; } } public double Length { get { return Math.Sqrt(Math.Pow(StartX - EndX, 2) + Math.Pow(StartX - EndY, 2)); } } } [Serializable] public class HLine : ROI { public HLine() { Type = "HLine"; } // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HLine(double x = 0, double y = 0, double phi = 0) { Type = "HLine"; X = x; Y = y; Phi = phi; } public HLine(HPoint point, double phi = 0) { Type = "HLine"; X = point.Row; Y = point.Column; Phi = phi; } } [Serializable] public class HPoint : ROI { public HPoint() { Type = "HPoint"; } // 带私有参数的构造函数 [JsonConstructor] // 标记为用于反序列化 public HPoint(double x, double y, double z = 0) { Type = "HPoint"; X = x; Y = y; Z = z; } public HPoint(OpenCvSharp.Point point) { Type = "HPoint"; X = point.X; Y = point.Y; } public HPoint(HPoint point) { Type = "HPoint"; X = point.X; Y = point.Y; } public HObject GetHObject() { HOperatorSet.GenRegionPoints(out HObject hObject, (HTuple)Row, (HTuple)Column); return hObject; } public Point2d ToPoint2d() { return new Point2d(X, Y); } } public class ROIConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(ROI); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jo = JObject.Load(reader); // 只调用一次 Load(reader) if (jo != null) { var type = jo["Type"]?.ToString(); // 获取类型标识符 // 根据类型标识符反序列化为具体类型 switch (type) { case "ROI": return jo.ToObject(); case "HRectangle2": return jo.ToObject(); case "HCircle": return jo.ToObject(); case "HSegment": return jo.ToObject(); case "HLine": return jo.ToObject(); case "HPoint": return jo.ToObject(); default: // 其他类型的处理方式 throw new JsonSerializationException($"Unknown type: {type}"); } } return null; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { try { if (value != null) { // 创建一个 JObject 来序列化 ROI 对象 JObject jo = JObject.FromObject(value, serializer); var type = value.GetType().Name; // 根据类型标识符反序列化为具体类型 switch (type) { case "ROI": ROI roi = value as ROI; if (roi == null) throw new JsonSerializationException($"Convert {type} to null"); // 开始写入 JSON 对象 writer.WriteStartObject(); writer.WritePropertyName("Type"); writer.WriteValue(roi.Type); // 结束对象 writer.WriteEndObject(); break; case "HRectangle2": HRectangle2 hRectangle2 = value as HRectangle2; if (hRectangle2 == null) throw new JsonSerializationException($"Convert {type} to null"); // 开始写入 JSON 对象 writer.WriteStartObject(); writer.WritePropertyName("Type"); writer.WriteValue(hRectangle2.Type); writer.WritePropertyName("X"); writer.WriteValue(hRectangle2.X); writer.WritePropertyName("Y"); writer.WriteValue(hRectangle2.Y); writer.WritePropertyName("Rotation"); writer.WriteValue(hRectangle2.Rotation); writer.WritePropertyName("Width"); writer.WriteValue(hRectangle2.Width); writer.WritePropertyName("Height"); writer.WriteValue(hRectangle2.Height); // 结束对象 writer.WriteEndObject(); break; case "HCircle": HCircle hCircle = value as HCircle; if (hCircle == null) throw new JsonSerializationException($"Convert {type} to null"); // 开始写入 JSON 对象 writer.WriteStartObject(); writer.WritePropertyName("Type"); writer.WriteValue(hCircle.Type); writer.WritePropertyName("X"); writer.WriteValue(hCircle.X); writer.WritePropertyName("Y"); writer.WriteValue(hCircle.Y); writer.WritePropertyName("Radius"); writer.WriteValue(hCircle.Radius); // 结束对象 writer.WriteEndObject(); break; case "HPoint": HPoint hPoint = value as HPoint; if (hPoint == null) throw new JsonSerializationException($"Convert {type} to null"); // 开始写入 JSON 对象 writer.WriteStartObject(); writer.WritePropertyName("Type"); writer.WriteValue(hPoint.Type); writer.WritePropertyName("X"); writer.WriteValue(hPoint.X); writer.WritePropertyName("Y"); writer.WriteValue(hPoint.Y); // 结束对象 writer.WriteEndObject(); break; case "HSegment": HSegment hSegment = value as HSegment; if (hSegment == null) throw new JsonSerializationException($"Convert {type} to null"); // 开始写入 JSON 对象 writer.WriteStartObject(); writer.WritePropertyName("Type"); writer.WriteValue(hSegment.Type); writer.WritePropertyName("StartX"); writer.WriteValue(hSegment.StartX); writer.WritePropertyName("StartY"); writer.WriteValue(hSegment.StartY); writer.WritePropertyName("EndX"); writer.WriteValue(hSegment.EndX); writer.WritePropertyName("EndY"); writer.WriteValue(hSegment.EndY); // 结束对象 writer.WriteEndObject(); break; case "HLine": default: // 其他类型的处理方式 throw new JsonSerializationException($"Unsupport convert {type}"); } } } catch (Exception ex) { // 输出异常信息进行调试 Debug.WriteLine($"Error: {ex.Message}"); } } } }