我下载的是Halcon-18.11。首先这是可以参考例程的。
例程地址C:\Users\Public\Documents\MVTec\HALCON-18.11-Progress\examples\c#\DrawingObjectsWPF
首先定义一个HSmartWindowControlWPF
然后我把DrawingObject相关的形状属性都定义成一个ROI,我使用了三个DrawingObject:Circle、Ellipse2、Rectangle2
public abstract class ShapeROI
{
public abstract HRegion ToRegion();
public abstract void Display(HWindow window);
public ShapeROI() { }
public ShapeROI(ShapeROI shapeROI) { }
}
public class EllipseROI : ShapeROI
{
///
/// 椭圆圆心坐标X
///
public double Row { get; set; }
///
/// 椭圆圆心坐标Y
///
public double Column { get; set; }
///
/// 弧度 0-360度 就是0- 2*3.14159
/// 从小到大是逆时针的
///
public double Phi { get; set; }
public double Radius1 { get; set; }
public double Radius2 { get; set; }
public EllipseROI() : this(50, 50, 0, 100, 100)
{
}
public EllipseROI(EllipseROI roi) : this(roi.Row, roi.Column, roi.Phi, roi.Radius1, roi.Radius2)
{
}
///
///
///
/// 圆心横坐标
/// 圆心纵坐标
/// 弧度,倾斜度
/// 半径1(左右)
/// 半径2(上下)
public EllipseROI(double row, double column, double phi, double radiu1, double radiu2)
{
this.Row = row;
this.Column = column;
this.Phi = phi;
this.Radius1 = radiu1;
this.Radius2 = radiu2;
}
public override HRegion ToRegion()
{
HOperatorSet.GenEllipse(
out HObject ellipse,
this.Row,
this.Column,
this.Phi,
this.Radius1,
this.Radius2
);
return new HRegion(ellipse);
}
public override void Display(HWindow window)
{
window.DispRegion(ToRegion());
}
public override string ToString()
{
return $@"圆心坐标=({Row.ToString("f")},{Column.ToString("f")}),旋转弧度={Phi.ToString("f")},长轴半径={Radius1.ToString("f")},短轴半径={Radius2.ToString("f")}";
}
}
public class RectROI : ShapeROI
{
///
/// 矩形中心X坐标
///
public double Row { get; set; }
///
/// 矩形中心Y坐标
///
public double Column{ get; set; }
///
/// 弧度 0-360度 就是0- 2*3.14159
/// 从小到大是逆时针的
///
public double Phi{ get; set; }
///
/// 宽的一半
///
public double Length1{ get; set; }
///
/// 高的一半
///
public double Length2{ get; set; }
public RectROI() : this(50, 50, 0, 100, 100)
{
}
public RectROI(RectROI roi):this(roi.Row,roi.Column, roi.Phi, roi.Length1,roi.Length2)
{
}
public RectROI(double row, double column, double phi, double length1, double length2)
{
this.Row = row;
this.Column = column;
this.Phi = phi;
this.Length1 = length1;
this.Length2 = length2;
}
public override HRegion ToRegion()
{
HOperatorSet.GenRectangle2(
out HObject rectangle,
this.Row,
this.Column,
this.Phi,
this.Length1,
this.Length2
);
return new HRegion(rectangle);
}
public override void Display(HWindow window)
{
window.DispRegion(ToRegion());
}
public override string ToString()
{
return $@"矩形中心坐标=({Row.ToString("f")},{Column.ToString("f")}),旋转弧度={Phi.ToString("f")};长边长度的一半={Length1.ToString("f")},短边长度的一半={Length2.ToString("f")}";
}
}
public class CircleROI : ShapeROI
{
///
/// 圆心坐标X
///
public double CenterX { get; set; }
///
/// 圆心坐标Y
///
public double CenterY { get; set; }
///
/// 半径
///
public double Radius { get; set; }
public Circle(double centerX, double centerY, double radius)
{
CenterX = centerX;
CenterY = centerY;
Radius = radius;
}
public Circle() : this(50, 50, 100)
{
}
public Circle(Circle copy) : this(copy.CenterX, copy.CenterY, copy.Radius)
{
}
public override HRegion ToRegion()
{
HOperatorSet.GenCircle(
out HObject circle,
this.CenterX,
this.CenterY,
this.Radius
);
return new HRegion(circle);
}
public override void Display(HWindow window)
{
window.DispRegion(ToRegion());
}
public override string ToString()
{
return $@"圆心坐标=({CenterX.ToString("f")},{CenterY.ToString("f")}),半径={Radius.ToString("f")}";
}
}
public class MyDrawingObject
{
object image_lock = new object();
public HTuple CreateRectangle2(HTuple windowHandle,RectROI rectROI, HDrawingObject.HDrawingObjectCallback hDrawingObjectCallback)
{
HOperatorSet.CreateDrawingObjectRectangle2(rectROI.Row, rectROI.Column,
rectROI.Phi, rectROI.Length1, rectROI.Length2,
out HTuple draw_id);
if (hDrawingObjectCallback != null)
{
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(hDrawingObjectCallback);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_resize", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_drag", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_attach", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_select", ptr);
}
lock (image_lock)
{
HOperatorSet.AttachDrawingObjectToWindow(windowHandle, draw_id);
}
return draw_id;
}
public HTuple CreateEllipse(HTuple windowHandle, EllipseROI ellipseROI, HDrawingObject.HDrawingObjectCallback hDrawingObjectCallback)
{
HOperatorSet.CreateDrawingObjectEllipse(ellipseROI.Row, ellipseROI.Column,
ellipseROI.Phi, ellipseROI.Radius1, ellipseROI.Radius2,
out HTuple draw_id);
if (hDrawingObjectCallback != null)
{
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(hDrawingObjectCallback);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_resize", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_drag", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_attach", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_select", ptr);
}
lock (image_lock)
{
HOperatorSet.AttachDrawingObjectToWindow(windowHandle, draw_id);
}
return draw_id;
}
public HTuple CreateCircle(HTuple windowHandle, CircleROI circle, HDrawingObject.HDrawingObjectCallback hDrawingObjectCallback)
{
HOperatorSet.CreateDrawingObjectCircle(circle.CenterX, circle.CenterY,circle.Radius,
out HTuple draw_id);
if (hDrawingObjectCallback != null)
{
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(hDrawingObjectCallback);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_resize", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_drag", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_attach", ptr);
HOperatorSet.SetDrawingObjectCallback(draw_id, "on_select", ptr);
}
lock (image_lock)
{
HOperatorSet.AttachDrawingObjectToWindow(windowHandle, draw_id);
}
return draw_id;
}
public void UpdateRectangle2(HTuple drawingObject, RectROI rectROI)
{
if (rectROI.Length1 <= 0 || rectROI.Length2 <= 0)
return;
HOperatorSet.SetDrawingObjectParams(drawingObject, "row", rectROI.Row);
HOperatorSet.SetDrawingObjectParams(drawingObject, "column", rectROI.Column);
HOperatorSet.SetDrawingObjectParams(drawingObject, "phi", rectROI.Phi);
HOperatorSet.SetDrawingObjectParams(drawingObject, "length1", rectROI.Length1);
HOperatorSet.SetDrawingObjectParams(drawingObject, "length2", rectROI.Length2);
}
public void UpdateEllipse(HTuple drawingObject, EllipseROI ellipseROI)
{
if (ellipseROI.Radius1 <= 0 || ellipseROI.Radius2 <= 0)
return;
HOperatorSet.SetDrawingObjectParams(drawingObject, "row", ellipseROI.Row);
HOperatorSet.SetDrawingObjectParams(drawingObject, "column", ellipseROI.Column);
HOperatorSet.SetDrawingObjectParams(drawingObject, "phi", ellipseROI.Phi);
HOperatorSet.SetDrawingObjectParams(drawingObject, "radius1", ellipseROI.Radius1);
HOperatorSet.SetDrawingObjectParams(drawingObject, "radius2", ellipseROI.Radius2);
}
public void UpdateCircle(HTuple drawingObject, CircleROI circle)
{
if (circle.Radius <= 0)
return;
HOperatorSet.SetDrawingObjectParams(drawingObject, "row", circle.CenterX);
HOperatorSet.SetDrawingObjectParams(drawingObject, "column", circle.CenterY);
HOperatorSet.SetDrawingObjectParams(drawingObject, "radius", circle.Radius);
}
///
/// 删除
///
///
///
public void RemoveDrawingObject(HTuple windowHandle, HTuple drawingObject)
{
HOperatorSet.DetachDrawingObjectFromWindow(windowHandle, drawingObject);
HOperatorSet.ClearDrawingObject(drawingObject);
}
}
public class ImageViewMode : BaseViewModel
{
HImage img;
public HImage Image
{
get { return img; }
set
{
if (img != value)
{
img = value;
RaisePropertyChanged(nameof(Image));
}
}
}
HWindow _HalconWindow;
public HWindow HalconWindow
{
get { return _HalconWindow; }
set
{
if (_HalconWindow != value)
{
_HalconWindow = value;
RaisePropertyChanged(nameof(HalconWindow));
}
}
}
ShapeROI _ShapeROI;
public ShapeROI ShapeROI
{
get
{
return _ShapeROI;
}
set
{
if (_ShapeROI != value)
{
var temp = _ShapeROI;
_ShapeROI = value;
RaisePropertyChanged(nameof(ShapeROI));
if (temp == null && value != null)
{
CreateROI(value);
}
else if (temp != null && value != null && !Equals(temp, value))
{
UpdateROI(value);
}
else if (temp != null && value == null)
{
ClearROI(value);
}
}
}
}
HTuple _DrawingObject;
public HTuple DrawingObject
{
get
{
return _DrawingObject;
}
set
{
if (_DrawingObject != value)
{
_DrawingObject = value;
RaisePropertyChanged(nameof(DrawingObject));
}
}
}
private MyDrawingObject myDrawingObject = new MyDrawingObject();
private HDrawingObject.HDrawingObjectCallback cb;
public void CreateROI(ShapeROI shapeROI)
{
if (HalconWindow == null)
return;
if (shapeROI is RectROI)
{
cb = new HDrawingObject.HDrawingObjectCallback(DisplayCallback);
DrawingObject = myDrawingObject.CreateRectangle2(HalconWindow, shapeROI as RectROI, cb);
}
else if (shapeROI is EllipseROI)
{
cb = new HDrawingObject.HDrawingObjectCallback(DisplayCallback);
DrawingObject = myDrawingObject.CreateEllipse(HalconWindow, shapeROI as EllipseROI, cb);
}
else if (shapeROI is Circle)
{
cb = new HDrawingObject.HDrawingObjectCallback(DisplayCallback);
DrawingObject = myDrawingObject.CreateCircle(HalconWindow, shapeROI as Circle, cb);
}
}
public void UpdateROI(ShapeROI shapeROI)
{
if (shapeROI is RectROI)
{
if (DrawingObject == null)
CreateROI(shapeROI);
else
myDrawingObject.UpdateRectangle2(DrawingObject, shapeROI as RectROI);
}
else if (shapeROI is EllipseROI)
{
if (DrawingObject == null)
CreateROI(shapeROI);
else
myDrawingObject.UpdateEllipse(DrawingObject, shapeROI as EllipseROI);
}
else if (shapeROI is Circle)
{
if (DrawingObject == null)
CreateROI(shapeROI);
else
myDrawingObject.UpdateCircle(DrawingObject, shapeROI as Circle);
}
}
public void ClearROI(ShapeROI shapeROI)
{
myDrawingObject.RemoveDrawingObject(HalconWindow, DrawingObject);
}
protected void DisplayCallback(IntPtr draw_id, IntPtr window_handle, string type)
{
HOperatorSet.GetDrawingObjectParams(draw_id, "type", out HTuple genParamValue);
Debug.WriteLine($"genParamValue:{genParamValue.ToString()}");
if (genParamValue.TupleEqual("ellipse"))
{
HOperatorSet.GetDrawingObjectParams(draw_id, "row", out HTuple row);
HOperatorSet.GetDrawingObjectParams(draw_id, "column", out HTuple column);
HOperatorSet.GetDrawingObjectParams(draw_id, "phi", out HTuple phi);
HOperatorSet.GetDrawingObjectParams(draw_id, "radius1", out HTuple radius1);
HOperatorSet.GetDrawingObjectParams(draw_id, "radius2", out HTuple radius2);
Debug.WriteLine($"row:{row},column:{column},phi:{phi},radius1:{radius1},radius2:{radius2}");
var ellipse = ShapeROI as EllipseROI;
ellipse.Row = row.D;
ellipse.Column = column.D;
ellipse.Phi = phi.D;
ellipse.Radius1 = radius1.D;
ellipse.Radius2 = radius2.D;
}
else if (genParamValue.TupleEqual("rectangle2"))
{
HOperatorSet.GetDrawingObjectParams(draw_id, "row", out HTuple row);
HOperatorSet.GetDrawingObjectParams(draw_id, "column", out HTuple column);
HOperatorSet.GetDrawingObjectParams(draw_id, "phi", out HTuple phi);
HOperatorSet.GetDrawingObjectParams(draw_id, "length1", out HTuple length1);
HOperatorSet.GetDrawingObjectParams(draw_id, "length2", out HTuple length2);
Debug.WriteLine($"row:{row},column:{column},phi:{phi},length1:{length1},length2:{length2}");
var rect = ShapeROI as RectROI;
rect.Row = row.D;
rect.Column = column.D;
rect.Phi = phi.D;
rect.Length1 = length1.D;
rect.Length2 = length2.D;
}
else if (genParamValue.TupleEqual("circle"))
{
HOperatorSet.GetDrawingObjectParams(draw_id, "row", out HTuple row);
HOperatorSet.GetDrawingObjectParams(draw_id, "column", out HTuple column);
HOperatorSet.GetDrawingObjectParams(draw_id, "radius", out HTuple radius);
Debug.WriteLine($"row:{row},column:{column},radius:{radius}");
var circle = ShapeROI as Circle;
circle.CenterX = row.D;
circle.CenterY = column.D;
circle.Radius = radius.D;
}
}
}