WPF中对Halcon的DrawingObject支持

我下载的是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")}";
    }
}

设置DrawingObject

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);
    }
}

ViewModel中

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;
        }
    }
}

你可能感兴趣的:(WPF,Halcon,wpf,Halcon)