mirror of
https://github.com/eggplantlwj/VisionEdit.git
synced 2026-03-25 17:26:35 +08:00
版本初始化,建立主窗体页面
This commit is contained in:
415
ImageWindow/Model/GraphicsContext.cs
Normal file
415
ImageWindow/Model/GraphicsContext.cs
Normal file
@@ -0,0 +1,415 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using HalconDotNet;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
public delegate void GCDelegate(string val);
|
||||
|
||||
/// <summary>
|
||||
/// This class contains the graphical context of an HALCON object. The
|
||||
/// set of graphical modes is defined by the hashlist 'graphicalSettings'.
|
||||
/// If the list is empty, then there is no difference to the graphical
|
||||
/// setting defined by the system by default. Otherwise, the provided
|
||||
/// HALCON window is adjusted according to the entries of the supplied
|
||||
/// graphical context (when calling applyContext())
|
||||
/// </summary>
|
||||
public class GraphicsContext
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the output color (see dev_set_color)
|
||||
/// </summary>
|
||||
public const string GC_COLOR = "Color";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the multi-color output (see dev_set_colored)
|
||||
/// </summary>
|
||||
public const string GC_COLORED = "Colored";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the line width (see set_line_width)
|
||||
/// </summary>
|
||||
public const string GC_LINEWIDTH = "LineWidth";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the drawing (see set_draw)
|
||||
/// </summary>
|
||||
public const string GC_DRAWMODE = "DrawMode";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the drawing shape (see set_shape)
|
||||
/// </summary>
|
||||
public const string GC_SHAPE = "Shape";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the LUT (lookup table) (see set_lut)
|
||||
/// </summary>
|
||||
public const string GC_LUT = "Lut";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the painting (see set_paint)
|
||||
/// </summary>
|
||||
public const string GC_PAINT = "Paint";
|
||||
|
||||
/// <summary>
|
||||
/// Graphical mode for the line style (see set_line_style)
|
||||
/// </summary>
|
||||
public const string GC_LINESTYLE = "LineStyle";
|
||||
|
||||
/// <summary>
|
||||
/// Hashlist containing entries for graphical modes (defined by GC_*),
|
||||
/// which is then linked to some HALCON object to describe its
|
||||
/// graphical context.
|
||||
/// </summary>
|
||||
private Hashtable graphicalSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Backup of the last graphical context applied to the window.
|
||||
/// </summary>
|
||||
public Hashtable stateOfSettings;
|
||||
|
||||
private IEnumerator iterator;
|
||||
|
||||
/// <summary>
|
||||
/// Option to delegate messages from the graphical context
|
||||
/// to some observer class
|
||||
/// </summary>
|
||||
public GCDelegate gcNotification;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a graphical context with no initial
|
||||
/// graphical modes
|
||||
/// </summary>
|
||||
public GraphicsContext()
|
||||
{
|
||||
graphicalSettings = new Hashtable(10, 0.2f);
|
||||
gcNotification = new GCDelegate(dummy);
|
||||
stateOfSettings = new Hashtable(10, 0.2f);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the graphical context with
|
||||
/// the modes defined in the hashtable 'settings'
|
||||
/// </summary>
|
||||
/// <param name="settings">
|
||||
/// List of modes, which describes the graphical context
|
||||
/// </param>
|
||||
public GraphicsContext(Hashtable settings)
|
||||
{
|
||||
graphicalSettings = settings;
|
||||
gcNotification = new GCDelegate(dummy);
|
||||
stateOfSettings = new Hashtable(10, 0.2f);
|
||||
}
|
||||
|
||||
/// <summary>Applies graphical context to the HALCON window</summary>
|
||||
/// <param name="window">Active HALCON window</param>
|
||||
/// <param name="cContext">
|
||||
/// List that contains graphical modes for window
|
||||
/// </param>
|
||||
public void applyContext(HWindow window, Hashtable cContext)
|
||||
{
|
||||
string key = "";
|
||||
string valS = "";
|
||||
int valI = -1;
|
||||
HTuple valH = null;
|
||||
|
||||
iterator = cContext.Keys.GetEnumerator();
|
||||
|
||||
try
|
||||
{
|
||||
while (iterator.MoveNext())
|
||||
{
|
||||
|
||||
key = (string)iterator.Current;
|
||||
|
||||
if (stateOfSettings.Contains(key) &&
|
||||
stateOfSettings[key] == cContext[key])
|
||||
continue;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GC_COLOR:
|
||||
valS = (string)cContext[key];
|
||||
window.SetColor(valS);
|
||||
if (stateOfSettings.Contains(GC_COLORED))
|
||||
stateOfSettings.Remove(GC_COLORED);
|
||||
|
||||
break;
|
||||
case GC_COLORED:
|
||||
valI = (int)cContext[key];
|
||||
window.SetColored(valI);
|
||||
|
||||
if (stateOfSettings.Contains(GC_COLOR))
|
||||
stateOfSettings.Remove(GC_COLOR);
|
||||
|
||||
break;
|
||||
case GC_DRAWMODE:
|
||||
valS = (string)cContext[key];
|
||||
window.SetDraw(valS);
|
||||
break;
|
||||
case GC_LINEWIDTH:
|
||||
valI = (int)cContext[key];
|
||||
window.SetLineWidth(valI);
|
||||
break;
|
||||
case GC_LUT:
|
||||
valS = (string)cContext[key];
|
||||
window.SetLut(valS);
|
||||
break;
|
||||
case GC_PAINT:
|
||||
valS = (string)cContext[key];
|
||||
window.SetPaint(valS);
|
||||
break;
|
||||
case GC_SHAPE:
|
||||
valS = (string)cContext[key];
|
||||
window.SetShape(valS);
|
||||
break;
|
||||
case GC_LINESTYLE:
|
||||
valH = (HTuple)cContext[key];
|
||||
window.SetLineStyle(valH);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (valI != -1)
|
||||
{
|
||||
if (stateOfSettings.Contains(key))
|
||||
stateOfSettings[key] = valI;
|
||||
else
|
||||
stateOfSettings.Add(key, valI);
|
||||
|
||||
valI = -1;
|
||||
}
|
||||
else if (valS != "")
|
||||
{
|
||||
if (stateOfSettings.Contains(key))
|
||||
stateOfSettings[key] = valI;
|
||||
else
|
||||
stateOfSettings.Add(key, valI);
|
||||
|
||||
valS = "";
|
||||
}
|
||||
else if (valH != null)
|
||||
{
|
||||
if (stateOfSettings.Contains(key))
|
||||
stateOfSettings[key] = valI;
|
||||
else
|
||||
stateOfSettings.Add(key, valI);
|
||||
|
||||
valH = null;
|
||||
}
|
||||
}//while
|
||||
}
|
||||
catch (HOperatorException e)
|
||||
{
|
||||
gcNotification(e.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_COLOR</summary>
|
||||
/// <param name="val">
|
||||
/// A single color, e.g. "blue", "green" ...etc.
|
||||
/// </param>
|
||||
public void setColorAttribute(string val)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(GC_COLORED))
|
||||
graphicalSettings.Remove(GC_COLORED);
|
||||
|
||||
addValue(GC_COLOR, val);
|
||||
}
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_COLORED</summary>
|
||||
/// <param name="val">
|
||||
/// The colored mode, which can be either "colored3" or "colored6"
|
||||
/// or "colored12"
|
||||
/// </param>
|
||||
public void setColoredAttribute(int val)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(GC_COLOR))
|
||||
graphicalSettings.Remove(GC_COLOR);
|
||||
|
||||
addValue(GC_COLORED, val);
|
||||
}
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_DRAWMODE</summary>
|
||||
/// <param name="val">
|
||||
/// One of the possible draw modes: "margin" or "fill"
|
||||
/// </param>
|
||||
public void setDrawModeAttribute(string val)
|
||||
{
|
||||
addValue(GC_DRAWMODE, val);
|
||||
}
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_LINEWIDTH</summary>
|
||||
/// <param name="val">
|
||||
/// The line width, which can range from 1 to 50
|
||||
/// </param>
|
||||
public void setLineWidthAttribute(int val)
|
||||
{
|
||||
addValue(GC_LINEWIDTH, val);
|
||||
}
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_LUT</summary>
|
||||
/// <param name="val">
|
||||
/// One of the possible modes of look up tables. For
|
||||
/// further information on particular setups, please refer to the
|
||||
/// Reference Manual entry of the operator set_lut.
|
||||
/// </param>
|
||||
public void setLutAttribute(string val)
|
||||
{
|
||||
addValue(GC_LUT, val);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_PAINT</summary>
|
||||
/// <param name="val">
|
||||
/// One of the possible paint modes. For further
|
||||
/// information on particular setups, please refer refer to the
|
||||
/// Reference Manual entry of the operator set_paint.
|
||||
/// </param>
|
||||
public void setPaintAttribute(string val)
|
||||
{
|
||||
addValue(GC_PAINT, val);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_SHAPE</summary>
|
||||
/// <param name="val">
|
||||
/// One of the possible shape modes. For further
|
||||
/// information on particular setups, please refer refer to the
|
||||
/// Reference Manual entry of the operator set_shape.
|
||||
/// </param>
|
||||
public void setShapeAttribute(string val)
|
||||
{
|
||||
addValue(GC_SHAPE, val);
|
||||
}
|
||||
|
||||
/// <summary>Sets a value for the graphical mode GC_LINESTYLE</summary>
|
||||
/// <param name="val">
|
||||
/// A line style mode, which works
|
||||
/// identical to the input for the HDevelop operator
|
||||
/// 'set_line_style'. For particular information on this
|
||||
/// topic, please refer to the Reference Manual entry of the operator
|
||||
/// set_line_style.
|
||||
/// </param>
|
||||
public void setLineStyleAttribute(HTuple val)
|
||||
{
|
||||
addValue(GC_LINESTYLE, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a value to the hashlist 'graphicalSettings' for the
|
||||
/// graphical mode described by the parameter 'key'
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// A graphical mode defined by the constant GC_*
|
||||
/// </param>
|
||||
/// <param name="val">
|
||||
/// Defines the value as an int for this graphical
|
||||
/// mode 'key'
|
||||
/// </param>
|
||||
private void addValue(string key, int val)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(key))
|
||||
graphicalSettings[key] = val;
|
||||
else
|
||||
graphicalSettings.Add(key, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a value to the hashlist 'graphicalSettings' for the
|
||||
/// graphical mode, described by the parameter 'key'
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// A graphical mode defined by the constant GC_*
|
||||
/// </param>
|
||||
/// <param name="val">
|
||||
/// Defines the value as a string for this
|
||||
/// graphical mode 'key'
|
||||
/// </param>
|
||||
private void addValue(string key, string val)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(key))
|
||||
graphicalSettings[key] = val;
|
||||
else
|
||||
graphicalSettings.Add(key, val);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a value to the hashlist 'graphicalSettings' for the
|
||||
/// graphical mode, described by the parameter 'key'
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// A graphical mode defined by the constant GC_*
|
||||
/// </param>
|
||||
/// <param name="val">
|
||||
/// Defines the value as a HTuple for this
|
||||
/// graphical mode 'key'
|
||||
/// </param>
|
||||
private void addValue(string key, HTuple val)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(key))
|
||||
graphicalSettings[key] = val;
|
||||
else
|
||||
graphicalSettings.Add(key, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the list of graphical settings.
|
||||
/// There will be no graphical changes made prior
|
||||
/// before drawing objects, since there are no
|
||||
/// graphical entries to be applied to the window.
|
||||
/// </summary>
|
||||
public void clear()
|
||||
{
|
||||
graphicalSettings.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an exact clone of this graphicsContext instance
|
||||
/// </summary>
|
||||
public GraphicsContext copy()
|
||||
{
|
||||
return new GraphicsContext((Hashtable)this.graphicalSettings.Clone());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If the hashtable contains the key, the corresponding
|
||||
/// hashtable value is returned
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// One of the graphical keys starting with GC_*
|
||||
/// </param>
|
||||
public object getGraphicsAttribute(string key)
|
||||
{
|
||||
if (graphicalSettings.ContainsKey(key))
|
||||
return graphicalSettings[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of the hashtable that carries the
|
||||
/// entries for the current graphical context
|
||||
/// </summary>
|
||||
/// <returns> current graphical context </returns>
|
||||
public Hashtable copyContextList()
|
||||
{
|
||||
return (Hashtable)graphicalSettings.Clone();
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
public void dummy(string val) { }
|
||||
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
51
ImageWindow/Model/HObjectEntry.cs
Normal file
51
ImageWindow/Model/HObjectEntry.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Collections;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class is an auxiliary class, which is used to
|
||||
/// link a graphical context to an HALCON object. The graphical
|
||||
/// context is described by a hashtable, which contains a list of
|
||||
/// graphical modes (e.g GC_COLOR, GC_LINEWIDTH and GC_PAINT)
|
||||
/// and their corresponding values (e.g "blue", "4", "3D-plot"). These
|
||||
/// graphical states are applied to the window before displaying the
|
||||
/// object.
|
||||
/// </summary>
|
||||
public class HObjectEntry
|
||||
{
|
||||
/// <summary>Hashlist defining the graphical context for HObj</summary>
|
||||
public Hashtable gContext;
|
||||
|
||||
/// <summary>HALCON object</summary>
|
||||
public HObject HObj;
|
||||
|
||||
|
||||
|
||||
/// <summary>Constructor</summary>
|
||||
/// <param name="obj">
|
||||
/// HALCON object that is linked to the graphical context gc.
|
||||
/// </param>
|
||||
/// <param name="gc">
|
||||
/// Hashlist of graphical states that are applied before the object
|
||||
/// is displayed.
|
||||
/// </param>
|
||||
public HObjectEntry(HObject obj, Hashtable gc)
|
||||
{
|
||||
gContext = gc;
|
||||
HObj = obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the entries of the class members Hobj and gContext
|
||||
/// </summary>
|
||||
public void clear()
|
||||
{
|
||||
gContext.Clear();
|
||||
HObj.Dispose();
|
||||
}
|
||||
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
1147
ImageWindow/Model/HWndCtrl.cs
Normal file
1147
ImageWindow/Model/HWndCtrl.cs
Normal file
File diff suppressed because it is too large
Load Diff
30
ImageWindow/Model/IViewWindow.cs
Normal file
30
ImageWindow/Model/IViewWindow.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using HalconDotNet;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
interface IViewWindow
|
||||
{
|
||||
void displayImage(HObject img);
|
||||
void resetWindowImage();
|
||||
void zoomWindowImage();
|
||||
void moveWindowImage();
|
||||
void noneWindowImage();
|
||||
void genRect1(double row1, double col1, double row2, double col2, ref List<ROI> rois);
|
||||
void genRect2(double row, double col, double phi, double length1, double length2, ref List<ROI> rois);
|
||||
void genCircle(double row, double col, double radius, ref List<ROI> rois);
|
||||
void genCircularArc(double row, double col, double radius,double startPhi, double extentPhi,string direct, ref List<ROI> rois);
|
||||
void genLine(double beginRow, double beginCol, double endRow, double endCol, ref List<ROI> rois);
|
||||
List<double> smallestActiveROI(out string name,out int index);
|
||||
ROI smallestActiveROI(out List<double> data, out int index);
|
||||
void selectROI(int index);
|
||||
void selectROI(List<ROI> rois, int index);
|
||||
void displayROI(List<ROI> rois);
|
||||
void removeActiveROI(ref List<ROI> rois);
|
||||
void saveROI(List<ROI> rois, string fileNmae);
|
||||
void loadROI(string fileName, out List<ROI> rois);
|
||||
}
|
||||
}
|
||||
187
ImageWindow/Model/ROI.cs
Normal file
187
ImageWindow/Model/ROI.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class is a base class containing virtual methods for handling
|
||||
/// ROIs. Therefore, an inheriting class needs to define/override these
|
||||
/// methods to provide the ROIController with the necessary information on
|
||||
/// its (= the ROIs) shape and position. The example project provides
|
||||
/// derived ROI shapes for rectangles, lines, circles, and circular arcs.
|
||||
/// To use other shapes you must derive a new class from the base class
|
||||
/// ROI and implement its methods.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ROI
|
||||
{
|
||||
private string color = "blue";
|
||||
|
||||
public string Color
|
||||
{
|
||||
get { return this.color; }
|
||||
set { this.color = value; }
|
||||
}
|
||||
|
||||
private string _type;
|
||||
public string Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._type ;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._type = value;
|
||||
}
|
||||
}
|
||||
|
||||
// class members of inheriting ROI classes
|
||||
protected int NumHandles;
|
||||
protected int activeHandleIdx;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to define the ROI to be 'positive' or 'negative'.
|
||||
/// </summary>
|
||||
protected int OperatorFlag;
|
||||
|
||||
/// <summary>Parameter to define the line style of the ROI.</summary>
|
||||
public HTuple flagLineStyle;
|
||||
|
||||
/// <summary>Constant for a positive ROI flag.</summary>
|
||||
public const int POSITIVE_FLAG = ROIController.MODE_ROI_POS;
|
||||
|
||||
/// <summary>Constant for a negative ROI flag.</summary>
|
||||
public const int NEGATIVE_FLAG = ROIController.MODE_ROI_NEG;
|
||||
|
||||
public const int ROI_TYPE_LINE = 10;
|
||||
public const int ROI_TYPE_CIRCLE = 11;
|
||||
public const int ROI_TYPE_CIRCLEARC = 12;
|
||||
public const int ROI_TYPE_RECTANCLE1 = 13;
|
||||
public const int ROI_TYPE_RECTANGLE2 = 14;
|
||||
|
||||
|
||||
protected HTuple posOperation = new HTuple();
|
||||
protected HTuple negOperation = new HTuple(new int[] { 2, 2 });
|
||||
|
||||
/// <summary>Constructor of abstract ROI class.</summary>
|
||||
public ROI() { }
|
||||
|
||||
public virtual void createRectangle1(double row1, double col1, double row2, double col2) { }
|
||||
public virtual void createRectangle2(double row, double col, double phi, double length1, double length2) { }
|
||||
public virtual void createCircle(double row,double col,double radius) { }
|
||||
public virtual void createCircularArc(double row, double col, double radius, double startPhi, double extentPhi, string direct) { }
|
||||
public virtual void createLine(double beginRow, double beginCol, double endRow, double endCol) { }
|
||||
|
||||
/// <summary>Creates a new ROI instance at the mouse position.</summary>
|
||||
/// <param name="midX">
|
||||
/// x (=column) coordinate for ROI
|
||||
/// </param>
|
||||
/// <param name="midY">
|
||||
/// y (=row) coordinate for ROI
|
||||
/// </param>
|
||||
public virtual void createROI(double midX, double midY) { }
|
||||
|
||||
/// <summary>Paints the ROI into the supplied window.</summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public virtual void draw(HalconDotNet.HWindow window) { }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y)
|
||||
/// </summary>
|
||||
/// <param name="x">x (=column) coordinate</param>
|
||||
/// <param name="y">y (=row) coordinate</param>
|
||||
/// <returns>
|
||||
/// Distance of the closest ROI handle.
|
||||
/// </returns>
|
||||
public virtual double distToClosestHandle(double x, double y)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window.
|
||||
/// </summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public virtual void displayActive(HalconDotNet.HWindow window) { }
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y).
|
||||
/// </summary>
|
||||
/// <param name="x">x (=column) coordinate</param>
|
||||
/// <param name="y">y (=row) coordinate</param>
|
||||
public virtual void moveByHandle(double x, double y) { }
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI.</summary>
|
||||
public virtual HRegion getRegion()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual double getDistanceFromStartPoint(double row, double col)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the model information described by
|
||||
/// the ROI.
|
||||
/// </summary>
|
||||
public virtual HTuple getModelData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Number of handles defined for the ROI.</summary>
|
||||
/// <returns>Number of handles</returns>
|
||||
public int getNumHandles()
|
||||
{
|
||||
return NumHandles;
|
||||
}
|
||||
|
||||
/// <summary>Gets the active handle of the ROI.</summary>
|
||||
/// <returns>Index of the active handle (from the handle list)</returns>
|
||||
public int getActHandleIdx()
|
||||
{
|
||||
return activeHandleIdx;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sign of the ROI object, being either
|
||||
/// 'positive' or 'negative'. This sign is used when creating a model
|
||||
/// region for matching applications from a list of ROIs.
|
||||
/// </summary>
|
||||
public int getOperatorFlag()
|
||||
{
|
||||
return OperatorFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sign of a ROI object to be positive or negative.
|
||||
/// The sign is used when creating a model region for matching
|
||||
/// applications by summing up all positive and negative ROI models
|
||||
/// created so far.
|
||||
/// </summary>
|
||||
/// <param name="flag">Sign of ROI object</param>
|
||||
public void setOperatorFlag(int flag)
|
||||
{
|
||||
OperatorFlag = flag;
|
||||
|
||||
switch (OperatorFlag)
|
||||
{
|
||||
case ROI.POSITIVE_FLAG:
|
||||
flagLineStyle = posOperation;
|
||||
break;
|
||||
case ROI.NEGATIVE_FLAG:
|
||||
flagLineStyle = negOperation;
|
||||
break;
|
||||
default:
|
||||
flagLineStyle = posOperation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
193
ImageWindow/Model/ROICircle.cs
Normal file
193
ImageWindow/Model/ROICircle.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// This class demonstrates one of the possible implementations for a
|
||||
/// circular ROI. ROICircle inherits from the base class ROI and
|
||||
/// implements (besides other auxiliary methods) all virtual methods
|
||||
/// defined in ROI.cs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ROICircle : ROI
|
||||
{
|
||||
|
||||
[XmlElement(ElementName = "Row")]
|
||||
public double Row
|
||||
{
|
||||
get { return this.midR; }
|
||||
set { this.midR = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Column")]
|
||||
public double Column
|
||||
{
|
||||
get { return this.midC; }
|
||||
set { this.midC = value; }
|
||||
}
|
||||
[XmlElement(ElementName = "Radius")]
|
||||
public double Radius
|
||||
{
|
||||
get { return this.radius; }
|
||||
set { this.radius = value; }
|
||||
}
|
||||
|
||||
|
||||
private double radius;
|
||||
private double row1, col1; // first handle
|
||||
private double midR, midC; // second handle
|
||||
|
||||
|
||||
public ROICircle()
|
||||
{
|
||||
NumHandles = 2; // one at corner of circle + midpoint
|
||||
activeHandleIdx = 1;
|
||||
}
|
||||
|
||||
public ROICircle(double row, double col, double radius)
|
||||
{
|
||||
createCircle(row, col, radius);
|
||||
}
|
||||
|
||||
public override void createCircle(double row, double col, double radius)
|
||||
{
|
||||
base.createCircle(row, col, radius);
|
||||
midR = row;
|
||||
midC = col;
|
||||
|
||||
this.radius = radius;
|
||||
|
||||
row1 = midR;
|
||||
col1 = midC + radius;
|
||||
}
|
||||
|
||||
/// <summary>Creates a new ROI instance at the mouse position</summary>
|
||||
public override void createROI(double midX, double midY)
|
||||
{
|
||||
midR = midY;
|
||||
midC = midX;
|
||||
|
||||
radius = 100;
|
||||
|
||||
row1 = midR;
|
||||
col1 = midC + radius;
|
||||
}
|
||||
|
||||
/// <summary>Paints the ROI into the supplied window</summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void draw(HalconDotNet.HWindow window)
|
||||
{
|
||||
window.DispCircle(midR, midC, radius);
|
||||
window.DispRectangle2(row1, col1, 0, 8, 8);
|
||||
window.DispRectangle2(midR, midC, 0, 8, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y)
|
||||
/// </summary>
|
||||
public override double distToClosestHandle(double x, double y)
|
||||
{
|
||||
double max = 10000;
|
||||
double [] val = new double[NumHandles];
|
||||
|
||||
val[0] = HMisc.DistancePp(y, x, row1, col1); // border handle
|
||||
val[1] = HMisc.DistancePp(y, x, midR, midC); // midpoint
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
{
|
||||
if (val[i] < max)
|
||||
{
|
||||
max = val[i];
|
||||
activeHandleIdx = i;
|
||||
}
|
||||
}// end of for
|
||||
return val[activeHandleIdx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window
|
||||
/// </summary>
|
||||
public override void displayActive(HalconDotNet.HWindow window)
|
||||
{
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
window.DispRectangle2(row1, col1, 0, 8, 8);
|
||||
break;
|
||||
case 1:
|
||||
window.DispRectangle2(midR, midC, 0, 8, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI</summary>
|
||||
public override HRegion getRegion()
|
||||
{
|
||||
HRegion region = new HRegion();
|
||||
region.GenCircle(midR, midC, radius);
|
||||
return region;
|
||||
}
|
||||
|
||||
public override double getDistanceFromStartPoint(double row, double col)
|
||||
{
|
||||
double sRow = midR; // assumption: we have an angle starting at 0.0
|
||||
double sCol = midC + 1 * radius;
|
||||
|
||||
double angle = HMisc.AngleLl(midR, midC, sRow, sCol, midR, midC, row, col);
|
||||
|
||||
if (angle < 0)
|
||||
angle += 2 * Math.PI;
|
||||
|
||||
return (radius * angle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model information described by
|
||||
/// the ROI
|
||||
/// </summary>
|
||||
public override HTuple getModelData()
|
||||
{
|
||||
return new HTuple(new double[] { midR, midC, radius });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y)
|
||||
/// </summary>
|
||||
public override void moveByHandle(double newX, double newY)
|
||||
{
|
||||
HTuple distance;
|
||||
double shiftX,shiftY;
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0: // handle at circle border
|
||||
|
||||
row1 = newY;
|
||||
col1 = newX;
|
||||
HOperatorSet.DistancePp(new HTuple(row1), new HTuple(col1),
|
||||
new HTuple(midR), new HTuple(midC),
|
||||
out distance);
|
||||
|
||||
radius = distance[0].D;
|
||||
break;
|
||||
case 1: // midpoint
|
||||
|
||||
shiftY = midR - newY;
|
||||
shiftX = midC - newX;
|
||||
|
||||
midR = newY;
|
||||
midC = newX;
|
||||
|
||||
row1 -= shiftY;
|
||||
col1 -= shiftX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
366
ImageWindow/Model/ROICircularArc.cs
Normal file
366
ImageWindow/Model/ROICircularArc.cs
Normal file
@@ -0,0 +1,366 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Xml.Serialization;
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class implements an ROI shaped as a circular
|
||||
/// arc. ROICircularArc inherits from the base class ROI and
|
||||
/// implements (besides other auxiliary methods) all virtual methods
|
||||
/// defined in ROI.cs.
|
||||
/// </summary>
|
||||
public class ROICircularArc : ROI
|
||||
{
|
||||
public double Row
|
||||
{
|
||||
get { return this.midR; }
|
||||
set { this.midR = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Column")]
|
||||
public double Column
|
||||
{
|
||||
get { return this.midC; }
|
||||
set { this.midC = value; }
|
||||
}
|
||||
[XmlElement(ElementName = "Radius")]
|
||||
public double Radius
|
||||
{
|
||||
get { return this.radius; }
|
||||
set { this.radius = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "StartPhi")]
|
||||
public double StartPhi
|
||||
{
|
||||
get { return this.startPhi; }
|
||||
set { this.startPhi = value; }
|
||||
}
|
||||
[XmlElement(ElementName = "ExtentPhi")]
|
||||
public double ExtentPhi
|
||||
{
|
||||
get { return this.extentPhi; }
|
||||
set { this.extentPhi = value; }
|
||||
}
|
||||
//handles
|
||||
private double midR, midC; // 0. handle: midpoint
|
||||
private double sizeR, sizeC; // 1. handle
|
||||
private double startR, startC; // 2. handle
|
||||
private double extentR, extentC; // 3. handle
|
||||
|
||||
//model data to specify the arc
|
||||
private double radius;
|
||||
private double startPhi, extentPhi; // -2*PI <= x <= 2*PI
|
||||
|
||||
//display attributes
|
||||
private HXLDCont contour;
|
||||
private HXLDCont arrowHandleXLD;
|
||||
private string circDir;
|
||||
private double TwoPI;
|
||||
private double PI;
|
||||
|
||||
|
||||
public ROICircularArc()
|
||||
{
|
||||
NumHandles = 4; // midpoint handle + three handles on the arc
|
||||
activeHandleIdx = 0;
|
||||
contour = new HXLDCont();
|
||||
circDir = "";
|
||||
|
||||
TwoPI = 2 * Math.PI;
|
||||
PI = Math.PI;
|
||||
|
||||
arrowHandleXLD = new HXLDCont();
|
||||
arrowHandleXLD.GenEmptyObj();
|
||||
}
|
||||
public ROICircularArc(double row, double col, double radius, double startPhi, double extentPhi)
|
||||
{
|
||||
createCircularArc(row, col, radius, startPhi, extentPhi, "positive");
|
||||
}
|
||||
|
||||
public override void createCircularArc(double row, double col, double radius, double startPhi, double extentPhi,string direct)
|
||||
{
|
||||
base.createCircularArc(row, col, radius, startPhi, extentPhi, direct);
|
||||
midR = row;
|
||||
midC = col;
|
||||
|
||||
this.radius = radius;
|
||||
|
||||
|
||||
sizeR = midR;
|
||||
sizeC = midC - radius;
|
||||
|
||||
this.startPhi = startPhi;
|
||||
if (direct == "positive")
|
||||
{
|
||||
this.extentPhi = extentPhi;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.extentPhi = extentPhi;
|
||||
}
|
||||
// circDir = "positive";
|
||||
circDir = direct;
|
||||
determineArcHandles();
|
||||
updateArrowHandle();
|
||||
}
|
||||
/// <summary>Creates a new ROI instance at the mouse position</summary>
|
||||
public override void createROI(double midX, double midY)
|
||||
{
|
||||
midR = midY;
|
||||
midC = midX;
|
||||
|
||||
radius = 100;
|
||||
|
||||
sizeR = midR;
|
||||
sizeC = midC - radius;
|
||||
|
||||
startPhi = PI * 0.25;
|
||||
extentPhi = PI * 1.5;
|
||||
circDir = "positive";
|
||||
|
||||
determineArcHandles();
|
||||
updateArrowHandle();
|
||||
}
|
||||
|
||||
/// <summary>Paints the ROI into the supplied window</summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void draw(HalconDotNet.HWindow window)
|
||||
{
|
||||
contour.Dispose();
|
||||
contour.GenCircleContourXld(midR, midC, radius, startPhi,
|
||||
(startPhi + extentPhi), circDir, 1.0);
|
||||
window.DispObj(contour);
|
||||
window.DispRectangle2(sizeR, sizeC, 0, 5, 5);
|
||||
window.DispRectangle2(midR, midC, 0, 5, 5);
|
||||
window.DispRectangle2(startR, startC, startPhi, 10, 2);
|
||||
window.DispObj(arrowHandleXLD);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y)
|
||||
/// </summary>
|
||||
public override double distToClosestHandle(double x, double y)
|
||||
{
|
||||
double max = 10000;
|
||||
double [] val = new double[NumHandles];
|
||||
|
||||
val[0] = HMisc.DistancePp(y, x, midR, midC); // midpoint
|
||||
val[1] = HMisc.DistancePp(y, x, sizeR, sizeC); // border handle
|
||||
val[2] = HMisc.DistancePp(y, x, startR, startC); // border handle
|
||||
val[3] = HMisc.DistancePp(y, x, extentR, extentC); // border handle
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
{
|
||||
if (val[i] < max)
|
||||
{
|
||||
max = val[i];
|
||||
activeHandleIdx = i;
|
||||
}
|
||||
}// end of for
|
||||
return val[activeHandleIdx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window
|
||||
/// </summary>
|
||||
public override void displayActive(HalconDotNet.HWindow window)
|
||||
{
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
window.DispRectangle2(midR, midC, 0, 5, 5);
|
||||
break;
|
||||
case 1:
|
||||
window.DispRectangle2(sizeR, sizeC, 0, 5, 5);
|
||||
break;
|
||||
case 2:
|
||||
window.DispRectangle2(startR, startC, startPhi, 10, 2);
|
||||
break;
|
||||
case 3:
|
||||
window.DispObj(arrowHandleXLD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y)
|
||||
/// </summary>
|
||||
public override void moveByHandle(double newX, double newY)
|
||||
{
|
||||
HTuple distance;
|
||||
double dirX, dirY, prior, next, valMax, valMin;
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0: // midpoint
|
||||
dirY = midR - newY;
|
||||
dirX = midC - newX;
|
||||
|
||||
midR = newY;
|
||||
midC = newX;
|
||||
|
||||
sizeR -= dirY;
|
||||
sizeC -= dirX;
|
||||
|
||||
determineArcHandles();
|
||||
break;
|
||||
|
||||
case 1: // handle at circle border
|
||||
sizeR = newY;
|
||||
sizeC = newX;
|
||||
|
||||
HOperatorSet.DistancePp(new HTuple(sizeR), new HTuple(sizeC),
|
||||
new HTuple(midR), new HTuple(midC), out distance);
|
||||
radius = distance[0].D;
|
||||
determineArcHandles();
|
||||
break;
|
||||
|
||||
case 2: // start handle for arc
|
||||
dirY = newY - midR;
|
||||
dirX = newX - midC;
|
||||
|
||||
startPhi = Math.Atan2(-dirY, dirX);
|
||||
|
||||
if (startPhi < 0)
|
||||
startPhi = PI + (startPhi + PI);
|
||||
|
||||
setStartHandle();
|
||||
prior = extentPhi;
|
||||
extentPhi = HMisc.AngleLl(midR, midC, startR, startC, midR, midC, extentR, extentC);
|
||||
|
||||
if (extentPhi < 0 && prior > PI * 0.8)
|
||||
extentPhi = (PI + extentPhi) + PI;
|
||||
else if (extentPhi > 0 && prior < -PI * 0.7)
|
||||
extentPhi = -PI - (PI - extentPhi);
|
||||
|
||||
break;
|
||||
|
||||
case 3: // end handle for arc
|
||||
dirY = newY - midR;
|
||||
dirX = newX - midC;
|
||||
|
||||
prior = extentPhi;
|
||||
next = Math.Atan2(-dirY, dirX);
|
||||
|
||||
if (next < 0)
|
||||
next = PI + (next + PI);
|
||||
|
||||
if (circDir == "positive" && startPhi >= next)
|
||||
extentPhi = (next + TwoPI) - startPhi;
|
||||
else if (circDir == "positive" && next > startPhi)
|
||||
extentPhi = next - startPhi;
|
||||
else if (circDir == "negative" && startPhi >= next)
|
||||
extentPhi = -1.0 * (startPhi - next);
|
||||
else if (circDir == "negative" && next > startPhi)
|
||||
extentPhi = -1.0 * (startPhi + TwoPI - next);
|
||||
|
||||
valMax = Math.Max(Math.Abs(prior), Math.Abs(extentPhi));
|
||||
valMin = Math.Min(Math.Abs(prior), Math.Abs(extentPhi));
|
||||
|
||||
if ((valMax - valMin) >= PI)
|
||||
extentPhi = (circDir == "positive") ? -1.0 * valMin : valMin;
|
||||
|
||||
setExtentHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
circDir = (extentPhi < 0) ? "negative" : "positive";
|
||||
updateArrowHandle();
|
||||
}
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI</summary>
|
||||
public override HRegion getRegion()
|
||||
{
|
||||
HRegion region;
|
||||
contour.Dispose();
|
||||
contour.GenCircleContourXld(midR, midC, radius, startPhi, (startPhi + extentPhi), circDir, 1.0);
|
||||
region = new HRegion(contour);
|
||||
return region;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model information described by the ROI
|
||||
/// </summary>
|
||||
public override HTuple getModelData()
|
||||
{
|
||||
return new HTuple(new double[] { midR, midC, radius, startPhi, extentPhi });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auxiliary method to determine the positions of the second and
|
||||
/// third handle.
|
||||
/// </summary>
|
||||
private void determineArcHandles()
|
||||
{
|
||||
setStartHandle();
|
||||
setExtentHandle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auxiliary method to recalculate the start handle for the arc
|
||||
/// </summary>
|
||||
private void setStartHandle()
|
||||
{
|
||||
startR = midR - radius * Math.Sin(startPhi);
|
||||
startC = midC + radius * Math.Cos(startPhi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auxiliary method to recalculate the extent handle for the arc
|
||||
/// </summary>
|
||||
private void setExtentHandle()
|
||||
{
|
||||
extentR = midR - radius * Math.Sin(startPhi + extentPhi);
|
||||
extentC = midC + radius * Math.Cos(startPhi + extentPhi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auxiliary method to display an arrow at the extent arc position
|
||||
/// </summary>
|
||||
private void updateArrowHandle()
|
||||
{
|
||||
double row1, col1, row2, col2;
|
||||
double rowP1, colP1, rowP2, colP2;
|
||||
double length,dr,dc, halfHW, sign, angleRad;
|
||||
double headLength = 15;
|
||||
double headWidth = 15;
|
||||
|
||||
arrowHandleXLD.Dispose();
|
||||
arrowHandleXLD.GenEmptyObj();
|
||||
|
||||
row2 = extentR;
|
||||
col2 = extentC;
|
||||
angleRad = (startPhi + extentPhi) + Math.PI * 0.5;
|
||||
|
||||
sign = (circDir == "negative") ? -1.0 : 1.0;
|
||||
row1 = row2 + sign * Math.Sin(angleRad) * 20;
|
||||
col1 = col2 - sign * Math.Cos(angleRad) * 20;
|
||||
|
||||
length = HMisc.DistancePp(row1, col1, row2, col2);
|
||||
if (length == 0)
|
||||
length = -1;
|
||||
|
||||
dr = (row2 - row1) / length;
|
||||
dc = (col2 - col1) / length;
|
||||
|
||||
halfHW = headWidth / 2.0;
|
||||
rowP1 = row1 + (length - headLength) * dr + halfHW * dc;
|
||||
rowP2 = row1 + (length - headLength) * dr - halfHW * dc;
|
||||
colP1 = col1 + (length - headLength) * dc - halfHW * dr;
|
||||
colP2 = col1 + (length - headLength) * dc + halfHW * dr;
|
||||
|
||||
if (length == -1)
|
||||
arrowHandleXLD.GenContourPolygonXld(row1, col1);
|
||||
else
|
||||
arrowHandleXLD.GenContourPolygonXld(new HTuple(new double[] { row1, row2, rowP1, row2, rowP2, row2 }),
|
||||
new HTuple(new double[] { col1, col2, colP1, col2, colP2, col2 }));
|
||||
}
|
||||
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
|
||||
816
ImageWindow/Model/ROIController.cs
Normal file
816
ImageWindow/Model/ROIController.cs
Normal file
@@ -0,0 +1,816 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using ViewWindow;
|
||||
using System.Collections;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
|
||||
public delegate void FuncROIDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// This class creates and manages ROI objects. It responds
|
||||
/// to mouse device inputs using the methods mouseDownAction and
|
||||
/// mouseMoveAction. You don't have to know this class in detail when you
|
||||
/// build your own C# project. But you must consider a few things if
|
||||
/// you want to use interactive ROIs in your application: There is a
|
||||
/// quite close connection between the ROIController and the HWndCtrl
|
||||
/// class, which means that you must 'register' the ROIController
|
||||
/// with the HWndCtrl, so the HWndCtrl knows it has to forward user input
|
||||
/// (like mouse events) to the ROIController class.
|
||||
/// The visualization and manipulation of the ROI objects is done
|
||||
/// by the ROIController.
|
||||
/// This class provides special support for the matching
|
||||
/// applications by calculating a model region from the list of ROIs. For
|
||||
/// this, ROIs are added and subtracted according to their sign.
|
||||
/// </summary>
|
||||
public class ROIController
|
||||
{
|
||||
public bool EditModel = true;
|
||||
|
||||
/// <summary>
|
||||
/// Constant for setting the ROI mode: positive ROI sign.
|
||||
/// </summary>
|
||||
public const int MODE_ROI_POS = 21;
|
||||
|
||||
/// <summary>
|
||||
/// Constant for setting the ROI mode: negative ROI sign.
|
||||
/// </summary>
|
||||
public const int MODE_ROI_NEG = 22;
|
||||
|
||||
/// <summary>
|
||||
/// Constant for setting the ROI mode: no model region is computed as
|
||||
/// the sum of all ROI objects.
|
||||
/// </summary>
|
||||
public const int MODE_ROI_NONE = 23;
|
||||
|
||||
/// <summary>Constant describing an update of the model region</summary>
|
||||
public const int EVENT_UPDATE_ROI = 50;
|
||||
|
||||
public const int EVENT_CHANGED_ROI_SIGN = 51;
|
||||
|
||||
/// <summary>Constant describing an update of the model region</summary>
|
||||
public const int EVENT_MOVING_ROI = 52;
|
||||
|
||||
public const int EVENT_DELETED_ACTROI = 53;
|
||||
|
||||
public const int EVENT_DELETED_ALL_ROIS = 54;
|
||||
|
||||
public const int EVENT_ACTIVATED_ROI = 55;
|
||||
|
||||
public const int EVENT_CREATED_ROI = 56;
|
||||
|
||||
|
||||
private ROI roiMode;
|
||||
private int stateROI;
|
||||
private double currX, currY;
|
||||
|
||||
|
||||
/// <summary>Index of the active ROI object</summary>
|
||||
public int activeROIidx;
|
||||
public int deletedIdx;
|
||||
|
||||
/// <summary>List containing all created ROI objects so far</summary>
|
||||
public ArrayList ROIList;
|
||||
|
||||
/// <summary>
|
||||
/// Region obtained by summing up all negative
|
||||
/// and positive ROI objects from the ROIList
|
||||
/// </summary>
|
||||
public HRegion ModelROI;
|
||||
|
||||
private string activeCol = "green";
|
||||
private string activeHdlCol = "red";
|
||||
private string inactiveCol = "blue";
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the HWndCtrl, the ROI Controller is registered to
|
||||
/// </summary>
|
||||
public HWndCtrl viewController;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate that notifies about changes made in the model region
|
||||
/// </summary>
|
||||
public IconicDelegate NotifyRCObserver;
|
||||
|
||||
/// <summary>Constructor</summary>
|
||||
protected internal ROIController()
|
||||
{
|
||||
stateROI = MODE_ROI_NONE;
|
||||
ROIList = new ArrayList();
|
||||
activeROIidx = -1;
|
||||
ModelROI = new HRegion();
|
||||
NotifyRCObserver = new IconicDelegate(dummyI);
|
||||
deletedIdx = -1;
|
||||
currX = currY = -1;
|
||||
}
|
||||
|
||||
/// <summary>Registers the HWndCtrl to this ROIController instance</summary>
|
||||
public void setViewController(HWndCtrl view)
|
||||
{
|
||||
viewController = view;
|
||||
}
|
||||
|
||||
/// <summary>Gets the ModelROI object</summary>
|
||||
public HRegion getModelRegion()
|
||||
{
|
||||
return ModelROI;
|
||||
}
|
||||
|
||||
/// <summary>Gets the List of ROIs created so far</summary>
|
||||
public ArrayList getROIList()
|
||||
{
|
||||
return ROIList;
|
||||
}
|
||||
|
||||
/// <summary>Get the active ROI</summary>
|
||||
public ROI getActiveROI()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (activeROIidx != -1)
|
||||
return ((ROI)ROIList[activeROIidx]);
|
||||
return null;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getActiveROIIdx()
|
||||
{
|
||||
return activeROIidx;
|
||||
}
|
||||
|
||||
public void setActiveROIIdx(int active)
|
||||
{
|
||||
activeROIidx = active;
|
||||
}
|
||||
|
||||
public int getDelROIIdx()
|
||||
{
|
||||
return deletedIdx;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To create a new ROI object the application class initializes a
|
||||
/// 'seed' ROI instance and passes it to the ROIController.
|
||||
/// The ROIController now responds by manipulating this new ROI
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="r">
|
||||
/// 'Seed' ROI object forwarded by the application forms class.
|
||||
/// </param>
|
||||
public void setROIShape(ROI r)
|
||||
{
|
||||
roiMode = r;
|
||||
roiMode.setOperatorFlag(stateROI);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sign of a ROI object to the value 'mode' (MODE_ROI_NONE,
|
||||
/// MODE_ROI_POS,MODE_ROI_NEG)
|
||||
/// </summary>
|
||||
public void setROISign(int mode)
|
||||
{
|
||||
stateROI = mode;
|
||||
|
||||
if (activeROIidx != -1)
|
||||
{
|
||||
((ROI)ROIList[activeROIidx]).setOperatorFlag(stateROI);
|
||||
viewController.repaint();
|
||||
NotifyRCObserver(ROIController.EVENT_CHANGED_ROI_SIGN);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the ROI object that is marked as active.
|
||||
/// If no ROI object is active, then nothing happens.
|
||||
/// </summary>
|
||||
public void removeActive()
|
||||
{
|
||||
if (activeROIidx != -1)
|
||||
{
|
||||
ROIList.RemoveAt(activeROIidx);
|
||||
deletedIdx = activeROIidx;
|
||||
activeROIidx = -1;
|
||||
viewController.repaint();
|
||||
NotifyRCObserver(EVENT_DELETED_ACTROI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the ModelROI region for all objects contained
|
||||
/// in ROIList, by adding and subtracting the positive and
|
||||
/// negative ROI objects.
|
||||
/// </summary>
|
||||
public bool defineModelROI()
|
||||
{
|
||||
HRegion tmpAdd, tmpDiff, tmp;
|
||||
double row, col;
|
||||
|
||||
if (stateROI == MODE_ROI_NONE)
|
||||
return true;
|
||||
|
||||
tmpAdd = new HRegion();
|
||||
tmpDiff = new HRegion();
|
||||
tmpAdd.GenEmptyRegion();
|
||||
tmpDiff.GenEmptyRegion();
|
||||
|
||||
for (int i=0; i < ROIList.Count; i++)
|
||||
{
|
||||
switch (((ROI)ROIList[i]).getOperatorFlag())
|
||||
{
|
||||
case ROI.POSITIVE_FLAG:
|
||||
tmp = ((ROI)ROIList[i]).getRegion();
|
||||
tmpAdd = tmp.Union2(tmpAdd);
|
||||
break;
|
||||
case ROI.NEGATIVE_FLAG:
|
||||
tmp = ((ROI)ROIList[i]).getRegion();
|
||||
tmpDiff = tmp.Union2(tmpDiff);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}//end of switch
|
||||
}//end of for
|
||||
|
||||
ModelROI = null;
|
||||
|
||||
if (tmpAdd.AreaCenter(out row, out col) > 0)
|
||||
{
|
||||
tmp = tmpAdd.Difference(tmpDiff);
|
||||
if (tmp.AreaCenter(out row, out col) > 0)
|
||||
ModelROI = tmp;
|
||||
}
|
||||
|
||||
//in case the set of positiv and negative ROIs dissolve
|
||||
if (ModelROI == null || ROIList.Count == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all variables managing ROI objects
|
||||
/// </summary>
|
||||
public void reset()
|
||||
{
|
||||
ROIList.Clear();
|
||||
activeROIidx = -1;
|
||||
ModelROI = null;
|
||||
roiMode = null;
|
||||
NotifyRCObserver(EVENT_DELETED_ALL_ROIS);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Deletes this ROI instance if a 'seed' ROI object has been passed
|
||||
/// to the ROIController by the application class.
|
||||
///
|
||||
/// </summary>
|
||||
public void resetROI()
|
||||
{
|
||||
activeROIidx = -1;
|
||||
roiMode = null;
|
||||
}
|
||||
|
||||
/// <summary>Defines the colors for the ROI objects</summary>
|
||||
/// <param name="aColor">Color for the active ROI object</param>
|
||||
/// <param name="inaColor">Color for the inactive ROI objects</param>
|
||||
/// <param name="aHdlColor">
|
||||
/// Color for the active handle of the active ROI object
|
||||
/// </param>
|
||||
public void setDrawColor(string aColor,
|
||||
string aHdlColor,
|
||||
string inaColor)
|
||||
{
|
||||
if (aColor != "")
|
||||
activeCol = aColor;
|
||||
if (aHdlColor != "")
|
||||
activeHdlCol = aHdlColor;
|
||||
if (inaColor != "")
|
||||
inactiveCol = inaColor;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Paints all objects from the ROIList into the HALCON window
|
||||
/// </summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
internal void paintData(HalconDotNet.HWindow window)
|
||||
{
|
||||
window.SetDraw("margin");
|
||||
window.SetLineWidth(1);
|
||||
if (ROIList.Count > 0)
|
||||
{
|
||||
window.SetColor(inactiveCol);
|
||||
window.SetDraw("margin");
|
||||
for (int i = 0; i < ROIList.Count; i++)
|
||||
{
|
||||
window.SetLineStyle(((ROI)ROIList[i]).flagLineStyle);
|
||||
((ROI)ROIList[i]).draw(window);
|
||||
}
|
||||
if (activeROIidx != -1)
|
||||
{
|
||||
window.SetColor(activeCol);
|
||||
window.SetLineStyle(((ROI)ROIList[activeROIidx]).flagLineStyle);
|
||||
((ROI)ROIList[activeROIidx]).draw(window);
|
||||
|
||||
window.SetColor(activeHdlCol);
|
||||
((ROI)ROIList[activeROIidx]).displayActive(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 以指定颜色显示ROI
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
internal void paintData(HalconDotNet.HWindow window,string color)
|
||||
{
|
||||
window.SetDraw("margin");
|
||||
window.SetLineWidth(1);
|
||||
if (ROIList.Count > 0)
|
||||
{
|
||||
window.SetColor(color);
|
||||
window.SetDraw("margin");
|
||||
for (int i = 0; i < ROIList.Count; i++)
|
||||
{
|
||||
window.SetLineStyle(((ROI)ROIList[i]).flagLineStyle);
|
||||
((ROI)ROIList[i]).draw(window);
|
||||
}
|
||||
if (activeROIidx != -1)
|
||||
{
|
||||
window.SetColor(color);
|
||||
window.SetLineStyle(((ROI)ROIList[activeROIidx]).flagLineStyle);
|
||||
((ROI)ROIList[activeROIidx]).draw(window);
|
||||
|
||||
window.SetColor(color);
|
||||
((ROI)ROIList[activeROIidx]).displayActive(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reaction of ROI objects to the 'mouse button down' event: changing
|
||||
/// the shape of the ROI and adding it to the ROIList if it is a 'seed'
|
||||
/// ROI.
|
||||
/// </summary>
|
||||
/// <param name="imgX">x coordinate of mouse event</param>
|
||||
/// <param name="imgY">y coordinate of mouse event</param>
|
||||
/// <returns></returns>
|
||||
public int mouseDownAction(double imgX, double imgY)
|
||||
{
|
||||
int idxROI= -1;
|
||||
double max = 10000, dist = 0;
|
||||
double epsilon = 35.0; //maximal shortest distance to one of
|
||||
//the handles
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createROI(imgX, imgY);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
else if (ROIList.Count > 0) // ... or an existing one is manipulated
|
||||
{
|
||||
activeROIidx = -1;
|
||||
|
||||
for (int i =0; i < ROIList.Count; i++)
|
||||
{
|
||||
dist = ((ROI)ROIList[i]).distToClosestHandle(imgX, imgY);
|
||||
if ((dist < max) && (dist < epsilon))
|
||||
{
|
||||
max = dist;
|
||||
idxROI = i;
|
||||
}
|
||||
}//end of for
|
||||
|
||||
if (idxROI >= 0)
|
||||
{
|
||||
activeROIidx = idxROI;
|
||||
NotifyRCObserver(ROIController.EVENT_ACTIVATED_ROI);
|
||||
}
|
||||
|
||||
viewController.repaint();
|
||||
}
|
||||
return activeROIidx;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reaction of ROI objects to the 'mouse button move' event: moving
|
||||
/// the active ROI.
|
||||
/// </summary>
|
||||
/// <param name="newX">x coordinate of mouse event</param>
|
||||
/// <param name="newY">y coordinate of mouse event</param>
|
||||
public void mouseMoveAction(double newX, double newY)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(EditModel ==false) return;
|
||||
if ((newX == currX) && (newY == currY))
|
||||
return;
|
||||
|
||||
((ROI)ROIList[activeROIidx]).moveByHandle(newX, newY);
|
||||
viewController.repaint();
|
||||
currX = newX;
|
||||
currY = newY;
|
||||
NotifyRCObserver(ROIController.EVENT_MOVING_ROI);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//没有显示roi的时候 移动鼠标会报错
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************/
|
||||
public void dummyI(int v)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************/
|
||||
/// <summary>
|
||||
/// 在指定位置显示ROI--Rectangle1
|
||||
/// </summary>
|
||||
/// <param name="row1"></param>
|
||||
/// <param name="col1"></param>
|
||||
/// <param name="row2"></param>
|
||||
/// <param name="col2"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void displayRect1(string color, double row1, double col1, double row2, double col2)
|
||||
{
|
||||
setROIShape(new ROIRectangle1());
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createRectangle1(row1, col1, row2, col2);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
roiMode.Color = color;
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint("blue");
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置显示ROI--Rectangle2
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="col"></param>
|
||||
/// <param name="phi"></param>
|
||||
/// <param name="length1"></param>
|
||||
/// <param name="length2"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void displayRect2(string color,double row, double col, double phi, double length1, double length2)
|
||||
{
|
||||
setROIShape(new ROIRectangle2());
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createRectangle2(row, col, phi, length1, length2);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
roiMode.Color = color;
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置生成ROI--Circle
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="col"></param>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void displayCircle(string color, double row, double col, double radius)
|
||||
{
|
||||
setROIShape(new ROICircle());
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createCircle(row, col, radius);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
roiMode.Color = color;
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
|
||||
public void displayCircularArc(string color, double row, double col, double radius, double startPhi, double extentPhi)
|
||||
{
|
||||
setROIShape(new ROICircle());
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createCircularArc(row, col, radius, startPhi, extentPhi, "positive");
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
roiMode.Color = color;
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在指定位置显示ROI--Line
|
||||
/// </summary>
|
||||
/// <param name="beginRow"></param>
|
||||
/// <param name="beginCol"></param>
|
||||
/// <param name="endRow"></param>
|
||||
/// <param name="endCol"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void displayLine(string color, double beginRow, double beginCol, double endRow, double endCol)
|
||||
{
|
||||
this.setROIShape(new ROILine());
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createLine(beginRow, beginCol, endRow, endCol);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
roiMode.Color = color;
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置生成ROI--Rectangle1
|
||||
/// </summary>
|
||||
/// <param name="row1"></param>
|
||||
/// <param name="col1"></param>
|
||||
/// <param name="row2"></param>
|
||||
/// <param name="col2"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void genRect1(double row1, double col1, double row2, double col2, ref System.Collections.Generic.List<ROI> rois)
|
||||
{
|
||||
setROIShape(new ROIRectangle1());
|
||||
|
||||
if (rois == null)
|
||||
{
|
||||
rois = new System.Collections.Generic.List<ROI>();
|
||||
}
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createRectangle1(row1, col1, row2, col2);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
rois.Add(roiMode);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置生成ROI--Rectangle2
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="col"></param>
|
||||
/// <param name="phi"></param>
|
||||
/// <param name="length1"></param>
|
||||
/// <param name="length2"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void genRect2(double row, double col, double phi, double length1, double length2, ref System.Collections.Generic.List<ROI> rois)
|
||||
{
|
||||
setROIShape(new ROIRectangle2());
|
||||
|
||||
if (rois == null)
|
||||
{
|
||||
rois = new System.Collections.Generic.List<ROI>();
|
||||
}
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createRectangle2(row, col, phi, length1, length2);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
rois.Add(roiMode);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置生成ROI--Circle
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="col"></param>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="rois"></param>
|
||||
public void genCircle(double row, double col, double radius, ref System.Collections.Generic.List<ROI> rois)
|
||||
{
|
||||
setROIShape(new ROICircle());
|
||||
|
||||
if (rois == null)
|
||||
{
|
||||
rois = new System.Collections.Generic.List<ROI>();
|
||||
}
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createCircle(row, col, radius);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
rois.Add(roiMode);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
|
||||
public void genCircularArc(double row, double col, double radius, double startPhi, double extentPhi, string direct, ref System.Collections.Generic.List<ROI> rois)
|
||||
{
|
||||
setROIShape(new ROICircularArc());
|
||||
|
||||
if (rois == null)
|
||||
{
|
||||
rois = new System.Collections.Generic.List<ROI>();
|
||||
}
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createCircularArc(row, col, radius, startPhi, extentPhi, direct);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
rois.Add(roiMode);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定位置生成ROI--Line
|
||||
/// </summary>
|
||||
/// <param name="beginRow"></param>
|
||||
/// <param name="beginCol"></param>
|
||||
/// <param name="endRow"></param>
|
||||
/// <param name="endCol"></param>
|
||||
/// <param name="rois"></param>
|
||||
protected internal void genLine(double beginRow, double beginCol, double endRow, double endCol, ref System.Collections.Generic.List<ROI> rois)
|
||||
{
|
||||
this.setROIShape(new ROILine());
|
||||
|
||||
if (rois == null)
|
||||
{
|
||||
rois = new System.Collections.Generic.List<ROI>();
|
||||
}
|
||||
|
||||
if (roiMode != null) //either a new ROI object is created
|
||||
{
|
||||
roiMode.createLine(beginRow, beginCol, endRow, endCol);
|
||||
roiMode.Type = roiMode.GetType().Name;
|
||||
rois.Add(roiMode);
|
||||
ROIList.Add(roiMode);
|
||||
roiMode = null;
|
||||
activeROIidx = ROIList.Count - 1;
|
||||
viewController.repaint();
|
||||
|
||||
NotifyRCObserver(ROIController.EVENT_CREATED_ROI);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取当前选中ROI的信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected internal System.Collections.Generic.List<double> smallestActiveROI(out string name, out int index)
|
||||
{
|
||||
name = "";
|
||||
int activeROIIdx = this.getActiveROIIdx();
|
||||
index = activeROIIdx;
|
||||
if (activeROIIdx > -1)
|
||||
{
|
||||
ROI region = this.getActiveROI();
|
||||
Type type = region.GetType();
|
||||
name = type.Name;
|
||||
|
||||
HTuple smallest = region.getModelData();
|
||||
System.Collections.Generic.List<double> resual = new System.Collections.Generic.List<double>();
|
||||
for (int i = 0; i < smallest.Length; i++)
|
||||
{
|
||||
resual.Add(smallest[i].D);
|
||||
}
|
||||
|
||||
return resual;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal ROI smallestActiveROI(out System.Collections.Generic.List<double> data, out int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
int activeROIIdx = this.getActiveROIIdx();
|
||||
index = activeROIIdx;
|
||||
data = new System.Collections.Generic.List<double>();
|
||||
|
||||
if (activeROIIdx > -1)
|
||||
{
|
||||
ROI region = this.getActiveROI();
|
||||
Type type = region.GetType();
|
||||
|
||||
HTuple smallest = region.getModelData();
|
||||
|
||||
for (int i = 0; i < smallest.Length; i++)
|
||||
{
|
||||
data.Add(smallest[i].D);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
data = null;
|
||||
index = 0;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除当前选中ROI
|
||||
/// </summary>
|
||||
/// <param name="roi"></param>
|
||||
protected internal void removeActiveROI(ref System.Collections.Generic.List<ROI> roi)
|
||||
{
|
||||
int activeROIIdx = this.getActiveROIIdx();
|
||||
if (activeROIIdx > -1)
|
||||
{
|
||||
this.removeActive();
|
||||
roi.RemoveAt(activeROIIdx);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 选中激活ROI
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
protected internal void selectROI(int index)
|
||||
{
|
||||
this.activeROIidx = index;
|
||||
this.NotifyRCObserver(ROIController.EVENT_ACTIVATED_ROI);
|
||||
this.viewController.repaint();
|
||||
}
|
||||
/// <summary>
|
||||
/// 复位窗口显示
|
||||
/// </summary>
|
||||
protected internal void resetWindowImage()
|
||||
{
|
||||
//this.viewController.resetWindow();
|
||||
this.viewController.repaint();
|
||||
}
|
||||
|
||||
protected internal void zoomWindowImage()
|
||||
{
|
||||
this.viewController.setViewState(HWndCtrl.MODE_VIEW_ZOOM);
|
||||
}
|
||||
|
||||
protected internal void moveWindowImage()
|
||||
{
|
||||
this.viewController.setViewState(HWndCtrl.MODE_VIEW_MOVE);
|
||||
}
|
||||
|
||||
protected internal void noneWindowImage()
|
||||
{
|
||||
this.viewController.setViewState(HWndCtrl.MODE_VIEW_NONE);
|
||||
}
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
249
ImageWindow/Model/ROILine.cs
Normal file
249
ImageWindow/Model/ROILine.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// This class demonstrates one of the possible implementations for a
|
||||
/// linear ROI. ROILine inherits from the base class ROI and
|
||||
/// implements (besides other auxiliary methods) all virtual methods
|
||||
/// defined in ROI.cs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ROILine : ROI
|
||||
{
|
||||
|
||||
[XmlElement(ElementName = "RowBegin")]
|
||||
public double RowBegin
|
||||
{
|
||||
get { return this.row1; }
|
||||
set { this.row1 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "ColumnBegin")]
|
||||
public double ColumnBegin
|
||||
{
|
||||
get { return this.col1; }
|
||||
set { this.col1 = value; }
|
||||
}
|
||||
[XmlElement(ElementName = "RowEnd")]
|
||||
public double RowEnd
|
||||
{
|
||||
get { return this.row2; }
|
||||
set { this.row2 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "ColumnEnd")]
|
||||
public double ColumnEnd
|
||||
{
|
||||
get { return this.col2; }
|
||||
set { this.col2 = value; }
|
||||
}
|
||||
|
||||
private double row1, col1; // first end point of line
|
||||
private double row2, col2; // second end point of line
|
||||
private double midR, midC; // midPoint of line
|
||||
|
||||
private HObject arrowHandleXLD;
|
||||
|
||||
public ROILine()
|
||||
{
|
||||
NumHandles = 3; // two end points of line
|
||||
activeHandleIdx = 2;
|
||||
arrowHandleXLD = new HXLDCont();
|
||||
arrowHandleXLD.GenEmptyObj();
|
||||
}
|
||||
|
||||
public ROILine(double beginRow, double beginCol, double endRow, double endCol)
|
||||
{
|
||||
createLine(beginRow, beginCol, endRow, endCol);
|
||||
}
|
||||
|
||||
public override void createLine(double beginRow, double beginCol, double endRow, double endCol)
|
||||
{
|
||||
base.createLine(beginRow, beginCol, endRow, endCol);
|
||||
|
||||
row1 = beginRow;
|
||||
col1 = beginCol;
|
||||
row2 = endRow;
|
||||
col2 = endCol;
|
||||
|
||||
midR = (row1 + row2) / 2.0;
|
||||
midC = (col1 + col2) / 2.0;
|
||||
|
||||
updateArrowHandle();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new ROI instance at the mouse position.</summary>
|
||||
public override void createROI(double midX, double midY)
|
||||
{
|
||||
midR = midY;
|
||||
midC = midX;
|
||||
|
||||
row1 = midR;
|
||||
col1 = midC - 50;
|
||||
row2 = midR;
|
||||
col2 = midC + 50;
|
||||
|
||||
updateArrowHandle();
|
||||
}
|
||||
/// <summary>Paints the ROI into the supplied window.</summary>
|
||||
public override void draw(HalconDotNet.HWindow window)
|
||||
{
|
||||
|
||||
window.DispLine(row1, col1, row2, col2);
|
||||
|
||||
window.DispRectangle2(row1, col1, 0, 8, 8);
|
||||
window.DispObj(arrowHandleXLD); //window.DispRectangle2( row2, col2, 0, 25, 25);
|
||||
window.DispRectangle2(midR, midC, 0, 8, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y).
|
||||
/// </summary>
|
||||
public override double distToClosestHandle(double x, double y)
|
||||
{
|
||||
|
||||
double max = 10000;
|
||||
double [] val = new double[NumHandles];
|
||||
|
||||
val[0] = HMisc.DistancePp(y, x, row1, col1); // upper left
|
||||
val[1] = HMisc.DistancePp(y, x, row2, col2); // upper right
|
||||
val[2] = HMisc.DistancePp(y, x, midR, midC); // midpoint
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
{
|
||||
if (val[i] < max)
|
||||
{
|
||||
max = val[i];
|
||||
activeHandleIdx = i;
|
||||
}
|
||||
}// end of for
|
||||
|
||||
return val[activeHandleIdx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window.
|
||||
/// </summary>
|
||||
public override void displayActive(HalconDotNet.HWindow window)
|
||||
{
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
window.DispRectangle2(row1, col1, 0, 8, 8);
|
||||
break;
|
||||
case 1:
|
||||
window.DispObj(arrowHandleXLD); //window.DispRectangle2(row2, col2, 0, 25, 25);
|
||||
break;
|
||||
case 2:
|
||||
window.DispRectangle2(midR, midC, 0, 8, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI.</summary>
|
||||
public override HRegion getRegion()
|
||||
{
|
||||
HRegion region = new HRegion();
|
||||
region.GenRegionLine(row1, col1, row2, col2);
|
||||
return region;
|
||||
}
|
||||
|
||||
public override double getDistanceFromStartPoint(double row, double col)
|
||||
{
|
||||
double distance = HMisc.DistancePp(row, col, row1, col1);
|
||||
return distance;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the model information described by
|
||||
/// the ROI.
|
||||
/// </summary>
|
||||
public override HTuple getModelData()
|
||||
{
|
||||
return new HTuple(new double[] { row1, col1, row2, col2 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y).
|
||||
/// </summary>
|
||||
public override void moveByHandle(double newX, double newY)
|
||||
{
|
||||
double lenR, lenC;
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0: // first end point
|
||||
row1 = newY;
|
||||
col1 = newX;
|
||||
|
||||
midR = (row1 + row2) / 2;
|
||||
midC = (col1 + col2) / 2;
|
||||
break;
|
||||
case 1: // last end point
|
||||
row2 = newY;
|
||||
col2 = newX;
|
||||
|
||||
midR = (row1 + row2) / 2;
|
||||
midC = (col1 + col2) / 2;
|
||||
break;
|
||||
case 2: // midpoint
|
||||
lenR = row1 - midR;
|
||||
lenC = col1 - midC;
|
||||
|
||||
midR = newY;
|
||||
midC = newX;
|
||||
|
||||
row1 = midR + lenR;
|
||||
col1 = midC + lenC;
|
||||
row2 = midR - lenR;
|
||||
col2 = midC - lenC;
|
||||
break;
|
||||
}
|
||||
updateArrowHandle();
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Auxiliary method </summary>
|
||||
private void updateArrowHandle()
|
||||
{
|
||||
double length,dr,dc, halfHW;
|
||||
double rrow1, ccol1,rowP1, colP1, rowP2, colP2;
|
||||
|
||||
double headLength = 16;
|
||||
double headWidth = 16;
|
||||
|
||||
|
||||
arrowHandleXLD.Dispose();
|
||||
arrowHandleXLD.GenEmptyObj();
|
||||
|
||||
rrow1 = row1 + (row2 - row1) * 0.9;
|
||||
ccol1 = col1 + (col2 - col1) * 0.9;
|
||||
|
||||
length = HMisc.DistancePp(rrow1, ccol1, row2, col2);
|
||||
if (length == 0)
|
||||
length = -1;
|
||||
|
||||
dr = (row2 - rrow1) / length;
|
||||
dc = (col2 - ccol1) / length;
|
||||
|
||||
halfHW = headWidth / 2.0;
|
||||
rowP1 = rrow1 + (length - headLength) * dr + halfHW * dc;
|
||||
rowP2 = rrow1 + (length - headLength) * dr - halfHW * dc;
|
||||
colP1 = ccol1 + (length - headLength) * dc - halfHW * dr;
|
||||
colP2 = ccol1 + (length - headLength) * dc + halfHW * dr;
|
||||
|
||||
if (length == -1)
|
||||
HOperatorSet.GenContourPolygonXld(out arrowHandleXLD,rrow1, ccol1);
|
||||
else
|
||||
HOperatorSet.GenContourPolygonXld(out arrowHandleXLD, new HTuple(new double[] { rrow1, row2, rowP1, row2, rowP2, row2 }),
|
||||
new HTuple(new double[] { ccol1, col2, colP1, col2, colP2, col2 }));
|
||||
}
|
||||
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
255
ImageWindow/Model/ROIRectangle1.cs
Normal file
255
ImageWindow/Model/ROIRectangle1.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// This class demonstrates one of the possible implementations for a
|
||||
/// (simple) rectangularly shaped ROI. ROIRectangle1 inherits
|
||||
/// from the base class ROI and implements (besides other auxiliary
|
||||
/// methods) all virtual methods defined in ROI.cs.
|
||||
/// Since a simple rectangle is defined by two data points, by the upper
|
||||
/// left corner and the lower right corner, we use four values (row1/col1)
|
||||
/// and (row2/col2) as class members to hold these positions at
|
||||
/// any time of the program. The four corners of the rectangle can be taken
|
||||
/// as handles, which the user can use to manipulate the size of the ROI.
|
||||
/// Furthermore, we define a midpoint as an additional handle, with which
|
||||
/// the user can grab and drag the ROI. Therefore, we declare NumHandles
|
||||
/// to be 5 and set the activeHandle to be 0, which will be the upper left
|
||||
/// corner of our ROI.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ROIRectangle1 : ROI
|
||||
{
|
||||
[XmlElement(ElementName = "Row1")]
|
||||
public double Row1
|
||||
{
|
||||
get { return this.row1; }
|
||||
set { this.row1 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Column1")]
|
||||
public double Column1
|
||||
{
|
||||
get { return this.col1; }
|
||||
set { this.col1 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Row2")]
|
||||
public double Row2
|
||||
{
|
||||
get { return this.row2; }
|
||||
set { this.row2 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Column2")]
|
||||
public double Column2
|
||||
{
|
||||
get { return this.col2; }
|
||||
set { this.col2 = value; }
|
||||
}
|
||||
private string color = "yellow";
|
||||
|
||||
|
||||
private double row1, col1; // upper left
|
||||
private double row2, col2; // lower right
|
||||
private double midR, midC; // midpoint
|
||||
|
||||
|
||||
/// <summary>Constructor</summary>
|
||||
public ROIRectangle1()
|
||||
{
|
||||
NumHandles = 5; // 4 corner points + midpoint
|
||||
activeHandleIdx = 4;
|
||||
}
|
||||
|
||||
public ROIRectangle1(double row1, double col1, double row2, double col2)
|
||||
{
|
||||
createRectangle1(row1, col1, row2, col2);
|
||||
}
|
||||
|
||||
public override void createRectangle1(double row1, double col1, double row2, double col2)
|
||||
{
|
||||
base.createRectangle1(row1, col1, row2, col2);
|
||||
this.row1 = row1;
|
||||
this.col1 = col1;
|
||||
this.row2 = row2;
|
||||
this.col2 = col2;
|
||||
midR = (this.row1 + this.row2) / 2.0;
|
||||
midC = (this.col1 + this.col2) / 2.0;
|
||||
}
|
||||
/// <summary>Creates a new ROI instance at the mouse position</summary>
|
||||
/// <param name="midX">
|
||||
/// x (=column) coordinate for interactive ROI
|
||||
/// </param>
|
||||
/// <param name="midY">
|
||||
/// y (=row) coordinate for interactive ROI
|
||||
/// </param>
|
||||
public override void createROI(double midX, double midY)
|
||||
{
|
||||
midR = midY;
|
||||
midC = midX;
|
||||
|
||||
row1 = midR - 25;
|
||||
col1 = midC - 25;
|
||||
row2 = midR + 25;
|
||||
col2 = midC + 25;
|
||||
}
|
||||
|
||||
/// <summary>Paints the ROI into the supplied window</summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void draw(HalconDotNet.HWindow window)
|
||||
{
|
||||
window.DispRectangle1(row1, col1, row2, col2);
|
||||
|
||||
window.DispRectangle2(row1, col1, 0, 8,8);
|
||||
window.DispRectangle2(row1, col2, 0, 8,8);
|
||||
window.DispRectangle2(row2, col2, 0, 8,8);
|
||||
window.DispRectangle2(row2, col1, 0, 8,8);
|
||||
window.DispRectangle2(midR, midC, 0, 8,8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y)
|
||||
/// </summary>
|
||||
/// <param name="x">x (=column) coordinate</param>
|
||||
/// <param name="y">y (=row) coordinate</param>
|
||||
/// <returns>
|
||||
/// Distance of the closest ROI handle.
|
||||
/// </returns>
|
||||
public override double distToClosestHandle(double x, double y)
|
||||
{
|
||||
|
||||
double max = 10000;
|
||||
double [] val = new double[NumHandles];
|
||||
|
||||
midR = ((row2 - row1) / 2) + row1;
|
||||
midC = ((col2 - col1) / 2) + col1;
|
||||
|
||||
val[0] = HMisc.DistancePp(y, x, row1, col1); // upper left
|
||||
val[1] = HMisc.DistancePp(y, x, row1, col2); // upper right
|
||||
val[2] = HMisc.DistancePp(y, x, row2, col2); // lower right
|
||||
val[3] = HMisc.DistancePp(y, x, row2, col1); // lower left
|
||||
val[4] = HMisc.DistancePp(y, x, midR, midC); // midpoint
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
{
|
||||
if (val[i] < max)
|
||||
{
|
||||
max = val[i];
|
||||
activeHandleIdx = i;
|
||||
}
|
||||
}// end of for
|
||||
|
||||
return val[activeHandleIdx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window
|
||||
/// </summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void displayActive(HalconDotNet.HWindow window)
|
||||
{
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
window.DispRectangle2(row1, col1, 0, 8,8);
|
||||
break;
|
||||
case 1:
|
||||
window.DispRectangle2(row1, col2, 0, 8,8);
|
||||
break;
|
||||
case 2:
|
||||
window.DispRectangle2(row2, col2, 0, 8,8);
|
||||
break;
|
||||
case 3:
|
||||
window.DispRectangle2(row2, col1, 0, 8,8);
|
||||
break;
|
||||
case 4:
|
||||
window.DispRectangle2(midR, midC, 0, 8,8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI</summary>
|
||||
public override HRegion getRegion()
|
||||
{
|
||||
HRegion region = new HRegion();
|
||||
region.GenRectangle1(row1, col1, row2, col2);
|
||||
return region;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model information described by
|
||||
/// the interactive ROI
|
||||
/// </summary>
|
||||
public override HTuple getModelData()
|
||||
{
|
||||
return new HTuple(new double[] { row1, col1, row2, col2 });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI instance. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y)
|
||||
/// </summary>
|
||||
/// <param name="newX">x mouse coordinate</param>
|
||||
/// <param name="newY">y mouse coordinate</param>
|
||||
public override void moveByHandle(double newX, double newY)
|
||||
{
|
||||
double len1, len2;
|
||||
double tmp;
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0: // upper left
|
||||
row1 = newY;
|
||||
col1 = newX;
|
||||
break;
|
||||
case 1: // upper right
|
||||
row1 = newY;
|
||||
col2 = newX;
|
||||
break;
|
||||
case 2: // lower right
|
||||
row2 = newY;
|
||||
col2 = newX;
|
||||
break;
|
||||
case 3: // lower left
|
||||
row2 = newY;
|
||||
col1 = newX;
|
||||
break;
|
||||
case 4: // midpoint
|
||||
len1 = ((row2 - row1) / 2);
|
||||
len2 = ((col2 - col1) / 2);
|
||||
|
||||
row1 = newY - len1;
|
||||
row2 = newY + len1;
|
||||
|
||||
col1 = newX - len2;
|
||||
col2 = newX + len2;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (row2 <= row1)
|
||||
{
|
||||
tmp = row1;
|
||||
row1 = row2;
|
||||
row2 = tmp;
|
||||
}
|
||||
|
||||
if (col2 <= col1)
|
||||
{
|
||||
tmp = col1;
|
||||
col1 = col2;
|
||||
col2 = tmp;
|
||||
}
|
||||
|
||||
midR = ((row2 - row1) / 2) + row1;
|
||||
midC = ((col2 - col1) / 2) + col1;
|
||||
|
||||
}//end of method
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
310
ImageWindow/Model/ROIRectangle2.cs
Normal file
310
ImageWindow/Model/ROIRectangle2.cs
Normal file
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using HalconDotNet;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class demonstrates one of the possible implementations for a
|
||||
/// (simple) rectangularly shaped ROI. To create this rectangle we use
|
||||
/// a center point (midR, midC), an orientation 'phi' and the half
|
||||
/// edge lengths 'length1' and 'length2', similar to the HALCON
|
||||
/// operator gen_rectangle2().
|
||||
/// The class ROIRectangle2 inherits from the base class ROI and
|
||||
/// implements (besides other auxiliary methods) all virtual methods
|
||||
/// defined in ROI.cs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ROIRectangle2 : ROI
|
||||
{
|
||||
|
||||
[XmlElement(ElementName = "Row")]
|
||||
public double Row
|
||||
{
|
||||
get { return this.midR; }
|
||||
set { this.midR = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Column")]
|
||||
public double Column
|
||||
{
|
||||
get { return this.midC; }
|
||||
set { this.midC = value; }
|
||||
}
|
||||
[XmlElement(ElementName = "Phi")]
|
||||
public double Phi
|
||||
{
|
||||
get { return this.phi; }
|
||||
set { this.phi = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Length1")]
|
||||
public double Lenth1
|
||||
{
|
||||
get { return this.length1; }
|
||||
set { this.length1 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Length2")]
|
||||
public double Lenth2
|
||||
{
|
||||
get { return this.length2; }
|
||||
set { this.length2 = value; }
|
||||
}
|
||||
/// <summary>Half length of the rectangle side, perpendicular to phi</summary>
|
||||
private double length1;
|
||||
|
||||
/// <summary>Half length of the rectangle side, in direction of phi</summary>
|
||||
private double length2;
|
||||
|
||||
/// <summary>Row coordinate of midpoint of the rectangle</summary>
|
||||
private double midR;
|
||||
|
||||
/// <summary>Column coordinate of midpoint of the rectangle</summary>
|
||||
private double midC;
|
||||
|
||||
/// <summary>Orientation of rectangle defined in radians.</summary>
|
||||
private double phi;
|
||||
|
||||
|
||||
//auxiliary variables
|
||||
HTuple rowsInit;
|
||||
HTuple colsInit;
|
||||
HTuple rows;
|
||||
HTuple cols;
|
||||
|
||||
HHomMat2D hom2D, tmp;
|
||||
|
||||
/// <summary>Constructor</summary>
|
||||
public ROIRectangle2()
|
||||
{
|
||||
NumHandles = 6; // 4 corners + 1 midpoint + 1 rotationpoint
|
||||
activeHandleIdx = 4;
|
||||
}
|
||||
|
||||
public ROIRectangle2(double row, double col, double phi, double length1, double length2)
|
||||
{
|
||||
createRectangle2(row, col, phi, length1, length2);
|
||||
}
|
||||
|
||||
public override void createRectangle2(double row, double col, double phi, double length1, double length2)
|
||||
{
|
||||
base.createRectangle2(row, col, phi, length1, length2);
|
||||
this.midR = row;
|
||||
this.midC = col;
|
||||
this.length1 = length1;
|
||||
this.length2 = length2;
|
||||
this.phi = phi;
|
||||
|
||||
rowsInit = new HTuple(new double[] {-1.0, -1.0, 1.0,
|
||||
1.0, 0.0, 0.0 });
|
||||
colsInit = new HTuple(new double[] {-1.0, 1.0, 1.0,
|
||||
-1.0, 0.0, 0.6 });
|
||||
//order ul , ur, lr, ll, mp, arrowMidpoint
|
||||
hom2D = new HHomMat2D();
|
||||
tmp = new HHomMat2D();
|
||||
|
||||
updateHandlePos();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new ROI instance at the mouse position</summary>
|
||||
/// <param name="midX">
|
||||
/// x (=column) coordinate for interactive ROI
|
||||
/// </param>
|
||||
/// <param name="midY">
|
||||
/// y (=row) coordinate for interactive ROI
|
||||
/// </param>
|
||||
public override void createROI(double midX, double midY)
|
||||
{
|
||||
midR = midY;
|
||||
midC = midX;
|
||||
|
||||
length1 = 100;
|
||||
length2 = 50;
|
||||
|
||||
phi = 0.0;
|
||||
|
||||
rowsInit = new HTuple(new double[] {-1.0, -1.0, 1.0,
|
||||
1.0, 0.0, 0.0 });
|
||||
colsInit = new HTuple(new double[] {-1.0, 1.0, 1.0,
|
||||
-1.0, 0.0, 0.6 });
|
||||
//order ul , ur, lr, ll, mp, arrowMidpoint
|
||||
hom2D = new HHomMat2D();
|
||||
tmp = new HHomMat2D();
|
||||
|
||||
updateHandlePos();
|
||||
}
|
||||
|
||||
/// <summary>Paints the ROI into the supplied window</summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void draw(HalconDotNet.HWindow window)
|
||||
{
|
||||
window.DispRectangle2(midR, midC, -phi, length1, length2);
|
||||
for (int i =0; i < NumHandles; i++)
|
||||
window.DispRectangle2(rows[i].D, cols[i].D, -phi, 8,8);
|
||||
|
||||
window.DispArrow(midR, midC, midR + (Math.Sin(phi) * length1 * 1.2),
|
||||
midC + (Math.Cos(phi) * length1 * 1.2), 5.0);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance of the ROI handle being
|
||||
/// closest to the image point(x,y)
|
||||
/// </summary>
|
||||
/// <param name="x">x (=column) coordinate</param>
|
||||
/// <param name="y">y (=row) coordinate</param>
|
||||
/// <returns>
|
||||
/// Distance of the closest ROI handle.
|
||||
/// </returns>
|
||||
public override double distToClosestHandle(double x, double y)
|
||||
{
|
||||
double max = 10000;
|
||||
double [] val = new double[NumHandles];
|
||||
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
val[i] = HMisc.DistancePp(y, x, rows[i].D, cols[i].D);
|
||||
|
||||
for (int i=0; i < NumHandles; i++)
|
||||
{
|
||||
if (val[i] < max)
|
||||
{
|
||||
max = val[i];
|
||||
activeHandleIdx = i;
|
||||
}
|
||||
}
|
||||
return val[activeHandleIdx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paints the active handle of the ROI object into the supplied window
|
||||
/// </summary>
|
||||
/// <param name="window">HALCON window</param>
|
||||
public override void displayActive(HalconDotNet.HWindow window)
|
||||
{
|
||||
window.DispRectangle2(rows[activeHandleIdx].D,
|
||||
cols[activeHandleIdx].D,
|
||||
-phi, 8,8);
|
||||
|
||||
if (activeHandleIdx == 5)
|
||||
window.DispArrow(midR, midC,
|
||||
midR + (Math.Sin(phi) * length1 * 1.2),
|
||||
midC + (Math.Cos(phi) * length1 * 1.2),
|
||||
5.0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the HALCON region described by the ROI</summary>
|
||||
public override HRegion getRegion()
|
||||
{
|
||||
HRegion region = new HRegion();
|
||||
region.GenRectangle2(midR, midC, -phi, length1, length2);
|
||||
return region;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model information described by
|
||||
/// the interactive ROI
|
||||
/// </summary>
|
||||
public override HTuple getModelData()
|
||||
{
|
||||
return new HTuple(new double[] { midR, midC, phi, length1, length2 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculates the shape of the ROI instance. Translation is
|
||||
/// performed at the active handle of the ROI object
|
||||
/// for the image coordinate (x,y)
|
||||
/// </summary>
|
||||
/// <param name="newX">x mouse coordinate</param>
|
||||
/// <param name="newY">y mouse coordinate</param>
|
||||
public override void moveByHandle(double newX, double newY)
|
||||
{
|
||||
double vX, vY, x=0, y=0;
|
||||
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
tmp = hom2D.HomMat2dInvert();
|
||||
x = tmp.AffineTransPoint2d(newX, newY, out y);
|
||||
|
||||
length2 = Math.Abs(y);
|
||||
length1 = Math.Abs(x);
|
||||
|
||||
checkForRange(x, y);
|
||||
break;
|
||||
case 4:
|
||||
midC = newX;
|
||||
midR = newY;
|
||||
break;
|
||||
case 5:
|
||||
vY = newY - rows[4].D;
|
||||
vX = newX - cols[4].D;
|
||||
phi = Math.Atan2(vY, vX);
|
||||
break;
|
||||
}
|
||||
updateHandlePos();
|
||||
}//end of method
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Auxiliary method to recalculate the contour points of
|
||||
/// the rectangle by transforming the initial row and
|
||||
/// column coordinates (rowsInit, colsInit) by the updated
|
||||
/// homography hom2D
|
||||
/// </summary>
|
||||
private void updateHandlePos()
|
||||
{
|
||||
hom2D.HomMat2dIdentity();
|
||||
hom2D = hom2D.HomMat2dTranslate(midC, midR);
|
||||
hom2D = hom2D.HomMat2dRotateLocal(phi);
|
||||
tmp = hom2D.HomMat2dScaleLocal(length1, length2);
|
||||
cols = tmp.AffineTransPoint2d(colsInit, rowsInit, out rows);
|
||||
}
|
||||
|
||||
|
||||
/* This auxiliary method checks the half lengths
|
||||
* (length1, length2) using the coordinates (x,y) of the four
|
||||
* rectangle corners (handles 0 to 3) to avoid 'bending' of
|
||||
* the rectangular ROI at its midpoint, when it comes to a
|
||||
* 'collapse' of the rectangle for length1=length2=0.
|
||||
* */
|
||||
private void checkForRange(double x, double y)
|
||||
{
|
||||
switch (activeHandleIdx)
|
||||
{
|
||||
case 0:
|
||||
if ((x < 0) && (y < 0))
|
||||
return;
|
||||
if (x >= 0) length1 = 0.01;
|
||||
if (y >= 0) length2 = 0.01;
|
||||
break;
|
||||
case 1:
|
||||
if ((x > 0) && (y < 0))
|
||||
return;
|
||||
if (x <= 0) length1 = 0.01;
|
||||
if (y >= 0) length2 = 0.01;
|
||||
break;
|
||||
case 2:
|
||||
if ((x > 0) && (y > 0))
|
||||
return;
|
||||
if (x <= 0) length1 = 0.01;
|
||||
if (y <= 0) length2 = 0.01;
|
||||
break;
|
||||
case 3:
|
||||
if ((x < 0) && (y > 0))
|
||||
return;
|
||||
if (x >= 0) length1 = 0.01;
|
||||
if (y <= 0) length2 = 0.01;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}//end of class
|
||||
}//end of namespace
|
||||
146
ImageWindow/Model/RoiData.cs
Normal file
146
ImageWindow/Model/RoiData.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using HalconDotNet;
|
||||
|
||||
namespace ViewWindow.Model
|
||||
{
|
||||
public class RoiData
|
||||
{
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Config.Rectangle1 _rectangle1;
|
||||
private Config.Rectangle2 _rectangle2;
|
||||
private Config.Circle _circle;
|
||||
private Config.Line _line;
|
||||
|
||||
[XmlElement(ElementName = "ID")]
|
||||
public int ID
|
||||
{
|
||||
get { return this._id; }
|
||||
set { this._id = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Name")]
|
||||
public string Name
|
||||
{
|
||||
get { return this._name; }
|
||||
set { this._name = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Rectangle1")]
|
||||
public Config.Rectangle1 Rectangle1
|
||||
{
|
||||
get { return this._rectangle1; }
|
||||
set { this._rectangle1 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Rectangle2")]
|
||||
public Config.Rectangle2 Rectangle2
|
||||
{
|
||||
get { return this._rectangle2; }
|
||||
set { this._rectangle2 = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Circle")]
|
||||
public Config.Circle Circle
|
||||
{
|
||||
get { return this._circle; }
|
||||
set { this._circle = value; }
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "Line")]
|
||||
public Config.Line Line
|
||||
{
|
||||
get { return this._line; }
|
||||
set { this._line = value; }
|
||||
}
|
||||
|
||||
|
||||
protected internal RoiData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected internal RoiData(int id, ROI roi)
|
||||
{
|
||||
this._id = id;
|
||||
HTuple m_roiData = null;
|
||||
|
||||
m_roiData = roi.getModelData();
|
||||
|
||||
switch (roi.Type)
|
||||
{
|
||||
case "ROIRectangle1":
|
||||
this._name = "Rectangle1";
|
||||
|
||||
if (m_roiData != null)
|
||||
{
|
||||
this._rectangle1 = new Config.Rectangle1(m_roiData[0].D, m_roiData[1].D, m_roiData[2].D, m_roiData[3].D);
|
||||
this._rectangle1.Color = roi.Color;
|
||||
}
|
||||
break;
|
||||
case "ROIRectangle2":
|
||||
this._name = "Rectangle2";
|
||||
|
||||
if (m_roiData != null)
|
||||
{
|
||||
this._rectangle2 = new Config.Rectangle2(m_roiData[0].D, m_roiData[1].D, m_roiData[2].D, m_roiData[3].D, m_roiData[4].D);
|
||||
this._rectangle2.Color = roi.Color;
|
||||
}
|
||||
break;
|
||||
case "ROICircle":
|
||||
this._name = "Circle";
|
||||
|
||||
if (m_roiData != null)
|
||||
{
|
||||
this._circle = new Config.Circle(m_roiData[0].D, m_roiData[1].D, m_roiData[2].D);
|
||||
this._circle.Color = roi.Color;
|
||||
}
|
||||
break;
|
||||
case "ROILine":
|
||||
this._name = "Line";
|
||||
|
||||
if (m_roiData != null)
|
||||
{
|
||||
this._line = new Config.Line(m_roiData[0].D, m_roiData[1].D, m_roiData[2].D, m_roiData[3].D);
|
||||
this._line.Color = roi.Color;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal RoiData(int id, Config.Rectangle1 rectangle1)
|
||||
{
|
||||
this._id = id;
|
||||
this._name = "Rectangle1";
|
||||
this._rectangle1 = rectangle1;
|
||||
}
|
||||
|
||||
protected internal RoiData(int id, Config.Rectangle2 rectangle2)
|
||||
{
|
||||
this._id = id;
|
||||
this._name = "Rectangle2";
|
||||
this._rectangle2 = rectangle2;
|
||||
}
|
||||
|
||||
protected internal RoiData(int id, Config.Circle circle)
|
||||
{
|
||||
this._id = id;
|
||||
this._name = "Circle";
|
||||
this._circle = circle;
|
||||
}
|
||||
|
||||
protected internal RoiData(int id, Config.Line line)
|
||||
{
|
||||
this._id = id;
|
||||
this._name = "Line";
|
||||
this._line = line;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user