Пример #1
0
        List <DlafFovDetectResult> _lstFovResults = new List <DlafFovDetectResult>(); //保存当前料片的测试结果

        public void OnCustomizeMsg(string msgCategory, object[] msgParams)            //其他自定义消息
        {
            BeginInvoke(new Action(() =>
            {
                if (msgCategory == DLAFOfflineSetectStation.SCM_PieceStart) //开始了一个料片检测
                {
                    if (_currRecipe == null)
                    {
                        _currRecipe = (JFHubCenter.Instance.RecipeManager as JFDLAFRecipeManager).GetRecipe("Product", cbRecipeID.Text) as JFDLAFProductRecipe;
                    }

                    _lstFovResults.Clear();
                    mapDetectCells.InitaialDieState();
                    rchDetectInfo.Text = "";
                    rchDetectInfo.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + "    开始检测");

                    _currICRow = -1;   //当前显示的ICRow
                    _currICCol = -1;
                    _currFov   = null; //当前显示的Fov
                    _picFolder = msgParams[0] as string;
                }
                else if (msgCategory == DLAFOfflineSetectStation.SCM_PieceEnd) //一个料片检测完成
                {
                }
                else if (msgCategory == DLAFOfflineSetectStation.SCM_FovDetectResult) //一个Fov检测完成 , 显示结果
                {
                    if (null != _currTaskImgs)
                    {
                        foreach (HObject ho in _currTaskImgs)
                        {
                            ho.Dispose();
                        }
                        _currTaskImgs = null;
                    }
                    _currTaskImgs           = msgParams[0] as List <HObject>; //从Fov中读出的原图
                    DlafFovDetectResult fdr = (msgParams[1] as DlafFovDetectResult).Clone();
                    _lstFovResults.Add(fdr);

                    _currICRow = fdr.ICRow;
                    _currICCol = fdr.ICCol;
                    _currFov   = fdr.FovName;



                    ShowFovImageResult();     //画图
                    UpdateErrorDataGrid(fdr); //将错误信息更新到DatagridView
                    UpdateDetectMapping(fdr); //将检测结果更新到Map控件


                    rchDetectInfo.AppendText("ICRow:" + fdr.ICRow + " ICCol:" + fdr.ICCol + " Fov:" + fdr.FovName + "-----\n");
                    rchDetectInfo.AppendText("检测" + (fdr.IsDetectSuccess ? "完成" : ("失败:" + fdr.DetectErrorInfo)) + "\n");
                }
            }));
        }
        /// <summary>
        /// 设置产品信号/批次号
        /// </summary>
        /// <param name="recipeID"></param>
        /// <param name="lotID"></param>
        /// <param name="errorInfo"></param>
        /// <returns></returns>
        public bool SetRecipeLot(string recipeID, string lotID, out string errorInfo)
        {
            if (string.IsNullOrEmpty(recipeID))
            {
                errorInfo = "参数RecipeID为空字串";
                _recipeID = null;
                return(false);
            }
            JFDLAFRecipeManager rm = JFHubCenter.Instance.RecipeManager as JFDLAFRecipeManager;

            if (null == rm || !rm.IsInitOK)
            {
                errorInfo = "配方管理器未设置/未初始化!";
                _recipeID = null;
                return(false);
            }
            string[] allRecipeIDS = rm.AllRecipeIDsInCategoty("Product");
            if (null == allRecipeIDS || !allRecipeIDS.Contains(recipeID))
            {
                errorInfo = "RecipeID:\"" + recipeID + "\"在配方管理器中不存在!";
                _recipeID = null;
                return(false);
            }
            _recipeID = recipeID;
            _recipe   = rm.GetRecipe("Product", _recipeID) as JFDLAFProductRecipe;


            if (string.IsNullOrEmpty(lotID))
            {
                _lotID    = null;
                errorInfo = "参数项LotID为空值";
                return(false);
            }

            _lotID = lotID;

            int fovCountInPiece = _recipe.FovCount * _recipe.ICCount;//料片所有Fov数量

            _fovResults  = new DlafFovDetectResult[fovCountInPiece];
            _fovCounteds = new bool[fovCountInPiece];



            errorInfo = "Success";
            return(true);
        }
Пример #3
0
        void UpdateTaskNameButtons(DlafFovDetectResult fdr)
        {
            if (null == _currRecipe)
            {
                return;
            }
            string[] taskNames = fdr.TaskNames;
            int      i         = 0;

            for (i = 0; i < taskNames.Length; i++)
            {
                if (i < _rbTaskNames.Length)
                {
                    _rbTaskNames[i].Visible = true;
                    _rbTaskNames[i].Enabled = true;
                    _rbTaskNames[i].Text    = taskNames[i];
                }
            }
            for (; i < _rbTaskNames.Length; i++)
            {
                _rbTaskNames[i].Visible = false;
            }
        }
        /// <summary>
        /// 输入一条Fov的检测结果
        /// </summary>
        /// <param name="fovResult">Fov检测结果</param>
        public void EntryFovResult(DlafFovDetectResult fr /*, out bool isLastFovInPiece*/)
        {
            if (null == fr)
            {
                return;
            }
            int fovIndexInDie = 0;

            string[] allFovNames = _recipe.FovNames();
            for (int i = 0; i < allFovNames.Length; i++)
            {
                if (fr.FovName == allFovNames[i])
                {
                    fovIndexInDie = i;
                    break;
                }
            }

            int idx = (fr.ICRow * _recipe.ColCount + fr.ICCol) * _recipe.FovCount + fovIndexInDie;

            _fovResults[idx]  = fr;
            _fovCounteds[idx] = false;
        }
Пример #5
0
        /// <summary>
        /// 将错误信息更新到列表中
        /// </summary>
        /// <param name="fdr"></param>
        void UpdateErrorDataGrid(DlafFovDetectResult fdr)
        {
            bool _isShowAllItems = chkShowAllItems.Checked;

            lbSelectedInfo.Text = "选中单元: Row=" + (fdr.ICRow + 1) + " Col=" + (fdr.ICCol + 1) + " FovName:" + fdr.FovName + " 结果:" + (fdr.IsFovOK ? "合格" : "不合格");
            dgvInspectResultsInFov.Rows.Clear();

            int dieIndex = 0;
            int dieCount = fdr.CurrColCount * fdr.CurrRowCount;

            if (dieCount <= 0)//Fov只是Die的一部分
            {
                dieCount = 1;
            }
            //表格行 : Die/检测项/检测结果/检测标准数据/检测结果数据/备注
            for (dieIndex = 0; dieIndex < dieCount; dieIndex++)
            {
                if (!fdr.IsDetectSuccess) //视觉算子出错
                {
                    DataGridViewRow row = new DataGridViewRow();

                    DataGridViewTextBoxCell dieIndexCell = new DataGridViewTextBoxCell();
                    dieIndexCell.Style.BackColor = Color.Red;
                    dieIndexCell.Value           = dieIndex + 1;
                    row.Cells.Add(dieIndexCell);


                    DataGridViewTextBoxCell detectItemCell = new DataGridViewTextBoxCell();
                    detectItemCell.Value           = "---";
                    detectItemCell.Style.ForeColor = Color.Red;
                    row.Cells.Add(detectItemCell);

                    DataGridViewTextBoxCell dieErrorCell = new DataGridViewTextBoxCell();
                    dieErrorCell.Value           = "检测出错:" + fdr.DetectErrorInfo;
                    dieErrorCell.Style.ForeColor = Color.Red;
                    row.Cells.Add(dieErrorCell);

                    DataGridViewTextBoxCell dieRefVelCell = new DataGridViewTextBoxCell();
                    dieRefVelCell.Value           = "---";
                    dieRefVelCell.Style.ForeColor = Color.Red;
                    row.Cells.Add(dieRefVelCell);


                    DataGridViewTextBoxCell dieDetectVelCell = new DataGridViewTextBoxCell();
                    dieDetectVelCell.Value           = "---";
                    dieDetectVelCell.Style.ForeColor = Color.Red;
                    row.Cells.Add(dieDetectVelCell);

                    DataGridViewTextBoxCell dieRemarksCell = new DataGridViewTextBoxCell();
                    string rowColInfo = "Die:" + (dieIndex + 1) + " 行:" + (dieIndex / dieCount + 1) + " 列:" + (dieIndex % dieCount + 1);
                    dieRemarksCell.Value           = rowColInfo;
                    dieRemarksCell.Style.ForeColor = Color.Red;
                    row.Cells.Add(dieRemarksCell);


                    dgvInspectResultsInFov.Rows.Add(row);
                }
                else //检测成功,列出每个检测项
                {
                    for (int i = 0; i < fdr.DieInspectResults[dieIndex].Length; i++)
                    {
                        if (!_isShowAllItems && fdr.DieInspectResults[dieIndex][i].IsDetectOK())
                        {
                            continue;
                        }
                        DataGridViewRow row      = new DataGridViewRow();
                        Color           txtColor = Color.DarkGreen;
                        if (!DlafFovDetectResult.IsInspectItemsOK(fdr.DieInspectResults[dieIndex]))
                        {
                            txtColor = Color.DarkRed;
                        }
                        DataGridViewTextBoxCell dieIndexCell = new DataGridViewTextBoxCell();
                        dieIndexCell.Style.ForeColor = txtColor;
                        dieIndexCell.Value           = dieIndex + 1;
                        row.Cells.Add(dieIndexCell);

                        DataGridViewTextBoxCell detectItemCell = new DataGridViewTextBoxCell();
                        detectItemCell.Value           = fdr.DieInspectResults[dieIndex][i].InspectID;
                        detectItemCell.Style.ForeColor = fdr.DieInspectResults[dieIndex][i].IsDetectOK() ? Color.DarkGreen : Color.DarkRed;
                        row.Cells.Add(detectItemCell);

                        DataGridViewTextBoxCell dieErrorCell = new DataGridViewTextBoxCell();
                        dieErrorCell.Value           = string.Join(" ", fdr.DieInspectResults[dieIndex][i].ErrorTexts);
                        dieErrorCell.Style.ForeColor = fdr.DieInspectResults[dieIndex][i].IsDetectOK() ? Color.DarkGreen : Color.DarkRed;
                        row.Cells.Add(dieErrorCell);


                        DataGridViewTextBoxCell dieRefVelCell = new DataGridViewTextBoxCell();
                        dieRefVelCell.Value = fdr.DieInspectResults[dieIndex][i].QualifiedDescript;
                        //dieRefVelCell.Style.ForeColor = fdr.DieInspectResults[dieIndex][i].IsDetectOK() ? Color.DarkGreen : Color.DarkRed;
                        row.Cells.Add(dieRefVelCell);


                        DataGridViewTextBoxCell dieDetectVelCell = new DataGridViewTextBoxCell();
                        dieDetectVelCell.Value = fdr.DieInspectResults[dieIndex][i].ResultDescript;
                        row.Cells.Add(dieDetectVelCell);

                        DataGridViewTextBoxCell dieRemarksCell = new DataGridViewTextBoxCell();
                        string rowColInfo = "Die:" + (dieIndex + 1) + " 行:" + (dieIndex / dieCount + 1) + " 列:" + (dieIndex % dieCount + 1);
                        dieRemarksCell.Value = rowColInfo;
                        row.Cells.Add(dieRemarksCell);


                        dgvInspectResultsInFov.Rows.Add(row);
                    }
                }
            }
        }
Пример #6
0
        //显示图像/以及测试结果
        void ShowFovImageResult()
        {
            if (null == _currRecipe)
            {
                return;
            }
            if (null == _currTaskImgs)
            {
                return;
            }

            int idxInRetList = (_currICRow * _currRecipe.ColCount + _currICCol) * _currRecipe.FovCount + _FovNameIndex(_currFov);

            if (null == _lstFovResults || idxInRetList >= _lstFovResults.Count)
            {
                //htDetectImg.RefreshWindow(_currTaskImgs[_currTask], null, "fit");
                return;
            }
            DlafFovDetectResult fdr = _lstFovResults[idxInRetList];

#if false                                            //老版本算子的显示
            htDetectImg.ColorName = "green";
            bool isShowImg = fdr.WireRegion != null; //fdr.DetectIterms != null && fdr.DetectIterms.ContainsKey("WireRegions");
            if (isShowImg)
            {
                htDetectImg.RefreshWindow(_currTaskImgs[_currTask], fdr.WireRegion, "fit");
            }


            htDetectImg.ColorName = "yellow";

            HObject OKRegion = null;
            HOperatorSet.GenEmptyRegion(out OKRegion);
            if (fdr.DetectIterms != null)
            {
                foreach (KeyValuePair <string, HObject> kvRegion in fdr.DetectIterms)
                {
                    if (kvRegion.Key == "WireRegions")
                    {
                        continue;
                    }
                    if (null != kvRegion.Value)
                    {
                        HOperatorSet.ConcatObj(OKRegion, kvRegion.Value, out OKRegion);
                    }
                }
                if (!isShowImg)
                {
                    htDetectImg.RefreshWindow(_currTaskImgs[_currTask], OKRegion, "fit");
                    isShowImg = true;
                }
                else
                {
                    htDetectImg.DispRegion(OKRegion);
                }
            }
            //显示ErrorRegion
            htDetectImg.ColorName = "red";
            HObject hoFailedRegion = null;
            HOperatorSet.GenEmptyRegion(out hoFailedRegion);
            if (null != fdr.DiesErrorRegions)
            {
                foreach (HObject[] hoRegs in fdr.DiesErrorRegions)
                {
                    if (null != hoRegs)
                    {
                        foreach (HObject hoReg in hoRegs)
                        {
                            if (null != hoReg)
                            {
                                HOperatorSet.ConcatObj(hoFailedRegion, hoReg, out hoFailedRegion);
                            }
                        }
                    }
                }
            }
            if (null != hoFailedRegion)
            {
                if (!isShowImg)
                {
                    htDetectImg.RefreshWindow(_currTaskImgs[_currTask], hoFailedRegion, "fit");
                }
                else
                {
                    htDetectImg.DispRegion(hoFailedRegion);
                }
            }
#endif
            bool _isShowAllItem = chkShowAllItems.Checked;
            htDetectImg.RefreshWindow(_currTaskImgs[_currTask], null, "fit");
            if (!fdr.IsDetectSuccess || null == fdr.DieInspectResults)
            {
                return;
            }

            HObject errRegion = null;//所有错误区域
            HOperatorSet.GenEmptyRegion(out errRegion);


            HObject bondRegion = null;
            HOperatorSet.GenEmptyRegion(out bondRegion);
            HObject wireRegion = null;
            HOperatorSet.GenEmptyRegion(out wireRegion);
            HObject epoxyRegion = null;
            HOperatorSet.GenEmptyRegion(out epoxyRegion);


            foreach (InspectResultItem[] dieItems in fdr.DieInspectResults)
            {
                foreach (InspectResultItem item in dieItems)
                {
                    if (!item.IsDetectOK())
                    {
                        HOperatorSet.ConcatObj(errRegion, item.ResultRegion, out errRegion);
                    }
                    if (!_isShowAllItem)
                    {
                        continue;
                    }

                    switch (item.InspectCategoty)
                    {
                    case InspectResultItem.Categoty.Frame:
                        break;

                    case InspectResultItem.Categoty.IC:
                        break;

                    case InspectResultItem.Categoty.Bond:
                        HOperatorSet.ConcatObj(bondRegion, item.ResultRegion, out bondRegion);
                        break;

                    case InspectResultItem.Categoty.Wire:
                        HOperatorSet.ConcatObj(wireRegion, item.ResultRegion, out wireRegion);
                        break;

                    case InspectResultItem.Categoty.Epoxy:
                        HOperatorSet.ConcatObj(epoxyRegion, item.ResultRegion, out epoxyRegion);
                        break;
                    }
                }
            }
            if (_isShowAllItem)
            {
                htDetectImg.ColorName = "green";
                htDetectImg.DispRegion(wireRegion);
                htDetectImg.ColorName = "yellow";
                htDetectImg.DispRegion(bondRegion);
                htDetectImg.ColorName = "blue";
                htDetectImg.DispRegion(epoxyRegion);
            }
            htDetectImg.ColorName = "red";
            htDetectImg.DispRegion(errRegion);
        }
Пример #7
0
        /// <summary>
        /// 更新Map控件
        /// </summary>
        /// <param name="fdr"></param>
        void UpdateDetectMapping(DlafFovDetectResult fdr)
        {
            int colInMap = fdr.ICCol * _currRecipe.FovCount + _FovNameIndex(fdr.FovName);

            mapDetectCells.SetDieState(fdr.ICRow, colInMap, fdr.IsFovOK ? "合格" : "不合格");
        }
Пример #8
0
        public DlafFovDetectResult Clone()
        {
            DlafFovDetectResult ret = new DlafFovDetectResult();

            ret.ICRow          = ICRow;
            ret.ICCol          = ICCol;
            ret.FovName        = FovName;
            ret.DetectDiesRows = DetectDiesRows;
            ret.DetectDiesCols = DetectDiesCols;
            ret.DiesErrorCodes = DiesErrorCodes;

            ret.DiesErrorTaskNames = DiesErrorTaskNames;

            //非托管对象
            if (null != DiesErrorRegions)
            {
                ret.DiesErrorRegions = new HObject[DiesErrorRegions.Length][];
                for (int i = 0; i < DiesErrorRegions.Length; i++)
                {
                    if (DiesErrorRegions[i] == null)
                    {
                        ret.DiesErrorRegions[i] = null;
                    }
                    else
                    {
                        ret.DiesErrorRegions[i] = new HObject[DiesErrorRegions[i].Length];
                        for (int j = 0; j < DiesErrorRegions[i].Length; j++)
                        {
                            ret.DiesErrorRegions[i][j] = DiesErrorRegions[i][j].CopyObj(1, -1);//Clone();
                        }
                    }
                }
            }
            else
            {
                ret.DiesErrorRegions = DiesErrorRegions;
            }



            if (null != DetectIterms)
            {
                ret.DetectIterms = new Dictionary <string, HObject>();
                foreach (string key in DetectIterms.Keys)
                {
                    HObject val = DetectIterms[key];
                    if (null == val)
                    {
                        ret.DetectIterms.Add(key, null);
                    }
                    else
                    {
                        ret.DetectIterms.Add(key, val.Clone());
                    }
                }
            }
            else
            {
                ret.DetectIterms = null;
            }


            if (null != DetectDiesImages)
            {
                ret.DetectDiesImages = new HObject[DetectDiesImages.Length];
                for (int i = 0; i < DetectDiesImages.Length; i++)
                {
                    ret.DetectDiesImages[i] = DetectDiesImages[i].Clone();
                }
            }
            else
            {
                ret.DetectDiesImages = null;
            }

            if (null != WireRegion)
            {
                ret.WireRegion = WireRegion.Clone();
            }
            else
            {
                ret.WireRegion = null;
            }



            return(ret);
        }
Пример #9
0
        protected override void RunLoopInWork()
        {
            NotifyCustomizeMsg(SCM_PieceStart, new object[] { _currPiecePicFolder });
            //Inspect_Node inpect = JFDLAFInspectionManager.Instance.GetInspectNode
            int rows = _currRecipe.RowCount;
            int cols = _currRecipe.ColCount;

            string[] fovNames = _currRecipe.FovNames();
            for (int currRow = 0; currRow < rows; currRow++)
            {
                for (int currCol = 0; currCol < cols; currCol++)
                {
                    for (int currFov = 0; currFov < fovNames.Length; currFov++)
                    {
                        CheckCmd(CycleMilliseconds); //检测是否有暂停/恢复/退出 消息
                        string fovName      = fovNames[currFov];
                        string fovSubFolder = "Row_" + currRow + "-" + "Col_" + currCol + "-Fov_" + fovName;
                        string fovFolder    = _currPiecePicFolder + "\\" + fovSubFolder;//存储图片的文件夹
                        if (!Directory.Exists(fovFolder))
                        {
                            ExitWork(WorkExitCode.Error, "Fov图片文件夹:\"" + fovFolder + "\"不存在");
                        }
                        InspectNode fovInspNode = JFDLAFInspectionManager.Instance.GetInspectNode(RecipeID, fovName);
                        if (null == fovInspNode)
                        {
                            ExitWork(WorkExitCode.Error, "算子管理器中不存在 RecipeID = " + RecipeID + " Fov = " + fovName + "  的检测算子");
                        }

                        string[] filesInFovFolder = Directory.GetFiles(fovFolder);//Fov文件夹中现有的文件
                        if (null == filesInFovFolder || filesInFovFolder.Length == 0)
                        {
                            ExitWork(WorkExitCode.Error, "Fov图片文件夹:\"" + fovFolder + "\"中没有文件");
                        }


                        string[]       taskNames = _currRecipe.TaskNames(fovName);
                        List <HObject> taskImgs  = new List <HObject>();
                        foreach (string taskName in taskNames)
                        {
                            HObject hoImg;
                            HOperatorSet.GenEmptyObj(out hoImg);
                            string taskImgFile = null;
                            foreach (string s in filesInFovFolder)
                            {
                                string exn = Path.GetExtension(s);
                                if (string.Compare(exn, ".bmp", true) != 0 &&
                                    string.Compare(exn, ".tiff", true) != 0 &&
                                    string.Compare(exn, ".tif", true) != 0 &&
                                    string.Compare(exn, ".jpg", true) != 0 &&
                                    string.Compare(exn, ".jpeg", true) != 0 &&
                                    string.Compare(exn, ".png", true) != 0)
                                {
                                    continue;                                     //先过滤掉非图像文件
                                }
                                string fnn = Path.GetFileNameWithoutExtension(s); //不带后缀的文件名
                                if (fnn.LastIndexOf(taskName) >= 0 &&
                                    fnn.Length == (fnn.LastIndexOf(taskName) + taskName.Length))
                                {
                                    taskImgFile = s;
                                    break;
                                }
                            }
                            if (null == taskImgFile)
                            {
                                ExitWork(WorkExitCode.Error, "Task = " + taskName + "  图片文件不存在");
                            }

                            HOperatorSet.ReadImage(out hoImg, taskImgFile);
                            taskImgs.Add(hoImg);
                        }

                        DlafFovDetectResult fdr = new DlafFovDetectResult();
                        fdr.FovName   = fovName;
                        fdr.ICRow     = currRow;
                        fdr.ICCol     = currCol;
                        fdr.TaskNames = taskNames;



                        string errorInfo;
                        //检测输入参数
                        HObject dieRegions;
                        int[]   dieRows, dieCols;
                        int     currDieRowCount, currDieColCount;
                        if (!_visionFixer.GetDetectRegionInFov(currRow, currCol, out dieRegions, out dieRows, out dieCols, out currDieRowCount, out currDieColCount, out errorInfo))
                        {
                            ExitWork(WorkExitCode.Error, "GetDetectRegionInFov failed,ErrorInfo:" + errorInfo);
                        }
                        fdr.DetectDiesRows = dieRows;
                        fdr.DetectDiesCols = dieCols;
                        fdr.CurrRowCount   = currDieRowCount;
                        fdr.CurrColCount   = currDieColCount;

                        //fdr.DieInspectResults = new List<InspectResultItem>[currDieRowCount* currDieColCount];
                        //for (int i = 0; i < currDieRowCount * currDieColCount; i++)
                        //    fdr.DieInspectResults[i] = new List<InspectResultItem>();

                        //检测输出参数
                        string          detectErrorInfo; //算子执行信息
                        List <int[]>    diesErrorCodes;  //= new List<int[]>();
                        List <string[]> diesErrorTaskNames;

                        List <HObject[]>             diesFailedRegions;
                        List <string[]>              diesErrorDetails; //错误的详细描述信息
                        Dictionary <string, HObject> detectItems;      //算子中输出的检测项(BondContours/WireRegions 等等)
                        Dictionary <string, string>  detectItemTaskNames;


                        //bool isDetectOK = fovInspNode.InspectImage(taskImgs.ToArray(), taskNames, dieRegions,
                        //                                            out detectErrorInfo, out diesErrorCodes, out diesErrorTaskNames, out diesFailedRegions,out diesErrorDetails,
                        //                                            out detectItems,out detectItemTaskNames);

                        //用于测试新数据结构
                        List <InspectResultItem[]> inspectResults = null;
                        bool isDetectOK = fovInspNode.InspectImage(taskImgs.ToArray(),
                                                                   dieRegions, out detectErrorInfo, out inspectResults);
                        fdr.DieInspectResults = inspectResults; //所有检测项


                        int dieCountInfov = dieRegions.CountObj();
                        //裁剪后的图象(按照Die的检测区域)
                        HObject[] dieImgs = new HObject[dieCountInfov];
                        HTuple    _row1, _col1, _row2, _col2;
                        HTuple    TWidth, THeight;
                        for (int i = 0; i < dieCountInfov; i++)
                        {
                            HOperatorSet.SmallestRectangle1(dieRegions.SelectObj(i + 1), out _row1, out _col1, out _row2, out _col2);
                            if (_row1 < 0)
                            {
                                _row1 = 0;
                            }
                            if (_col1 < 0)
                            {
                                _col1 = 0;
                            }
                            HOperatorSet.GetImageSize(taskImgs[0], out TWidth, out THeight);
                            if (_row2 > THeight)
                            {
                                _row2 = THeight;
                            }
                            if (_col2 > TWidth)
                            {
                                _row2 = TWidth;
                            }

                            HObject hoImages = null; //一颗Die的多通道图
                            HOperatorSet.GenEmptyObj(out hoImages);
                            for (int j = 0; j < taskImgs.Count; j++)
                            {
                                HObject ho;
                                HOperatorSet.CropRectangle1(taskImgs[j], out ho, _row1, _col1, _row2, _col2);
                                HOperatorSet.ConcatObj(hoImages, ho, out hoImages);
                            }
                            dieImgs[i] = hoImages;
                        }
                        fdr.DetectDiesImages = dieImgs;
                        fdr.IsDetectSuccess  = isDetectOK;
                        fdr.DetectErrorInfo  = detectErrorInfo;
                        //if (null != diesErrorCodes)
                        //    fdr.DiesErrorCodes = diesErrorCodes.ToArray();
                        //else
                        //    fdr.DiesErrorCodes = null;

                        //if (null != diesErrorTaskNames)
                        //    fdr.DiesErrorTaskNames = diesErrorTaskNames.ToArray();
                        //else
                        //    fdr.DiesErrorTaskNames = null;

                        //if (null != diesFailedRegions)
                        //    fdr.DiesErrorRegions = diesFailedRegions.ToArray();
                        //else
                        //    fdr.DiesErrorRegions = null;

                        //if (diesErrorDetails != null)
                        //    fdr.DiesErrorDetails = diesErrorDetails.ToArray();
                        //else
                        //    fdr.DiesErrorDetails = null;


                        //fdr.DetectIterms = detectItems;
                        //fdr.DetectItemTaskNames = detectItemTaskNames;
                        //if (fdr.DetectIterms != null && fdr.DetectIterms.ContainsKey("WireRegions"))
                        //{
                        //    fdr.WireRegion = fdr.DetectIterms["WireRegions"];
                        //    fdr.WireRegionTaskName = fdr.DetectItemTaskNames["WireRegions"];
                        //    fdr.DetectIterms.Remove("WireRegions");
                        //    fdr.DetectItemTaskNames.Remove("WireRegions");
                        //}



                        NotifyCustomizeMsg(SCM_FovDetectResult, new object[] {
                            taskImgs, //FOV原图
                            fdr       //测试结果
                        });
                    }
                }
            }
            NotifyCustomizeMsg(SCM_PieceEnd, null);
            ExitWork(WorkExitCode.Normal, "");
        }
        /// <summary>
        /// 尝试将现有队列中的Fov结果合并为Die结果,并输出
        /// (已经被计算合并过的FovResult将不再参与计算)
        /// </summary>
        /// <returns></returns>
        public InspectionData[] DisChargeDieResults()
        {
            if (null == _fovResults)
            {
                return(null);
            }
            List <InspectionData> ret = new List <InspectionData>();

            bool isSmallDie = _recipe.DieRowInFov * _recipe.DieColInFov > 0; //一个Fov中是否含有多个Die

            if (isSmallDie)                                                  //小Die
            {
                for (int i = 0; i < _fovResults.Length; i++)
                {
                    DlafFovDetectResult fovResult = _fovResults[i];
                    if (null == fovResult) //fov检测结果还没有输入
                    {
                        continue;
                    }
                    if (_fovCounteds[i]) //fov检测结果已经被统计过
                    {
                        continue;
                    }
                    for (int j = 0; j < fovResult.DetectDiesRows.Length; j++)
                    {
                        int            dieRow   = _recipe.DieRowInFov * fovResult.ICRow + fovResult.DetectDiesRows[j]; //料片中的die行列值
                        int            dieCol   = _recipe.DieColInFov * fovResult.ICCol + fovResult.DetectDiesCols[j];
                        InspectionData inspData = new InspectionData();
                        inspData.RecipeID        = _recipeID;
                        inspData.LotID           = _lotID;
                        inspData.FrameID         = _pieceID;
                        inspData.FovNames        = _recipe.FovNames();
                        inspData.TaskNamesInFovs = new string[inspData.FovNames.Length][];
                        for (int h = 0; h < inspData.FovNames.Length; h++)
                        {
                            inspData.TaskNamesInFovs[h] = _recipe.TaskNames(inspData.FovNames[h]);
                        }
                        inspData.Code2D      = null;
                        inspData.ColumnIndex = dieCol;
                        inspData.RowIndex    = dieRow;

                        if (null == fovResult.DetectDiesImages) //可能无图,(作为工站/界面交互数据)
                        {
                            inspData.Image = null;
                        }
                        else
                        {
                            inspData.Image = fovResult.DetectDiesImages[j].Clone();
                        }
                        if (!fovResult.IsDetectSuccess) //图象检测失败
                        {
                            inspData.InspectionResult = InspectionResults.NG;
                        }
                        else //图象检测成功
                        {
                            //金线区域
                            inspData.Wire = null;
                            if (null != fovResult.WireRegion)
                            {
                                HObject wireRegion   = fovResult.WireRegion;         //fovResult.DetectIterms["WireRegions"];
                                string  wrieTaskName = fovResult.WireRegionTaskName; //fovResult.DetectItemTaskNames["WireRegions"];
                                int     taskIdx      = 0;
                                for (int h = 0; h < inspData.TaskNamesInFovs[0].Length; h++)
                                {
                                    if (inspData.TaskNamesInFovs[0][h] == wrieTaskName)
                                    {
                                        taskIdx = h;
                                        break;
                                    }
                                }
                                HObject emptyRegion;
                                HOperatorSet.GenEmptyRegion(out emptyRegion);
                                HObject hoConcatReg;
                                if (taskIdx == 0)
                                {
                                    hoConcatReg = wireRegion.Clone();
                                    for (int h = 1; h < inspData.TaskNamesInFovs[0].Length; h++)
                                    {
                                        HOperatorSet.ConcatObj(hoConcatReg, emptyRegion, out hoConcatReg);
                                    }
                                }
                                else
                                {
                                    HOperatorSet.GenEmptyRegion(out hoConcatReg);
                                    for (int h = 1; h < inspData.TaskNamesInFovs[0].Length; h++)
                                    {
                                        if (taskIdx == h)
                                        {
                                            HOperatorSet.ConcatObj(hoConcatReg, wireRegion.Clone(), out hoConcatReg);
                                        }
                                        else
                                        {
                                            HOperatorSet.ConcatObj(hoConcatReg, emptyRegion, out hoConcatReg);
                                        }
                                    }
                                }

                                inspData.Wire = hoConcatReg;
                            }

                            inspData.Region = null; //保存所有出错的Region , 一维长度和序号
                            if (fovResult.DiesErrorRegions != null &&
                                fovResult.DiesErrorRegions[j] != null &&
                                fovResult.DiesErrorRegions[j].Length > 0)
                            {
                                HObject ho = fovResult.DiesErrorRegions[j][0].Clone();

                                for (int h = 1; h < fovResult.DiesErrorRegions[j].Length; h++)
                                {
                                    HOperatorSet.ConcatObj(ho, fovResult.DiesErrorRegions[j][h], out ho);
                                }
                                inspData.Region = ho;
                            }

                            int[] errorCodes = fovResult.DiesErrorCodes[j];
                            if (errorCodes.Length == 1 && errorCodes[0] == 0) //检测合格
                            {
                                inspData.InspectionResult = InspectionResults.OK;
                                inspData.List_DefectData  = null;
                            }
                            else
                            {
                                inspData.InspectionResult = InspectionResults.NG;
                                inspData.List_DefectData  = new List <DefectData>();
                                for (int h = 0; h < fovResult.DiesErrorCodes.Length; h++)
                                {
                                    DefectData dd = new DefectData();
                                    dd.DefectTypeIndex = errorCodes[h];
                                    dd.ErrorDetail     = fovResult.DiesErrorDetails[j][h];
                                    dd.ImageIndex      = _ImgIndex(fovResult.FovName, fovResult.DiesErrorTaskNames[j][h]);

                                    inspData.List_DefectData.Add(dd);
                                }
                            }

                            inspData.SuccessRegion           = null; //所有检测成功区域
                            inspData.SuccessRegionTypes      = null;
                            inspData.SuccessRegionImageIndex = null;
                            if (null != fovResult.DetectIterms && fovResult.DetectIterms.Count > 0)  //存在除了金线之外的其他检测项
                            {
                                List <HObject> itemRegs   = new List <HObject>();
                                List <string>  itemTyps   = new List <string>();
                                List <int>     itemImgIdx = new List <int>();
                                foreach (string itemName in fovResult.DetectIterms.Keys)
                                {
                                    itemRegs.Add(fovResult.DetectIterms[itemName]);
                                    itemTyps.Add(itemName);
                                    string tskName = fovResult.DetectItemTaskNames[itemName];
                                    for (int k = 0; k < fovResult.TaskNames[0].Length; k++)
                                    {
                                        if (tskName == fovResult.TaskNames[k])
                                        {
                                            itemImgIdx.Add(k);
                                            break;
                                        }
                                    }
                                }

                                if (itemRegs.Count() == 1)
                                {
                                    inspData.SuccessRegion = itemRegs[0];
                                }
                                else
                                {
                                    HObject hoReg = itemRegs[0].Clone();
                                    for (int h = 1; h < itemRegs.Count(); h++)
                                    {
                                        HOperatorSet.ConcatObj(hoReg, itemRegs[h], out hoReg);
                                    }
                                    inspData.SuccessRegion = hoReg;
                                }
                                inspData.SuccessRegionTypes      = itemTyps.ToArray();
                                inspData.SuccessRegionImageIndex = itemImgIdx.ToArray();
                            }
                            if (null == inspData.List_DefectData)
                            {
                                inspData.List_DefectData = new List <DefectData>();
                            }
                            ret.Add(inspData);
                        }
                        _fovCounteds[i] = true;
                    }
                }
            }
            else //大Die,一颗Die包含多个Fov
            {
                int fovCountInDie = _recipe.FovCount;
                for (int i = 0; i < _fovResults.Length; i += fovCountInDie)
                {
                    bool isFovsCan2Die = true; //多个Fov是否能集成为一个Die
                    for (int j = 0; j < fovCountInDie; j++)
                    {
                        if (null == _fovResults[i + j] || _fovCounteds[i])
                        {
                            isFovsCan2Die = false;
                            break;
                        }
                    }
                    if (!isFovsCan2Die)
                    {
                        continue;
                    }


                    InspectionData inspData = new InspectionData();
                    inspData.RecipeID        = _recipeID;
                    inspData.LotID           = _lotID;
                    inspData.FrameID         = _pieceID;
                    inspData.FovNames        = _recipe.FovNames();
                    inspData.TaskNamesInFovs = new string[inspData.FovNames.Length][];
                    for (int h = 0; h < inspData.FovNames.Length; h++)
                    {
                        inspData.TaskNamesInFovs[h] = _recipe.TaskNames(inspData.FovNames[h]);
                    }
                    inspData.Code2D      = null;
                    inspData.ColumnIndex = _fovResults[i].ICCol;
                    inspData.RowIndex    = _fovResults[i].ICRow;

                    HObject           hoImg                 = null; ////将Die所属的所有多通道的图平铺成一维数组
                    HObject           hoWire                = null;
                    HObject           hoErrorRegions        = null;
                    bool              isDieOK               = true; //整颗die的检测结果是否OK
                    List <DefectData> lstDefectData         = new List <DefectData>();
                    HObject           hoSuccessRegion       = null;
                    List <string>     lstSuccessRegionTypes = new List <string>();
                    List <int>        lstSuccessImgIndex    = new List <int>();
                    for (int j = i; j < i + fovCountInDie; j++) //将多个Fov合为一个Die
                    {
                        DlafFovDetectResult fovRet = _fovResults[j];

                        HObject hoTaskImgs = fovRet.DetectDiesImages[0]; //每个Fov中只有一个Die(的一部分)
                        if (null == hoImg)                               //第一个
                        {
                            hoImg = hoTaskImgs.Clone();
                        }
                        else
                        {
                            for (int k = 0; k < hoTaskImgs.CountObj(); k++)
                            {
                                HOperatorSet.ConcatObj(hoImg, hoTaskImgs.CopyObj(k + 1, 1), out hoImg);
                            }
                        }

                        HObject hoRegion = fovRet.WireRegion;//将所有Fov中的WireRegion平铺成一维数组
                        if (null == hoRegion)
                        {
                            HOperatorSet.GenEmptyRegion(out hoRegion);
                        }
                        if (null == hoWire)
                        {
                            hoWire = hoRegion.Clone();
                            for (int k = 1; k < fovRet.TaskNames.Length; k++)
                            {
                                HOperatorSet.ConcatObj(hoWire, hoRegion.Clone(), out hoWire);
                            }
                        }
                        else
                        {
                            for (int k = 0; k < fovRet.TaskNames.Length; k++)
                            {
                                HOperatorSet.ConcatObj(hoWire, hoRegion.Clone(), out hoWire);
                            }
                        }

                        if (!fovRet.IsDetectSuccess)//视觉检测失败
                        {
                        }
                        else
                        {
                            ///错误区域
                            if (fovRet.DiesErrorCodes[0].Length != 1 || fovRet.DiesErrorCodes[0][0] == 0)
                            {
                                isDieOK = false;
                                DefectData df = new DefectData();
                                df.DefectTypeIndex = fovRet.DiesErrorCodes[0][0];
                                df.ErrorDetail     = fovRet.DiesErrorDetails[0][0];
                                df.ImageIndex      = _ImgIndex(fovRet.FovName, fovRet.DiesErrorTaskNames[0][0]);
                                lstDefectData.Add(df);
                                if (null == hoErrorRegions)
                                {
                                    hoErrorRegions = fovRet.DiesErrorRegions[0][0].Clone();
                                }
                                else
                                {
                                    HOperatorSet.ConcatObj(hoErrorRegions, fovRet.DiesErrorRegions[0][0], out hoErrorRegions);
                                }
                                for (int k = 1; k < fovRet.DiesErrorCodes[0].Length; k++)
                                {
                                    df = new DefectData();
                                    df.DefectTypeIndex = fovRet.DiesErrorCodes[0][k];
                                    df.ErrorDetail     = fovRet.DiesErrorDetails[0][k];
                                    df.ImageIndex      = _ImgIndex(fovRet.FovName, fovRet.DiesErrorTaskNames[0][k]);
                                    lstDefectData.Add(df);
                                    HOperatorSet.ConcatObj(hoErrorRegions, fovRet.DiesErrorRegions[0][k], out hoErrorRegions);
                                }
                            }


                            /*public HObject*/
                            if (fovRet.DetectIterms != null && fovRet.DetectIterms.Count > 0)
                            {
                                foreach (KeyValuePair <string, HObject> kv in fovRet.DetectIterms)
                                {
                                    if (null == hoSuccessRegion)
                                    {
                                        hoSuccessRegion = kv.Value.Clone();
                                    }
                                    else
                                    {
                                        HOperatorSet.ConcatObj(hoSuccessRegion, kv.Value, out hoSuccessRegion);
                                    }
                                    lstSuccessRegionTypes.Add(kv.Key);
                                    lstSuccessImgIndex.Add(_ImgIndex(fovRet.FovName, kv.Key));
                                }
                            }
                        }
                        _fovCounteds[j] = true;
                    }
                    inspData.Image  = hoImg;
                    inspData.Wire   = hoWire;
                    inspData.Region = hoErrorRegions;
                    if (isDieOK)
                    {
                        inspData.InspectionResult = InspectionResults.OK;
                        inspData.List_DefectData  = null;
                    }
                    else
                    {
                        inspData.InspectionResult = InspectionResults.NG;
                        inspData.List_DefectData  = lstDefectData;
                    }

                    if (null != hoSuccessRegion)
                    {
                        inspData.SuccessRegion           = hoSuccessRegion; //所有检测成功区域
                        inspData.SuccessRegionTypes      = lstSuccessRegionTypes.ToArray();
                        inspData.SuccessRegionImageIndex = lstSuccessImgIndex.ToArray();
                    }
                    if (null == inspData.List_DefectData)
                    {
                        inspData.List_DefectData = new List <DefectData>();
                    }
                    ret.Add(inspData);
                }
            }


            if (ret.Count() == 0)
            {
                return(null);
            }
            return(ret.ToArray());
        }