/// <summary>
        /// Creates a measure object based on the model data
        /// defined by the ROI instance and the parameters
        /// describing the measure context.
        /// </summary>
        protected void UpdateMeasure()
        {
            double extent, sPhi, radius;

            if (mHandle != null)
            {
                mHandle.Dispose();
            }

            mMeasAssist.exceptionText = "";

            try
            {
                switch (mROIType)
                {
                case ROI.ROI_TYPE_CIRCLEARC:

                    radius = mROICoord[2].D;
                    sPhi   = mROICoord[3].D;
                    extent = mROICoord[4].D;


                    mMeasROI = GenSurCircle(mROICoord, mMeasAssist.mRoiWidth);
                    mHandle  = new HMeasure(mROICoord[0].D, mROICoord[1].D, radius,
                                            sPhi, extent,
                                            mMeasAssist.mRoiWidth,
                                            mMeasAssist.mWidth, mMeasAssist.mHeight,
                                            mMeasAssist.mInterpolation);

                    break;

                case ROI.ROI_TYPE_CIRCLE:
                    //記錄 ROI 範圍
                    mMeasROI = GenSurCircle2(mROICoord, mMeasAssist.mRoiWidth);

                    break;

                case ROI.ROI_TYPE_LINE:
                case ROI.ROI_TYPE_POINT:


                    mMeasROI = GenSurRect2(mROICoord, mROICoord[4]);
                    mHandle  = new HMeasure(mMeasROI[0].D, mMeasROI[1].D,
                                            mMeasROI[2].D, mMeasROI[3].D, mMeasROI[4].D,
                                            mMeasAssist.mWidth, mMeasAssist.mHeight,
                                            mMeasAssist.mInterpolation);
                    break;
                }
            }
            catch (HOperatorException e)
            {
                mEdgeXLD.Dispose();
                mMeasureRegion.Dispose();
                mMeasAssist.exceptionText = e.Message;
                ClearResultData();
                return;
            }
            UpdateResults();
            UpdateMeasureRegion();
        }
Exemplo n.º 2
0
        public void FindLine(HImage image, double Row, double Column, double Phi, double Length1, double Length2, ushort pointNum, ushort EdgeWidth, ushort EdgeThresold, EdgePolarEnum edgePolar, EdgeTypeEnum edgeType, out PointF firstPoint, out PointF endPoint, out double angle, out HXLDCont[] cross, out HXLDCont line)
        {
            double[] row          = new double[pointNum];
            double[] column       = new double[pointNum];
            HTuple   _rowEdges    = new HTuple();
            HTuple   _columnEdges = new HTuple();

            image.GetImageSize(out int width, out int height);
            for (int i = 0; i <= (pointNum - 1) / 2; i++)//遍历搜索点数的一半
            {
                row[i]                   = Row - (Length2 - 2.0 * Length2 * (i + 1) / (pointNum + 1)) * Math.Cos(Phi);
                column[i]                = Column - (Length2 - 2.0 * Length2 * (i + 1) / (pointNum + 1)) * Math.Sin(Phi);
                row[pointNum - 1 - i]    = 2 * Row - row[i];
                column[pointNum - 1 - i] = 2 * Column - column[i];
            }
            for (int i = 0; i < pointNum - 1; i++)
            {
                HMeasure measure = new HMeasure(row[i], column[i], Phi, Length1, EdgeWidth, width, height, "nearest_neighbor");                                                              //获得测量矩形
                measure.MeasurePos(image, 1, EdgeThresold, edgePolar.ToString(), edgeType.ToString(), out HTuple rowEdge, out HTuple columnEdge, out HTuple Amplitude, out HTuple distance); //提取垂直于矩形或环形弧的直边
                if (rowEdge.Length > 0 && columnEdge.Length > 0)
                {
                    _rowEdges    = _rowEdges.TupleConcat(rowEdge);
                    _columnEdges = _columnEdges.TupleConcat(columnEdge);
                }
            }
            if (_rowEdges.Length > 5)
            {
                HXLDCont Contour = new HXLDCont(_rowEdges, _columnEdges);
                Contour.SmoothContoursXld(5);
                Contour.FitLineContourXld("tukey", -1, 0, 5, 2, out double rowBegin, out double columnBegin, out double rowEnd, out double columnEnd, out double nr, out double nc, out double dist);
                Contour.GenContourPolygonXld(new HTuple(rowBegin, rowEnd), new HTuple(columnBegin, columnEnd));
                cross = new HXLDCont[_rowEdges.Length];
                for (int i = 0; i < _rowEdges.Length; i++)
                {
                    HXLDCont _cross = new HXLDCont();
                    _cross.GenCrossContourXld(_rowEdges[i], _columnEdges[i], 30d, 0);
                    cross[i] = _cross;
                }
                firstPoint = new PointF((float)columnBegin, (float)rowBegin);
                endPoint   = new PointF((float)columnEnd, (float)rowEnd);
                angle      = HMisc.AngleLx(rowBegin, columnBegin, rowEnd, columnEnd) * 180 / Math.PI;
                line       = Contour;
            }
            else
            {
                firstPoint = new PointF(0, 0);
                endPoint   = new PointF(0, 0);
                cross      = null;
                line       = null;
                angle      = 0;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// The client MUST be connected to access to this service.
        /// Allow a hubapp client to create a hMessage with a hMeasure payload.
        /// </summary>
        /// <param name="actor"></param>
        /// <param name="value"></param>
        /// <param name="unit"></param>
        /// <param name="mOptions"></param>
        /// <returns></returns>
        public HMessage BuildMeasure(string actor, string value, string unit, HMessageOptions mOptions)
        {
            if (actor == null || actor.Length <= 0)
            {
                throw new MissingAttrException("actor");
            }
            if (value == null || value.Length <= 0)
            {
                throw new MissingAttrException("value");
            }
            if (unit == null || unit.Length <= 0)
            {
                throw new MissingAttrException("unit");
            }

            HMeasure hmeasure = new HMeasure();

            hmeasure.SetUnit(unit);
            hmeasure.SetValue(value);

            HMessage message = BuildMessage(actor, "hMeasure", hmeasure, mOptions);

            return(message);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Creates a measure object based on the model data
        /// defined by the ROI instance and the parameters
        /// describing the measure context.
        /// </summary>
        protected void UpdateMeasure()
        {
            double extent, sPhi, radius;

            if (mHandle != null)
                mHandle.Dispose();

            mMeasAssist.exceptionText = "";

            try
            {
                switch (mROIType)
                {
                    case ROI.ROI_TYPE_CIRCLEARC:

                        radius = mROICoord[2].D;
                        sPhi = mROICoord[3].D;
                        extent = mROICoord[4].D;

                        mMeasROI = GenSurCircle(mROICoord, mMeasAssist.mRoiWidth);
                        mHandle = new HMeasure(mROICoord[0].D, mROICoord[1].D, radius,
                                                sPhi, extent,
                                                mMeasAssist.mRoiWidth,
                                                mMeasAssist.mWidth, mMeasAssist.mHeight,
                                                mMeasAssist.mInterpolation);

                        break;
                    case ROI.ROI_TYPE_LINE:

                        mMeasROI = GenSurRect2(mROICoord, mMeasAssist.mRoiWidth);
                        mHandle = new HMeasure(mMeasROI[0].D, mMeasROI[1].D,
                                               mMeasROI[2].D, mMeasROI[3].D, mMeasROI[4].D,
                                               mMeasAssist.mWidth, mMeasAssist.mHeight,
                                               mMeasAssist.mInterpolation);
                        break;
                }
            }
            catch (HOperatorException e)
            {
                mEdgeXLD.Dispose();
                mMeasureRegion.Dispose();
                mMeasAssist.exceptionText = e.Message;
                ClearResultData();
                return;
            }
            UpdateResults();
            UpdateMeasureRegion();
        }
Exemplo n.º 5
0
        private void Action()
        {
            double    S1, S2;
            HTuple    RowCheck, ColumnCheck, AngleCheck, Score;
            HHomMat2D Matrix = new HHomMat2D();
            HRegion   ModelRegionTrans;
            HTuple    Rect1RowCheck, Rect1ColCheck;
            HTuple    Rect2RowCheck, Rect2ColCheck;
            HRegion   Rectangle1 = new HRegion();
            HRegion   Rectangle2 = new HRegion();
            HMeasure  Measure1, Measure2;
            HTuple    RowEdgeFirst1, ColumnEdgeFirst1;
            HTuple    AmplitudeFirst1, RowEdgeSecond1;
            HTuple    ColumnEdgeSecond1, AmplitudeSecond1;
            HTuple    IntraDistance1, InterDistance1;
            HTuple    RowEdgeFirst2, ColumnEdgeFirst2;
            HTuple    AmplitudeFirst2, RowEdgeSecond2;
            HTuple    ColumnEdgeSecond2, AmplitudeSecond2;
            HTuple    IntraDistance2, InterDistance2;
            HTuple    MinDistance;
            int       NumLeads;

            HSystem.SetSystem("flush_graphic", "false");
            Img.GrabImage(Framegrabber);
            Img.DispObj(Window);

            // Find the IC in the current image.
            S1 = HSystem.CountSeconds();
            ShapeModel.FindShapeModel(Img, 0,
                                      new HTuple(360).TupleRad().D,
                                      0.7, 1, 0.5, "least_squares",
                                      4, 0.9, out RowCheck, out ColumnCheck,
                                      out AngleCheck, out Score);
            S2 = HSystem.CountSeconds();
            MatchingTimeLabel.Text = "Time: " +
                                     String.Format("{0,4:F1}", (S2 - S1) * 1000) + "ms";
            MatchingScoreLabel.Text = "Score: ";

            if (RowCheck.Length == 1)
            {
                MatchingScoreLabel.Text = "Score: " +
                                          String.Format("{0:F5}", Score.D);
                // Rotate the model for visualization purposes.
                Matrix.VectorAngleToRigid(new HTuple(Row), new HTuple(Column), new HTuple(0.0),
                                          RowCheck, ColumnCheck, AngleCheck);

                ModelRegionTrans = ModelRegion.AffineTransRegion(Matrix, "false");
                Window.SetColor("green");
                Window.SetDraw("fill");
                ModelRegionTrans.DispObj(Window);
                // Compute the parameters of the measurement rectangles.
                Matrix.AffineTransPixel(Rect1Row, Rect1Col,
                                        out Rect1RowCheck, out Rect1ColCheck);
                Matrix.AffineTransPixel(Rect2Row, Rect2Col,
                                        out Rect2RowCheck, out Rect2ColCheck);

                // For visualization purposes, generate the two rectangles as
                // regions and display them.
                Rectangle1.GenRectangle2(Rect1RowCheck.D, Rect1ColCheck.D,
                                         RectPhi + AngleCheck.D,
                                         RectLength1, RectLength2);
                Rectangle2.GenRectangle2(Rect2RowCheck.D, Rect2ColCheck.D,
                                         RectPhi + AngleCheck.D,
                                         RectLength1, RectLength2);
                Window.SetColor("blue");
                Window.SetDraw("margin");
                Rectangle1.DispObj(Window);
                Rectangle2.DispObj(Window);
                // Do the actual measurements.
                S1       = HSystem.CountSeconds();
                Measure1 = new HMeasure(Rect1RowCheck.D, Rect1ColCheck.D,
                                        RectPhi + AngleCheck.D,
                                        RectLength1, RectLength2,
                                        ImgWidth, ImgHeight, "bilinear");
                Measure2 = new HMeasure(Rect2RowCheck.D, Rect2ColCheck.D,
                                        RectPhi + AngleCheck.D,
                                        RectLength1, RectLength2,
                                        ImgWidth, ImgHeight, "bilinear");
                Measure1.MeasurePairs(Img, 2, 90,
                                      "positive", "all",
                                      out RowEdgeFirst1,
                                      out ColumnEdgeFirst1,
                                      out AmplitudeFirst1,
                                      out RowEdgeSecond1,
                                      out ColumnEdgeSecond1,
                                      out AmplitudeSecond1,
                                      out IntraDistance1,
                                      out InterDistance1);
                Measure2.MeasurePairs(Img, 2, 90,
                                      "positive", "all",
                                      out RowEdgeFirst2,
                                      out ColumnEdgeFirst2,
                                      out AmplitudeFirst2,
                                      out RowEdgeSecond2,
                                      out ColumnEdgeSecond2,
                                      out AmplitudeSecond2,
                                      out IntraDistance2,
                                      out InterDistance2);
                S2 = HSystem.CountSeconds();
                MeasureTimeLabel.Text = "Time: " +
                                        String.Format("{0,5:F1}", (S2 - S1) * 1000) + "ms";
                Window.SetColor("red");
                Window.DispLine(RowEdgeFirst1 - RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeFirst1 - RectLength2 * Math.Sin(AngleCheck),
                                RowEdgeFirst1 + RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeFirst1 + RectLength2 * Math.Sin(AngleCheck));
                Window.DispLine(RowEdgeSecond1 - RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeSecond1 - RectLength2 * Math.Sin(AngleCheck),
                                RowEdgeSecond1 + RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeSecond1 + RectLength2 * Math.Sin(AngleCheck));
                Window.DispLine(RowEdgeFirst2 - RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeFirst2 - RectLength2 * Math.Sin(AngleCheck),
                                RowEdgeFirst2 + RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeFirst2 + RectLength2 * Math.Sin(AngleCheck));
                Window.DispLine(RowEdgeSecond2 - RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeSecond2 - RectLength2 * Math.Sin(AngleCheck),
                                RowEdgeSecond2 + RectLength2 * Math.Cos(AngleCheck),
                                ColumnEdgeSecond2 + RectLength2 * Math.Sin(AngleCheck));
                NumLeads             = IntraDistance1.Length + IntraDistance2.Length;
                MeasureNumLabel.Text = "Number of leads: " +
                                       String.Format("{0:D2}", NumLeads);
                MinDistance           = InterDistance1.TupleConcat(InterDistance2).TupleMin();
                MeasureDistLabel.Text = "Minimum lead distance: " +
                                        String.Format("{0:F3}", MinDistance.D);
                HSystem.SetSystem("flush_graphic", "true");
                // Force the graphics window update by displaying an offscreen pixel
                Window.DispLine(-1.0, -1.0, -1.0, -1.0);
            }
        }
Exemplo n.º 6
0
 public HMessage BuildMessage(string actor, string type, HMeasure payload, HMessageOptions mOptions)
 {
     return(InnerBuildMessage(actor, type, payload, mOptions));
 }
Exemplo n.º 7
0
        /// <summary>
        /// 演算法改這裡
        /// </summary>
        public override void UpdateResults()
        {
            if (mHandle == null)
                return;

            mMeasAssist.exceptionText = "";

            try
            {
                HObject imageReduced;
                HOperatorSet.GenEmptyObj(out imageReduced);
                //建 ROI
                var roiModel = mRoi.getModelData();
                HTuple row = roiModel[0];
                var column = roiModel[1];
                var phi = roiModel[2];
                var length1 = roiModel[3];
                var length2 = roiModel[4];
                //Halcon 徑度轉角度
                double degree = phi.D.HalconPhiToDegree();

                bool terminate = false;
                double degreeSeed, finalDegree;
                degreeSeed = finalDegree = degree;

                //reset result
                mResult = new EdgeResult();
                //旋轉角度, Search Point
                while (!HasResult)
                {
                    var region = getRectangle2(row, column, degreeSeed, length1, length2);
                    var regionImage = getRegionImage(region);
                    //Reset Handle and mResult
                    mHandle = new HMeasure(mMeasROI[0].D, mMeasROI[1].D,
                                               degreeSeed.ToHalconPhi(), mMeasROI[3].D, mMeasROI[4].D,
                                               mMeasAssist.mWidth, mMeasAssist.mHeight,
                                               mMeasAssist.mInterpolation);
                    measurePos(regionImage);
                    finalDegree = degreeSeed;
                    degreeSeed = getNextSeed(degreeSeed, phi.D, ref terminate);
                    if (terminate) break;
                }
                mResultWorld = new EdgeResult(mResult);

                //Update Model
                var updateableROI = mRoi as ViewROI.Interface.IROIModelUpdateable;
                if (updateableROI != null)
                {
                    mMeasROI[2].D = finalDegree.ToHalconPhi();
                    var updateROIModel = new ROIViewModel()
                    {
                        CenterRow = row.D,
                        CenterCol = column.D,
                        Phi = finalDegree.ToHalconPhi(),
                        Length = length1.D,
                        Width = length2.D,
                    };
                    updateableROI.UpdateROIModel(updateROIModel);
                }

            }
            catch (HOperatorException e)
            {
                mEdgeXLD.Dispose();
                mMeasAssist.exceptionText = e.Message;
                mResultWorld = new EdgeResult();
                return;
            }
            UpdateXLD();
        }
Exemplo n.º 8
0
        private double FindPositionBottle(HImage Image, DataType.AlgoritmoControlloLivelloParam param, bool useIconic, ref ArrayList iconicList)
        {
            double columnCenter = 0;

            HMeasure MeasureHandle = null;
            HImage   ImgEmfatize   = null;

            try
            {
                double Rowstart, Rowend, Colstart, Colend;
                int    Width, Height;
                Image.GetImageSize(out Width, out Height);

                Rowstart = 0.0;
                Rowend   = Height;
                Colstart = Width / 2;
                Colend   = Width / 2;

                if (useIconic)
                {
                    iconicList.Add(new Utilities.ObjectToDisplay("Line", new HTuple(Rowstart, Colstart, Rowend, Colend), "red", 1));
                }

                param.RectCentraggio.Column = Width / 2;

                if (useIconic)
                {
                    // genero i due rettangoli per la misura dell'inclinazione bottiglia
                    // solo per visualizzazione
                    HRegion rectangleCentraggio = new HRegion();
                    rectangleCentraggio.GenRectangle2(param.RectCentraggio.Row, Width / 2, 0, param.RectCentraggio.Length1, param.RectCentraggio.Length2);
                    iconicList.Add(new Utilities.ObjectToDisplay(rectangleCentraggio, "red", 1));
                }

                // Determine all edge pairs that have a negative transition, i.e., edge pairs that enclose dark regions.
                const string Interpolation = "nearest_neighbor";
                HTuple       RowEdge_first, ColumnEdge_first, Amplitude_first, Distance_first;
                HTuple       RowEdge_last, ColumnEdge_last, Amplitude_last, Distance_last;

                ImgEmfatize = Image.Emphasize(7, 7, param.EmphasizeFactorx10 / 10.0);

                // Misura degli edge sul primo rettangolo
                MeasureHandle = new HMeasure(param.RectCentraggio.Row, Width / 2, 0, param.RectCentraggio.Length1, param.RectCentraggio.Length2, Width, Height, Interpolation);
                MeasureHandle.MeasurePos(ImgEmfatize, param.Sigmax10 / 10.0, param.Thresholdx10 / 10.0, "all", "first", out RowEdge_first, out ColumnEdge_first, out Amplitude_first, out Distance_first);
                MeasureHandle.Dispose();        // Libera lo spazio associato a 'MeasureHandle'

                MeasureHandle = new HMeasure(param.RectCentraggio.Row, Width / 2, Math.PI, param.RectCentraggio.Length1, param.RectCentraggio.Length2, Width, Height, Interpolation);
                MeasureHandle.MeasurePos(ImgEmfatize, param.Sigmax10 / 10.0, param.Thresholdx10 / 10.0, "all", "first", out RowEdge_last, out ColumnEdge_last, out Amplitude_last, out Distance_last);
                MeasureHandle.Dispose();        // Libera lo spazio associato a 'MeasureHandle'

                if (RowEdge_first.Length == 1 && RowEdge_last.Length == 1 && ColumnEdge_first.Length == 1 && ColumnEdge_last.Length == 1)
                {
                    columnCenter = (ColumnEdge_last.D + ColumnEdge_first.D) / 2;

                    if (useIconic)
                    {
                        iconicList.Add(new Utilities.ObjectToDisplay("Cross", new HTuple(RowEdge_first.D, ColumnEdge_first.D, 15, Math.PI / 4), "magenta", 1));
                        iconicList.Add(new Utilities.ObjectToDisplay("Cross", new HTuple(RowEdge_last.D, ColumnEdge_last.D, 15, Math.PI / 4), "magenta", 1));
                        iconicList.Add(new Utilities.ObjectToDisplay("Cross", new HTuple(RowEdge_last.D, columnCenter, 15, Math.PI / 4), "green", 1));
                    }
                }
                else
                {
                    columnCenter = Width / 2;
                }
            }
            catch (Exception)
            {
                columnCenter = 0;
            }
            finally
            {
                if (MeasureHandle != null)
                {
                    MeasureHandle.Dispose();
                }
                if (ImgEmfatize != null)
                {
                    ImgEmfatize.Dispose();
                }
            }

            return(columnCenter);
        }
Exemplo n.º 9
0
        private bool AnalisiLivello(HImage Img, DataType.AlgoritmoControlloLivelloParam param, double centerColumn, bool regolazioni, out bool errorLevelMin, out bool errorLevelMax, out bool errorEmpty, ref ArrayList iconicList)
        {
            bool ret = false;


            errorLevelMin = false;
            errorLevelMax = false;
            errorEmpty    = false;


            int Width, Height;

            Img.GetImageSize(out Width, out Height);

            const string Interpolation = "nearest_neighbor";
            string       Transition    = param.LiquidoChiaro ? "negative" : "positive";
            const string Select        = "first";
            const double delta         = 30.0;

            // Disegna la regione per il calcolo del Livello
            HRegion Rectangle = new HRegion();

            Rectangle.GenRectangle2(param.RectLivello.Row, centerColumn, param.RectLivello.Angle, param.RectLivello.Length1, param.RectLivello.Length2);

            HMeasure MeasureHandle = new HMeasure(param.RectLivello.Row, centerColumn, param.RectLivello.Angle, param.RectLivello.Length1, param.RectLivello.Length2, Width, Height, Interpolation);

            HTuple RowEdge, ColumnEdge, Amplitude, Distance;

            Img.MeasurePos(MeasureHandle, param.SigmaLivellox10 / 10.0, param.ThresholdLivellox10 / 10.0, Transition, Select, out RowEdge, out ColumnEdge, out Amplitude, out Distance);

            MeasureHandle.Dispose();

            if (RowEdge.Length > 0)
            {
                double altezzaSchiuma = RowEdge.D;

                if (altezzaSchiuma >= param.RowMaxLivello && altezzaSchiuma <= param.RowMinLivello)
                {
                    if (param.LiquidoChiaro)
                    {
                        ret = true;
                    }
                    else
                    {
                        HRegion rectangleThreshold = new HRegion();
                        //double row = altezzaSchiuma + (paramLevel.rowMin - altezzaSchiuma) / 2;
                        double row    = altezzaSchiuma + (param.RectLivello.Row + param.RectLivello.Length1 - altezzaSchiuma) / 2;
                        double column = centerColumn;
                        //double length1 = (paramLevel.rowMin - altezzaSchiuma) / 2;
                        double length1 = (param.RectLivello.Row + param.RectLivello.Length1 - altezzaSchiuma) / 2;
                        double length2 = param.RectLivello.Length2;

                        rectangleThreshold.GenRectangle2(row, column, param.RectLivello.Angle, length1, length2);

                        HImage  imgReduced      = Img.ReduceDomain(rectangleThreshold);
                        HRegion regionThreshold = imgReduced.Threshold((double)param.ThresholdMin, (double)param.ThresholdMax);
                        imgReduced.Dispose();

                        double r, c;
                        int    area = rectangleThreshold.AreaCenter(out r, out c);
                        rectangleThreshold.Dispose();

                        HRegion regionSelect = regionThreshold.SelectShape("area", "and", area * 0.7, double.MaxValue);
                        regionThreshold.Dispose();

                        ret = regionSelect.CountObj() == 1;
                        iconicList.Add(new Utilities.ObjectToDisplay(regionSelect, "blue", 3)
                        {
                            DrawMode = "fill"
                        });
                    }
                }
                else if (altezzaSchiuma < param.RowMaxLivello)
                {
                    errorLevelMax = true;
                }
                else if (altezzaSchiuma > param.RowMinLivello)
                {
                    errorLevelMin = true;
                }

                iconicList.Add(new Utilities.ObjectToDisplay("Line", new HTuple(altezzaSchiuma, centerColumn - delta, altezzaSchiuma, centerColumn + delta), ret ? "green" : "red", 3));
            }
            else
            {
                if (param.UseThreshold)
                {
                    if (param.LiquidoChiaro)
                    {
                        HRegion rectangleThreshold = new HRegion();
                        rectangleThreshold.GenRectangle2(param.QuotaControlloVuoto, centerColumn, 0.0, param.LarghezzaControlloVuoto, 20);

                        HImage imgReduced = Img.ReduceDomain(rectangleThreshold);
                        rectangleThreshold.Dispose();

                        HRegion regionThreshold = imgReduced.Threshold((double)param.ThresholdMin, (double)param.ThresholdMax);
                        imgReduced.Dispose();

                        HRegion connectedRegions = regionThreshold.Connection();
                        regionThreshold.Dispose();

                        HRegion filledCandidates = connectedRegions.FillUp();
                        connectedRegions.Dispose();

                        HRegion regionMax = filledCandidates.SelectShapeStd("max_area", 0);

                        double row, col;
                        int    area = regionMax.AreaCenter(out row, out col);
                        regionMax.Dispose();

                        if (area > param.SogliaAreaControlloVuoto)
                        {
                            iconicList.Add(new Utilities.ObjectToDisplay(filledCandidates, "green", 1)
                            {
                                DrawMode = "fill"
                            });
                            ret = true;
                        }
                        else
                        {
                            iconicList.Add(new Utilities.ObjectToDisplay(filledCandidates, "red", 1)
                            {
                                DrawMode = "fill"
                            });
                            ret = false;
                        }

                        iconicList.Add(new Utilities.ObjectToDisplay(area.ToString(), "blue", (int)(row - 50), (int)(col - param.LarghezzaControlloVuoto)));
                    }
                    else
                    {
                        HRegion rectangleThreshold = new HRegion();
                        rectangleThreshold.GenRectangle2(param.RowMaxLivello + (param.RowMinLivello - param.RowMaxLivello) / 2
                                                         , centerColumn
                                                         , param.RectLivello.Angle
                                                         , (param.RowMinLivello - param.RowMaxLivello) / 2
                                                         , param.RectLivello.Length2);

                        HImage  imgReduced      = Img.ReduceDomain(rectangleThreshold);
                        HRegion regionThreshold = imgReduced.Threshold((double)param.ThresholdMin, (double)param.ThresholdMax);
                        imgReduced.Dispose();

                        double r, c;
                        int    area = rectangleThreshold.AreaCenter(out r, out c);

                        HRegion regionSelect = regionThreshold.SelectShape("area", "and", area * 0.7, double.MaxValue);

                        ret = regionSelect.CountObj() == 1;
                        regionSelect.Dispose();

                        iconicList.Add(new Utilities.ObjectToDisplay(rectangleThreshold, "red", 1));
                        iconicList.Add(new Utilities.ObjectToDisplay(regionThreshold, "red", 1)
                        {
                            DrawMode = "fill"
                        });
                    }

                    if (ret == false)
                    {
                        errorEmpty = true;
                    }
                }
            }

            iconicList.Add(new Utilities.ObjectToDisplay(Rectangle, "red", 2));

            iconicList.Add(new Utilities.ObjectToDisplay("Line", new HTuple(param.RowMaxLivello, centerColumn - delta, param.RowMaxLivello, centerColumn + delta), "cyan", 3));
            iconicList.Add(new Utilities.ObjectToDisplay("Max", "cyan", (int)(param.RowMaxLivello - delta), (int)(centerColumn + 2 * delta)));

            iconicList.Add(new Utilities.ObjectToDisplay("Line", new HTuple(param.RowMinLivello, centerColumn - delta, param.RowMinLivello, centerColumn + delta), "cyan", 3));
            iconicList.Add(new Utilities.ObjectToDisplay("Min", "cyan", (int)(param.RowMinLivello), (int)(centerColumn + 2 * delta)));

            return(ret);
        }
        /// <summary>
        /// 演算法改這裡
        /// </summary>
        public override void UpdateResults()
        {
            if (mHandle == null)
            {
                return;
            }

            mMeasAssist.exceptionText = "";

            try
            {
                HObject imageReduced;
                HOperatorSet.GenEmptyObj(out imageReduced);
                //建 ROI
                var    roiModel = mRoi.getModelData();
                HTuple row      = roiModel[0];
                var    column   = roiModel[1];
                var    phi      = roiModel[2];
                var    length1  = roiModel[3];
                var    length2  = roiModel[4];
                //Halcon 徑度轉角度
                double degree = phi.D.HalconPhiToDegree();

                bool   terminate = false;
                double degreeSeed, finalDegree;
                degreeSeed = finalDegree = degree;

                //reset result
                mResult = new EdgeResult();
                //旋轉角度, Search Point
                while (!HasResult)
                {
                    var region      = getRectangle2(row, column, degreeSeed, length1, length2);
                    var regionImage = getRegionImage(region);
                    //Reset Handle and mResult
                    mHandle = new HMeasure(mMeasROI[0].D, mMeasROI[1].D,
                                           degreeSeed.ToHalconPhi(), mMeasROI[3].D, mMeasROI[4].D,
                                           mMeasAssist.mWidth, mMeasAssist.mHeight,
                                           mMeasAssist.mInterpolation);
                    measurePos(regionImage);
                    finalDegree = degreeSeed;
                    degreeSeed  = getNextSeed(degreeSeed, phi.D, ref terminate);
                    if (terminate)
                    {
                        break;
                    }
                }
                mResultWorld = new EdgeResult(mResult);

                //Update Model
                var updateableROI = mRoi as ViewROI.Interface.IROIModelUpdateable;
                if (updateableROI != null)
                {
                    mMeasROI[2].D = finalDegree.ToHalconPhi();
                    var updateROIModel = new ROIViewModel()
                    {
                        CenterRow = row.D,
                        CenterCol = column.D,
                        Phi       = finalDegree.ToHalconPhi(),
                        Length    = length1.D,
                        Width     = length2.D,
                    };
                    updateableROI.UpdateROIModel(updateROIModel);
                }
            }
            catch (HOperatorException e)
            {
                mEdgeXLD.Dispose();
                mMeasAssist.exceptionText = e.Message;
                mResultWorld = new EdgeResult();
                return;
            }
            UpdateXLD();
        }