public void DealSmoothing(ParRaisedEdgeSmooth parRaisedEdgeSmooth, HObject ho_ImageBinary, HObject ho_RegionBinary, ResultRaisedEdge result, Hashtable htResult) { ParSmooth par = parRaisedEdgeSmooth.g_ParSmooth; #region 定义 HObject ho_ROI = null; HObject ho_FilterROI = null; HObject ho_FilterInverseROI = null; // Local control variables HTuple hv_Width = null, hv_Height = null; HTuple hv_RowInit = new HTuple(), hv_ColInit = new HTuple(); HTuple hv_Row1 = null, hv_Col1 = null; HTuple hv_Row2 = null, hv_Col2 = null; HTuple hv_AreaDilation = new HTuple(), hv_RowDilation = new HTuple(); HTuple hv_ColumnDilation = new HTuple(), hv_NumberSmooth = new HTuple(); HTuple hv_RowS = new HTuple(); HTuple hv_ColS = new HTuple(), hv_InvertedCol = new HTuple(); HTuple hv_InvertedRow = new HTuple(), hv_ConcatCol = new HTuple(); HTuple hv_ConcatRow = new HTuple(), hv_NumberRegionDilation1 = new HTuple(); // Local iconic variables //怎么把图片和region导入 HObject ho_ImageReduced; HObject ho_Region, ho_RegionDilation; HObject ho_rectErosion1, ho_BorderOrigin; HObject ho_ConnectedRegionDilation = null; HObject ho_BinImage = null; HObject ho_ImageBinReduced = null, ho_BorderOriginal = null, ho_SmoothedBoaderOriginal = null; HObject ho_SelectedSmoothedContours = null, ho_ObjectSelected = null; HObject ho_ContourConcat = null, ho_RegionParall = null, ho_ImageParall = null; HObject ho_RegionError = null, ho_ConnectedRegions = null, ho_RegionErosionError = null; HObject ho_RegionDilationError = null; //求取缺陷 HObject ho_BorderFull = null; HObject ho_SmoothedContoursFull = null; HObject ho_ParaFull = null; HObject ho_ParaRegionFull = null; HObject ho_RegionROIFull = null; HObject ho_ErrorFull = null; HObject ho_FilterErrorFull = null;//崩缺求取中,剪掉台阶面崩缺后的缺陷 HObject ho_ErrorRegioinFull = null; HObject ho_ErrorConnectFull = null; HObject ho_ErrorSelectFull = null; HObject ho_ErrorXldFull = null; HObject ho_SmoothedContoursFullLongest = null; HOperatorSet.GenEmptyObj(out ho_SmoothedContoursFullLongest); HOperatorSet.GenEmptyObj(out ho_ImageReduced); HOperatorSet.GenEmptyObj(out ho_Region); HOperatorSet.GenEmptyObj(out ho_RegionDilation); HOperatorSet.GenEmptyObj(out ho_rectErosion1); HOperatorSet.GenEmptyObj(out ho_BorderOrigin); HOperatorSet.GenEmptyObj(out ho_ConnectedRegionDilation); HOperatorSet.GenEmptyObj(out ho_BinImage); HOperatorSet.GenEmptyObj(out ho_ImageBinReduced); HOperatorSet.GenEmptyObj(out ho_BorderOriginal); HOperatorSet.GenEmptyObj(out ho_SmoothedBoaderOriginal); HOperatorSet.GenEmptyObj(out ho_SelectedSmoothedContours); HOperatorSet.GenEmptyObj(out ho_ObjectSelected); HOperatorSet.GenEmptyObj(out ho_ContourConcat); HOperatorSet.GenEmptyObj(out ho_RegionParall); HOperatorSet.GenEmptyObj(out ho_ImageParall); HOperatorSet.GenEmptyObj(out ho_RegionError); HOperatorSet.GenEmptyObj(out ho_ConnectedRegions); HOperatorSet.GenEmptyObj(out ho_RegionErosionError); HOperatorSet.GenEmptyObj(out ho_RegionDilationError); HOperatorSet.GenEmptyObj(out ho_BorderFull); HOperatorSet.GenEmptyObj(out ho_SmoothedContoursFull); HOperatorSet.GenEmptyObj(out ho_FilterInverseROI); HOperatorSet.GenEmptyObj(out ho_FilterErrorFull); HOperatorSet.GenEmptyObj(out ho_ParaFull); HOperatorSet.GenEmptyObj(out ho_ParaRegionFull); #endregion 定义 try { int smooth = (par.SmoothValue / 2) * 2 + 1;//平滑系数只能是奇数 HOperatorSet.GetImageSize(ho_ImageBinary, out hv_Width, out hv_Height); //求取ROI FunROI funCirROI = new FunROI(); bool blResult = false; string anno = ""; ho_ROI = funCirROI.CreateOneROI(parRaisedEdgeSmooth.g_ParROI.g_ParROIExcute_L[0], htResult, out blResult, out anno); //对ROI区域进行腐蚀,剔除多余轮廓的边界 HOperatorSet.ErosionCircle(ho_ROI, out ho_rectErosion1, 20); HOperatorSet.ReduceDomain(ho_ImageBinary, ho_rectErosion1, out ho_ImageReduced); //通过ROI截图 HOperatorSet.Intersection(ho_RegionBinary, ho_ROI, out ho_RegionDilation); //对二值化图片求取轮廓 HOperatorSet.ThresholdSubPix(ho_ImageReduced, out ho_BorderOrigin, 100); //迭代十次 for (int i = 0; i < par.Num; i++) { hv_Row1 = new HTuple(); hv_Col1 = new HTuple(); hv_Row2 = new HTuple(); hv_Col2 = new HTuple(); //剔除主体之外的噪声点 ho_ConnectedRegionDilation.Dispose(); HOperatorSet.Connection(ho_RegionDilation, out ho_ConnectedRegionDilation); HOperatorSet.AreaCenter(ho_ConnectedRegionDilation, out hv_AreaDilation, out hv_RowDilation, out hv_ColumnDilation); ho_RegionDilation.Dispose(); //保留主体 HOperatorSet.SelectShape(ho_ConnectedRegionDilation, out ho_RegionDilation, "area", "and", 50000, int.MaxValue); //主题二值化以后的图片 ho_BinImage.Dispose(); HOperatorSet.RegionToBin(ho_RegionDilation, out ho_BinImage, 255, 0, hv_Width, hv_Height); //二值化缩减轮廓 ho_ImageBinReduced.Dispose(); HOperatorSet.ReduceDomain(ho_BinImage, ho_rectErosion1, out ho_ImageBinReduced); //*************************** //生成带有方向梯度的边界,用平滑后的边界和原始边界的平移生成轮廓处理 //生成内边界 ho_BorderOriginal.Dispose(); HOperatorSet.ThresholdSubPix(ho_ImageBinReduced, out ho_BorderOriginal, 100); //角点非圆弧 ho_SmoothedBoaderOriginal.Dispose(); HOperatorSet.SmoothContoursXld(ho_BorderOriginal, out ho_SmoothedBoaderOriginal, smooth); //筛选轮廓 ho_SelectedSmoothedContours.Dispose(); HOperatorSet.SelectContoursXld(ho_SmoothedBoaderOriginal, out ho_SelectedSmoothedContours, "contour_length", par.SelectAreaLow, 99999999, -0.5, 0.5); HOperatorSet.CountObj(ho_SelectedSmoothedContours, out hv_NumberSmooth); if ((int)(new HTuple(hv_NumberSmooth.TupleGreater(1))) != 0) { int numSmooth = hv_NumberSmooth.ToIArr()[0] - 1; for (int j = 0; j < numSmooth; j++) { ho_ObjectSelected.Dispose(); HOperatorSet.SelectObj(ho_SelectedSmoothedContours, out ho_ObjectSelected, j + 1); HOperatorSet.GetContourXld(ho_ObjectSelected, out hv_RowS, out hv_ColS); HOperatorSet.TupleConcat(hv_RowInit, hv_RowS, out hv_RowInit); HOperatorSet.TupleConcat(hv_ColInit, hv_ColS, out hv_ColInit); } } else { HOperatorSet.GetContourXld(ho_SelectedSmoothedContours, out hv_RowInit, out hv_ColInit); } //生成平行轮廓的点 HTuple[] rowCol = null; GenParallPoint(par.Position, par.DefectType, (int)par.GapIn, (int)par.GapOut, hv_RowInit, hv_ColInit, out rowCol); hv_Row1 = rowCol[0]; hv_Col1 = rowCol[1]; hv_Row2 = rowCol[2]; hv_Col2 = rowCol[3]; //生成平行轮廓包围的区域 HOperatorSet.TupleInverse(hv_Col2, out hv_InvertedCol); HOperatorSet.TupleInverse(hv_Row2, out hv_InvertedRow); HOperatorSet.TupleConcat(hv_Col1, hv_InvertedCol, out hv_ConcatCol); HOperatorSet.TupleConcat(hv_Row1, hv_InvertedRow, out hv_ConcatRow); //select_contours_xld (SmoothedContours, SelectedSmoothedContours, 'contour_length', 50, 99999999, -0.5, 0.5) //HOperatorSet.SelectContoursXld(ho_ContourConcat, out ho_ContourConcat, "contour_length", par.ErrorAreaValue, 99999999, -0.5, 0.5); if (hv_ConcatRow.Length == 0) { result.LevelError_e = LevelError_enum.Error; result.Annotation = par.NameCell.ToString() + "hv_ConcatRow的数量为0"; result.SetDefault(); return; } ho_ContourConcat.Dispose(); HOperatorSet.GenContourPolygonXld(out ho_ContourConcat, hv_ConcatRow, hv_ConcatCol); //生成平行轮廓region ho_RegionParall.Dispose(); HOperatorSet.GenRegionContourXld(ho_ContourConcat, out ho_RegionParall, "filled"); ho_ImageParall.Dispose(); HOperatorSet.ReduceDomain(ho_BinImage, ho_RegionParall, out ho_ImageParall); ho_RegionError.Dispose(); HOperatorSet.Threshold(ho_ImageParall, out ho_RegionError, 100, 255); ho_ConnectedRegions.Dispose(); HOperatorSet.Connection(ho_RegionError, out ho_ConnectedRegions); //轮廓的内边界先外移1个像素,再膨胀靠近(忽略最小1个像素的地方) ho_RegionErosionError.Dispose(); HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_RegionErosionError, "area", "and", par.ErrorAreaValue, 99999999); //膨胀缺陷 ho_RegionDilationError.Dispose(); HOperatorSet.DilationCircle(ho_RegionErosionError, out ho_RegionDilationError, par.DilationDefectValue); //剔除残留 HOperatorSet.Difference(ho_RegionDilation, ho_RegionDilationError, out ho_RegionDilation); HOperatorSet.CountObj(ho_RegionDilationError, out hv_NumberRegionDilation1); if ((int)(new HTuple(hv_NumberRegionDilation1.TupleEqual(0))) != 0) { break; } } //完整图片 ho_BinImage.Dispose(); HOperatorSet.RegionToBin(ho_RegionDilation, out ho_BinImage, 255, 0, hv_Width, hv_Height); ho_ImageBinReduced.Dispose(); HOperatorSet.ReduceDomain(ho_BinImage, ho_rectErosion1, out ho_ImageBinReduced); //完整轮廓 ho_BorderFull.Dispose(); HOperatorSet.ThresholdSubPix(ho_ImageBinReduced, out ho_BorderFull, 100); ho_SmoothedContoursFull.Dispose(); HOperatorSet.SmoothContoursXld(ho_BorderFull, out ho_SmoothedContoursFull, smooth); HTuple hv_ho_SmoothedContoursFullNumber = null; HOperatorSet.CountObj(ho_SmoothedContoursFull, out hv_ho_SmoothedContoursFullNumber);//计算平滑区域的xld个数 //如果完整轮廓为空,则返回 if (hv_ho_SmoothedContoursFullNumber == 0) { result.LevelError_e = LevelError_enum.Error; result.Annotation = par.NameCell.ToString() + "ho_SmoothedContoursFull的数量为0"; result.SetDefault(); return; } //计算完整轮廓的长度 HTuple hv_SmoothedContoursFullLength = null; HOperatorSet.LengthXld(ho_SmoothedContoursFull, out hv_SmoothedContoursFullLength); //找到完整轮廓中最长的一段,剔除干扰小段 HOperatorSet.SelectObj(ho_SmoothedContoursFull, out ho_SmoothedContoursFullLongest, (((hv_SmoothedContoursFullLength.TupleSortIndex() )).TupleSelect((new HTuple(hv_SmoothedContoursFullLength.TupleLength())) - 1)) + 1); HTuple[] rowColFull = null; HOperatorSet.GetContourXld(ho_SmoothedContoursFullLongest, out hv_RowInit, out hv_ColInit); GenParallPoint(par.Position, par.DefectType, 0, (int)par.GapOut, hv_RowInit, hv_ColInit, out rowColFull); hv_Row1 = rowColFull[0]; hv_Col1 = rowColFull[1]; hv_Row2 = rowColFull[2]; hv_Col2 = rowColFull[3]; //生成平行轮廓包围的区域 HOperatorSet.TupleInverse(hv_Col2, out hv_InvertedCol); HOperatorSet.TupleInverse(hv_Row2, out hv_InvertedRow); HOperatorSet.TupleConcat(hv_Col1, hv_InvertedCol, out hv_ConcatCol); HOperatorSet.TupleConcat(hv_Row1, hv_InvertedRow, out hv_ConcatRow); ho_ContourConcat.Dispose(); HOperatorSet.GenContourPolygonXld(out ho_ContourConcat, hv_ConcatRow, hv_ConcatCol); HOperatorSet.GenRegionContourXld(ho_ContourConcat, out ho_RegionROIFull, "filled"); HOperatorSet.ReduceDomain(ho_ImageBinary, ho_RegionROIFull, out ho_ErrorFull); ho_FilterErrorFull.Dispose(); ho_FilterInverseROI.Dispose(); if (par.DefectType == "Shell" && parRaisedEdgeSmooth.g_ParROI.g_ParROIExcute_L.Count > 1) { ho_FilterROI = funCirROI.CreateOneROI(parRaisedEdgeSmooth.g_ParROI.g_ParROIExcute_L[1], htResult, out blResult, out anno); HOperatorSet.Complement(ho_FilterROI, out ho_FilterInverseROI); HOperatorSet.ReduceDomain(ho_ErrorFull, ho_FilterInverseROI, out ho_FilterErrorFull); } else { ho_FilterErrorFull = ho_ErrorFull.Clone(); } HOperatorSet.Threshold(ho_FilterErrorFull, out ho_ErrorRegioinFull, 100, 255); HOperatorSet.Connection(ho_ErrorRegioinFull, out ho_ErrorConnectFull); HTuple numError = 0; HTuple rowFull = null; HTuple colFull = null; HTuple disMin = null; HTuple disMax = null; HTuple disMinSort = null; HTuple disMinSortIndex = null; HTuple areaError = null; HTuple rowError = null; HTuple colError = null; HOperatorSet.CountObj(ho_ErrorConnectFull, out numError); HObject ho_ErrorSelectedPart; for (int i = 0; i < numError; i++) { HOperatorSet.SelectObj(ho_ErrorConnectFull, out ho_ErrorSelectedPart, i + 1); HOperatorSet.GenContourRegionXld(ho_ErrorSelectedPart, out ho_ErrorXldFull, "border"); HOperatorSet.GetContourXld(ho_ErrorXldFull, out rowFull, out colFull); HOperatorSet.DistancePc(ho_SmoothedContoursFullLongest, rowFull, colFull, out disMin, out disMax); HOperatorSet.TupleSort(disMin, out disMinSort); HOperatorSet.TupleSortIndex(disMin, out disMinSortIndex); //for (int j = 0; j < disMax.Length; j++) //{ if (disMinSort[disMinSort.Length - 1] > par.NormalTh) { HOperatorSet.AreaCenter(ho_ErrorSelectedPart, out areaError, out rowError, out colError); result.X_L.Add(colFull[disMinSortIndex[disMinSort.Length - 1].I]); result.Y_L.Add(rowFull[disMinSortIndex[disMinSort.Length - 1].I]); result.R_L.Add(0); double dist = disMinSort[disMinSort.Length - 1]; result.Height_L.Add(Math.Round(dist, 1)); result.Area_L.Add(areaError.ToDArr()[0]); break; } //} } //区域个数 result.Num = result.X_L.Count; if (result.Num == 0) { //如果前一次结果为error,那么即使这次的结果是OK,也要保持ERROR的状态 if (result.LevelError_e == LevelError_enum.Error) { result.SetDefault(); } else { result.LevelError_e = LevelError_enum.OK; result.Annotation = par.NameCell.ToString() + "缺陷个数为0"; result.SetDefault(); } } //添加显示 AddDisplay(par.g_ParOutput, result); } catch (Exception ex) { result.LevelError_e = LevelError_enum.Error; result.Annotation = par.NameCell.ToString() + ex.Message.ToString(); result.SetDefault(); Log.L_I.WriteError(NameClass, ex); } finally { #region 记录 RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ImageBinary", ho_ImageBinary); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ROI", ho_ROI); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_FilterROI", ho_FilterROI); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_rectErosion1", ho_rectErosion1); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ImageReduced", ho_ImageReduced); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_Region", ho_Region); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionDilation", ho_RegionDilation); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_BorderOrigin", ho_BorderOrigin); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ConnectedRegionDilation", ho_ConnectedRegionDilation); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_BinImage", ho_BinImage); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_BorderOriginal", ho_BorderOriginal); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_SmoothedBoaderOriginal", ho_SmoothedBoaderOriginal); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_SelectedSmoothedContours", ho_SelectedSmoothedContours); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ObjectSelected", ho_ObjectSelected); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ContourConcat", ho_ContourConcat); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionParall", ho_RegionParall); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_FilterErrorFull", ho_FilterErrorFull); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ImageParall", ho_ImageParall); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionError", ho_RegionError); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ConnectedRegions", ho_ConnectedRegions); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionErosionError", ho_RegionErosionError); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionDilationError", ho_RegionDilationError); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_BorderFull", ho_BorderFull); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_SmoothedContoursFull", ho_SmoothedContoursFull); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_SmoothedContoursFullLongest", ho_SmoothedContoursFullLongest); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_RegionROIFull", ho_RegionROIFull); RecordHoject(parRaisedEdgeSmooth, result, NameClass, "ho_ErrorConnectFull", ho_ErrorConnectFull); #endregion 记录 } }
public static void GenDefectRegions(Bitmap bitmap, List <Rectangle> rectangles, double radiusOfDilation, out List <SingleDefectRegion> defectRegions) { defectRegions = new List <SingleDefectRegion>(); HObject ho_image; HObject ho_ConnectedDilations; HTuple hv_Row1OfRectangles = new HTuple(); HTuple hv_Row2OfRectangles = new HTuple(); HTuple hv_Column1OfRectangles = new HTuple(); HTuple hv_Column2OfRectangles = new HTuple(); HTuple hv_RadiusOfDilation = new HTuple(); HTuple hv_IndexOfRectangles = new HTuple(); HTuple hv_NumberListOfRectangles = new HTuple(); // initialation HOperatorSet.GenEmptyObj(out ho_image); ho_image.Dispose(); ImageOperateTools.Bitmap8HObjectBpp8(bitmap, out ho_image); for (int i = 0; i < rectangles.Count; i++) { var rectangle = rectangles[i]; hv_Row1OfRectangles.Append(new HTuple(rectangle.Top)); hv_Row2OfRectangles.Append(new HTuple(rectangle.Bottom)); hv_Column1OfRectangles.Append(new HTuple(rectangle.Left)); hv_Column2OfRectangles.Append(new HTuple(rectangle.Right)); } hv_RadiusOfDilation = radiusOfDilation; dilate_regions_pro(ho_image, out ho_ConnectedDilations, hv_Row1OfRectangles, hv_Row2OfRectangles, hv_Column1OfRectangles, hv_Column2OfRectangles, hv_RadiusOfDilation, out hv_IndexOfRectangles, out hv_NumberListOfRectangles); List <int> defectInfoIndexList = new List <int>(); List <int> defectInfoNumberList = new List <int>(); if (hv_IndexOfRectangles.TupleLength() > 0 && hv_NumberListOfRectangles.TupleLength() > 0) { defectInfoIndexList.AddRange(hv_IndexOfRectangles.ToIArr()); defectInfoNumberList.AddRange(hv_NumberListOfRectangles.ToIArr()); } else { return; } HOperatorSet.CountObj(ho_ConnectedDilations, out var hv_NumberOfDilations); for (var index = 1; index <= hv_NumberOfDilations; ++index) { SingleDefectRegion defectRegion = new SingleDefectRegion(); HOperatorSet.SelectObj(ho_ConnectedDilations, out var ho_Dilation, index); // DefectRegion.DefectInfoIndexList for (var cnt = 0; cnt < defectInfoNumberList[index - 1]; ++cnt) { defectRegion.DefectInfoIndexList.Add(defectInfoIndexList[0]); defectInfoIndexList.RemoveAt(0); } // DefectRegion.Xldxxx convert_single_region_to_points(ho_Dilation, out var hv_posYs, out var hv_posXs, out var hv_pointsNum); if (hv_posYs.TupleLength() > 0) { defectRegion.XldYs.AddRange(hv_posYs.ToDArr()); } if (hv_posXs.TupleLength() > 0) { defectRegion.XldXs.AddRange(hv_posXs.ToDArr()); } if (hv_pointsNum.TupleLength() > 0) { defectRegion.XldPointCount.AddRange(hv_pointsNum.ToIArr()); } // DefectRegion.SmallestRect HOperatorSet.SmallestRectangle1(ho_Dilation, out var hv_Row1, out var hv_Column1, out var hv_Row2, out var hv_Column2); defectRegion.SmallestRect = Rectangle.FromLTRB(hv_Column1.I, hv_Row1.I, hv_Column2.I, hv_Row2.I); defectRegions.Add(defectRegion); } return; }