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;
|
}
|
|
/// <summary>
|
/// 矩形宽度的一半
|
/// </summary>
|
public double SemiLength1 = 200;
|
/// <summary>
|
/// 矩形宽度
|
/// </summary>
|
public double Width
|
{
|
get { return SemiLength1 * 2; }
|
set
|
{
|
double result = 0;
|
value = double.TryParse(value.ToString(), out result) ? result : 0;
|
SemiLength1 = (value / 2.0);
|
}
|
}
|
|
/// <summary>
|
/// 矩形高度的一半
|
/// </summary>
|
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<ROI>();
|
case "HRectangle2":
|
return jo.ToObject<HRectangle2>();
|
case "HCircle":
|
return jo.ToObject<HCircle>();
|
case "HSegment":
|
return jo.ToObject<HSegment>();
|
case "HLine":
|
return jo.ToObject<HLine>();
|
case "HPoint":
|
return jo.ToObject<HPoint>();
|
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}");
|
}
|
}
|
}
|
}
|