/// <summary>
 /// 建構子
 /// </summary>
 /// <param name="roi"></param>
 /// <param name="mAssist"></param>
 public MeasurementCircle(ROI roi, MeasureAssistant mAssist)
     : base(roi, mAssist)
 {
     mResult = new CircleResult();
     _cameraOut = new HTuple();
     UpdateMeasure();
 }
 /// <summary>
 /// 建構子
 /// </summary>
 /// <param name="roi"></param>
 /// <param name="mAssist"></param>
 public MeasurementCircle(ROI roi, MeasureAssistant mAssist)
     : base(roi, mAssist)
 {
     mResult    = new CircleResult();
     _cameraOut = new HTuple();
     UpdateMeasure();
 }
 public CircleResult(CircleResult result)
     : this(result.Row, result.Col, result.Radius, result.StartPhi, result.EndPhi, result.PointOrder)
 {
 }
Esempio n. 4
0
        public MeasureResult Action()
        {
            #region 輸出結果
            CircleResult mResult = null;
            #endregion

            // Local iconic variables

            HObject ho_R17_Circle = null;
            HObject ho_R17_ROI_Image = null, ho_R17_Region = null, ho_R17_ImageReduced = null;
            HObject ho_R17_Edges = null, ho_R17_ContoursSplit = null, ho_R17_SingleSegment = null;
            HObject ho_R17_ContEllipse = null;

            // Local control variables

            HTuple hv_msgOffsetY, hv_msgOffsetX;
            HTuple hv_STD_Row;
            HTuple hv_STD_Col, hv_Img_Row, hv_Img_Col, hv_Img_Rotate_Angle;
            HTuple hv_OffsetRow, hv_OffsetCol, hv_STD_R17_Row, hv_STD_R17_Col;
            HTuple hv_STD_R17_V_Row, hv_STD_R17_V_Col, hv_R17_X, hv_R17_Y;
            HTuple hv_R17_Pos_Row, hv_R17_Pos_Col, hv_R17_R;
            HTuple hv_alpha = new HTuple(), hv_R17_low = new HTuple();
            HTuple hv_R17_high = new HTuple(), hv_R17_NumSegments = new HTuple();
            HTuple hv_NumCircles = new HTuple(), hv_Num_Circle_Point = new HTuple();
            HTuple hv_R17 = new HTuple(), hv_i = new HTuple(), hv_Attrib = new HTuple();
            HTuple hv_R17_Row = new HTuple(), hv_R17_Column = new HTuple();
            HTuple hv_R17_Radius = new HTuple(), hv_R17_StartPhi = new HTuple();
            HTuple hv_R17_EndPhi = new HTuple(), hv_R17_PointOrder = new HTuple();
            HTuple hv_R17_MinDist = new HTuple(), hv_R17_MaxDist = new HTuple();
            HTuple hv_R17_AvgDist = new HTuple(), hv_R17_SigmaDist = new HTuple();

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_R17_Circle);
            HOperatorSet.GenEmptyObj(out ho_R17_ROI_Image);
            HOperatorSet.GenEmptyObj(out ho_R17_Region);
            HOperatorSet.GenEmptyObj(out ho_R17_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_R17_Edges);
            HOperatorSet.GenEmptyObj(out ho_R17_ContoursSplit);
            HOperatorSet.GenEmptyObj(out ho_R17_SingleSegment);
            HOperatorSet.GenEmptyObj(out ho_R17_ContEllipse);

            //Measure: SDMS_R17
            //Author: John Hsieh
            //Date: 2012
            // dev_update_off(...); only in hdevelop
            HOperatorSet.SetSystem("border_shape_models", "false");

            //****Message Args
            hv_msgOffsetY = 100;
            hv_msgOffsetX = 100;

            //****Model Args

            //STD 中心點
            hv_STD_Row = 772;
            hv_STD_Col = 1003;

            //目前圖形 中心點
            hv_Img_Row = hv_AllModelRow.Clone();
            hv_Img_Col = hv_AllModelColumn.Clone();

            //目前圖形 Rotate Angle
            hv_Img_Rotate_Angle = hv_AllModelAngle.Clone();

            //目前圖形偏移量
            hv_OffsetRow = hv_Img_Row - hv_STD_Row;
            hv_OffsetCol = hv_Img_Col - hv_STD_Col;

            //****Display
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
            }
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
            }
            //*****R17
            //STD R17_ 位置
            hv_STD_R17_Row = 802;
            hv_STD_R17_Col = 660;

            //STD 向量 STD_R17_
            hv_STD_R17_V_Row = hv_STD_R17_Row - hv_STD_Row;
            hv_STD_R17_V_Col = hv_STD_R17_Col - hv_STD_Col;

            //R17_X, R17_Y 分量
            hv_R17_X = (hv_STD_R17_V_Col * (hv_Img_Rotate_Angle.TupleCos())) + (hv_STD_R17_V_Row * (hv_Img_Rotate_Angle.TupleSin()
                ));
            hv_R17_Y = (hv_STD_R17_V_Row * (hv_Img_Rotate_Angle.TupleCos())) - (hv_STD_R17_V_Col * (hv_Img_Rotate_Angle.TupleSin()
                ));

            //目前圖形 R17_ 位置
            hv_R17_Pos_Row = (hv_STD_Row + hv_R17_Y) + hv_OffsetRow;
            hv_R17_Pos_Col = (hv_STD_Col + hv_R17_X) + hv_OffsetCol;

            hv_R17_R = 17;

            ho_R17_Circle.Dispose();
            HOperatorSet.GenCircle(out ho_R17_Circle, hv_R17_Pos_Row, hv_R17_Pos_Col, hv_R17_R);
            if (HDevWindowStack.IsOpen())
            {
                //dev_display (R17_Circle)
            }
            //stop ()

            ho_R17_ROI_Image.Dispose();
            HOperatorSet.ReduceDomain(ho_Image, ho_R17_Circle, out ho_R17_ROI_Image);
            ho_R17_Region.Dispose();
            HOperatorSet.FastThreshold(ho_R17_ROI_Image, out ho_R17_Region, 100, 255, 15);
            ho_R17_ImageReduced.Dispose();
            HOperatorSet.ReduceDomain(ho_R17_ROI_Image, ho_R17_Region, out ho_R17_ImageReduced
                );
            //stop ()
            //sobel_fast 具有較寬的選擇範圍,搭配 alpha 參數 (alpha 越大, 容錯範圍大)
            hv_alpha = 0.9;
            hv_R17_low = 10;
            hv_R17_high = 60;
            ho_R17_Edges.Dispose();
            HOperatorSet.EdgesSubPix(ho_R17_ImageReduced, out ho_R17_Edges, "sobel_fast",
                hv_alpha, hv_R17_low, hv_R17_high);
            //stop ()
            //*所有的數值越小,表示容錯範圍大,反之亦然
            ho_R17_ContoursSplit.Dispose();
            HOperatorSet.SegmentContoursXld(ho_R17_Edges, out ho_R17_ContoursSplit, "lines_circles",
                17, 1, 1);
            //Display the results
            //===========================================================
            HOperatorSet.CountObj(ho_R17_ContoursSplit, out hv_R17_NumSegments);
            hv_NumCircles = 0;
            hv_Num_Circle_Point = 0;
            hv_R17 = 999;
            for (hv_i = 1; hv_i.Continue(hv_R17_NumSegments, 1); hv_i = hv_i.TupleAdd(1))
            {
                ho_R17_SingleSegment.Dispose();
                HOperatorSet.SelectObj(ho_R17_ContoursSplit, out ho_R17_SingleSegment, hv_i);
                HOperatorSet.GetContourGlobalAttribXld(ho_R17_SingleSegment, "cont_approx",
                    out hv_Attrib);
                if ((int)(new HTuple(hv_Attrib.TupleEqual(1))) != 0)
                {
                    HOperatorSet.FitCircleContourXld(ho_R17_SingleSegment, "atukey", -1, 2,
                        hv_Num_Circle_Point, 5, 2, out hv_R17_Row, out hv_R17_Column, out hv_R17_Radius,
                        out hv_R17_StartPhi, out hv_R17_EndPhi, out hv_R17_PointOrder);
                    ho_R17_ContEllipse.Dispose();
                    HOperatorSet.GenEllipseContourXld(out ho_R17_ContEllipse, hv_R17_Row, hv_R17_Column,
                        0, hv_R17_Radius, hv_R17_Radius, 0, (new HTuple(360)).TupleRad(), "positive",
                        1.0);
                    if (HDevWindowStack.IsOpen())
                    {
                        HOperatorSet.DispObj(ho_R17_ContEllipse, HDevWindowStack.GetActive());
                    }
                    HOperatorSet.DistEllipseContourXld(ho_R17_SingleSegment, "algebraic", -1,
                        0, hv_R17_Row, hv_R17_Column, 0, hv_R17_Radius, hv_R17_Radius, out hv_R17_MinDist,
                        out hv_R17_MaxDist, out hv_R17_AvgDist, out hv_R17_SigmaDist);
                    hv_NumCircles = hv_NumCircles + 1;
                    if ((int)(new HTuple(hv_R17.TupleGreater(hv_R17_Radius))) != 0)
                    {
                        hv_R17 = hv_R17_Radius.Clone();
                        mResult = new CircleResult()
                        {
                            Row = new HTuple(hv_R17_Row),
                            Col = new HTuple(hv_R17_Column),
                            Radius = new HTuple(hv_R17_Radius),
                            StartPhi = new HTuple(hv_R17_StartPhi),
                            EndPhi = new HTuple(hv_R17_EndPhi),
                            PointOrder = new HTuple(hv_R17_PointOrder),
                        };
                    }
                    //stop ()
                }
            }

            ho_R17_Circle.Dispose();
            ho_R17_ROI_Image.Dispose();
            ho_R17_Region.Dispose();
            ho_R17_ImageReduced.Dispose();
            ho_R17_Edges.Dispose();
            ho_R17_ContoursSplit.Dispose();
            ho_R17_SingleSegment.Dispose();
            ho_R17_ContEllipse.Dispose();

            return mResult;
        }
Esempio n. 5
0
        /// <summary>
        /// 初始化後才能叫用 Action
        /// </summary>
        public MeasureResult Action()
        {
            #region 輸出結果, CircleResult or Distance Result
            CircleResult mResult = null;
            #endregion

            // Local iconic variables

            HObject ho_R1_Circle = null;
            HObject ho_R1_ROI_Image = null, ho_R1_Region = null, ho_R1_ImageReduced = null;
            HObject ho_R1_Edges = null, ho_R1_ContoursSplit = null, ho_R1_SingleSegment = null;
            //HObject ho_R1_ContEllipse = null;

            // Local control variables

            HTuple hv_msgOffsetY, hv_msgOffsetX;
            //HTuple hv_AllModelId;
            HTuple hv_STD_Row;
            HTuple hv_STD_Col, hv_Img_Row, hv_Img_Col, hv_Img_Rotate_Angle;
            HTuple hv_OffsetRow, hv_OffsetCol, hv_STD_R1_Row, hv_STD_R1_Col;
            HTuple hv_STD_R1_V_Row, hv_STD_R1_V_Col, hv_R1_X, hv_R1_Y;
            HTuple hv_R1_Pos_Row, hv_R1_Pos_Col, hv_R1_R;
            HTuple hv_alpha = new HTuple(), hv_R1_low = new HTuple(), hv_R1_high = new HTuple();
            HTuple hv_R1_NumSegments = new HTuple(), hv_NumCircles = new HTuple();
            HTuple hv_Num_Circle_Point = new HTuple(), hv_R1 = new HTuple();
            HTuple hv_R1_limit = new HTuple(), hv_i = new HTuple(), hv_Attrib = new HTuple();
            HTuple hv_R1_Row = new HTuple(), hv_R1_Column = new HTuple();
            HTuple hv_R1_Radius = new HTuple(), hv_R1_StartPhi = new HTuple();
            HTuple hv_R1_EndPhi = new HTuple(), hv_R1_PointOrder = new HTuple();
            HTuple hv_R1_MinDist = new HTuple(), hv_R1_MaxDist = new HTuple();
            HTuple hv_R1_AvgDist = new HTuple(), hv_R1_SigmaDist = new HTuple();
            HTuple hv_ResultText = new HTuple(), hv_MeasureReasult;

            // Initialize local and output iconic variables
            //HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_R1_Circle);
            HOperatorSet.GenEmptyObj(out ho_R1_ROI_Image);
            HOperatorSet.GenEmptyObj(out ho_R1_Region);
            HOperatorSet.GenEmptyObj(out ho_R1_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_R1_Edges);
            HOperatorSet.GenEmptyObj(out ho_R1_ContoursSplit);
            HOperatorSet.GenEmptyObj(out ho_R1_SingleSegment);
            //HOperatorSet.GenEmptyObj(out ho_R1_ContEllipse);

            //Measure: SDMS_R1
            //Author: John Hsieh
            //Date: 2012
            //ho_Image.Dispose();
            //HOperatorSet.ReadImage(out ho_Image, "D:/Projects/Halcon/SDMS/SDMS_Measure/Images/E-1/E1-1.bmp");
            //dev_open_window_fit_image(ho_Image, 0, 0, -1, -1, out hv_WindowHandle);
            //dev_update_off ()
            // dev_update_window(...); only in hdevelop
            HOperatorSet.SetSystem("border_shape_models", "false");

            //****Message Args
            hv_msgOffsetY = 100;
            hv_msgOffsetX = 100;

            //****Model All
            //HOperatorSet.ReadShapeModel("D:/Projects/Halcon/SDMS/SDMS_Measure/Model/MatchingAll.shm",
            //	out hv_AllModelId);
            //ho_AllModelContours.Dispose();
            //HOperatorSet.GetShapeModelContours(out ho_AllModelContours, hv_AllModelId, 1);
            //HOperatorSet.FindShapeModel(ho_Image, hv_AllModelId, (new HTuple(0)).TupleRad()
            //	, (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 6, 0.75, out hv_AllModelRow,
            //	out hv_AllModelColumn, out hv_AllModelAngle, out modelScore);

            //****Model Args

            //STD 中心點
            hv_STD_Row = 772;
            hv_STD_Col = 1003;

            //目前圖形 中心點
            hv_Img_Row = hv_AllModelRow.Clone();
            hv_Img_Col = hv_AllModelColumn.Clone();

            //目前圖形 Rotate Angle
            hv_Img_Rotate_Angle = hv_AllModelAngle.Clone();

            //目前圖形偏移量
            hv_OffsetRow = hv_Img_Row - hv_STD_Row;
            hv_OffsetCol = hv_Img_Col - hv_STD_Col;

            //****R1
            //STD R1_ 位置
            hv_STD_R1_Row = 589;
            hv_STD_R1_Col = 705;

            //STD 向量 STD_R1_
            hv_STD_R1_V_Row = hv_STD_R1_Row - hv_STD_Row;
            hv_STD_R1_V_Col = hv_STD_R1_Col - hv_STD_Col;

            //R1_X, R1_Y 分量
            hv_R1_X = (hv_STD_R1_V_Col * (hv_Img_Rotate_Angle.TupleCos())) + (hv_STD_R1_V_Row * (hv_Img_Rotate_Angle.TupleSin()
                ));
            hv_R1_Y = (hv_STD_R1_V_Row * (hv_Img_Rotate_Angle.TupleCos())) - (hv_STD_R1_V_Col * (hv_Img_Rotate_Angle.TupleSin()
                ));

            //目前圖形 R1_ 位置
            hv_R1_Pos_Row = (hv_STD_Row + hv_R1_Y) + hv_OffsetRow;
            hv_R1_Pos_Col = (hv_STD_Col + hv_R1_X) + hv_OffsetCol;

            hv_R1_R = 20;
            //*ROI
            ho_R1_Circle.Dispose();
            HOperatorSet.GenCircle(out ho_R1_Circle, hv_R1_Pos_Row, hv_R1_Pos_Col, hv_R1_R);
            ho_R1_ROI_Image.Dispose();
            HOperatorSet.ReduceDomain(ho_Image, ho_R1_Circle, out ho_R1_ROI_Image);
            ho_R1_Region.Dispose();
            HOperatorSet.FastThreshold(ho_R1_ROI_Image, out ho_R1_Region, 100, 255, 20);
            ho_R1_ImageReduced.Dispose();
            HOperatorSet.ReduceDomain(ho_R1_ROI_Image, ho_R1_Region, out ho_R1_ImageReduced
                );

            //sobel_fast 具有較寬的選擇範圍,搭配 alpha 參數 (alpha 越大, 容錯範圍大)
            hv_alpha = 0.9;
            hv_R1_low = 20;
            hv_R1_high = 40;
            ho_R1_Edges.Dispose();
            HOperatorSet.EdgesSubPix(ho_R1_ImageReduced, out ho_R1_Edges, "sobel_fast",
                hv_alpha, hv_R1_low, hv_R1_high);
            //stop ()
            //*所有的數值越小,表示容錯範圍大,反之亦然
            ho_R1_ContoursSplit.Dispose();
            HOperatorSet.SegmentContoursXld(ho_R1_Edges, out ho_R1_ContoursSplit, "lines_circles",
                17, 1, 1);
            //Display the results
            //===========================================================
            HOperatorSet.CountObj(ho_R1_ContoursSplit, out hv_R1_NumSegments);
            hv_NumCircles = 0;
            hv_Num_Circle_Point = 5;
            hv_R1 = 999;
            hv_R1_limit = 10;
            for (hv_i = 1; hv_i.Continue(hv_R1_NumSegments, 1); hv_i = hv_i.TupleAdd(1))
            {
                ho_R1_SingleSegment.Dispose();
                HOperatorSet.SelectObj(ho_R1_ContoursSplit, out ho_R1_SingleSegment, hv_i);
                HOperatorSet.GetContourGlobalAttribXld(ho_R1_SingleSegment, "cont_approx", out hv_Attrib);

                if ((int)(new HTuple(hv_Attrib.TupleEqual(1))) != 0)
                {
                    HOperatorSet.FitCircleContourXld(ho_R1_SingleSegment, "atukey", -1, 2,
                        hv_Num_Circle_Point, 5, 2, out hv_R1_Row, out hv_R1_Column, out hv_R1_Radius,
                        out hv_R1_StartPhi, out hv_R1_EndPhi, out hv_R1_PointOrder);

                    //ho_R1_ContEllipse.Dispose();
                    //HOperatorSet.GenEllipseContourXld(out ho_R1_ContEllipse, hv_R1_Row, hv_R1_Column,
                    //	0, hv_R1_Radius, hv_R1_Radius, 0, (new HTuple(360)).TupleRad(), "positive",
                    //	1.0);

                    //HOperatorSet.DistEllipseContourXld(ho_R1_SingleSegment, "algebraic", -1,
                    //	0, hv_R1_Row, hv_R1_Column, 0, hv_R1_Radius, hv_R1_Radius, out hv_R1_MinDist,
                    //	out hv_R1_MaxDist, out hv_R1_AvgDist, out hv_R1_SigmaDist);

                    hv_NumCircles = hv_NumCircles + 1;
                    if ((int)(new HTuple(hv_R1.TupleGreater(hv_R1_Radius))) != 0)
                    {
                        hv_R1 = hv_R1_Radius.Clone();
                        //hv_ResultText = (((("C" + hv_NumCircles) + ": Radius = ") + (hv_R1_Radius.TupleString(
                        //	".3"))) + " / MaxDeviation: ") + (hv_R1_MaxDist.TupleString(".3"));
                        //HOperatorSet.SetTposition(hv_WindowHandle, hv_R1_Pos_Row - hv_msgOffsetY,
                        //	hv_R1_Pos_Col - hv_msgOffsetX);
                        //HOperatorSet.WriteString(hv_WindowHandle, "R1");

                        #region 組合結果
                        mResult = new CircleResult(new HTuple(hv_R1_Row)
                                                , new HTuple(hv_R1_Column)
                                                , new HTuple(hv_R1_Radius)
                                                , new HTuple(hv_R1_StartPhi)
                                                , new HTuple(hv_R1_EndPhi)
                                                , new HTuple(hv_R1_PointOrder)) { };
                        #endregion
                    }
                }
            }
            hv_MeasureReasult = hv_R1.Clone();
            //****R1 End
            //ho_Image.Dispose();
            ho_R1_Circle.Dispose();
            ho_R1_ROI_Image.Dispose();
            ho_R1_Region.Dispose();
            ho_R1_ImageReduced.Dispose();
            ho_R1_Edges.Dispose();
            ho_R1_ContoursSplit.Dispose();
            ho_R1_SingleSegment.Dispose();
            //ho_R1_ContEllipse.Dispose();

            return mResult;
        }
Esempio n. 6
0
        public MeasureResult Action()
        {
            #region 輸出結果
            CircleResult mResult = null;
            #endregion

            HTuple hv_STD_Row;
            HTuple hv_STD_Col, hv_Img_Row, hv_Img_Col, hv_Img_Rotate_Angle;
            HTuple hv_OffsetRow, hv_OffsetCol;
            HOperatorSet.SetSystem("border_shape_models", "false");

            //STD 中心點
            hv_STD_Row = 839.5;
            hv_STD_Col = 1046.5;

            //目前圖形 中心點
            hv_Img_Row = hv_AllModelRow.Clone();
            hv_Img_Col = hv_AllModelColumn.Clone();

            //目前圖形 Rotate Angle
            hv_Img_Rotate_Angle = hv_AllModelAngle.Clone();

            //目前圖形偏移量
            hv_OffsetRow = hv_Img_Row - hv_STD_Row;
            hv_OffsetCol = hv_Img_Col - hv_STD_Col;

            //圓ROI
            //HTuple f_ROI_Row = 874.4296875;
            //HTuple f_ROI_Col = 737.209150326797;
            //HTuple f_radius = 11.353000779328;

            HTuple f_ROI_Row = 875.6796875;
            HTuple f_ROI_Col = 738.565359477124;
            HTuple f_radius = 20.0;

            //重定位
            HTuple f_ROI_Cur_Row, f_ROI_Cur_Col;
            PositionLocater.ReLocater(hv_STD_Row, hv_STD_Col, hv_AllModelAngle, hv_OffsetRow, hv_OffsetCol, f_ROI_Row, f_ROI_Col, out f_ROI_Cur_Row, out f_ROI_Cur_Col);

            /**/

            #region Measure
            var cROIController = new ROIController();
            var cAssistant = new MeasureAssistant(cROIController);

            var hImage = ho_Image as HImage;
            cAssistant.setImage(hImage);

            /*參數值*/
            cAssistant.mThresh = 40.0;
            cAssistant.mSigma = 1.0;
            cAssistant.mRoiWidth = 10;
            cAssistant.mInterpolation = "nearest_neighbor";
            cAssistant.mSelPair = false;
            cAssistant.mTransition = "all";
            cAssistant.mPosition = "all";
            cAssistant.mDispEdgeLength = 30;
            cAssistant.mDispROIWidth = true;
            cAssistant.setUnit("cm");

            cAssistant.mInitThresh = 40.0;
            cAssistant.mInitSigma = 1.0;
            cAssistant.mInitRoiWidth = 10;

            var roiF = new ROICircle() { ROIMeasureType = MeasureType.Circle };
            //roiF.MakeROI(416, 998, 0, 26.5, 71.2);
            roiF.MakeROI(f_ROI_Cur_Row, f_ROI_Cur_Col, f_radius);

            double inc = 0.3;
            double miniRadius = 0.1;
            double maxRadius = 0.3;
            double currentRadius = 0;
            int doingCount = 0;
            //0.1,0.2,0.3

            MeasureViewModel model = null;
            var inBoundry = false;
            do
            {
                roiF.MakeROI(f_ROI_Cur_Row, f_ROI_Cur_Col, f_radius);
                var fitCircle = new MeasurementCircle(roiF, cAssistant);
                model = fitCircle.GetViewModel();
                if (model.Distance != null && model.Distance.TupleLength() > 0)
                {
                    currentRadius = CameraSystem.ToRealWorldValue(model.Distance.D);
                    inBoundry = (miniRadius <= currentRadius && currentRadius <= maxRadius);
                    if (inBoundry)
                    {
                        mResult = new CircleResult()
                        {
                            Row = new HTuple(model.Row1),
                            Col = new HTuple(model.Col1),
                            Radius = new HTuple(model.Distance),
                            StartPhi = new HTuple(model.StartPhi),
                            EndPhi = new HTuple(model.EndPhi),
                            PointOrder = new HTuple(model.PointOrder),
                        };
                        break;
                    }
                }
                if (currentRadius < miniRadius) f_radius += inc;
                else f_radius -= inc;
                doingCount++;
                if (doingCount > 15) break;
            }
            while (!inBoundry);

            #endregion

            return mResult;
        }
Esempio n. 7
0
        public MeasureResult Action()
        {
            #region 輸出結果
            CircleResult mResult = null;
            #endregion

            // Local iconic variables

            HObject ho_R3_Circle = null;
            HObject ho_R3_ROI_Image = null, ho_R3_Region = null, ho_R3_ImageReduced = null;
            HObject ho_R3_Edges = null, ho_R3_ContoursSplit = null, ho_R3_SingleSegment = null;
            HObject ho_R3_ContEllipse = null;

            // Local control variables

            HTuple hv_msgOffsetY, hv_msgOffsetX;
            HTuple hv_STD_Row;
            HTuple hv_STD_Col, hv_Img_Row, hv_Img_Col, hv_Img_Rotate_Angle;
            HTuple hv_OffsetRow, hv_OffsetCol, hv_R3_R;
            HTuple hv_STD_R3_Row = new HTuple(), hv_STD_R3_Col = new HTuple();
            HTuple hv_STD_R3_V_Row = new HTuple(), hv_STD_R3_V_Col = new HTuple();
            HTuple hv_R3_X = new HTuple(), hv_R3_Y = new HTuple(), hv_R3_Pos_Row = new HTuple();
            HTuple hv_R3_Pos_Col = new HTuple(), hv_alpha = new HTuple();
            HTuple hv_R3_low = new HTuple(), hv_R3_high = new HTuple();
            HTuple hv_R3_NumSegments = new HTuple(), hv_NumCircles = new HTuple();
            HTuple hv_Num_Circle_Point = new HTuple(), hv_R3 = new HTuple();
            HTuple hv_i = new HTuple(), hv_Attrib = new HTuple(), hv_R3_Row = new HTuple();
            HTuple hv_R3_Column = new HTuple(), hv_R3_Radius = new HTuple();
            HTuple hv_R3_StartPhi = new HTuple(), hv_R3_EndPhi = new HTuple();
            HTuple hv_R3_PointOrder = new HTuple(), hv_R3_MinDist = new HTuple();
            HTuple hv_R3_MaxDist = new HTuple(), hv_R3_AvgDist = new HTuple();
            HTuple hv_R3_SigmaDist = new HTuple();

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_R3_Circle);
            HOperatorSet.GenEmptyObj(out ho_R3_ROI_Image);
            HOperatorSet.GenEmptyObj(out ho_R3_Region);
            HOperatorSet.GenEmptyObj(out ho_R3_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_R3_Edges);
            HOperatorSet.GenEmptyObj(out ho_R3_ContoursSplit);
            HOperatorSet.GenEmptyObj(out ho_R3_SingleSegment);
            HOperatorSet.GenEmptyObj(out ho_R3_ContEllipse);

            //Measure: SDMS_R3
            //Author: John Hsieh
            //Date: 2012
            //ho_Image.Dispose();
            //HOperatorSet.ReadImage(out ho_Image, "Images/STD.bmp");
            //dev_open_window_fit_image(ho_Image, 0, 0, -1, -1, out hv_WindowHandle);
            //// dev_update_off(...); only in hdevelop
            HOperatorSet.SetSystem("border_shape_models", "false");

            //****Message Args
            hv_msgOffsetY = 100;
            hv_msgOffsetX = 100;

            //****Model All
            //HOperatorSet.ReadShapeModel("D:/Projects/Halcon/SDMS/SDMS_Measure/Model/MatchingAll.shm",
            //	out hv_AllModelId);
            //ho_AllModelContours.Dispose();
            //HOperatorSet.GetShapeModelContours(out ho_AllModelContours, hv_AllModelId, 1);
            //HOperatorSet.FindShapeModel(ho_Image, hv_AllModelId, (new HTuple(0)).TupleRad()
            //	, (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 6, 0.75, out hv_AllModelRow,
            //	out hv_AllModelColumn, out hv_AllModelAngle, out hv_AllModelScore);

            //****Model Args

            //STD 中心點
            hv_STD_Row = 772;
            hv_STD_Col = 1003;

            //目前圖形 中心點
            hv_Img_Row = hv_AllModelRow.Clone();
            hv_Img_Col = hv_AllModelColumn.Clone();

            //目前圖形 Rotate Angle
            hv_Img_Rotate_Angle = hv_AllModelAngle.Clone();

            //目前圖形偏移量
            hv_OffsetRow = hv_Img_Row - hv_STD_Row;
            hv_OffsetCol = hv_Img_Col - hv_STD_Col;

            //****Display
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
            }
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
            }
            //*****R3
            hv_R3_R = 29;

            //STD R3_ 位置
            hv_STD_R3_Row = 252;
            hv_STD_R3_Col = 1381;

            //STD 向量 STD_R3_
            hv_STD_R3_V_Row = hv_STD_R3_Row - hv_STD_Row;
            hv_STD_R3_V_Col = hv_STD_R3_Col - hv_STD_Col;

            //R3_X, R3_Y 分量
            hv_R3_X = (hv_STD_R3_V_Col * (hv_Img_Rotate_Angle.TupleCos())) + (hv_STD_R3_V_Row * (hv_Img_Rotate_Angle.TupleSin()
                ));
            hv_R3_Y = (hv_STD_R3_V_Row * (hv_Img_Rotate_Angle.TupleCos())) - (hv_STD_R3_V_Col * (hv_Img_Rotate_Angle.TupleSin()
                ));

            //目前圖形 R3_ 位置
            hv_R3_Pos_Row = (hv_STD_Row + hv_R3_Y) + hv_OffsetRow;
            hv_R3_Pos_Col = (hv_STD_Col + hv_R3_X) + hv_OffsetCol;

            //** 開始計算
            ho_R3_Circle.Dispose();
            HOperatorSet.GenCircle(out ho_R3_Circle, hv_R3_Pos_Row, hv_R3_Pos_Col, hv_R3_R);
            ho_R3_ROI_Image.Dispose();
            HOperatorSet.ReduceDomain(ho_Image, ho_R3_Circle, out ho_R3_ROI_Image);
            ho_R3_Region.Dispose();
            HOperatorSet.FastThreshold(ho_R3_ROI_Image, out ho_R3_Region, 100, 255, 15);
            ho_R3_ImageReduced.Dispose();
            HOperatorSet.ReduceDomain(ho_R3_ROI_Image, ho_R3_Region, out ho_R3_ImageReduced
                );
            //stop ()
            //sobel_fast 具有較寬的選擇範圍,搭配 alpha 參數 (alpha 越大, 容錯範圍大)
            hv_alpha = 0.9;
            hv_R3_low = 20;
            hv_R3_high = 60;
            ho_R3_Edges.Dispose();
            HOperatorSet.EdgesSubPix(ho_R3_ImageReduced, out ho_R3_Edges, "sobel_fast",
                hv_alpha, hv_R3_low, hv_R3_high);
            //stop ()
            //*所有的數值越小,表示容錯範圍大,反之亦然
            ho_R3_ContoursSplit.Dispose();
            HOperatorSet.SegmentContoursXld(ho_R3_Edges, out ho_R3_ContoursSplit, "lines_circles",
                17, 4, 2);
            //Display the results
            //===========================================================
            HOperatorSet.CountObj(ho_R3_ContoursSplit, out hv_R3_NumSegments);
            hv_NumCircles = 0;
            hv_Num_Circle_Point = 0;
            hv_R3 = 999;
            for (hv_i = 1; hv_i.Continue(hv_R3_NumSegments, 1); hv_i = hv_i.TupleAdd(1))
            {
                ho_R3_SingleSegment.Dispose();
                HOperatorSet.SelectObj(ho_R3_ContoursSplit, out ho_R3_SingleSegment, hv_i);
                HOperatorSet.GetContourGlobalAttribXld(ho_R3_SingleSegment, "cont_approx",
                    out hv_Attrib);
                if ((int)(new HTuple(hv_Attrib.TupleEqual(1))) != 0)
                {
                    HOperatorSet.FitCircleContourXld(ho_R3_SingleSegment, "atukey", -1, 2,
                        hv_Num_Circle_Point, 5, 2, out hv_R3_Row, out hv_R3_Column, out hv_R3_Radius,
                        out hv_R3_StartPhi, out hv_R3_EndPhi, out hv_R3_PointOrder);

                    hv_NumCircles = hv_NumCircles + 1;
                    if ((int)(new HTuple(hv_R3.TupleGreater(hv_R3_Radius))) != 0)
                    {
                        hv_R3 = hv_R3_Radius.Clone();
                        mResult = new CircleResult()
                        {
                            Row = new HTuple(hv_R3_Row),
                            Col = new HTuple(hv_R3_Column),
                            Radius = new HTuple(hv_R3_Radius),
                            StartPhi = new HTuple(hv_R3_StartPhi),
                            EndPhi = new HTuple(hv_R3_EndPhi),
                            PointOrder = new HTuple(hv_R3_PointOrder),
                        };
                        //HOperatorSet.SetTposition(hv_WindowHandle, (hv_R3_Pos_Row - hv_msgOffsetY) + 60,
                        //	(hv_R3_Pos_Col + hv_msgOffsetX) - 60);
                        //HOperatorSet.WriteString(hv_WindowHandle, "R3");
                        //stop ()
                    }
                }
            }

            //*****R3 End
            ho_R3_Circle.Dispose();
            ho_R3_ROI_Image.Dispose();
            ho_R3_Region.Dispose();
            ho_R3_ImageReduced.Dispose();
            ho_R3_Edges.Dispose();
            ho_R3_ContoursSplit.Dispose();
            ho_R3_SingleSegment.Dispose();
            ho_R3_ContEllipse.Dispose();

            return mResult;
        }
        /// <summary>
        /// 更新量測結果.
        /// 量測演算法放這裡
        /// </summary>
        public override void UpdateResults()
        {
            if (mMeasAssist.mImage == null)
            {
                return;
            }


            #region 初始化數值
            if (!String.IsNullOrEmpty(mMeasAssist.FitCircleAlgo))
            {
                _Algorithm = new HTuple(mMeasAssist.FitCircleAlgo);
            }

            //init result
            mResult = new CircleResult();

            // Local iconic variables
            HObject ho_MeasureROI, ho_ImageReduced;
            HObject ho_Border, tmp_Border;

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_MeasureROI);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_Border);
            HOperatorSet.GenEmptyObj(out tmp_Border);
            #endregion

            try
            {
                //******* Create ROI ********
                ho_MeasureROI.Dispose();
                HOperatorSet.GenCircle(out ho_MeasureROI, mROICoord[0], mROICoord[1], mROICoord[2]);
                HRegion region = new HRegion();
                region.GenCircle(mROICoord[0].D, mROICoord[1].D, mROICoord[2].D);

                //****** Area Center, 取得目標區域的 pixels 數 ***********
                HTuple area, areaRow, areaColumn;
                double areaPixels = 0.0;
                HOperatorSet.AreaCenter(region, out area, out areaRow, out areaColumn);
                areaPixels = area.D;

                //****** 取得影像 ******
                var himage = mMeasAssist.getImage();

                //******* Extract ROI Image *****
                ho_ImageReduced.Dispose();
                HOperatorSet.ReduceDomain(himage, ho_MeasureROI, out ho_ImageReduced);

                //******* Filter ****************
                var subpixThreadhold = mMeasAssist.SubpixThreadhold;
                HOperatorSet.GenEmptyObj(out ho_Border);
                HOperatorSet.ThresholdSubPix(ho_ImageReduced, out ho_Border, subpixThreadhold);

                if (mMeasAssist.ApplyCalibration && mMeasAssist.IsCalibrationValid)
                {
                    if (_cameraOut.TupleLength() == 0)
                    {
                        _cameraOut = HMisc.ChangeRadialDistortionCamPar("adaptive", mMeasAssist.CameraIn, 0.0);
                    }
                    //var rectifyImage = himage.ChangeRadialDistortionImage(region, mMeasAssist.CameraIn, cameraOut);
                    HObject calibrationBorder;
                    HOperatorSet.GenEmptyObj(out calibrationBorder);
                    HOperatorSet.ChangeRadialDistortionContoursXld(ho_Border, out calibrationBorder, mMeasAssist.CameraIn, _cameraOut);
                    mResult = fitCircle(calibrationBorder, areaPixels);
                }
                else
                {
                    mResult = fitCircle(ho_Border, areaPixels);
                }
            }
            catch (HOperatorException ex)
            {
                Hanbo.Log.LogManager.Error(ex);
                mResultWorld = new CircleResult();
                mResult      = new CircleResult();
            }
            finally
            {
                ho_MeasureROI.Dispose();
                ho_ImageReduced.Dispose();
                ho_Border.Dispose();
            }
            UpdateXLD();
        }
 public override void ClearResultData()
 {
     mResultWorld = new CircleResult();
 }
        private CircleResult fitCircle(HObject ho_Border, double areaPixels)
        {
            var result = new CircleResult();

            try
            {
                // Local control variables
                HTuple hv_Row, hv_Column, hv_Radius, hv_StartPhi;
                HTuple hv_EndPhi, hv_PointOrder;

                //******* Choice Candidate Objects
                HObject ho_SelectedContours;
                HOperatorSet.GenEmptyObj(out ho_SelectedContours);
                ho_SelectedContours.Dispose();
                HOperatorSet.SelectContoursXld(ho_Border, out ho_SelectedContours, "contour_length",
                                               10, Int16.MaxValue, -0.5, 0.5);

                //******* Fit Circle ************
                HTuple  hv_Number, hv_Index;
                HObject ho_ObjectSelected;
                HOperatorSet.GenEmptyObj(out ho_ObjectSelected);
                HOperatorSet.CountObj(ho_SelectedContours, out hv_Number);
                var resultRadius = 0.0;
                for (hv_Index = 1; hv_Index.Continue(hv_Number, 1); hv_Index = hv_Index.TupleAdd(1))
                {
                    ho_ObjectSelected.Dispose();
                    HOperatorSet.SelectObj(ho_SelectedContours, out ho_ObjectSelected, hv_Index);
                    HOperatorSet.FitCircleContourXld(ho_SelectedContours
                                                     , _Algorithm, _MaxNumPoints, _MaxClosureDist, _ClippingEndPoints, _Iterations, _ClippingFactor
                                                     , out hv_Row, out hv_Column, out hv_Radius, out hv_StartPhi, out hv_EndPhi, out hv_PointOrder);

                    //Answer
                    var radiusIndex = -1;
                    if (hv_Radius.TupleLength() > 0)
                    {
                        radiusIndex = DistanceHelper.GetApproximateRadiusIndex(hv_Radius.DArr, areaPixels);
                        if (radiusIndex > -1)
                        {
                            //取最大的 Circle
                            if (resultRadius < hv_Radius.DArr[radiusIndex])
                            {
                                result = new CircleResult(new HTuple(hv_Row.DArr[radiusIndex])
                                                          , new HTuple(hv_Column.DArr[radiusIndex])
                                                          , new HTuple(hv_Radius.DArr[radiusIndex])
                                                          , hv_StartPhi
                                                          , hv_EndPhi
                                                          , hv_PointOrder)
                                {
                                };
                                resultRadius = hv_Radius.DArr[radiusIndex];
                            }
                        }
                    }
                }
            }
            catch (HOperatorException ex)
            {
                Hanbo.Log.LogManager.Error(ex);
            }
            return(result);
        }
Esempio n. 11
0
 public CircleResult(CircleResult result)
     : this(result.Row, result.Col, result.Radius, result.StartPhi, result.EndPhi, result.PointOrder)
 {
 }
 public override void ClearResultData()
 {
     mResultWorld = new CircleResult();
 }
        private CircleResult fitCircle(HObject ho_Border, double areaPixels)
        {
            var result = new CircleResult();
            try
            {
                // Local control variables
                HTuple hv_Row, hv_Column, hv_Radius, hv_StartPhi;
                HTuple hv_EndPhi, hv_PointOrder;

                //******* Choice Candidate Objects
                HObject ho_SelectedContours;
                HOperatorSet.GenEmptyObj(out ho_SelectedContours);
                ho_SelectedContours.Dispose();
                HOperatorSet.SelectContoursXld(ho_Border, out ho_SelectedContours, "contour_length",
                    10, Int16.MaxValue, -0.5, 0.5);

                //******* Fit Circle ************
                HTuple hv_Number, hv_Index;
                HObject ho_ObjectSelected;
                HOperatorSet.GenEmptyObj(out ho_ObjectSelected);
                HOperatorSet.CountObj(ho_SelectedContours, out hv_Number);
                var resultRadius = 0.0;
                for (hv_Index = 1; hv_Index.Continue(hv_Number, 1); hv_Index = hv_Index.TupleAdd(1))
                {
                    ho_ObjectSelected.Dispose();
                    HOperatorSet.SelectObj(ho_SelectedContours, out ho_ObjectSelected, hv_Index);
                    HOperatorSet.FitCircleContourXld(ho_SelectedContours
                    , _Algorithm, _MaxNumPoints, _MaxClosureDist, _ClippingEndPoints, _Iterations, _ClippingFactor
                    , out hv_Row, out hv_Column, out hv_Radius, out hv_StartPhi, out hv_EndPhi, out hv_PointOrder);

                    //Answer
                    var radiusIndex = -1;
                    if (hv_Radius.TupleLength() > 0)
                    {
                        radiusIndex = DistanceHelper.GetApproximateRadiusIndex(hv_Radius.DArr, areaPixels);
                        if (radiusIndex > -1)
                        {
                            //取最大的 Circle
                            if (resultRadius < hv_Radius.DArr[radiusIndex])
                            {
                                result = new CircleResult(new HTuple(hv_Row.DArr[radiusIndex])
                                                            , new HTuple(hv_Column.DArr[radiusIndex])
                                                            , new HTuple(hv_Radius.DArr[radiusIndex])
                                                            , hv_StartPhi
                                                            , hv_EndPhi
                                                            , hv_PointOrder) { };
                                resultRadius = hv_Radius.DArr[radiusIndex];
                            }
                        }
                    }
                }
            }
            catch (HOperatorException ex)
            {
                Hanbo.Log.LogManager.Error(ex);
            }
            return result;
        }
        /// <summary>
        /// 更新量測結果.
        /// 量測演算法放這裡
        /// </summary>
        public override void UpdateResults()
        {
            if (mMeasAssist.mImage == null) return;

            #region 初始化數值
            if (!String.IsNullOrEmpty(mMeasAssist.FitCircleAlgo))
                _Algorithm = new HTuple(mMeasAssist.FitCircleAlgo);

            //init result
            mResult = new CircleResult();

            // Local iconic variables
            HObject ho_MeasureROI, ho_ImageReduced;
            HObject ho_Border, tmp_Border;

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_MeasureROI);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_Border);
            HOperatorSet.GenEmptyObj(out tmp_Border);
            #endregion

            try
            {
                //******* Create ROI ********
                ho_MeasureROI.Dispose();
                HOperatorSet.GenCircle(out ho_MeasureROI, mROICoord[0], mROICoord[1], mROICoord[2]);
                HRegion region = new HRegion();
                region.GenCircle(mROICoord[0].D, mROICoord[1].D, mROICoord[2].D);

                //****** Area Center, 取得目標區域的 pixels 數 ***********
                HTuple area, areaRow, areaColumn;
                double areaPixels = 0.0;
                HOperatorSet.AreaCenter(region, out area, out areaRow, out areaColumn);
                areaPixels = area.D;

                //****** 取得影像 ******
                var himage = mMeasAssist.getImage();

                //******* Extract ROI Image *****
                ho_ImageReduced.Dispose();
                HOperatorSet.ReduceDomain(himage, ho_MeasureROI, out ho_ImageReduced);

                //******* Filter ****************
                var subpixThreadhold = mMeasAssist.SubpixThreadhold;
                HOperatorSet.GenEmptyObj(out ho_Border);
                HOperatorSet.ThresholdSubPix(ho_ImageReduced, out ho_Border, subpixThreadhold);

                if (mMeasAssist.ApplyCalibration && mMeasAssist.IsCalibrationValid)
                {
                    if (_cameraOut.TupleLength() == 0)
                    {
                        _cameraOut = HMisc.ChangeRadialDistortionCamPar("adaptive", mMeasAssist.CameraIn, 0.0);
                    }
                    //var rectifyImage = himage.ChangeRadialDistortionImage(region, mMeasAssist.CameraIn, cameraOut);
                    HObject calibrationBorder;
                    HOperatorSet.GenEmptyObj(out calibrationBorder);
                    HOperatorSet.ChangeRadialDistortionContoursXld(ho_Border, out calibrationBorder, mMeasAssist.CameraIn, _cameraOut);
                    mResult = fitCircle(calibrationBorder, areaPixels);
                }
                else
                {
                    mResult = fitCircle(ho_Border, areaPixels);
                }

            }
            catch (HOperatorException ex)
            {
                Hanbo.Log.LogManager.Error(ex);
                mResultWorld = new CircleResult();
                mResult = new CircleResult();
            }
            finally
            {
                ho_MeasureROI.Dispose();
                ho_ImageReduced.Dispose();
                ho_Border.Dispose();
            }
            UpdateXLD();
        }
Esempio n. 15
0
        public MeasureResult Action()
        {
            #region 輸出結果
            CircleResult mResult = null;
            #endregion
            // Local iconic variables

            HObject ho_R6_Circle = null;
            HObject ho_R6_ROI_Image = null, ho_R6_Region = null, ho_R6_RegionBorder = null;
            HObject ho_R6_RegionDilation = null, ho_R6_ImageReduced = null;
            HObject ho_R6_Edges = null, ho_R6_ContoursSplit = null, ho_R6_SingleSegment = null;
            HObject ho_R6_ContEllipse = null;

            // Local control variables

            HTuple hv_msgOffsetY, hv_msgOffsetX;
            HTuple hv_STD_Row;
            HTuple hv_STD_Col, hv_Img_Row, hv_Img_Col, hv_Img_Rotate_Angle;
            HTuple hv_OffsetRow, hv_OffsetCol, hv_R6;
            HTuple hv_STD_R6_Row = new HTuple(), hv_STD_R6_Col = new HTuple();
            HTuple hv_STD_R6_V_Row = new HTuple(), hv_STD_R6_V_Col = new HTuple();
            HTuple hv_R6_X = new HTuple(), hv_R6_Y = new HTuple(), hv_R6_Pos_Row = new HTuple();
            HTuple hv_R6_Pos_Col = new HTuple(), hv_R6_R = new HTuple();
            HTuple hv_R6_R_Max = new HTuple(), hv_R6_R_Inc = new HTuple();
            HTuple hv_R6_NumSegments = new HTuple(), hv_NumCircles = new HTuple();
            HTuple hv_Num_Circle_Point = new HTuple(), hv_i = new HTuple();
            HTuple hv_Attrib = new HTuple(), hv_R6_Row = new HTuple();
            HTuple hv_R6_Column = new HTuple(), hv_R6_Radius = new HTuple();
            HTuple hv_R6_StartPhi = new HTuple(), hv_R6_EndPhi = new HTuple();
            HTuple hv_R6_PointOrder = new HTuple(), hv_R6_MinDist = new HTuple();
            HTuple hv_R6_MaxDist = new HTuple(), hv_R6_AvgDist = new HTuple();
            HTuple hv_R6_SigmaDist = new HTuple();

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_R6_Circle);
            HOperatorSet.GenEmptyObj(out ho_R6_ROI_Image);
            HOperatorSet.GenEmptyObj(out ho_R6_Region);
            HOperatorSet.GenEmptyObj(out ho_R6_RegionBorder);
            HOperatorSet.GenEmptyObj(out ho_R6_RegionDilation);
            HOperatorSet.GenEmptyObj(out ho_R6_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_R6_Edges);
            HOperatorSet.GenEmptyObj(out ho_R6_ContoursSplit);
            HOperatorSet.GenEmptyObj(out ho_R6_SingleSegment);
            HOperatorSet.GenEmptyObj(out ho_R6_ContEllipse);

            //Measure: SDMS_R6
            //Author: John Hsieh
            //Date: 2012
            // dev_update_off(...); only in hdevelop
            HOperatorSet.SetSystem("border_shape_models", "false");

            //****Message Args
            hv_msgOffsetY = 100;
            hv_msgOffsetX = 100;

            //****Model Args

            //STD 中心點
            hv_STD_Row = 772;
            hv_STD_Col = 1003;

            //目前圖形 中心點
            hv_Img_Row = hv_AllModelRow.Clone();
            hv_Img_Col = hv_AllModelColumn.Clone();

            //目前圖形 Rotate Angle
            hv_Img_Rotate_Angle = hv_AllModelAngle.Clone();

            //目前圖形偏移量
            hv_OffsetRow = hv_Img_Row - hv_STD_Row;
            hv_OffsetCol = hv_Img_Col - hv_STD_Col;

            //****Display
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
            }
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
            }
            //*****R6
            hv_R6 = 999;
            //STD R6_ 位置
            hv_STD_R6_Row = 1292;
            hv_STD_R6_Col = 639;

            //STD 向量 STD_R6_
            hv_STD_R6_V_Row = hv_STD_R6_Row - hv_STD_Row;
            hv_STD_R6_V_Col = hv_STD_R6_Col - hv_STD_Col;

            //R6_X, R6_Y 分量
            hv_R6_X = (hv_STD_R6_V_Col * (hv_Img_Rotate_Angle.TupleCos())) + (hv_STD_R6_V_Row * (hv_Img_Rotate_Angle.TupleSin()
                ));
            hv_R6_Y = (hv_STD_R6_V_Row * (hv_Img_Rotate_Angle.TupleCos())) - (hv_STD_R6_V_Col * (hv_Img_Rotate_Angle.TupleSin()
                ));

            //目前圖形 R4 位置
            hv_R6_Pos_Row = (hv_STD_Row + hv_R6_Y) + hv_OffsetRow;
            hv_R6_Pos_Col = (hv_STD_Col + hv_R6_X) + hv_OffsetCol;

            //R6_Region 由半徑 29 開始搜尋, 最大搜尋至 41, Inc =2
            hv_R6_R = 29;
            hv_R6_R_Max = 41;
            hv_R6_R_Inc = 2;
            while ((int)((new HTuple(hv_R6.TupleEqual(999))).TupleAnd(new HTuple(hv_R6_R.TupleLess(
                hv_R6_R_Max)))) != 0)
            {
                //*******************************
                ho_R6_Circle.Dispose();
                HOperatorSet.GenCircle(out ho_R6_Circle, hv_R6_Pos_Row, hv_R6_Pos_Col, hv_R6_R);
                ho_R6_ROI_Image.Dispose();
                HOperatorSet.ReduceDomain(ho_Image, ho_R6_Circle, out ho_R6_ROI_Image);
                ho_R6_Region.Dispose();
                HOperatorSet.Threshold(ho_R6_ROI_Image, out ho_R6_Region, 100, 255);
                ho_R6_RegionBorder.Dispose();
                HOperatorSet.Boundary(ho_R6_Region, out ho_R6_RegionBorder, "inner");
                ho_R6_RegionDilation.Dispose();
                HOperatorSet.DilationCircle(ho_R6_RegionBorder, out ho_R6_RegionDilation,
                    1.5);
                ho_R6_ImageReduced.Dispose();
                HOperatorSet.ReduceDomain(ho_R6_ROI_Image, ho_R6_RegionDilation, out ho_R6_ImageReduced
                    );
                ho_R6_Edges.Dispose();
                HOperatorSet.EdgesSubPix(ho_R6_ImageReduced, out ho_R6_Edges, "lanser2",
                    0.3, 40, 90);

                //fast_threshold (R6_ROI_Image, R6_Region, 80, 255, 15)
                //reduce_domain (R6_ROI_Image, R6_Region, R6_ImageReduced)
                //sobel_fast 具有較寬的選擇範圍,搭配 alpha 參數 (alpha 越大, 容錯範圍大)
                //alpha := 10
                //R6_low := 10
                //R6_high := 60
                //edges_sub_pix (R6_ImageReduced, R6_Edges, 'sobel_fast', alpha, R6_low, R6_high)
                //stop ()
                //*所有的數值越小,表示容錯範圍大,反之亦然
                ho_R6_ContoursSplit.Dispose();
                HOperatorSet.SegmentContoursXld(ho_R6_Edges, out ho_R6_ContoursSplit, "lines_circles",
                    6, 4, 4);

                //Display the results
                //===========================================================
                HOperatorSet.CountObj(ho_R6_ContoursSplit, out hv_R6_NumSegments);
                hv_NumCircles = 0;
                hv_Num_Circle_Point = 0;
                for (hv_i = 1; hv_i.Continue(hv_R6_NumSegments, 1); hv_i = hv_i.TupleAdd(1))
                {
                    ho_R6_SingleSegment.Dispose();
                    HOperatorSet.SelectObj(ho_R6_ContoursSplit, out ho_R6_SingleSegment, hv_i);
                    HOperatorSet.GetContourGlobalAttribXld(ho_R6_SingleSegment, "cont_approx",
                        out hv_Attrib);
                    if ((int)(new HTuple(hv_Attrib.TupleEqual(1))) != 0)
                    {
                        HOperatorSet.FitCircleContourXld(ho_R6_SingleSegment, "atukey", -1, 2,
                            hv_Num_Circle_Point, 5, 2, out hv_R6_Row, out hv_R6_Column, out hv_R6_Radius,
                            out hv_R6_StartPhi, out hv_R6_EndPhi, out hv_R6_PointOrder);
                        ho_R6_ContEllipse.Dispose();
                        HOperatorSet.GenEllipseContourXld(out ho_R6_ContEllipse, hv_R6_Row, hv_R6_Column,
                            0, hv_R6_Radius, hv_R6_Radius, 0, (new HTuple(360)).TupleRad(), "positive",
                            1.0);
                        if (HDevWindowStack.IsOpen())
                        {
                            HOperatorSet.DispObj(ho_R6_ContEllipse, HDevWindowStack.GetActive()
                                );
                        }
                        HOperatorSet.DistEllipseContourXld(ho_R6_SingleSegment, "algebraic",
                            -1, 0, hv_R6_Row, hv_R6_Column, 0, hv_R6_Radius, hv_R6_Radius, out hv_R6_MinDist,
                            out hv_R6_MaxDist, out hv_R6_AvgDist, out hv_R6_SigmaDist);
                        hv_NumCircles = hv_NumCircles + 1;
                        if ((int)(new HTuple(hv_R6.TupleGreater(hv_R6_Radius))) != 0)
                        {
                            hv_R6 = hv_R6_Radius.Clone();
                            mResult = new CircleResult()
                            {
                                Row = new HTuple(hv_R6_Row),
                                Col = new HTuple(hv_R6_Column),
                                Radius = new HTuple(hv_R6_Radius),
                                StartPhi = new HTuple(hv_R6_StartPhi),
                                EndPhi = new HTuple(hv_R6_EndPhi),
                                PointOrder = new HTuple(hv_R6_PointOrder),
                            };
                        }
                    }
                }
                hv_R6_R = hv_R6_R + hv_R6_R_Inc;
            }

            ho_R6_Circle.Dispose();
            ho_R6_ROI_Image.Dispose();
            ho_R6_Region.Dispose();
            ho_R6_RegionBorder.Dispose();
            ho_R6_RegionDilation.Dispose();
            ho_R6_ImageReduced.Dispose();
            ho_R6_Edges.Dispose();
            ho_R6_ContoursSplit.Dispose();
            ho_R6_SingleSegment.Dispose();
            ho_R6_ContEllipse.Dispose();

            return mResult;
        }