/// <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);
        }
        /// <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;
        }
Esempio n. 3
0
        //DLAFDetectResultTransfer _detectResultTransfer = new DLAFDetectResultTransfer();
        //受到自定义消息
        public void OnCustomizeMsg(string msgCategory, object[] msgParams)
        {
            fmTips.AddOneTips("工站消息Categoty:" + msgCategory);
            BeginInvoke(new Action(() => {
                if (msgCategory == CMC_ShowJFImage) //显示一个IJFImage对象
                {
                    object ob;
                    IJFImage ij = msgParams[0] as IJFImage;
                    if (null == ij)
                    {
                        fmTips.AddOneTips("消息参数IJFImage == null");
                        return;
                    }
                    int err = ij.GenHalcon(out ob);
                    if (err != 0)
                    {
                        fmTips.AddOneTips("参数IJFImage.GenHalcon 出错:" + ij.GetErrorInfo(err));
                        return;
                    }
                    htWindowControl1.DispImage(ob as HObject);
                }
                else if (msgCategory == CMC_ShowHO)//显示一个Halcon对象
                {
                    htWindowControl1.DispImage(msgParams[0] as HObject);
                }
                else if (CMC_StartNewPiece == msgCategory)
                {
                    rchRDetectInfo.Text = "";
                    string pieceID      = msgParams[0] as string;
                    rchRDetectInfo.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + msgParams[0] + " 开始检测,PieceID = pieceID");
                    //_detectResultTransfer.SetPieceID(pieceID);
                    for (int i = 0; i < _currRecipe.RowNumber; i++)
                    {
                        for (int j = 0; j < _currRecipe.ColumnNumber * _currRecipe.BlockNumber; j++)
                        {
                            mappCtrl.SetDieState(i, j, "未检测");
                        }
                    }
                    _lstInspectData.Clear();
                }
                else if (msgCategory == CMC_InspectResult) //一个FOV的检测结果
                {
                    IJFImage[] orgImgs      = msgParams[0] as IJFImage[];
                    DlafFovDetectResult fdr = (msgParams[1] as DlafFovDetectResult); //.Clone();
                    int imgIndex2Show       = 0;
                    if (_isShowRealtimeDetectImg)                                    //需要实时显示图像
                    {
                        string taskName2Show = cbTaskImgShow.Text;
                        if (!string.IsNullOrEmpty(taskName2Show))
                        {
                            for (int i = 0; i < fdr.TaskNames.Length; i++)
                            {
                                if (fdr.TaskNames[i] == taskName2Show)
                                {
                                    imgIndex2Show = i;
                                    break;
                                }
                            }
                        }

                        //if (null != fdr.WireRegion) //老版本的数据显示功能
                        //{
                        //    htWindowControl1.ColorName = "green"; //金线为绿色显示
                        //    if(null != _hoOrgImgShowing)
                        //    {
                        //        _hoOrgImgShowing.Dispose();
                        //        _hoOrgImgShowing = null;

                        //    }

                        //    Object ob;
                        //    orgImgs[imgIndex2Show].GenHalcon(out ob);
                        //    _hoOrgImgShowing = ob as HObject;
                        //    htWindowControl1.RefreshWindow(_hoOrgImgShowing, fdr.WireRegion, "fit");
                        //}
                        //if (null != fdr.DetectIterms && fdr.DetectIterms.Count > 0)
                        //{
                        //    htWindowControl1.ColorName = "yellow"; //其他成功检测项显示为黄色
                        //    foreach (HObject ho in fdr.DetectIterms.Values)
                        //        htWindowControl1.DispRegion(ho);
                        //}

                        //if(null != fdr.DiesErrorRegions)
                        //{
                        //    htWindowControl1.ColorName = "red"; //错误区域显示为红色
                        //    foreach(HObject[] errorRegions in fdr.DiesErrorRegions)
                        //        if(null != errorRegions)
                        //            foreach(HObject ho in errorRegions)
                        //                htWindowControl1.DispRegion(ho);
                        //}


                        //新数据结构的显示
                        if (null != _hoOrgImgShowing)
                        {
                            _hoOrgImgShowing.Dispose();
                            _hoOrgImgShowing = null;
                        }

                        Object ob;
                        if (0 != orgImgs[imgIndex2Show].GenHalcon(out ob)) //图像转化出错
                        {
                            htWindowControl1.ClearHWindow();
                        }
                        else
                        {
                            _hoOrgImgShowing = (HObject)ob;
                            htWindowControl1.RefreshWindow(_hoOrgImgShowing, 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);

                        bool _isShowAllItem = !chkJustShowNG.Checked;
                        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)
                        {
                            htWindowControl1.ColorName = "green";
                            htWindowControl1.DispRegion(wireRegion);
                            htWindowControl1.ColorName = "yellow";
                            htWindowControl1.DispRegion(bondRegion);
                            htWindowControl1.ColorName = "blue";
                            htWindowControl1.DispRegion(epoxyRegion);
                        }
                        htWindowControl1.ColorName = "red";
                        htWindowControl1.DispRegion(errRegion);
                    }


                    if (fdr.DetectDiesImages != null)
                    {
                        foreach (HObject ho in fdr.DetectDiesImages)
                        {
                            ho.Dispose();
                        }
                    }


                    ///错误信息显示
                    StringBuilder sbInfo = new StringBuilder();
                    sbInfo.AppendLine("Fov:" + fdr.FovName + " 检测结果:");
                    if (!fdr.IsDetectSuccess)
                    {
                        sbInfo.AppendLine("图像检测失败,ErrorInfo:" + fdr.DetectErrorInfo);
                    }
                    else
                    {
                        if (fdr.IsFovOK)
                        {
                            sbInfo.AppendLine("检测结果: OK");
                        }
                        else
                        {
                            for (int i = 0; i < fdr.DetectDiesRows.Length; i++)
                            {
                                if (fdr.IsDieOK(i))
                                {
                                    sbInfo.AppendLine("Row-" + fdr.ICRow + " Col-" + fdr.ICCol + " Die-" + i + " OK");
                                }
                                else
                                {
                                    sbInfo.AppendLine("Row-" + fdr.ICRow + " Col-" + fdr.ICCol + " Die-" + i + " NG  错误信息:");
                                    int[] errors = fdr.DiesErrorCodes[i];
                                    //for(int j = 0; j < errors.Length;j++)
                                    //    sbInfo.AppendLine("ErrCode:" + errors[j] + " Info:" + InspectNode.DieErrorDescript(errors[j]) + "In Task:" + fdr.DiesErrorTaskNames[i][j]);
                                }
                            }
                        }
                    }


                    fmTips.AddOneTips(sbInfo.ToString());
                    rchRDetectInfo.AppendText(sbInfo.ToString());

                    //将Fov检测项填入表格
                    dgvDetectItems.Rows.Clear();
                    if (null != fdr.DieInspectResults)
                    {
                        bool _isShowAllItems = !chkJustShowNG.Checked;


                        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 dieDetectVelCell = new DataGridViewTextBoxCell();
                                dieDetectVelCell.Value           = "---";
                                dieDetectVelCell.Style.ForeColor = Color.Red;
                                row.Cells.Add(dieDetectVelCell);


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

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


                                dgvDetectItems.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);


                                    dgvDetectItems.Rows.Add(row);
                                }
                            }
                        }
                    }
                }
                else if (CMC_DieResults == msgCategory)
                {
                    InspectionData[] inspDatas = msgParams[0] as InspectionData[];
                    if (null == inspDatas)
                    {
                        return;
                    }
                    _lstInspectData.AddRange(inspDatas);
                    foreach (InspectionData inspData in inspDatas)
                    {
                        mappCtrl.SetDieState(inspData.RowIndex, inspData.ColumnIndex, inspData.InspectionResult == InspectionResults.OK ? "合格" : "不合格");
                    }
                }
                else if (CMC_PieceFinished == msgCategory)
                {
                    bool isOnLineReview        = (bool)JFHubCenter.Instance.SystemCfg.GetItemValue("在线复判");
                    string recipeID            = msgParams[0] as string;
                    string lotID               = msgParams[1] as string;
                    string pieceID             = msgParams[2] as string;
                    string inspectResultFolder = msgParams[3] as string;
                    string pictureFolder       = msgParams[4] as string;
                    rchRDetectInfo.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + recipeID + " 检测完成");
                    if (!isOnLineReview)
                    {
                        fmTips.AddOneTips(msgParams[0] + " 检测完成");
                    }
                    else
                    {
                        FormDLAFReview fm = new FormDLAFReview();
                        fm.SetReviewParam(recipeID, lotID, pieceID, inspectResultFolder + "\\" + recipeID + ".db", pictureFolder);
                        fm.ShowDialog();
                        JFHubCenter.Instance.DataPool.SetItemValue("检测工站:在线复判完成", true);
                    }
                }
                else
                {
                }
            }));
        }
        /// <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            currCol  = j % fovResult.CurrColCount;
                        int            currRow  = j / fovResult.CurrColCount;
                        int            dieRow   = _recipe.DieRowInFov * fovResult.ICRow + currRow; //fovResult.DetectDiesRows[j]; //料片中的die行列值
                        int            dieCol   = _recipe.DieColInFov * fovResult.ICCol + currCol; //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 = InspectionResult.NG;
                            DefectData df = new DefectData();
                            df.DefectTypeIndex = -1;
                            df.ImageIndex      = _ImgIndex(fovResult.FovName, fovResult.TaskNames[0]);
                            df.ErrorDetail     = fovResult.DetectErrorInfo;
                            inspData.List_DefectData.Add(df);
                            //fovRet.Dispose();
                        }
                        else //图象检测成功
                        {
                            //金线区域
                            inspData.Wire = null;
                            if (null != fovResult.WireRegion)
                            {
                                HObject wireRegion = fovResult.WireRegion;//fovResult.DetectIterms["WireRegions"];
                                if (wireRegion.CountObj() < 1)
                                {
                                    HOperatorSet.GenEmptyRegion(out wireRegion);
                                }
                                HOperatorSet.Union1(wireRegion, out wireRegion);
                                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;
                            }
                            else
                            {
                                HObject hoTmp;
                                HOperatorSet.GenEmptyRegion(out hoTmp);
                                inspData.Region = hoTmp;
                            }

                            int[] errorCodes = fovResult.DiesErrorCodes[j];
                            if (errorCodes.Length == 1 && errorCodes[0] == 0) //检测合格
                            {
                                inspData.InspectionResult = InspectionResult.OK;
                                inspData.List_DefectData  = null;
                            }
                            else
                            {
                                inspData.InspectionResult = InspectionResult.NG;
                                inspData.List_DefectData  = new List <DefectData>();
                                for (int h = 0; h < fovResult.DiesErrorCodes[j].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;
                        //统计完结果后立即释放内存
                    }
                    _fovResults[i].Dispose();
                }
            }
            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];
                        if (!fovRet.IsFovOK)
                        {
                            isDieOK = false;
                        }
                        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 || !hoRegion.IsInitialized())
                        {
                            HOperatorSet.GenEmptyRegion(out hoRegion);
                        }
                        else
                        {
                            if (hoRegion.CountObj() > 0)
                            {
                                HObject hoTmp;
                                HOperatorSet.GenEmptyRegion(out hoTmp);
                                hoTmp.Dispose();
                                HOperatorSet.Union1(hoRegion, out hoTmp);
                                hoRegion = hoTmp;
                            }
                            else
                            {
                                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)//视觉检测失败
                        {
                            DefectData df = new DefectData();
                            df.DefectTypeIndex = -1;
                            df.ImageIndex      = _ImgIndex(fovRet.FovName, fovRet.TaskNames[0]);
                            df.ErrorDetail     = fovRet.DetectErrorInfo;
                            lstDefectData.Add(df);
                            fovRet.Dispose();
                        }
                        else
                        {
                            if (!fovRet.IsDieOK(0))
                            {
                                ///错误区域
                                //if (fovRet.DiesErrorCodes[0].Length != 1 || fovRet.DiesErrorCodes[0][0] == 0)
                                {
                                    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;
                        //统计完结果后立即释放内存
                        _fovResults[j].Dispose();
                    }
                    inspData.Image = hoImg;
                    inspData.Wire  = hoWire;

                    inspData.Region = hoErrorRegions;
                    if (isDieOK)
                    {
                        inspData.InspectionResult = InspectionResult.OK;
                        inspData.List_DefectData  = null;
                    }
                    else
                    {
                        inspData.InspectionResult = InspectionResult.NG;
                        inspData.List_DefectData  = lstDefectData;
                        //if (null == inspData.List_DefectData || inspData.List_DefectData.Count == 0)
                        //    MessageBox.Show("检查 inspData.List_DefectData ");
                    }

                    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());
        }
        public DlafFovDetectResult Clone()
        {
            DlafFovDetectResult ret = new DlafFovDetectResult();

            ret.ICRow             = ICRow;
            ret.ICCol             = ICCol;
            ret.FovName           = FovName;
            ret.TaskNames         = TaskNames;
            ret.DetectDiesRows    = DetectDiesRows;
            ret.DetectDiesCols    = DetectDiesCols;
            ret.DiesErrorCodes    = DiesErrorCodes;
            ret.IsDetectSuccess   = IsDetectSuccess;
            ret.DetectErrorInfo   = DetectErrorInfo;
            ret.CurrColCount      = CurrColCount;
            ret.CurrRowCount      = CurrRowCount;
            ret.DieInspectResults = DieInspectResults;

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

            ret.DiesErrorDetails = DiesErrorDetails;



            return(ret);
        }