using System; using System.Collections.Generic; using OpenCvSharp; using System.Linq; using System.Windows.Forms; using SmartCoalApplication.Base.CommTool; using SmartCoalApplication.Base.AuxiliaryCalcModel; namespace SmartCoalApplication.Base.AutoMeasure { public class HoleType : AutoMeasureAnalysis { } public class DataInfor { public DataInfor() { drawType = "MeasureVLine"; deleteFlag = 2; } public int deleteFlag { set; get; } public string name { set; get; } public string drawType { set; get; } public string ID { set; get; } public double value { set; get; } public System.Drawing.Point point1 = new System.Drawing.Point(); public System.Drawing.Point point2 = new System.Drawing.Point(); public string aliasName { set; get; } public void Set(double v, int x1, int y1, int x2, int y2) { value = v; point1.X = x1; point1.Y = y1; point2.X = x2; point2.Y = y2; } } public class ShuangcengbanYou : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor kongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100143"; shangJicaitong.aliasName = "OXWURH"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100144"; xiaJicaitong.aliasName = "ZPXAJW"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100147"; shangMiantong.aliasName = "AFZADE"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100148"; xiaMiantong.aliasName = "YATJHW"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100145"; shangMiantong_Jicaitong.aliasName = "GJUWJL"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100146"; xiaMiantong_Jicaitong.aliasName = "COKHSE"; kongtong.name = "孔銅"; kongtong.drawType = "MeasureHLine"; kongtong.ID = "100149"; kongtong.aliasName = "NIVNMR"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(kongtong); number = 7; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //获得目标区域图片 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); //上下裁剪 int[] y = new int[2] { 0, 0 }; Mat cropContour = new Mat(); ceju.Crop(imageContour, out y, out cropContour, isCropFlag); //去亮光 int[] b = new int[4] { 0, 0, 0, 0 }; Mat cropContour2 = new Mat(); int border = 0; ceju.CropLight(cropContour, out border, out cropContour2, "right"); // 计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(cropContour2, out dataArea, "right"); int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; int upper = y[0]; if (isCropFlag) { upper += Y; border += X; } //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(cropContour2, out ordinateL1, middleMianJicaitong, dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(cropContour2, out ordinateL3, dataArea[0], middleMianJicaitong, ordinateL1, -1); shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + upper, middleMianJicaitong + border, (int)ordinateL3 + upper); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(cropContour2, out ordinateL4, dataArea[0], middleMianJicaitong, ordinateL3, 1); double ordinateL6 = 0; ceju.ExtractLines2(cropContour2, out ordinateL6, middleMianJicaitong, dataArea[1], 1); double ordinateL4Copy = 0; ceju.ExtractLines2(cropContour2, out ordinateL4Copy, middleMianJicaitong, dataArea[1], ordinateL6, -1); if (ordinateL4Copy < ordinateL4) ordinateL4 = ordinateL4Copy; xiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + upper, middleMianJicaitong + border, (int)ordinateL6 + upper); UpdateSuccessLine(); // 提取L2 Mat cropGreen = imageGreen[y[0], y[1], border, imageGreen.Cols - 1]; double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + upper, middleMiantong + border, (int)ordinateL2 + upper); shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + upper, middleJicaitong + border, (int)ordinateL3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L5 double ordinateL5 = 0; if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5); xiaMiantong.Set(ordinateL6 - ordinateL5, middleMiantong + border, (int)ordinateL5 + upper, middleMiantong + border, (int)ordinateL6 + upper); xiaJicaitong.Set(ordinateL5 - ordinateL4, middleJicaitong + border, (int)ordinateL4 + upper, middleJicaitong + border, (int)ordinateL5 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesL2R(cropContour2, out ordinateV1, (int)ordinateL3, (int)ordinateL4); double ordinateV2 = 0; ceju.ExtractVerticalLinesL2R(cropContour2, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1); int middle2 = (int)((ordinateL3 + ordinateL4) / 2); kongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, middle2 + upper, (int)ordinateV2 + border, middle2 + upper); UpdateSuccessLine(); //if (isCropFlag) // UpdateDataInfor(X, Y); } } public class ShuangcengbanZuo : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor kongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100135"; shangJicaitong.aliasName = "CTBCIP"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100136"; xiaJicaitong.aliasName = "DJASEN"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100139"; shangMiantong.aliasName = "MIUUXZ"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100140"; xiaMiantong.aliasName = "XAVAPO"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100137"; shangMiantong_Jicaitong.aliasName = "PMMGUC"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100138"; xiaMiantong_Jicaitong.aliasName = "CUTRFE"; kongtong.name = "孔銅"; kongtong.drawType = "MeasureHLine"; kongtong.ID = "100141"; kongtong.aliasName = "LHCLAP"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(kongtong); number = 7; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); //上下裁剪 int[] y = new int[2] { 0, 0 }; Mat cropContour = new Mat(); ceju.Crop(imageContour, out y, out cropContour, isCropFlag); //去亮光 int[] b = new int[4] { 0, 0, 0, 0 }; Mat cropContour2 = new Mat(); int border = 0; ceju.CropLight(cropContour, out border, out cropContour2, "left"); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(cropContour2, out dataArea, "left"); int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; int upper = y[0]; if (isCropFlag) { upper += Y; border += X; } //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(cropContour2, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(cropContour2, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + upper, middleMianJicaitong + border, (int)ordinateL3 + upper); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(cropContour2, out ordinateL4, dataArea[0], dataArea[1], ordinateL3, 1); double ordinateL6 = 0; ceju.ExtractLines2(cropContour2, out ordinateL6, dataArea[0], dataArea[1], 1); xiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + upper, middleMianJicaitong + border, (int)ordinateL6 + upper); UpdateSuccessLine(); // 提取L2 Mat cropGreen = imageGreen[y[0], y[1], border, imageGreen.Cols - 1]; double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + upper, middleMiantong + border, (int)ordinateL2 + upper); shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + upper, middleJicaitong + border, (int)ordinateL3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L5 double ordinateL5 = 0; if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5); xiaMiantong.Set(ordinateL6 - ordinateL5, middleMiantong + border, (int)ordinateL5 + upper, middleMiantong + border, (int)ordinateL6 + upper); xiaJicaitong.Set(ordinateL5 - ordinateL4, middleJicaitong + border, (int)ordinateL4 + upper, middleJicaitong + border, (int)ordinateL5 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropContour2, out ordinateV1, (int)ordinateL3, (int)ordinateL4); double ordinateV2 = 0; ceju.ExtractVerticalLinesR2L(cropContour2, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1); int middle2 = (int)((ordinateL3 + ordinateL4) / 2); kongtong.Set(Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, middle2 + upper, (int)ordinateV2 + border, middle2 + upper ); UpdateSuccessLine(); } } public class ShuangcengbanQuan : AutoMeasureAnalysis { public DataInfor leftShangJicaitong = new DataInfor(); public DataInfor leftXiaJicaitong = new DataInfor(); public DataInfor leftShangMiantong_Jicaitong = new DataInfor(); public DataInfor leftXiaMiantong_Jicaitong = new DataInfor(); public DataInfor leftShangMiantong = new DataInfor(); public DataInfor leftXiaMiantong = new DataInfor(); public DataInfor leftKongtong = new DataInfor(); public DataInfor leftJiaoneisuo = new DataInfor(); public DataInfor rightShangJicaitong = new DataInfor(); public DataInfor rightXiaJicaitong = new DataInfor(); public DataInfor rightShangMiantong_Jicaitong = new DataInfor(); public DataInfor rightXiaMiantong_Jicaitong = new DataInfor(); public DataInfor rightShangMiantong = new DataInfor(); public DataInfor rightXiaMiantong = new DataInfor(); public DataInfor rightKongtong = new DataInfor(); public DataInfor rightJiaoneisuo = new DataInfor(); public DataInfor shangKongjing = new DataInfor(); public DataInfor xiaKongjing = new DataInfor(); private void Initialize() { dataInfors = new List(); leftShangJicaitong.name = "左側上基材銅"; leftShangJicaitong.ID = "100151"; leftShangJicaitong.aliasName = "NJJSLV"; leftXiaJicaitong.name = "左側下基材銅"; leftXiaJicaitong.ID = "100152"; leftXiaJicaitong.aliasName = "ZMVGAK"; leftShangMiantong_Jicaitong.name = "左側上面銅+基材銅"; leftShangMiantong_Jicaitong.ID = "100153"; leftShangMiantong_Jicaitong.aliasName = "VHUWKJ"; leftXiaMiantong_Jicaitong.name = "左側下面銅+基材銅"; leftXiaMiantong_Jicaitong.ID = "100154"; leftXiaMiantong_Jicaitong.aliasName = "BRTMTH"; leftShangMiantong.name = "左側上面銅"; leftShangMiantong.ID = "100155"; leftShangMiantong.aliasName = "YXCKZF"; leftXiaMiantong.name = "左側下面銅"; leftXiaMiantong.ID = "100156"; leftXiaMiantong.aliasName = "ABLLTX"; leftKongtong.name = "左側孔銅"; leftKongtong.drawType = "MeasureHLine"; leftKongtong.ID = "100157"; leftKongtong.aliasName = "RJVFMC"; leftJiaoneisuo.name = "左側膠内縮"; leftJiaoneisuo.drawType = "MeasureHLine"; leftJiaoneisuo.ID = "300168"; leftJiaoneisuo.aliasName = "XJSSRG"; rightShangJicaitong.name = "右側上基材銅"; rightShangJicaitong.ID = "100158"; rightShangJicaitong.aliasName = "ZEASAC"; rightXiaJicaitong.name = "右側下基材銅"; rightXiaJicaitong.ID = "100159"; rightXiaJicaitong.aliasName = "NULVEP"; rightShangMiantong_Jicaitong.name = "右側上面銅+基材銅"; rightShangMiantong_Jicaitong.ID = "100160"; rightShangMiantong_Jicaitong.aliasName = "LQEEIH"; rightXiaMiantong_Jicaitong.name = "右側下面銅+基材銅"; rightXiaMiantong_Jicaitong.ID = "100161"; rightXiaMiantong_Jicaitong.aliasName = "RZQRLW"; rightShangMiantong.name = "右側上面銅"; rightShangMiantong.ID = "100162"; rightShangMiantong.aliasName = "BCUPMA"; rightXiaMiantong.name = "右側下面銅"; rightXiaMiantong.ID = "100163"; rightXiaMiantong.aliasName = "LQWSEW"; rightKongtong.name = "右側孔銅"; rightKongtong.drawType = "MeasureHLine"; rightKongtong.ID = "100164"; rightKongtong.aliasName = "XJSSRE"; rightJiaoneisuo.name = "右側膠内縮"; rightJiaoneisuo.drawType = "MeasureHLine"; rightJiaoneisuo.ID = "300167"; rightJiaoneisuo.aliasName = "XJSSRF"; shangKongjing.name = "上孔徑"; shangKongjing.drawType = "MeasureHLine"; shangKongjing.ID = "100165"; shangKongjing.aliasName = "IBTYKT"; xiaKongjing.name = "下孔徑"; xiaKongjing.drawType = "MeasureHLine"; xiaKongjing.ID = "100166"; xiaKongjing.aliasName = "KDJMHF"; dataInfors.Add(leftShangJicaitong); dataInfors.Add(leftXiaJicaitong); dataInfors.Add(leftShangMiantong_Jicaitong); dataInfors.Add(leftXiaMiantong_Jicaitong); dataInfors.Add(leftShangMiantong); dataInfors.Add(leftXiaMiantong); dataInfors.Add(leftKongtong); dataInfors.Add(leftJiaoneisuo); dataInfors.Add(rightShangJicaitong); dataInfors.Add(rightXiaJicaitong); dataInfors.Add(rightShangMiantong_Jicaitong); dataInfors.Add(rightXiaMiantong_Jicaitong); dataInfors.Add(rightShangMiantong); dataInfors.Add(rightXiaMiantong); dataInfors.Add(rightKongtong); dataInfors.Add(rightJiaoneisuo); dataInfors.Add(shangKongjing); dataInfors.Add(xiaKongjing); number = 16; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.Crop2(image, out cropEdge, out y, out b, /*true 避免4(9)4(12)和7(10)这样目标区域过于靠下区域的图片定位下面铜错误*/isCropFlag); //待自测scc-4if (!isCropFlag && y[1] + 300 == image.Rows) // ceju.Crop2(image, out cropEdge, out y, out b, true/*isCropFlag*/); Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]]; Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]]; Mat cropLeft = image[y[0], y[1], b[0], b[1]]; Mat cropRight = image[y[0], y[1], b[2], b[3]]; if (isCropFlag) { y[0] += Y; b[0] += X; b[2] += X; } ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]); ComputeRight(cropRight, cropEdgeRight, image, y, b[2]); } private void ComputeLeft(Mat cropLeft, Mat cropCloseLeft, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropLeft); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "left"); //dataArea[0] -= 50; dataArea[1] -= 30; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); //待自测scc-4_0_to delete and test leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1); double ordinateL4 = 0; ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1); //待自测scc-4_0_to delete and test double ordinateL4Copy = 0; ceju.ExtractLines(imageContour, out ordinateL4Copy, middleMianJicaitong - 10, middleMianJicaitong + 10, ordinateL3, 1); if (ordinateL4Copy < ordinateL4) ordinateL4 = ordinateL4Copy; leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]); UpdateSuccessLine(); //// 提取L2 //double ordinateL2 = 0; //if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) //{ // ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1); // double[] ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 }; // ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong // , ordinateL2, ordinateL2, out ordinateL2_Acc, 1, false); // leftShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]); // leftShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); // UpdateSuccessLine(); // UpdateSuccessLine(); //} //// 提取L5 //double ordinateL5 = 0; //if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1]) //{ // ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2); // double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 }; // ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong // , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, false); // leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]); // leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]); // UpdateSuccessLine(); // UpdateSuccessLine(); //} //根据提取的面铜和基材铜,获取到孔铜和胶内缩后,根据胶内缩结果验证面铜和基材铜的横坐标,如果位置不符合规律,需要重新计算面铜和基材铜 //待自测scc-4_0_to add and test //// 提取竪綫 //double ordinateV1 = 0; //ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1, (int)ordinateL3, (int)ordinateL4); //double ordinateV2 = 0; //////精准找到面铜的标记点,避免直线拟合导致测量精度不够 ////Mat mat1 = new Mat(); ////Cv2.Normalize(imageContour, mat1, 0, 255, NormTypes.MinMax); ////Cv2.ImShow("imageContour", mat1); ////Cv2.WaitKey(); //int[] result1 = ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1); //int middle2 = (int)((ordinateL3 + ordinateL4) / 2); //leftKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]); UpdateSuccessLine(); //待自测scc-4_0_to add and test //leftJiaoneisuo.Set(ordinateV2 - result1[0], (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]); //UpdateSuccessLine(); ////待自测scc-4_0_to add and test //根据提取的面铜和基材铜,获取到孔铜和胶内缩后,根据胶内缩结果验证面铜和基材铜的横坐标,如果位置不符合规律,需要重新计算面铜和基材铜 //if (ordinateV2 > middleMiantong + 5/*10*/) //{ // leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); // UpdateSuccessLine(); // leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]); // UpdateSuccessLine(); //} //else //{//重新计算 面铜和基材铜 // //dataArea[0] -= 50; // dataArea[1] = (int)ordinateV2 - 30; // //dataArea[1] -= 30; // dataArea[0] = dataArea[1] - 100; // middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; // middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; // middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; // //提取綫條 // ordinateL1 = 0; // ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); // ordinateL3 = 0; // ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); // //leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); // //UpdateSuccessLine(); // ordinateL6 = 0; // ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1); // ordinateL4 = 0; // ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1); // leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); // UpdateSuccessLine(); // leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]); // UpdateSuccessLine(); //} // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1); double[] ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 }; ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong , ordinateL2, ordinateL2, out ordinateL2_Acc, 1, 2, false); //纠正02781的偏差,避免出现斜对角抖动过大的问题 if (Math.Abs(ordinateL2_Acc[0] - ordinateL2_Acc[1]) * 2 > Math.Abs(middleMiantong - middleJicaitong) - 2) //if (ordinateL2_Acc[0] == ordinateL2 || ordinateL2_Acc[0] == ordinateL2) ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 }; if (Math.Abs(ordinateL2_Acc[0]- (ordinateL1+ordinateL3)/2) < Math.Abs(ordinateL2_Acc[1]- (ordinateL1+ordinateL3)/2)) ordinateL2_Acc[1] = ordinateL2_Acc[0]; else ordinateL2_Acc[0] = ordinateL2_Acc[1]; leftShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]); leftShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L5 double ordinateL5 = 0; if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1]) { /*double ordinateL5_2 = */ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2, true); double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 }; ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, true); if (Math.Abs(ordinateL2_Acc[0] - ordinateL2_Acc[1]) * 2 > Math.Abs(middleMiantong - middleJicaitong) - 2) if (Math.Abs(ordinateL2_Acc[0]- (ordinateL4+ordinateL6)/2) < Math.Abs(ordinateL2_Acc[1]- (ordinateL4+ordinateL6)/2)) ordinateL2_Acc[1] = ordinateL2_Acc[0]; else ordinateL2_Acc[0] = ordinateL2_Acc[1]; //if (ordinateL2_Acc[0] == 0 && ordinateL2_Acc[1] == 0) //{ // ordinateL2_Acc[0] = (ordinateL6 * 3 + ordinateL4) / 4; // ordinateL2_Acc[1] = ordinateL2_Acc[0]; //} if (ordinateL2_Acc[0] == 0 && ordinateL2_Acc[1] == 0) {//重新测定 ordinateL2_Acc[0] = (ordinateL6 * 3 + ordinateL4) / 4; ordinateL2_Acc[1] = ordinateL2_Acc[0]; leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]); leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); try { // 二、计算数据提取区域 int[] dataArea_2 = new int[2]; //ceju.GetDataArea(imageContour, out dataArea, "left"); ////dataArea[0] -= 50; dataArea_2[0] = dataArea[1] - 10; dataArea_2[1] = dataArea_2[0] + dataArea[1] - dataArea[0]; int middleMianJicaitong_2 = (dataArea_2[0] + dataArea_2[1]) / 2; int middleMiantong_2 = (middleMianJicaitong_2 + dataArea_2[1]) / 2; int middleJicaitong_2 = (dataArea_2[0] + middleMianJicaitong_2) / 2; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea_2[0], dataArea_2[1], 1); //double ordinateL4 = 0; //ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1); ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea_2[0], dataArea_2[1], out ordinateL5, 2); if (ordinateL5 != 0) { ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 }; ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea_2[0], dataArea_2[1], middleMiantong, middleJicaitong , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, false); } leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong_2 + border, (int)ordinateL4 + y[0], middleMianJicaitong_2 + border, (int)ordinateL6 + y[0]); UpdateSuccessLine(); leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong_2 + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong_2 + border, (int)ordinateL6 + y[0]); leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong_2 + border, (int)ordinateL4 + y[0], middleJicaitong_2 + border, (int)ordinateL2_Acc[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } catch (Exception) { } } else { leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]); leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } } //待自测scc-4_0_to delete and test // 提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1, (int)ordinateL3, (int)ordinateL4); double ordinateV2 = 0; int[] result1 = ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1); int middle2 = (int)((ordinateL3 + ordinateL4) / 2); leftKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]); UpdateSuccessLine(); leftJiaoneisuo.Set(ordinateV2 - result1[0], (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]); UpdateSuccessLine(); double ordinateV1Upper = 0; ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20); double ordinateV2Upper = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20, ordinateV1Upper); double ordinateV1Lower = 0; ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10); double ordinateV2Lower = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10, ordinateV1Lower); shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2Upper + border, (int)ordinateL1 - 10 + y[0]); xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV2Lower + border, (int)ordinateL6 + 10 + y[0]); } private void ComputeRight(Mat cropRight, Mat cropCloseRight, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropRight); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "right"); dataArea[0] += 50; dataArea[1] += 20; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); rightShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1); double ordinateL4 = 0; ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1); rightXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]); UpdateSuccessLine(); // 四、提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1/*, false*/); double[] ordinateL2_Acc = new double[] { ordinateL2 - 10, ordinateL2 -10 }; ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong , ordinateL2 /* 待自测scc-5_0_to debug and test- 5 */, ordinateL2 /*待自测scc-5_0_to debug and test- 5*/, out ordinateL2_Acc, 1, 2, false/* 待自测scc-5_0_to debug and test false */); ////精准找到面铜的标记点,避免直线拟合导致测量精度不够 //Mat mat1 = new Mat(); //Cv2.Normalize(imageGreen, mat1, 0, 255, NormTypes.MinMax); //Cv2.ImShow("imageGreen", mat1); //Cv2.WaitKey(); rightShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]); rightShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 五、提取L5 double ordinateL5 = 0; if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2/*, true*/); //Mat mat1 = new Mat(); //Cv2.Normalize(imageGreen, mat1, 0, 255, NormTypes.MinMax); //Cv2.ImShow("imageGreen", mat1); //Cv2.WaitKey(); double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 }; //待自测scc-5_0_to delete and test ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, false); rightXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]); rightXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageContour.png", imageContour * 127); //提取竪綫 double ordinateV1 = 0; double ordinateV2 = 0; int[] result1 = new int[] { 0, 0 }; try { //解决两层板有些孔铜找不到的问题 int verMargin = 20; if (ordinateL4 - ordinateL3 < 20) verMargin = 0; else if (ordinateL4 - ordinateL3 < 40) verMargin = 10; ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1, (int)ordinateL3 + verMargin, (int)ordinateL4 - verMargin); result1 = ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + verMargin, (int)ordinateL4 - verMargin, ordinateV1, false); } catch (Exception) { } int middle2 = (int)((ordinateL3 + ordinateL4) / 2); rightKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]); UpdateSuccessLine(); rightJiaoneisuo.Set(result1[0] - ordinateV2, (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]); UpdateSuccessLine(); double ordinateV1Upper = 0; ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20); double ordinateV2Upper = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20, ordinateV1Upper); double ordinateV1Lower = 0; ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10); double ordinateV2Lower = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10, ordinateV1Lower); shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2Upper + border, (int)ordinateL1 - 10 + y[0]); xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV2Lower + border, (int)ordinateL6 + 10 + y[0]); if (xiaKongjing.point1.Y != xiaKongjing.point2.Y) { int kongjingY = Math.Max(xiaKongjing.point1.Y, xiaKongjing.point2.Y); xiaKongjing.point1.Y = kongjingY; xiaKongjing.point2.Y = kongjingY; } shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X; xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X; UpdateSuccessLine(); UpdateSuccessLine(); } } public class SancengbanYou : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor cucaodu = new DataInfor(); public DataInfor shangKongtong = new DataInfor(); public DataInfor xiaKongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100104"; shangJicaitong.aliasName = "BGHYOX"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100105"; xiaJicaitong.aliasName = "BGWDNC"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100106"; shangMiantong_Jicaitong.aliasName = "SQMNJW"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100107"; xiaMiantong_Jicaitong.aliasName = "CVJYIF"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100108"; shangMiantong.aliasName = "MJLBAA"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100109"; xiaMiantong.aliasName = "ZCHBNJ"; cucaodu.name = "粗糙度"; cucaodu.drawType = "MeasureHLine"; cucaodu.ID = "100110"; cucaodu.aliasName = "QDTTQQ"; shangKongtong.name = "上孔銅"; shangKongtong.ID = "100111"; shangKongtong.aliasName = "UIKKYT"; shangKongtong.drawType = "MeasureHLine"; xiaKongtong.name = "下孔銅"; xiaKongtong.ID = "100112"; xiaKongtong.aliasName = "SIRZJN"; xiaKongtong.drawType = "MeasureHLine"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(cucaodu); dataInfors.Add(shangKongtong); dataInfors.Add(xiaKongtong); number = 9; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag); //分割 Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]];//用於測量邊緣竪綫 Mat cropRight = image[y[0], y[1], b[2], b[3]]; if (isCropFlag) { y[0] += Y; b[2] += X; } ComputeRight(cropRight, cropEdgeRight, image, y, b[2]); } private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropRight); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "right"); dataArea[0] += 30; //dataArea[1] += 50; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, dataArea[0], dataArea[1], ordinateL4, -1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1); xiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 四、提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 五、提取L7 double ordinateL7 = 0; if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7); xiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]); xiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20); double ordinateV4 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3); xiaKongtong.Set(ordinateV4 - ordinateV3, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]); UpdateSuccessLine(); //計算粗糙度 int roughness; int[] roughnessOrdinate = new int[2]; ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "right", out roughness, out roughnessOrdinate); cucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } } public class SancengbanZuo : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor cucaodu = new DataInfor(); public DataInfor shangKongtong = new DataInfor(); public DataInfor xiaKongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100094"; shangJicaitong.aliasName = "BURQWZ"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100095"; xiaJicaitong.aliasName = "CJQGSX"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100096"; shangMiantong_Jicaitong.aliasName = "PCNGFF"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100097"; xiaMiantong_Jicaitong.aliasName = "ONRAHR"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100098"; shangMiantong.aliasName = "BHTPXN"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100099"; xiaMiantong.aliasName = "RHZRXH"; cucaodu.name = "粗糙度"; cucaodu.drawType = "MeasureHLine"; cucaodu.ID = "100100"; cucaodu.aliasName = "PCTABZ"; shangKongtong.name = "上孔銅"; shangKongtong.drawType = "MeasureHLine"; shangKongtong.ID = "100101"; shangKongtong.aliasName = "IGTYVF"; xiaKongtong.name = "下孔銅"; xiaKongtong.drawType = "MeasureHLine"; xiaKongtong.ID = "100102"; xiaKongtong.aliasName = "KIVJLJ"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(cucaodu); dataInfors.Add(shangKongtong); dataInfors.Add(xiaKongtong); number = 9; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat cropEdge = new Mat(); int[] y = new int[2];//上下裁剪边界 int[] b = new int[4];//左右裁剪边界 ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag); Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]]; Mat cropLeft = image[y[0], y[1], b[0], b[1]]; if (isCropFlag) { y[0] += Y; b[0] += X; } ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]); } private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropLeft); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "left"); dataArea[1] -= 30; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 5, middleJicaitong + 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 5, middleJicaitong + 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 5, middleJicaitong + 5, ordinateL5, -1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1); double ordinateL6Copy = 0; ceju.ExtractLines(imageContour, out ordinateL6Copy, middleJicaitong - 5, middleJicaitong + 5, ordinateL5, 1); if (ordinateL6Copy < ordinateL6) { ordinateL6 = ordinateL6Copy; } xiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L7 double ordinateL7 = 0; if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7); xiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]); xiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongtong.Set(Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20); double ordinateV4 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3); xiaKongtong.Set(Math.Abs(ordinateV4 - ordinateV3), (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]); UpdateSuccessLine(); //計算粗糙度 int roughness; int[] roughnessOrdinate = new int[2]; ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "left", out roughness, out roughnessOrdinate); cucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } } public class SancengbanQuan : AutoMeasureAnalysis { public DataInfor leftShangJicaitong = new DataInfor(); public DataInfor leftXiaJicaitong = new DataInfor(); public DataInfor leftShangMiantong_Jicaitong = new DataInfor(); public DataInfor leftXiaMiantong_Jicaitong = new DataInfor(); public DataInfor leftShangMiantong = new DataInfor(); public DataInfor leftXiaMiantong = new DataInfor(); public DataInfor leftCucaodu = new DataInfor(); public DataInfor leftShangKongtong = new DataInfor(); public DataInfor leftXiaKongtong = new DataInfor(); public DataInfor rightShangJicaitong = new DataInfor(); public DataInfor rightXiaJicaitong = new DataInfor(); public DataInfor rightShangMiantong_Jicaitong = new DataInfor(); public DataInfor rightXiaMiantong_Jicaitong = new DataInfor(); public DataInfor rightShangMiantong = new DataInfor(); public DataInfor rightXiaMiantong = new DataInfor(); public DataInfor rightCucaodu = new DataInfor(); public DataInfor rightShangKongtong = new DataInfor(); public DataInfor rightXiaKongtong = new DataInfor(); public DataInfor shangKongjing = new DataInfor(); public DataInfor xiaKongjing = new DataInfor(); private void Initialize() { dataInfors = new List(); leftShangJicaitong.name = "左側上基材銅"; leftShangJicaitong.ID = "100114"; leftShangJicaitong.aliasName = "YNDKLJ"; leftXiaJicaitong.name = "左側下基材銅"; leftXiaJicaitong.ID = "100115"; leftXiaJicaitong.aliasName = "VVTXVV"; leftShangMiantong_Jicaitong.name = "左側上面銅+基材銅"; leftShangMiantong_Jicaitong.ID = "100116"; leftShangMiantong_Jicaitong.aliasName = "ESDAMJ"; leftXiaMiantong_Jicaitong.name = "左側下面銅+基材銅"; leftXiaMiantong_Jicaitong.ID = "100117"; leftXiaMiantong_Jicaitong.aliasName = "XYKOKE"; leftShangMiantong.name = "左側上面銅"; leftShangMiantong.ID = "100118"; leftShangMiantong.aliasName = "GWBGEG"; leftXiaMiantong.name = "左側下面銅"; leftXiaMiantong.ID = "100119"; leftXiaMiantong.aliasName = "AYQHQR"; leftCucaodu.name = "左側粗糙度"; leftCucaodu.drawType = "MeasureHLine"; leftCucaodu.ID = "100120"; leftCucaodu.aliasName = "QYNTBB"; leftShangKongtong.name = "左側上孔銅"; leftShangKongtong.drawType = "MeasureHLine"; leftShangKongtong.ID = "100121"; leftShangKongtong.aliasName = "BHKHAE"; leftXiaKongtong.name = "左側下孔銅"; leftXiaKongtong.drawType = "MeasureHLine"; leftXiaKongtong.ID = "100122"; leftXiaKongtong.aliasName = "BSJUWI"; rightShangJicaitong.name = "右側上基材銅"; rightShangJicaitong.ID = "100123"; rightShangJicaitong.aliasName = "YYTSDH"; rightXiaJicaitong.name = "右側下基材銅"; rightXiaJicaitong.ID = "100124"; rightXiaJicaitong.aliasName = "JCFGSW"; rightShangMiantong_Jicaitong.name = "右側上面銅+基材銅"; rightShangMiantong_Jicaitong.ID = "100125"; rightShangMiantong_Jicaitong.aliasName = "PATOEU"; rightXiaMiantong_Jicaitong.name = "右側下面銅+基材銅"; rightXiaMiantong_Jicaitong.ID = "100126"; rightXiaMiantong_Jicaitong.aliasName = "BODILZ"; rightShangMiantong.name = "右側上面銅"; rightShangMiantong.ID = "100127"; rightShangMiantong.aliasName = "PAWYCE"; rightXiaMiantong.name = "右側下面銅"; rightXiaMiantong.ID = "100128"; rightXiaMiantong.aliasName = "BTSYPM"; rightCucaodu.name = "右側粗糙度"; rightCucaodu.drawType = "MeasureHLine"; rightCucaodu.ID = "100129"; rightCucaodu.aliasName = "CTHDOR"; rightShangKongtong.name = "右側上孔銅"; rightShangKongtong.drawType = "MeasureHLine"; rightShangKongtong.ID = "100130"; rightShangKongtong.aliasName = "ZOBMSJ"; rightXiaKongtong.name = "右側下孔銅"; rightXiaKongtong.drawType = "MeasureHLine"; rightXiaKongtong.ID = "100131"; rightXiaKongtong.aliasName = "MHXLFR"; shangKongjing.name = "上孔徑"; shangKongjing.drawType = "MeasureHLine"; shangKongjing.ID = "100132"; shangKongjing.aliasName = "YZTKSZ"; xiaKongjing.name = "下孔徑"; xiaKongjing.drawType = "MeasureHLine"; xiaKongjing.ID = "100133"; xiaKongjing.aliasName = "MHAVDA"; dataInfors.Add(leftShangJicaitong); dataInfors.Add(leftXiaJicaitong); dataInfors.Add(leftShangMiantong_Jicaitong); dataInfors.Add(leftXiaMiantong_Jicaitong); dataInfors.Add(leftShangMiantong); dataInfors.Add(leftXiaMiantong); dataInfors.Add(leftCucaodu); dataInfors.Add(leftShangKongtong); dataInfors.Add(leftXiaKongtong); dataInfors.Add(rightShangJicaitong); dataInfors.Add(rightXiaJicaitong); dataInfors.Add(rightShangMiantong_Jicaitong); dataInfors.Add(rightXiaMiantong_Jicaitong); dataInfors.Add(rightShangMiantong); dataInfors.Add(rightXiaMiantong); dataInfors.Add(rightCucaodu); dataInfors.Add(rightShangKongtong); dataInfors.Add(rightXiaKongtong); dataInfors.Add(shangKongjing); dataInfors.Add(xiaKongjing); number = 20; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag); Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]]; Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]]; Mat cropLeft = image[y[0], y[1], b[0], b[1]]; Mat cropRight = image[y[0], y[1], b[2], b[3]]; if (isCropFlag) { y[0] += Y; b[0] += X; b[2] += X; } ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]); ComputeRight(cropRight, cropEdgeRight, image, y, b[2]); } private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropLeft); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "left"); dataArea[1] -= 30; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL5, -1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1); double ordinateL6New = 0; ceju.ExtractLines(imageContour, out ordinateL6New, dataArea[0], dataArea[1], ordinateL5, 1); if (ordinateL6New < ordinateL6) ordinateL6 = ordinateL6New; leftXiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); leftShangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); leftShangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L7 double ordinateL7 = 0; if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7); leftXiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]); leftXiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40, 1); double ordinateV2 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);//, 3); //Cv2.ImWrite("", imageContour); leftShangKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2 + border, (int)ordinateL1 - 10 + y[0]); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20, 2); double ordinateV4 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);//, 4); leftXiaKongtong.Set(ordinateV3 - ordinateV4, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]); xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV4 + border, (int)ordinateL8 + 10 + y[0]); UpdateSuccessLine(); //計算粗糙度 int roughness = 0; int[] roughnessOrdinate = new int[4]; ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "left", out roughness, out roughnessOrdinate); leftCucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropRight); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲取目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "right"); dataArea[0] += 30; //dataArea[1] += 50; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); rightShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL5, -1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1); double ordinateL6 = 0; ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1); double ordinateL6Copy = 0; ceju.ExtractLines(imageContour, out ordinateL6Copy, dataArea[0], dataArea[1], ordinateL5, 1); if (ordinateL6Copy < ordinateL6) ordinateL6 = ordinateL6Copy; rightXiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); rightShangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); rightShangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L7 double ordinateL7 = 0; if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7); rightXiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]); rightXiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40, 1); double ordinateV2 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); rightShangKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2 + border, shangKongjing.point1.Y); shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X; UpdateSuccessLine(); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20, 2); double ordinateV4 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3); rightXiaKongtong.Set(ordinateV4 - ordinateV3, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]); xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV4 + border, xiaKongjing.point1.Y); xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X; UpdateSuccessLine(); UpdateSuccessLine(); //计算粗糙度 int roughness = 0; int[] roughnessOrdinate = new int[4]; ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "right", out roughness, out roughnessOrdinate); rightCucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } } public class SicengbanYou : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor shangCucaodu = new DataInfor(); public DataInfor xiaCucaodu = new DataInfor(); public DataInfor shangKongtong = new DataInfor(); public DataInfor zhongKongtong = new DataInfor(); public DataInfor xiaKongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100079"; shangJicaitong.aliasName = "SJTBNK"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100080"; xiaJicaitong.aliasName = "KVCZGJ"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100081"; shangMiantong_Jicaitong.aliasName = "FCEGZX"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100082"; xiaMiantong_Jicaitong.aliasName = "OBVYTZ"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100083"; shangMiantong.aliasName = "ENWFZN"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100084"; xiaMiantong.aliasName = "SVDPKP"; shangCucaodu.name = "上粗糙度"; shangCucaodu.drawType = "MeasureHLine"; shangCucaodu.ID = "100085"; shangCucaodu.aliasName = "OQCFTN"; xiaCucaodu.name = "下粗糙度"; xiaCucaodu.drawType = "MeasureHLine"; xiaCucaodu.ID = "100086"; xiaCucaodu.aliasName = "CJTXBP"; shangKongtong.name = "上孔銅"; shangKongtong.drawType = "MeasureHLine"; shangKongtong.ID = "100087"; shangKongtong.aliasName = "HFBQJZ"; zhongKongtong.name = "中孔銅"; zhongKongtong.drawType = "MeasureHLine"; zhongKongtong.ID = "100088"; zhongKongtong.aliasName = "LQDNNH"; xiaKongtong.name = "下孔銅"; xiaKongtong.drawType = "MeasureHLine"; xiaKongtong.ID = "100089"; xiaKongtong.aliasName = "MMNDTU"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(shangCucaodu); dataInfors.Add(xiaCucaodu); dataInfors.Add(shangKongtong); dataInfors.Add(zhongKongtong); dataInfors.Add(xiaKongtong); number = 11; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 调色 Mat sobel = new Mat(); ceju.Sobel(imageGreen, out sobel); Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3)); Mat close = new Mat(); Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se); Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu); ceju.Fill(thresh, out thresh, 1); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag); Mat cropEdgeRight = thresh[y[0], y[1], b[2], b[3]];//四层边缘图像用新的 Mat cropRight = image[y[0], y[1], b[2], b[3]]; if (isCropFlag) { y[0] += Y; b[2] += X; } ComputeRight(cropRight, cropEdgeRight, image, y, b[2]); } private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropRight); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲取目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "right"); dataArea[0] += 30; //dataArea[1] += 50; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); shangMiantong_Jicaitong.Set((int)(ordinateL3 - ordinateL1), middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleMiantong - 5, middleMiantong + 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong - 5, middleMiantong + 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong - 5, middleMiantong + 5, ordinateL5, -1); double ordinateL6 = 0; ceju.ExtractLines(imageContour, out ordinateL6, middleMiantong - 5, middleMiantong + 5, ordinateL5, 1); double ordinateL7 = 0; ceju.ExtractLines(imageContour, out ordinateL7, middleMiantong - 5, middleMiantong + 5, ordinateL6, -1); double ordinateL10 = 0; ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1); double ordinateL8Copy = 0; ceju.ExtractLines(imageContour, out ordinateL8Copy, middleMiantong - 5, middleMiantong + 5, ordinateL7, 1); if (ordinateL8Copy < ordinateL8) ordinateL8 = ordinateL8Copy; xiaMiantong_Jicaitong.Set((int)(ordinateL10 - ordinateL8), middleMianJicaitong + border, (int)ordinateL10 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set((int)(ordinateL2 - ordinateL1), middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); shangJicaitong.Set((int)(ordinateL3 - ordinateL2), middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L9 double ordinateL9 = 0; if (ordinateL8 + 10 < ordinateL10 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL8 + 10, (int)ordinateL10 - 10, dataArea[0], dataArea[1], out ordinateL9); xiaMiantong.Set((int)(ordinateL10 - ordinateL9), middleMiantong + border, (int)ordinateL10 + y[0], middleMiantong + border, (int)ordinateL9 + y[0]); xiaJicaitong.Set((int)(ordinateL9 - ordinateL8), middleJicaitong + border, (int)ordinateL9 + y[0], middleJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongtong.Set((int)(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL5 + 20, (int)ordinateL6 - 20); double ordinateV4 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL5 + 20, (int)ordinateL6 - 20, ordinateV3); int middle = (int)(ordinateL5 + ordinateL6) / 2; zhongKongtong.Set((int)(ordinateV4 - ordinateV3), (int)ordinateV3 + border, middle + y[0], (int)ordinateV4 + border, middle + y[0]); UpdateSuccessLine(); double ordinateV5 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20); double ordinateV6 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5); xiaKongtong.Set((int)(ordinateV6 - ordinateV5), (int)ordinateV5 + border, (int)ordinateL8 - 30 + y[0], (int)ordinateV6 + border, (int)ordinateL8 - 30 + y[0]); UpdateSuccessLine(); //计算粗糙度 int shangRoughness = 0, xiaRoughness = 0; int[] shangRoughnessOrdinate = new int[4]; int[] xiaRoughnessOrdinate = new int[4]; ceju.GetSicengRoughness(imageContour, (int)ordinateL3 + 15, (int)ordinateL4 - 15, (int)ordinateV2, "right", out shangRoughness, out shangRoughnessOrdinate); shangCucaodu.Set(shangRoughness, shangRoughnessOrdinate[0] + border, shangRoughnessOrdinate[1] + y[0], shangRoughnessOrdinate[2] + border, shangRoughnessOrdinate[3] + y[0]); UpdateSuccessLine(); ceju.GetSicengRoughness(imageContour, (int)ordinateL7 + 15, (int)ordinateL8 - 15, (int)ordinateV6, "right", out xiaRoughness, out xiaRoughnessOrdinate); xiaCucaodu.Set(xiaRoughness, xiaRoughnessOrdinate[0] + border, xiaRoughnessOrdinate[1] + y[0], xiaRoughnessOrdinate[2] + border, xiaRoughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } } public class SicengbanZuo : AutoMeasureAnalysis { public DataInfor shangJicaitong = new DataInfor(); public DataInfor xiaJicaitong = new DataInfor(); public DataInfor shangMiantong_Jicaitong = new DataInfor(); public DataInfor xiaMiantong_Jicaitong = new DataInfor(); public DataInfor shangMiantong = new DataInfor(); public DataInfor xiaMiantong = new DataInfor(); public DataInfor shangCucaodu = new DataInfor(); public DataInfor xiaCucaodu = new DataInfor(); public DataInfor shangKongtong = new DataInfor(); public DataInfor zhongKongtong = new DataInfor(); public DataInfor xiaKongtong = new DataInfor(); private void Initialize() { dataInfors = new List(); shangJicaitong.name = "上基材銅"; shangJicaitong.ID = "100067"; shangJicaitong.aliasName = "TXAKXC"; xiaJicaitong.name = "下基材銅"; xiaJicaitong.ID = "100068"; xiaJicaitong.aliasName = "DLBNQX"; shangMiantong_Jicaitong.name = "上面銅+基材銅"; shangMiantong_Jicaitong.ID = "100069"; shangMiantong_Jicaitong.aliasName = "ZSLKWV"; xiaMiantong_Jicaitong.name = "下面銅+基材銅"; xiaMiantong_Jicaitong.ID = "100070"; xiaMiantong_Jicaitong.aliasName = "NZRVGX"; shangMiantong.name = "上面銅"; shangMiantong.ID = "100071"; shangMiantong.aliasName = "YAXUTY"; xiaMiantong.name = "下面銅"; xiaMiantong.ID = "100072"; xiaMiantong.aliasName = "YSHGYR"; shangCucaodu.name = "上粗糙度"; shangCucaodu.ID = "100073"; shangCucaodu.drawType = "MeasureHLine"; shangCucaodu.aliasName = "LVOOIZ"; xiaCucaodu.name = "下粗糙度"; xiaCucaodu.drawType = "MeasureHLine"; xiaCucaodu.ID = "100074"; xiaCucaodu.aliasName = "HGPYBG"; shangKongtong.name = "上孔銅"; shangKongtong.drawType = "MeasureHLine"; shangKongtong.ID = "100075"; shangKongtong.aliasName = "NPBMEV"; zhongKongtong.name = "中孔銅"; zhongKongtong.drawType = "MeasureHLine"; zhongKongtong.ID = "100076"; zhongKongtong.aliasName = "ASITOE"; xiaKongtong.name = "下孔銅"; xiaKongtong.drawType = "MeasureHLine"; xiaKongtong.ID = "100077"; xiaKongtong.aliasName = "DMCGFP"; dataInfors.Add(shangJicaitong); dataInfors.Add(xiaJicaitong); dataInfors.Add(shangMiantong_Jicaitong); dataInfors.Add(xiaMiantong_Jicaitong); dataInfors.Add(shangMiantong); dataInfors.Add(xiaMiantong); dataInfors.Add(shangCucaodu); dataInfors.Add(xiaCucaodu); dataInfors.Add(shangKongtong); dataInfors.Add(zhongKongtong); dataInfors.Add(xiaKongtong); number = 11; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 调色 Mat sobel = new Mat(); ceju.Sobel(imageGreen, out sobel); Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3)); Mat close = new Mat(); Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se); Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu); ceju.Fill(thresh, out thresh, 1); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag); Mat cropEdgeLeft = thresh[y[0], y[1], b[0], b[1]];//四层边缘图像用新的 Mat cropLeft = image[y[0], y[1], b[0], b[1]]; if (isCropFlag) { y[0] += Y; b[0] += X; } ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]); } private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropLeft); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "left"); dataArea[1] -= 70; if (dataArea[1] - dataArea[0] < 20) dataArea[0] -= 70; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); shangMiantong_Jicaitong.Set((int)(ordinateL3 - ordinateL1), middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 15, middleJicaitong - 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, -1); double ordinateL6 = 0; ceju.ExtractLines(imageContour, out ordinateL6, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, 1); double ordinateL7 = 0; ceju.ExtractLines(imageContour, out ordinateL7, middleJicaitong - 15, middleJicaitong - 5, ordinateL6, -1); double ordinateL10 = 0; ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1); double ordinateL8Copy = 0; ceju.ExtractLines(imageContour, out ordinateL8Copy, middleJicaitong - 15, middleJicaitong - 5, ordinateL7, 1); if (ordinateL8Copy < ordinateL8) ordinateL8 = ordinateL8Copy; xiaMiantong_Jicaitong.Set((int)(ordinateL10 - ordinateL8), middleMianJicaitong + border, (int)ordinateL10 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); // 提取L2 double ordinateL2 = 0; if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2); shangMiantong.Set((int)(ordinateL2 - ordinateL1), middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]); shangJicaitong.Set((int)(ordinateL3 - ordinateL2), middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 提取L9 double ordinateL9 = 0; if (ordinateL8 + 10 < ordinateL10 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)ordinateL8 + 10, (int)ordinateL10 - 10, dataArea[0], dataArea[1], out ordinateL9); xiaMiantong.Set((int)(ordinateL10 - ordinateL9), middleMiantong + border, (int)ordinateL10 + y[0], middleMiantong + border, (int)ordinateL9 + y[0]); xiaJicaitong.Set((int)(ordinateL9 - ordinateL8), middleJicaitong + border, (int)ordinateL9 + y[0], middleJicaitong + border, (int)ordinateL8 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongtong.Set((int)Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]); UpdateSuccessLine(); double ordinateV3 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20); double ordinateV4 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3); int middle = (int)(ordinateL5 + ordinateL6) / 2; zhongKongtong.Set((int)Math.Abs(ordinateV4 - ordinateV3), (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]); UpdateSuccessLine(); double ordinateV5 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20); double ordinateV6 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5); xiaKongtong.Set((int)Math.Abs(ordinateV6 - ordinateV5), (int)ordinateV5 + border, (int)ordinateL8 - 30 + y[0], (int)ordinateV6 + border, (int)ordinateL8 - 30 + y[0]); UpdateSuccessLine(); //计算粗糙度 int shangRoughness = 0, xiaRoughness = 0; int[] shangRoughnessOrdinate = new int[4]; int[] xiaRoughnessOrdinate = new int[4]; ceju.GetSicengRoughness(imageContour, (int)ordinateL3 + 15, (int)ordinateL4 - 15, (int)ordinateV2, "left", out shangRoughness, out shangRoughnessOrdinate); shangCucaodu.Set(shangRoughness, shangRoughnessOrdinate[0] + border, shangRoughnessOrdinate[1] + y[0], shangRoughnessOrdinate[2] + border, shangRoughnessOrdinate[3] + y[0]); UpdateSuccessLine(); ceju.GetSicengRoughness(imageContour, (int)ordinateL7 + 15, (int)ordinateL8 - 15, (int)ordinateV6, "left", out xiaRoughness, out xiaRoughnessOrdinate); xiaCucaodu.Set(xiaRoughness, xiaRoughnessOrdinate[0] + border, xiaRoughnessOrdinate[1] + y[0], xiaRoughnessOrdinate[2] + border, xiaRoughnessOrdinate[3] + y[0]); UpdateSuccessLine(); } } public class SicengbanKongjing : AutoMeasureAnalysis { public DataInfor shangKongjing = new DataInfor(); public DataInfor xiaKongjing = new DataInfor(); public void Initialize() { dataInfors = new List(); shangKongjing.name = "上孔徑"; shangKongjing.drawType = "MeasureHLine"; shangKongjing.ID = "100091"; shangKongjing.aliasName = "OQWENM"; xiaKongjing.name = "下孔徑"; xiaKongjing.drawType = "MeasureHLine"; xiaKongjing.ID = "100092"; xiaKongjing.aliasName = "BUDLXU"; dataInfors.Add(shangKongjing); dataInfors.Add(xiaKongjing); success = 0; number = 2; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 调色 Mat sobel = new Mat(); ceju.Sobel(imageGreen, out sobel); Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3)); Mat close = new Mat(); Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se); Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu); ceju.Fill(thresh, out thresh, 1); Mat cropEdge = new Mat(); int[] y = new int[2]; int[] b = new int[4]; ceju.CropSicengKongjing(image, out cropEdge, out y, out b, isCropFlag); Mat cropEdgeLeft = thresh[y[0], y[1], b[0], b[1]]; Mat cropEdgeRight = thresh[y[0], y[1], b[2], b[3]];//四层边缘图像用新的 Mat cropLeft = image[y[0], y[1], b[0], b[1]]; Mat cropRight = image[y[0], y[1], b[2], b[3]]; if (isCropFlag) { y[0] += Y; b[0] += X; b[2] += X; } ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]); ComputeRight(cropRight, cropEdgeRight, image, y, b[2]); } private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropLeft); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲取目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "left"); dataArea[1] -= 70; dataArea[0] -= 70; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 15, middleJicaitong - 5, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, -1); double ordinateL6 = 0; ceju.ExtractLines(imageContour, out ordinateL6, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, 1); double ordinateL7 = 0; ceju.ExtractLines(imageContour, out ordinateL7, middleJicaitong - 15, middleJicaitong - 5, ordinateL6, -1); double ordinateL10 = 0; ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1); double ordinateL8Copy = 0; ceju.ExtractLines(imageContour, out ordinateL8Copy, middleJicaitong - 15, middleJicaitong - 5, ordinateL7, 1); if (ordinateL8Copy < ordinateL8) ordinateL8 = ordinateL8Copy; //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2 + border, (int)ordinateL1 - 10 + y[0]); double ordinateV5 = 0; ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20); double ordinateV6 = 0; ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5); xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV6 + border, (int)ordinateL10 + 10 + y[0]); } private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border) { Ceju ceju = new Ceju(); //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(cropRight); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲取目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); // 二、计算数据提取区域 int[] dataArea = new int[2]; ceju.GetDataArea(imageContour, out dataArea, "right"); dataArea[0] += 30; //dataArea[1] += 50; int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2; int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2; //提取綫條 double ordinateL1 = 0; ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1); double ordinateL3 = 0; ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1); double ordinateL4 = 0; ceju.ExtractLines(imageContour, out ordinateL4, middleMiantong + 5, middleMiantong + 15, ordinateL3, 1); double ordinateL5 = 0; ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong + 5, middleMiantong + 15, ordinateL4, -1); if (ordinateL5 - ordinateL4 < 40) ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong + 5, middleMiantong + 15, ordinateL5, -1); double ordinateL6 = 0; ceju.ExtractLines(imageContour, out ordinateL6, middleMiantong + 5, middleMiantong + 15, ordinateL5, 1); double ordinateL7 = 0; ceju.ExtractLines(imageContour, out ordinateL7, middleMiantong + 5, middleMiantong + 15, ordinateL6, -1); double ordinateL10 = 0; ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1); double ordinateL8 = 0; ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1); double ordinateL8Copy = 0; ceju.ExtractLines(imageContour, out ordinateL8Copy, middleMiantong + 5, middleMiantong + 15, ordinateL7, 1); if (ordinateL8Copy < ordinateL8) ordinateL8 = ordinateL8Copy; //提取竪綫 double ordinateV1 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40); double ordinateV2 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1); shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2 + border, shangKongjing.point1.Y); shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X; UpdateSuccessLine(); double ordinateV5 = 0; ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20); double ordinateV6 = 0; ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5); xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV6 + border, xiaKongjing.point1.Y); xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X; UpdateSuccessLine(); } } public class Qianmangkong : AutoMeasureAnalysis { public DataInfor leftJicaitong = new DataInfor(); public DataInfor rightJicaitong = new DataInfor(); public DataInfor leftMiantong_Jicaitong = new DataInfor(); public DataInfor rightMiantong_Jicaitong = new DataInfor(); public DataInfor leftMiantong = new DataInfor(); public DataInfor rightMiantong = new DataInfor(); public DataInfor leftKongtong = new DataInfor(); public DataInfor rightKongtong = new DataInfor(); public DataInfor shangKongjing = new DataInfor(); public DataInfor xiaKongjing = new DataInfor(); public DataInfor kongdi = new DataInfor(); public DataInfor kongdiyaoshiliang = new DataInfor(); public DataInfor leftMinimumRing = new DataInfor(); public DataInfor rightMinimumRing = new DataInfor(); private void Initialize() { dataInfors = new List(); leftJicaitong.name = "左基材銅"; leftJicaitong.ID = "100001"; leftJicaitong.aliasName = "SVLUXI"; rightJicaitong.name = "右基材銅"; rightJicaitong.ID = "100002"; rightJicaitong.aliasName = "FDHENG"; leftMiantong_Jicaitong.name = "左面銅+基材銅"; leftMiantong_Jicaitong.ID = "100003"; leftMiantong_Jicaitong.aliasName = "GSFVKE"; rightMiantong_Jicaitong.name = "右面銅+基材銅"; rightMiantong_Jicaitong.ID = "100004"; rightMiantong_Jicaitong.aliasName = "EOZDNW"; leftMiantong.name = "左面銅"; leftMiantong.ID = "100005"; leftMiantong.aliasName = "EOOIMB"; rightMiantong.name = "右面銅"; rightMiantong.ID = "100006"; rightMiantong.aliasName = "DSUAYP"; leftKongtong.name = "左孔銅"; leftKongtong.drawType = "MeasureLine"; leftKongtong.ID = "100007"; leftKongtong.aliasName = "DTIFWU"; rightKongtong.name = "右孔銅"; rightKongtong.drawType = "MeasureLine"; rightKongtong.ID = "100008"; rightKongtong.aliasName = "XFNVKM"; shangKongjing.name = "上孔徑"; shangKongjing.drawType = "MeasureHLine"; shangKongjing.ID = "100009"; shangKongjing.aliasName = "FIWASX"; xiaKongjing.name = "下孔徑"; xiaKongjing.drawType = "MeasureHLine"; xiaKongjing.ID = "100010"; xiaKongjing.aliasName = "QLIOHM"; kongdi.name = "孔底"; kongdi.ID = "100011"; kongdi.aliasName = "YVOVEU"; kongdiyaoshiliang.name = "孔底咬蝕量"; kongdiyaoshiliang.ID = "100012"; kongdiyaoshiliang.aliasName = "IAZJJN"; leftMinimumRing.name = "左孔環"; leftMinimumRing.ID = "200001"; leftMinimumRing.aliasName = "VKRGES"; leftMinimumRing.drawType = "MeasureHLine"; rightMinimumRing.name = "右孔環"; rightMinimumRing.ID = "200002"; rightMinimumRing.aliasName = "XOLSKM"; rightMinimumRing.drawType = "MeasureHLine"; dataInfors.Add(leftJicaitong); dataInfors.Add(rightJicaitong); dataInfors.Add(leftMiantong_Jicaitong); dataInfors.Add(rightMiantong_Jicaitong); dataInfors.Add(leftMiantong); dataInfors.Add(rightMiantong); dataInfors.Add(leftKongtong); dataInfors.Add(rightKongtong); dataInfors.Add(shangKongjing); dataInfors.Add(xiaKongjing); dataInfors.Add(kongdi); dataInfors.Add(kongdiyaoshiliang); dataInfors.Add(leftMinimumRing); dataInfors.Add(rightMinimumRing); success = 0; number = 16; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //避免旋轉白邊的裁剪 int border = 0; int upper = 0; if (!isCropFlag) { int range = 0; ceju.CropBothSide(image, out image, out range); border += range; upper += range; } // 一、预处理 DateTime t = DateTime.Now; //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲得目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageContour.jpg", imageContour * 255); //裁剪 int[] y = new int[2]; Mat cropContour = new Mat(); ceju.Crop(imageContour, out y, out cropContour, isCropFlag); Mat cropContourOrigin = image[y[0], y[1], 0, image.Cols - 1]; //ceju.ImageShow(cropContour*255); //Cv2.ImWrite(@"C:\Users\54434\Desktop\2.jpg", cropContour * 255); upper += y[0]; if (isCropFlag) { upper += Y; border = X; } //计算提取区域 int[] dataArea = new int[4]; ceju.GetMangkongDataAreaForQian(cropContour, out dataArea); dataArea[1] -= 20; dataArea[2] += 20; int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2; int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2; int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2; int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2; int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2; //计算横线高度 double leftOrdinateMiantong = 0; //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropContour.jpg", cropContour * 255); ceju.ExtractLines(cropContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1); double leftOrdinateMian_Jicaitong = 0; ceju.ExtractLines(cropContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1); double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2; //ceju.LineShow(image, new Point(dataArea[0], leftOrdinate1 + y[0]), new Point(dataArea[1], 150 + y[0])); //ceju.ImageShow(image); double leftOrdinate3 = 0; ceju.ExtractLines(cropContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1); leftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, (int)leftOrdinate3 + upper); UpdateSuccessLine(); double leftOrdinate4 = 0; ceju.ExtractLines(cropContour, out leftOrdinate4, dataArea[0], dataArea[1], leftOrdinate3, 1); double leftOrdinate5 = 0; ceju.ExtractLines2(cropContour, out leftOrdinate5, dataArea[0], dataArea[1], cropContour.Rows - 1, 1); double leftOrdinate4Copy = 0; ceju.ExtractLines2(cropContour, out leftOrdinate4Copy, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, leftOrdinate5, -1); if (leftOrdinate4Copy < leftOrdinate4 && leftOrdinate4Copy > 0) leftOrdinate4 = leftOrdinate4Copy; double rightOrdinateMiantong = 0; ceju.ExtractLines(cropContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1); double rightOrdinateMian_Jicaitong = 0; ceju.ExtractLines(cropContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1); double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2; double rightOrdinate3 = 0; ceju.ExtractLines(cropContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1); rightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, (int)rightOrdinate3 + upper); UpdateSuccessLine(); double rightOrdinate4 = 0; ceju.ExtractLines(cropContour, out rightOrdinate4, dataArea[2], dataArea[3], rightOrdinate3, 1); double rightOrdinate5 = 0; ceju.ExtractLines2(cropContour, out rightOrdinate5, dataArea[2], dataArea[3], cropContour.Rows - 1, 1); double rightOrdinate4Copy = 0; ceju.ExtractLines2(cropContour, out rightOrdinate4Copy, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, rightOrdinate5, -1); if (rightOrdinate4Copy < rightOrdinate4 && rightOrdinate4Copy > 0) rightOrdinate4 = rightOrdinate4Copy; //求L2 Mat cropGreen = imageGreen[y[0], y[1], 0, imageGreen.Cols - 1]; //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropGreen.jpg", cropGreen); double leftOrdinate2 = 0; double rightOrdinate2 = 0; if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2); leftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, (int)leftOrdinate2 + upper); leftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, (int)leftOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3]) { ceju.InsideLine(cropGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2); rightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, (int)rightOrdinate2 + upper); rightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, (int)rightOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageRed.jpg", imageRed); //下孔径 Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu); thresh = thresh[y[0], y[1], 0, thresh.Cols]; Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); Mat close = new Mat(); Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose); Mat fill = new Mat(); ceju.Fill(close, out fill, 1); //Cv2.ImWrite(@"C:\Users\54434\Desktop\fill.jpg", fill * 255); //ceju.ImageShow(fill * 255); int[] apertureLow = new int[2]; //ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea); ceju.GetLowerAperture(fill, out apertureLow, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, (int)leftOrdinate5 - 10, (int)rightOrdinate5 - 10, dataArea); UpdateSuccessLine(); Mat apertureContour = cropContour.Clone(); Cv2.Rectangle(apertureContour, new Rect(0, (int)leftOrdinate2, cropContour.Cols, 1), new Scalar(1), -1); ceju.Fill(apertureContour, out apertureContour, 1); //上孔径 int[] leftAperture, rightAperture; ceju.ShangKongjing(/*image[y[0],y[1],0,image.Cols-1],*/ apertureContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture); shangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper, rightAperture[1] + border, (int)leftOrdinate1 - 10 + upper); UpdateSuccessLine(); int[] apertureBegin = leftAperture; int[] apertureEnd = rightAperture; //孔径中点 //double middleAperture = (aperture[0] + aperture[1]) / 2; double middleAperture = (leftAperture[1] + rightAperture[1]) / 2; //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标 //用新目标区域 Mat contour2 = new Mat(); double T = Cv2.Threshold(imageRed, contour2, 0, 1, ThresholdTypes.Otsu); contour2 = imageRed.Threshold((T - 20), 1, ThresholdTypes.Binary); Mat cropContour2 = contour2[y[0], y[1], 0, contour2.Cols]; //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropContour2.jpg", cropContour2 * 255); if (!this.isNewSuanfa) { double[] kongtong = new double[2]; int[] pointLeft = new int[2]; int[] pointRight = new int[2]; //按照从上到下顺序找白色点,计算第一个白色点到下面的端点,通过最小距离确认上面这个端点的位置 ceju.GetKongtong(cropContour2, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight); leftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + upper, pointLeft[1] + border, pointLeft[0] + upper); rightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + upper, pointRight[1] + border, pointRight[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } else { //新孔铜 int[] pointLeft2 = new int[2]; int[] pointRight2 = new int[2]; double[] kongtong2 = new double[2]; int[] leftKongtongPoint = new int[2]; int[] rightKongtongPoint = new int[2]; Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone(); ceju.GetNewKongtong(newImageRed, cropContour2, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); leftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + upper, pointLeft2[1] + border, pointLeft2[0] + upper); rightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + upper, pointRight2[1] + border, pointRight2[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //最小孔环 int[] pointLeftRing = new int[2]; int[] pointRightRing = new int[2]; ceju.GetMinmumRing(cropContour2, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left"); ceju.GetMinmumRing(cropContour2, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], cropContour2.Cols - 100, out pointRightRing, "right"); //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper); //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper); leftMinimumRing.Set((leftKongtong.point1.X - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftKongtong.point1.X , (int)leftOrdinate1 - 10 + upper); rightMinimumRing.Set((pointRightRing[1]- (rightKongtong.point1.X -border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightKongtong.point1.X , (int)rightOrdinate1 - 10 + upper); //Cv2.Circle(imageRed, pointLeft3[1], pointLeft3[0], 1, 1, 1); //new Window("imageRed_Line", WindowMode.Normal, imageRed); //孔底与孔深 //提取曲面最凸点坐标 int[] curveVertex = new int[2]; //孔径平均高度 double middleApertureY; ceju.CurveVertex(cropContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY); Mat tempCrop = new Mat(cropContourOrigin, new Rect(apertureBegin[1]+50, (int)(leftOrdinate4 - 25), apertureEnd[1] - apertureBegin[1] - 100, (isCropFlag)?60:50)).CvtColor(ColorConversionCodes.BGR2GRAY); double otsu = Cv2.Threshold(tempCrop, tempCrop, 0, 255, ThresholdTypes.Triangle); int nums = int.MaxValue; int row = 0; bool blackwhite = false; for(int i=0; i< tempCrop.Height; i++) { int v = tempCrop.Row[i].CountNonZero(); if(v == 0) { blackwhite = true; } if(blackwhite) { if(v ==0) row = i; } else { if (tempCrop.Row[i].CountNonZero() < nums) { nums = tempCrop.Row[i].CountNonZero(); row = i; } } } //Cv2.ImWrite(@"C:\Users\zyh\Desktop\2.jpg", tempCrop); //求L6 double t1 = 0; double t2 = 0; double ordinate6 = 0; ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1); ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2); if (t1 - 20 < t2 - 10) { int tempDi = (int)(leftOrdinate4 - 30) + row + upper; if ((tempDi+5) < leftOrdinate4 + upper) tempDi = (int)(leftOrdinate4 + 5 + upper); if (tempDi == (leftOrdinate4 + upper)) tempDi = (int)(leftOrdinate4 + 5 + upper); if (tempDi- (leftOrdinate4 + upper) > 25) tempDi = (int)(leftOrdinate4 + 5 + upper); ceju.InsideLine(cropGreen, (int)t1 - 20, (int)t2 - 10, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6); xiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 20 + upper, apertureLow[1] + border, (int)ordinate6 + 20 + upper); kongdi.Set(Math.Abs(tempDi - (curveVertex[0] + upper)), curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, tempDi/*(int)ordinate6 + upper*/); UpdateSuccessLine(); if (leftOrdinate4 < rightOrdinate4) kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)leftOrdinate4 + upper)), leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, tempDi); else kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)rightOrdinate4 + upper)), rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, tempDi); UpdateSuccessLine(); } #region[清理内存] if (imageContour != null && !imageContour.IsDisposed) { imageContour.Dispose(); } if (cropContour != null && !cropContour.IsDisposed) { cropContour.Dispose(); } if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (image != null && !image.IsDisposed) { image.Dispose(); } if (cropContourOrigin != null && !cropContourOrigin.IsDisposed) { cropContourOrigin.Dispose(); } if (cropGreen != null && !cropGreen.IsDisposed) { cropGreen.Dispose(); } if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (seClose != null && !seClose.IsDisposed) { seClose.Dispose(); } if (contour2 != null && !contour2.IsDisposed) { contour2.Dispose(); } if (cropContour2 != null && !cropContour2.IsDisposed) { cropGreen.Dispose(); } if (tempCrop != null && !tempCrop.IsDisposed) { tempCrop.Dispose(); } this.result.Dispose(); ceju = null; #endregion GC.Collect(); } } public class DancengShenmangkong : AutoMeasureAnalysis { public DataInfor leftJicaitong = new DataInfor(); public DataInfor rightJicaitong = new DataInfor(); public DataInfor leftMiantong_Jicaitong = new DataInfor(); public DataInfor rightMiantong_Jicaitong = new DataInfor(); public DataInfor leftMiantong = new DataInfor(); public DataInfor rightMiantong = new DataInfor(); public DataInfor leftKongtong = new DataInfor(); public DataInfor rightKongtong = new DataInfor(); public DataInfor shangKongjing = new DataInfor(); public DataInfor xiaKongjing = new DataInfor(); public DataInfor kongdi = new DataInfor(); public DataInfor kongdiyaoshiliang = new DataInfor(); public DataInfor leftJiaohou = new DataInfor(); public DataInfor rightJiaohou = new DataInfor(); public DataInfor leftJiaoneisuo = new DataInfor(); public DataInfor rightJiaoneisuo = new DataInfor(); public DataInfor kongshen = new DataInfor(); public DataInfor leftMinimumRing = new DataInfor(); public DataInfor rightMinimumRing = new DataInfor(); private void Initialize() { dataInfors = new List(); leftJicaitong.name = "左基材銅"; leftJicaitong.ID = "100014"; leftJicaitong.aliasName = "TMCNME"; rightJicaitong.name = "右基材銅"; rightJicaitong.ID = "100015"; rightJicaitong.aliasName = "YEKCUU"; leftMiantong_Jicaitong.name = "左面銅+基材銅"; leftMiantong_Jicaitong.ID = "100016"; leftMiantong_Jicaitong.aliasName = "GENRYR"; rightMiantong_Jicaitong.name = "右面銅+基材銅"; rightMiantong_Jicaitong.ID = "100017"; rightMiantong_Jicaitong.aliasName = "RIZGOG"; leftMiantong.name = "左面銅"; leftMiantong.ID = "100018"; leftMiantong.aliasName = "CWAJGB"; rightMiantong.name = "右面銅"; rightMiantong.ID = "100019"; rightMiantong.aliasName = "SICQLP"; leftKongtong.name = "左孔銅"; leftKongtong.ID = "100020"; leftKongtong.drawType = "MeasureLine"; leftKongtong.aliasName = "MKQRXB"; rightKongtong.name = "右孔銅"; rightKongtong.ID = "100021"; rightKongtong.drawType = "MeasureLine"; rightKongtong.aliasName = "SIFAJZ"; shangKongjing.name = "上孔徑"; shangKongjing.drawType = "MeasureHLine"; shangKongjing.ID = "100022"; shangKongjing.aliasName = "VAFZDF"; xiaKongjing.name = "下孔徑"; xiaKongjing.drawType = "MeasureHLine"; xiaKongjing.ID = "100023"; xiaKongjing.aliasName = "KKAQFF"; kongdi.name = "孔底"; kongdi.ID = "100024"; kongdi.aliasName = "QPMAHB"; kongdiyaoshiliang.name = "孔底咬蝕量"; kongdiyaoshiliang.ID = "100025"; kongdiyaoshiliang.aliasName = "XDLURS"; leftJiaohou.name = "左膠厚"; leftJiaohou.ID = "100027"; leftJiaohou.aliasName = "RJGNOS"; rightJiaohou.name = "右膠厚"; rightJiaohou.ID = "100028"; rightJiaohou.aliasName = "AHXFIU"; leftJiaoneisuo.name = "左膠内縮"; leftJiaoneisuo.ID = "100029"; leftJiaoneisuo.drawType = "MeasureHLine"; leftJiaoneisuo.aliasName = "TODTGP"; rightJiaoneisuo.name = "右膠内縮"; rightJiaoneisuo.ID = "100030"; rightJiaoneisuo.drawType = "MeasureHLine"; rightJiaoneisuo.aliasName = "QLIZTB"; kongshen.name = "孔深"; kongshen.ID = "100026"; kongshen.aliasName = "UCWPHT"; leftMinimumRing.name = "左孔環"; leftMinimumRing.ID = "200003"; leftMinimumRing.aliasName = "VACGES"; leftMinimumRing.drawType = "MeasureHLine"; rightMinimumRing.name = "右孔環"; rightMinimumRing.ID = "200004"; rightMinimumRing.aliasName = "XBCSKM"; rightMinimumRing.drawType = "MeasureHLine"; dataInfors.Add(leftJicaitong); dataInfors.Add(rightJicaitong); dataInfors.Add(leftMiantong_Jicaitong); dataInfors.Add(rightMiantong_Jicaitong); dataInfors.Add(leftMiantong); dataInfors.Add(rightMiantong); dataInfors.Add(leftKongtong); dataInfors.Add(rightKongtong); dataInfors.Add(shangKongjing); dataInfors.Add(xiaKongjing); dataInfors.Add(kongdi); dataInfors.Add(kongdiyaoshiliang); dataInfors.Add(leftJiaohou); dataInfors.Add(rightJiaohou); dataInfors.Add(leftJiaoneisuo); dataInfors.Add(rightJiaoneisuo); dataInfors.Add(kongshen); dataInfors.Add(leftMinimumRing); dataInfors.Add(rightMinimumRing); number = 19; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //避免旋轉白邊的裁剪 int border = 0; int upper = 0; int tempupper = 0; if (!isCropFlag) { int range = 0; ceju.CropBothSide(image, out image, out range); border += range; upper += range; tempupper += range; } // 一、预处理 DateTime t = DateTime.Now; //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //獲取目標區域 Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); //上下裁剪 int[] y = new int[2]; Mat cropContour = new Mat(); ceju.Crop(imageContour, out y, out cropContour, isCropFlag); upper += y[0]; if (isCropFlag) { upper += Y; border = X; } //计算提取区域 int[] dataArea = new int[4]; ceju.GetMangkongDataArea(cropContour, out dataArea); dataArea[1] -= 20; dataArea[2] += 20; int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2; int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2; int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2; int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2; int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2; //计算横线高度 double leftOrdinateMiantong = 0; ceju.ExtractLines(cropContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1); double leftOrdinateMian_Jicaitong = 0; ceju.ExtractLines(cropContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1); double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2; double leftOrdinate3 = 0; ceju.ExtractLines(cropContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1); leftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, (int)leftOrdinate3 + upper); UpdateSuccessLine(); double leftOrdinate4 = 0; ceju.ExtractLines(cropContour, out leftOrdinate4, dataArea[0], dataArea[1], leftOrdinate3, 1); double leftOrdinate5 = 0; ceju.ExtractLines(cropContour, out leftOrdinate5, dataArea[0], dataArea[1], leftOrdinate4, -1); //double leftOrdinate4Copy = 0; //ceju.ExtractLines2(cropContour, out leftOrdinate4Copy, dataArea[0], dataArea[1], leftOrdinate5, -1); //if (leftOrdinate4Copy < leftOrdinate4 && leftOrdinate4Copy > 0) // leftOrdinate4 = leftOrdinate4Copy; double rightOrdinateMiantong = 0; ceju.ExtractLines(cropContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1); double rightOrdinateMian_Jicaitong = 0; ceju.ExtractLines(cropContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1); double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2; double rightOrdinate3 = 0; ceju.ExtractLines(cropContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1); rightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, (int)rightOrdinate3 + upper); UpdateSuccessLine(); double rightOrdinate4 = 0; ceju.ExtractLines(cropContour, out rightOrdinate4, dataArea[2], dataArea[3], rightOrdinate3, 1); double rightOrdinate5 = 0; ceju.ExtractLines(cropContour, out rightOrdinate5, dataArea[2], dataArea[3], rightOrdinate4, -1); //double rightOrdinate4Copy = 0; //ceju.ExtractLines2(cropContour, out rightOrdinate4Copy, dataArea[2], dataArea[3], rightOrdinate5, -1); //求L2 Mat cropGreen = imageGreen[y[0], y[1], 0, imageGreen.Cols - 1]; double leftOrdinate2 = 0; double rightOrdinate2 = 0; if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(cropGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2); leftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, (int)leftOrdinate2 + upper); leftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, (int)leftOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3]) { ceju.InsideLine(cropGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2); rightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, (int)rightOrdinate2 + upper); rightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, (int)rightOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //下孔径 Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu); thresh = thresh[y[0], y[1], 0, thresh.Cols]; Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); Mat close = new Mat(); Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose); Mat fill = new Mat(); ceju.Fill(close, out fill, 1); int[] apertureLow = new int[2]; ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea); UpdateSuccessLine(); Mat apertureContour = cropContour.Clone(); Cv2.Rectangle(apertureContour, new Rect(0, (int)leftOrdinate2, cropContour.Cols, 1), new Scalar(1), -1); ceju.Fill(apertureContour, out apertureContour, 1); //上孔径 int[] leftAperture, rightAperture; //ceju.ShangKongjing(/*image[y[0],y[1],0,image.Cols-1],*/ apertureContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture); ceju.ShenmangkongShangkongjing(cropContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture); int[] apertureBegin = leftAperture; int[] apertureEnd = rightAperture; //孔径中点 double middleAperture = (leftAperture[1] + rightAperture[1]) / 2; shangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper, rightAperture[1] + border, (int)leftOrdinate1 - 10 + upper); UpdateSuccessLine(); //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标 if (!isNewSuanfa) { double[] kongtong = new double[2]; int[] pointLeft = new int[2]; int[] pointRight = new int[2]; ceju.GetKongtong(cropContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight); leftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + upper, pointLeft[1] + border, pointLeft[0] + upper); rightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + upper, pointRight[1] + border, pointRight[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } else { int[] pointLeft2 = new int[2]; int[] pointRight2 = new int[2]; double[] kongtong2 = new double[2]; int[] leftKongtongPoint = new int[2]; int[] rightKongtongPoint = new int[2]; Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone(); //ceju.GetNewKongtong(newImageRed, cropContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); ceju.ShenmangkongNewKongtong(newImageRed, cropContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); leftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + upper, pointLeft2[1] + border, pointLeft2[0] + upper); rightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + upper, pointRight2[1] + border, pointRight2[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //最小孔环 int[] pointLeftRing = new int[2]; int[] pointRightRing = new int[2]; ceju.GetMinmumRing(cropContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left"); ceju.GetMinmumRing(cropContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], cropContour.Cols - 100, out pointRightRing, "right"); //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper); //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper); leftMinimumRing.Set((leftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftKongtong.point1.X, (int)leftOrdinate1 - 10 + upper); rightMinimumRing.Set((pointRightRing[1] - (rightKongtong.point1.X - border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightKongtong.point1.X, (int)rightOrdinate1 - 10 + upper); //孔底与孔深 //提取曲面最凸点坐标 int[] curveVertex = new int[2]; //孔径平均高度 double middleApertureY; ceju.CurveVertex(cropContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY); Mat tempCrop = new Mat(image, new Rect(apertureBegin[1] + 50, (int)(leftOrdinate4 + (isCropFlag ? y[0] : upper) - tempupper), apertureEnd[1] - apertureBegin[1] - 50, 35)).CvtColor(ColorConversionCodes.BGR2GRAY); double otsu = Cv2.Threshold(tempCrop, tempCrop, 0, 255, ThresholdTypes.Triangle); int nums = int.MaxValue; int row = 0; for (int i = 0; i < tempCrop.Height; i++) { if (tempCrop.Row[i].CountNonZero() < nums) { nums = tempCrop.Row[i].CountNonZero(); row = i; } } int tempDi = (int)(leftOrdinate4 + upper + row); // - (isCropFlag ? 50 : 0)); if ((tempDi + 5) < leftOrdinate4 + upper) tempDi = (int)(leftOrdinate4 + 5 + upper); if (tempDi == (leftOrdinate4 + upper)) tempDi = (int)(leftOrdinate4 + 5 + upper); //if (tempDi - (leftOrdinate4 + upper) > 25) tempDi = (int)(leftOrdinate4 + 13 + upper); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\2.jpg", tempCrop); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\21.jpg", image); if (leftOrdinate1 < rightOrdinate1) kongshen.Set(curveVertex[0] - leftOrdinate1, curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, (int)leftOrdinate1 + upper); else kongshen.Set(curveVertex[0] - rightOrdinate1, curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, (int)rightOrdinate1 + upper); UpdateSuccessLine(); //求L6 double t1 = 0; double t2 = 0; double ordinate6 = 0; ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1); ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2); ceju.InsideLine(cropGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6); xiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 10 + upper, apertureLow[1] + border, (int)ordinate6 + 10 + upper); kongdi.Set(Math.Abs(tempDi - (curveVertex[0] + upper)), curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, tempDi/*(int)ordinate6 + upper*/); UpdateSuccessLine(); if (leftOrdinate4 < rightOrdinate4) kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)leftOrdinate4 + upper)), leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, tempDi); else kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)rightOrdinate4 + upper)), rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, tempDi); UpdateSuccessLine(); //计算胶线 Mat cropRed = imageRed[y[0], y[1], 0, imageRed.Cols]; int[] ordinateGlue = new int[2]; ceju.GetGlue(cropRed, out ordinateGlue, (int)leftOrdinate3 + 20, (int)leftOrdinate4 - 20, (int)rightOrdinate3 + 20, (int)rightOrdinate4 - 20, dataArea); leftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, (int)ordinateGlue[0] + upper); rightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, (int)ordinateGlue[1] + upper); UpdateSuccessLine(); UpdateSuccessLine(); // 十一、计算胶内缩 int[] upperWaist = new int[2]; int[] lowerWaist = new int[2]; ceju.GetWaist(fill, out upperWaist, out lowerWaist, (int)ordinateGlue[0] - 20, ordinateGlue, (int)leftOrdinate4 - 20, dataArea); leftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, ordinateGlue[0] + upper, upperWaist[0] + border, ordinateGlue[0] + upper); rightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, ordinateGlue[1] + upper, upperWaist[1] + border, ordinateGlue[1] + upper); UpdateSuccessLine(); UpdateSuccessLine(); #region[释放内存] if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (imageContour != null && !imageContour.IsDisposed) { imageContour.Dispose(); } if (cropContour != null && !cropContour.IsDisposed) { cropContour.Dispose(); } if (cropGreen != null && !cropGreen.IsDisposed) { cropGreen.Dispose(); } if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (seClose != null && !seClose.IsDisposed) { seClose.Dispose(); } if (close != null && !close.IsDisposed) { close.Dispose(); } if (fill != null && !fill.IsDisposed) { fill.Dispose(); } if (apertureContour != null && !apertureContour.IsDisposed) { apertureContour.Dispose(); } if (tempCrop != null && !tempCrop.IsDisposed) { tempCrop.Dispose(); } if (cropRed != null && !cropRed.IsDisposed) { cropRed.Dispose(); } #endregion } } public class ShuangcengShenmangkong : AutoMeasureAnalysis { public DataInfor shangcengLeftJicaitong = new DataInfor(); public DataInfor shangcengRightJicaitong = new DataInfor(); public DataInfor shangcengLeftMiantong_Jicaitong = new DataInfor(); public DataInfor shangcengRightMiantong_Jicaitong = new DataInfor(); public DataInfor shangcengLeftMiantong = new DataInfor(); public DataInfor shangcengRightMiantong = new DataInfor(); public DataInfor shangcengLeftKongtong = new DataInfor(); public DataInfor shangcengRightKongtong = new DataInfor(); public DataInfor shangcengShangKongjing = new DataInfor(); public DataInfor shangcengXiaKongjing = new DataInfor(); public DataInfor shangcengKongdi = new DataInfor(); public DataInfor shangcengKongdiyaoshiliang = new DataInfor(); public DataInfor shangcengLeftJiaohou = new DataInfor(); public DataInfor shangcengRightJiaohou = new DataInfor(); public DataInfor shangcengLeftJiaoneisuo = new DataInfor(); public DataInfor shangcengRightJiaoneisuo = new DataInfor(); public DataInfor shangcengKongshen = new DataInfor(); public DataInfor shangcengLeftMinimumRing = new DataInfor(); public DataInfor shangcengRightMinimumRing = new DataInfor(); public DataInfor xiacengLeftJicaitong = new DataInfor(); public DataInfor xiacengRightJicaitong = new DataInfor(); public DataInfor xiacengLeftMiantong_Jicaitong = new DataInfor(); public DataInfor xiacengRightMiantong_Jicaitong = new DataInfor(); public DataInfor xiacengLeftMiantong = new DataInfor(); public DataInfor xiacengRightMiantong = new DataInfor(); public DataInfor xiacengLeftKongtong = new DataInfor(); public DataInfor xiacengRightKongtong = new DataInfor(); public DataInfor xiacengShangKongjing = new DataInfor(); public DataInfor xiacengXiaKongjing = new DataInfor(); public DataInfor xiacengKongdi = new DataInfor(); public DataInfor xiacengKongdiyaoshiliang = new DataInfor(); public DataInfor xiacengLeftJiaohou = new DataInfor(); public DataInfor xiacengRightJiaohou = new DataInfor(); public DataInfor xiacengLeftJiaoneisuo = new DataInfor(); public DataInfor xiacengRightJiaoneisuo = new DataInfor(); public DataInfor xiacengKongshen = new DataInfor(); public DataInfor xiacengLeftMinimumRing = new DataInfor(); public DataInfor xiacengRightMinimumRing = new DataInfor(); private void Initialize() { dataInfors = new List(); shangcengLeftJicaitong.name = "上層左基材銅"; shangcengLeftJicaitong.ID = "100032"; shangcengLeftJicaitong.aliasName = "RJMHJL"; shangcengRightJicaitong.name = "上層右基材銅"; shangcengRightJicaitong.ID = "100033"; shangcengRightJicaitong.aliasName = "PFFQND"; shangcengLeftMiantong_Jicaitong.name = "上層左面銅+基材銅"; shangcengLeftMiantong_Jicaitong.ID = "100034"; shangcengLeftMiantong_Jicaitong.aliasName = "RJPRHV"; shangcengRightMiantong_Jicaitong.name = "上層右面銅+基材銅"; shangcengRightMiantong_Jicaitong.ID = "100035"; shangcengRightMiantong_Jicaitong.aliasName = "RJDWFA"; shangcengLeftMiantong.name = "上層左面銅"; shangcengLeftMiantong.ID = "100036"; shangcengLeftMiantong.aliasName = "ECZVTI"; shangcengRightMiantong.name = "上層右面銅"; shangcengRightMiantong.ID = "100037"; shangcengRightMiantong.aliasName = "UOBCYX"; shangcengLeftKongtong.name = "上層左孔銅"; shangcengLeftKongtong.ID = "100038"; shangcengLeftKongtong.drawType = "MeasureLine"; shangcengLeftKongtong.aliasName = "UOPHXC"; shangcengRightKongtong.name = "上層右孔銅"; shangcengRightKongtong.ID = "100039"; shangcengRightKongtong.drawType = "MeasureLine"; shangcengRightKongtong.aliasName = "QZQRQJ"; shangcengShangKongjing.name = "上層上孔徑"; shangcengShangKongjing.ID = "100040"; shangcengShangKongjing.drawType = "MeasureHLine"; shangcengShangKongjing.aliasName = "DNVEQI"; shangcengXiaKongjing.name = "上層下孔徑"; shangcengXiaKongjing.ID = "100041"; shangcengXiaKongjing.drawType = "MeasureHLine"; shangcengXiaKongjing.aliasName = "GHORIT"; shangcengKongdi.name = "上層孔底"; shangcengKongdi.ID = "100042"; shangcengKongdi.aliasName = "TZLQVC"; shangcengKongdiyaoshiliang.name = "上層孔底咬蝕量"; shangcengKongdiyaoshiliang.ID = "100043"; shangcengKongdiyaoshiliang.aliasName = "AYHPVK"; shangcengLeftJiaohou.name = "上層左膠厚"; shangcengLeftJiaohou.ID = "100045"; shangcengLeftJiaohou.aliasName = "OYYRYX"; shangcengRightJiaohou.name = "上層右膠厚"; shangcengRightJiaohou.ID = "100046"; shangcengRightJiaohou.aliasName = "JDZUDT"; shangcengLeftJiaoneisuo.name = "上層左膠内縮"; shangcengLeftJiaoneisuo.drawType = "MeasureHLine"; shangcengLeftJiaoneisuo.ID = "100047"; shangcengLeftJiaoneisuo.aliasName = "HBZSLZ"; shangcengRightJiaoneisuo.name = "上層右膠内縮"; shangcengRightJiaoneisuo.drawType = "MeasureHLine"; shangcengRightJiaoneisuo.ID = "100048"; shangcengRightJiaoneisuo.aliasName = "SLJJQL"; shangcengKongshen.name = "上層孔深"; shangcengKongshen.ID = "100044"; shangcengKongshen.aliasName = "WCXZED"; xiacengLeftJicaitong.name = "下層左基材銅"; xiacengLeftJicaitong.ID = "100049"; xiacengLeftJicaitong.aliasName = "GTQTBN"; xiacengRightJicaitong.name = "下層右基材銅"; xiacengRightJicaitong.ID = "100050"; xiacengRightJicaitong.aliasName = "QVHPWI"; xiacengLeftMiantong_Jicaitong.name = "下層左面銅+基材銅"; xiacengLeftMiantong_Jicaitong.ID = "100051"; xiacengLeftMiantong_Jicaitong.aliasName = "BZTDLX"; xiacengRightMiantong_Jicaitong.name = "下層右面銅+基材銅"; xiacengRightMiantong_Jicaitong.ID = "100052"; xiacengRightMiantong_Jicaitong.aliasName = "EONMCP"; xiacengLeftMiantong.name = "下層左面銅"; xiacengLeftMiantong.ID = "100053"; xiacengLeftMiantong.aliasName = "RWTXNQ"; xiacengRightMiantong.name = "下層右面銅"; xiacengRightMiantong.ID = "100054"; xiacengRightMiantong.aliasName = "QWNJRC"; xiacengLeftKongtong.name = "下層左孔銅"; xiacengLeftKongtong.ID = "100055"; xiacengLeftKongtong.drawType = "MeasureLine"; xiacengLeftKongtong.aliasName = "CMQVHF"; xiacengRightKongtong.name = "下層右孔銅"; xiacengRightKongtong.ID = "100056"; xiacengRightKongtong.drawType = "MeasureLine"; xiacengRightKongtong.aliasName = "RHBBML"; xiacengShangKongjing.name = "下層上孔徑"; xiacengShangKongjing.ID = "100057"; xiacengShangKongjing.drawType = "MeasureHLine"; xiacengShangKongjing.aliasName = "DAXAZU"; xiacengXiaKongjing.name = "下層下孔徑"; xiacengXiaKongjing.ID = "100058"; xiacengXiaKongjing.drawType = "MeasureHLine"; xiacengXiaKongjing.aliasName = "ZVWQIS"; xiacengKongdi.name = "下層孔底"; xiacengKongdi.ID = "100059"; xiacengKongdi.aliasName = "SXCBGU"; xiacengKongdiyaoshiliang.name = "下層孔底咬蝕量"; xiacengKongdiyaoshiliang.ID = "100060"; xiacengKongdiyaoshiliang.aliasName = "RIGVHF"; xiacengLeftJiaohou.name = "下層左膠厚"; xiacengLeftJiaohou.ID = "100062"; xiacengLeftJiaohou.aliasName = "DPHRWS"; xiacengRightJiaohou.name = "下層右膠厚"; xiacengRightJiaohou.ID = "100063"; xiacengRightJiaohou.aliasName = "GFAANK"; xiacengLeftJiaoneisuo.name = "下層左膠内縮"; xiacengLeftJiaoneisuo.ID = "100064"; xiacengLeftJiaoneisuo.drawType = "MeasureHLine"; xiacengLeftJiaoneisuo.aliasName = "CLKYTI"; xiacengRightJiaoneisuo.name = "下層右膠内縮"; xiacengRightJiaoneisuo.ID = "100065"; xiacengRightJiaoneisuo.drawType = "MeasureHLine"; xiacengRightJiaoneisuo.aliasName = "QTRIEK"; xiacengKongshen.name = "下層孔深"; xiacengKongshen.ID = "100061"; xiacengKongshen.aliasName = "FPNFSH"; shangcengLeftMinimumRing.name = "上層左孔環"; shangcengLeftMinimumRing.ID = "200005"; shangcengLeftMinimumRing.aliasName = "VACGJK"; shangcengLeftMinimumRing.drawType = "MeasureHLine"; shangcengRightMinimumRing.name = "上層右孔環"; shangcengRightMinimumRing.ID = "200006"; shangcengRightMinimumRing.aliasName = "XBCWRF"; shangcengRightMinimumRing.drawType = "MeasureHLine"; xiacengLeftMinimumRing.name = "下層左孔環"; xiacengLeftMinimumRing.ID = "200007"; xiacengLeftMinimumRing.aliasName = "GBCGJK"; xiacengLeftMinimumRing.drawType = "MeasureHLine"; xiacengRightMinimumRing.name = "下層右孔環"; xiacengRightMinimumRing.ID = "200008"; xiacengRightMinimumRing.aliasName = "PDCWRF"; xiacengRightMinimumRing.drawType = "MeasureHLine"; dataInfors.Add(shangcengLeftJicaitong); dataInfors.Add(shangcengRightJicaitong); dataInfors.Add(shangcengLeftMiantong_Jicaitong); dataInfors.Add(shangcengRightMiantong_Jicaitong); dataInfors.Add(shangcengLeftMiantong); dataInfors.Add(shangcengRightMiantong); dataInfors.Add(shangcengLeftKongtong); dataInfors.Add(shangcengRightKongtong); dataInfors.Add(shangcengShangKongjing); dataInfors.Add(shangcengXiaKongjing); dataInfors.Add(shangcengKongdi); dataInfors.Add(shangcengKongdiyaoshiliang); dataInfors.Add(shangcengLeftJiaohou); dataInfors.Add(shangcengRightJiaohou); dataInfors.Add(shangcengLeftJiaoneisuo); dataInfors.Add(shangcengRightJiaoneisuo); dataInfors.Add(shangcengKongshen); dataInfors.Add(shangcengLeftMinimumRing); dataInfors.Add(shangcengRightMinimumRing); dataInfors.Add(xiacengLeftJicaitong); dataInfors.Add(xiacengRightJicaitong); dataInfors.Add(xiacengLeftMiantong_Jicaitong); dataInfors.Add(xiacengRightMiantong_Jicaitong); dataInfors.Add(xiacengLeftMiantong); dataInfors.Add(xiacengRightMiantong); dataInfors.Add(xiacengLeftKongtong); dataInfors.Add(xiacengRightKongtong); dataInfors.Add(xiacengShangKongjing); dataInfors.Add(xiacengXiaKongjing); dataInfors.Add(xiacengKongdi); dataInfors.Add(xiacengKongdiyaoshiliang); dataInfors.Add(xiacengLeftJiaohou); dataInfors.Add(xiacengRightJiaohou); dataInfors.Add(xiacengLeftJiaoneisuo); dataInfors.Add(xiacengRightJiaoneisuo); dataInfors.Add(xiacengKongshen); dataInfors.Add(xiacengLeftMinimumRing); dataInfors.Add(xiacengRightMinimumRing); number = 38; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); //避免旋轉白邊的裁剪 int range = 0; if (!isCropFlag) { ceju.CropBothSide(image, out image, out range); } Mat imageGray = image.CvtColor(ColorConversionCodes.BGR2GRAY); Mat contour = imageGray.Threshold(0, 1, ThresholdTypes.Otsu); //裁剪 Mat crop = new Mat(); int[] y = new int[2]; ceju.CropShenmangkongShuangceng(contour, out y, out crop, isCropFlag); //new Window("imageGray", WindowMode.Normal, imageGray); //new Window("contour", WindowMode.Normal, contour); //new Window("contour", WindowMode.Normal, contour * 255); //new Window("crop", WindowMode.Normal, crop * 255); //Cv2.WaitKey(); //上下分开 int y1 = 0, y2 = 0; int[] sums = new int[crop.Rows]; for (int i = 0; i < crop.Rows; i++) { sums[i] = 0; for (int j = 0; j < crop.Cols; j++) { sums[i] += crop.Get(i, j); } } int length = sums.Length; int[] partSum = sums.Skip(length / 4).Take(length / 2).ToArray(); int min = partSum.Min(); for (int i = length / 4; i < length / 4 * 3; i++) { if (sums[i] < min + 50) { y1 = i; break; } } for (int i = length / 4 * 3; i > length / 4; i--) { if (sums[i] < min + 50) { y2 = i; break; } } int middle = (y2 + y1) / 2 + y[0]; Mat crop1 = new Mat(); crop1 = image[y[0], middle, 0, crop.Cols - 1].Clone(); Mat crop2 = new Mat(); crop2 = image[middle, y[1], 0, crop.Cols - 1].Clone(); Cv2.Flip(crop2, crop2, FlipMode.X); //new Window("crop1", WindowMode.Normal, crop1); //new Window("crop2", WindowMode.Normal, crop2); //Cv2.WaitKey(); int border = 0; y[0] += range; middle += range; border = range; if (isCropFlag) { y[0] += Y; middle += Y; border = X; } ComputeUpper(image, crop1, y, border); ComputeLower(image, crop2, middle, border); } public void ComputeUpper(Mat image, Mat crop1, int[] y, int border) { Ceju ceju = new Ceju(); // 一、预处理 DateTime t = DateTime.Now; //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(crop1); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; // 獲取目標區域 Mat imageContour = new Mat(); ceju.GetShenmangkongContour(imageRed, out imageContour); //计算提取区域 int[] dataArea = new int[4]; ceju.GetMangkongDataArea(imageContour, out dataArea); dataArea[1] -= 20; dataArea[2] += 20; if (dataArea[1] - dataArea[0] < 5) dataArea[0] -= 20; if (dataArea[3] - dataArea[2] < 5) dataArea[3] += 20; int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2; int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2; int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2; int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2; int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2; //计算横线高度 double leftOrdinateMiantong = 0; ceju.ExtractLines(imageContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1); double leftOrdinateMian_Jicaitong = 0; ceju.ExtractLines(imageContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1); double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2; double leftOrdinate3 = 0; ceju.ExtractLines(imageContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1); shangcengLeftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + y[0], leftMiddleMianJicaitong + border, (int)leftOrdinate3 + y[0]); UpdateSuccessLine(); double leftOrdinate4 = 0; ceju.ExtractLines(imageContour, out leftOrdinate4, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate3, 1); double leftOrdinate5 = 0; ceju.ExtractLines2(imageContour, out leftOrdinate5, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, 1); double leftOrdinate4Copy = 0; ceju.ExtractLines2(imageContour, out leftOrdinate4Copy, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate5, -1); if (leftOrdinate4Copy < leftOrdinate4) leftOrdinate4 = leftOrdinate4Copy; double rightOrdinateMiantong = 0; ceju.ExtractLines(imageContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1); double rightOrdinateMian_Jicaitong = 0; ceju.ExtractLines(imageContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1); double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2; double rightOrdinate3 = 0; ceju.ExtractLines(imageContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1); shangcengRightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + y[0], rightMiddleMianJicaitong + border, (int)rightOrdinate3 + y[0]); UpdateSuccessLine(); double rightOrdinate4 = 0; ceju.ExtractLines(imageContour, out rightOrdinate4, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate3, 1); double rightOrdinate5 = 0; ceju.ExtractLines2(imageContour, out rightOrdinate5, rightMiddleMiantong - 10, rightMiddleMiantong + 10, 1); double rightOrdinate4Copy = 0; ceju.ExtractLines2(imageContour, out rightOrdinate4Copy, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate5, -1); if (rightOrdinate4Copy < rightOrdinate4) rightOrdinate4 = rightOrdinate4Copy; //求L2 double leftOrdinate2 = 0; double rightOrdinate2 = 0; if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2); shangcengLeftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + y[0], leftMiddleMiantong + border, (int)leftOrdinate2 + y[0]); shangcengLeftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + y[0], leftMiddleJicaitong + border, (int)leftOrdinate3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3]) { ceju.InsideLine(imageGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2); shangcengRightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + y[0], rightMiddleMiantong + border, (int)rightOrdinate2 + y[0]); shangcengRightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + y[0], rightMiddleJicaitong + border, (int)rightOrdinate3 + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //下孔径 Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu); Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); Mat close = new Mat(); Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose); Mat fill = new Mat(); ceju.Fill(close, out fill, 1); int[] apertureLow = new int[2]; ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea); UpdateSuccessLine(); //上孔径 int[] leftAperture, rightAperture; //ceju.ShangKongjing(imageContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture); ceju.ShenmangkongShangkongjing(imageContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture); int[] apertureBegin = leftAperture; int[] apertureEnd = rightAperture; //孔径中点 double middleAperture = (leftAperture[1] + rightAperture[1]) / 2; shangcengShangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 30 + y[0], rightAperture[1] + border, (int)leftOrdinate1 - 30 + y[0]); UpdateSuccessLine(); //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标 if (!isNewSuanfa) { double[] kongtong = new double[2]; int[] pointLeft = new int[2]; int[] pointRight = new int[2]; ceju.GetKongtong(imageContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight); shangcengLeftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + y[0], pointLeft[1] + border, pointLeft[0] + y[0]); shangcengRightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + y[0], pointRight[1] + border, pointRight[0] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } else { int[] pointLeft2 = new int[2]; int[] pointRight2 = new int[2]; double[] kongtong2 = new double[2]; int[] leftKongtongPoint = new int[2]; int[] rightKongtongPoint = new int[2]; //Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone(); //ceju.GetNewKongtong(imageRed, imageContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); ceju.ShenmangkongNewKongtong(imageRed, imageContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); shangcengLeftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + y[0], pointLeft2[1] + border, pointLeft2[0] + y[0]); shangcengRightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + y[0], pointRight2[1] + border, pointRight2[0] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } //最小孔环 int[] pointLeftRing = new int[2]; int[] pointRightRing = new int[2]; ceju.GetMinmumRing(imageContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left"); ceju.GetMinmumRing(imageContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], imageContour.Cols - 100, out pointRightRing, "right"); //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper); //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper); shangcengLeftMinimumRing.Set((shangcengLeftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + y[0], shangcengLeftKongtong.point1.X, (int)leftOrdinate1 - 10 + y[0]); shangcengRightMinimumRing.Set((pointRightRing[1] - (shangcengRightKongtong.point1.X - border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + y[0], shangcengRightKongtong.point1.X, (int)rightOrdinate1 - 10 + y[0]); //孔底与孔深 //提取曲面最凸点坐标 int[] curveVertex = new int[2]; //孔径平均高度 double middleApertureY; ceju.CurveVertex(imageContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY); if (curveVertex[0] > leftOrdinate1 || curveVertex[0] > rightOrdinate1) { if (leftOrdinate1 < rightOrdinate1) shangcengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)leftOrdinate1 + y[0]); else shangcengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)rightOrdinate1 + y[0]); } else { if (leftOrdinate1 < rightOrdinate1) shangcengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)rightOrdinate1 + y[0]); else shangcengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)leftOrdinate1 + y[0]); } UpdateSuccessLine(); //求L6 double t1 = 0; double t2 = 0; double ordinate6 = 0; ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1); ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2); if (t1 > 20 && t2 > t1 + 5 + 20) { ceju.InsideLine(imageGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6); shangcengKongdi.Set(ordinate6 - curveVertex[0], curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)ordinate6 + y[0]); UpdateSuccessLine(); shangcengXiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 10 + y[0], apertureLow[1] + border, (int)ordinate6 + 10 + y[0]); } if (leftOrdinate4 < rightOrdinate4) shangcengKongdiyaoshiliang.Set(ordinate6 - leftOrdinate4, leftMiddleMianJicaitong + border, (int)leftOrdinate4 + y[0], leftMiddleMianJicaitong + border, (int)ordinate6 + y[0]); else shangcengKongdiyaoshiliang.Set(ordinate6 - rightOrdinate4, rightMiddleMianJicaitong + border, (int)rightOrdinate4 + y[0], rightMiddleMianJicaitong + border, (int)ordinate6 + y[0]); UpdateSuccessLine(); //计算胶线 int[] ordinateGlue = new int[2]; //CejuFunction.GetGlue(imageRed, dataArea, (int)leftOrdinate3 + 20, (int)leftOrdinate4 - 20, (int)rightOrdinate3 + 20, (int)rightOrdinate4 - 20, out ordinateGlue); if (leftOrdinate3 > 0 && leftOrdinate4 > leftOrdinate3 + 20 && rightOrdinate3 > 0 && rightOrdinate4 > rightOrdinate3 + 20) { ceju.GetGlue2(imageRed, out ordinateGlue, (int)leftOrdinate3 + 5, (int)leftOrdinate4 - 5, (int)rightOrdinate3 + 5, (int)rightOrdinate4 - 5, dataArea); shangcengLeftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, (int)leftOrdinate4 + y[0], leftMiddleMianJicaitong + border, (int)ordinateGlue[0] + y[0]); shangcengRightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, (int)rightOrdinate4 + y[0], rightMiddleMianJicaitong + border, (int)ordinateGlue[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } // 十一、计算胶内缩 int[] upperWaist = new int[2]; int[] lowerWaist = new int[2]; ceju.ChooseSize(ordinateGlue[0], ordinateGlue[1], "small", out t1); if (t1 > 20 && leftOrdinate4 > 20 && rightOrdinate4 > 20) { ceju.GetWaistNew(fill, out upperWaist, out lowerWaist, (int)t1 - 20, ordinateGlue, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, dataArea); shangcengLeftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, ordinateGlue[0] + y[0], upperWaist[0] + border, ordinateGlue[0] + y[0]); shangcengRightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, ordinateGlue[1] + y[0], upperWaist[1] + border, ordinateGlue[1] + y[0]); UpdateSuccessLine(); UpdateSuccessLine(); } } public void ComputeLower(Mat image, Mat crop2, int upper, int border) { Ceju ceju = new Ceju(); int rows = crop2.Rows; int cols = crop2.Cols; // 一、预处理 //获得蓝色,绿色,红色通道图片 Mat[] bgr = Cv2.Split(crop2); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; Mat imageContour = new Mat(); ceju.GetShenmangkongContour(imageRed, out imageContour); //计算提取区域 int[] dataArea = new int[4]; ceju.GetMangkongDataArea(imageContour, out dataArea); dataArea[1] -= 20; dataArea[2] += 20; if (dataArea[1] - dataArea[0] < 5) dataArea[0] -= 20; if (dataArea[3] - dataArea[2] < 5) dataArea[3] += 20; int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2; int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2; int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2; int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2; int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2; int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2; //计算横线高度 double leftOrdinateMiantong = 0; ceju.ExtractLines(imageContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1); double leftOrdinateMian_Jicaitong = 0; ceju.ExtractLines(imageContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1); double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2; double leftOrdinate3 = 0; ceju.ExtractLines(imageContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1); xiacengLeftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, rows - (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, rows - (int)leftOrdinate3 + upper); UpdateSuccessLine(); double leftOrdinate4 = 0; ceju.ExtractLines(imageContour, out leftOrdinate4, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate3, 1); double leftOrdinate5 = 0; ceju.ExtractLines2(imageContour, out leftOrdinate5, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, 1); double leftOrdinate4Copy = 0; ceju.ExtractLines2(imageContour, out leftOrdinate4Copy, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate5, -1); if (leftOrdinate4Copy < leftOrdinate4) leftOrdinate4 = leftOrdinate4Copy; double rightOrdinateMiantong = 0; ceju.ExtractLines(imageContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1); double rightOrdinateMian_Jicaitong = 0; ceju.ExtractLines(imageContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1); double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2; double rightOrdinate3 = 0; ceju.ExtractLines(imageContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1); xiacengRightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, rows - (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, rows - (int)rightOrdinate3 + upper); UpdateSuccessLine(); double rightOrdinate4 = 0; ceju.ExtractLines(imageContour, out rightOrdinate4, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate3, 1); double rightOrdinate5 = 0; ceju.ExtractLines2(imageContour, out rightOrdinate5, rightMiddleMiantong - 10, rightMiddleMiantong + 10, 1); double rightOrdinate4Copy = 0; ceju.ExtractLines2(imageContour, out rightOrdinate4Copy, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate5, -1); if (rightOrdinate4Copy < rightOrdinate4) rightOrdinate4 = rightOrdinate4Copy; //求L2 double leftOrdinate2 = 0; double rightOrdinate2 = 0; if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1]) { ceju.InsideLine(imageGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2); xiacengLeftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, rows - (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, rows - (int)leftOrdinate2 + upper); xiacengLeftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, rows - (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, rows - (int)leftOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3]) { ceju.InsideLine(imageGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2); xiacengRightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, rows - (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, rows - (int)rightOrdinate2 + upper); xiacengRightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, rows - (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, rows - (int)rightOrdinate3 + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //下孔径 Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu); Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); Mat close = new Mat(); Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose); Mat fill = new Mat(); ceju.Fill(close, out fill, 1); int[] apertureLow = new int[2]; ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea); UpdateSuccessLine(); //上孔径 int[] leftAperture, rightAperture; //ceju.ShangKongjing(imageContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture); ceju.ShenmangkongShangkongjing(imageContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture); int[] apertureBegin = leftAperture; int[] apertureEnd = rightAperture; //孔径中点 double middleAperture = (leftAperture[1] + rightAperture[1]) / 2; xiacengShangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, rows - ((int)leftOrdinate1 - 30) + upper, rightAperture[1] + border, rows - ((int)leftOrdinate1 - 30) + upper); UpdateSuccessLine(); //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标 if (!isNewSuanfa) { double[] kongtong = new double[2]; int[] pointLeft = new int[2]; int[] pointRight = new int[2]; ceju.GetKongtong(imageContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight); xiacengLeftKongtong.Set(kongtong[0], leftAperture[1] + border, rows - leftAperture[0] + upper, pointLeft[1] + border, rows - pointLeft[0] + upper); xiacengRightKongtong.Set(kongtong[1], rightAperture[1] + border, rows - rightAperture[0] + upper, pointRight[1] + border, rows - pointRight[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } else { int[] pointLeft2 = new int[2]; int[] pointRight2 = new int[2]; double[] kongtong2 = new double[2]; int[] leftKongtongPoint = new int[2]; int[] rightKongtongPoint = new int[2]; //Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone(); //ceju.GetNewKongtong(imageRed, imageContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); ceju.ShenmangkongNewKongtong(imageRed, imageContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2); xiacengLeftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, rows - leftKongtongPoint[0] + upper, pointLeft2[1] + border, rows - pointLeft2[0] + upper); xiacengRightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rows - rightKongtongPoint[0] + upper, pointRight2[1] + border, rows - pointRight2[0] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } //最小孔环 int[] pointLeftRing = new int[2]; int[] pointRightRing = new int[2]; ceju.GetMinmumRing(imageContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left"); ceju.GetMinmumRing(imageContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], imageContour.Cols - 100, out pointRightRing, "right"); //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper); //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper); xiacengLeftMinimumRing.Set((xiacengLeftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, rows - (int)leftOrdinate1 + 10 + upper, xiacengLeftKongtong.point1.X, rows - (int)leftOrdinate1 + 10 + upper); xiacengRightMinimumRing.Set((pointRightRing[1] - (xiacengRightKongtong.point1.X - border)), pointRightRing[1] + border, rows - (int)rightOrdinate1 + 10 + upper, xiacengRightKongtong.point1.X, rows - (int)rightOrdinate1 + 10 + upper); //孔底与孔深 //提取曲面最凸点坐标 int[] curveVertex = new int[2]; //孔径平均高度 double middleApertureY; ceju.CurveVertex(imageContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY); if (curveVertex[0] > leftOrdinate1 || curveVertex[0] > rightOrdinate1) { if (leftOrdinate1 < rightOrdinate1) xiacengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)leftOrdinate1 + upper); else xiacengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)rightOrdinate1 + upper); } else { if (leftOrdinate1 < rightOrdinate1) xiacengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)rightOrdinate1 + upper); else xiacengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)leftOrdinate1 + upper); } UpdateSuccessLine(); //求L6 double t1 = 0; double t2 = 0; double ordinate6 = 0; ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1); ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2); if (t1 > 20 && t2 > t1 + 5 + 20) { ceju.InsideLine(imageGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6); xiacengXiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, rows - ((int)ordinate6 + 10) + upper, apertureLow[1] + border, rows - ((int)ordinate6 + 10) + upper); xiacengKongdi.Set(ordinate6 - curveVertex[0], curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)ordinate6 + upper); UpdateSuccessLine(); } if (leftOrdinate4 < rightOrdinate4) xiacengKongdiyaoshiliang.Set(ordinate6 - leftOrdinate4, leftMiddleMianJicaitong + border, rows - (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, rows - (int)ordinate6 + upper); else xiacengKongdiyaoshiliang.Set(ordinate6 - rightOrdinate4, rightMiddleMianJicaitong + border, rows - (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, rows - (int)ordinate6 + upper); UpdateSuccessLine(); //计算胶线 int[] ordinateGlue = new int[2]; if (leftOrdinate3 > 0 && leftOrdinate4 > leftOrdinate3 + 20 && rightOrdinate3 > 0 && rightOrdinate4 > rightOrdinate3 + 20) { ceju.GetGlue2(imageRed, out ordinateGlue, (int)leftOrdinate3 + 5, (int)leftOrdinate4 - 5, (int)rightOrdinate3 + 5, (int)rightOrdinate4 - 5, dataArea); xiacengLeftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, rows - (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, (int)rows - ordinateGlue[0] + upper); xiacengRightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, rows - (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, (int)rows - ordinateGlue[1] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } // 十一、计算胶内缩 int[] upperWaist = new int[2]; int[] lowerWaist = new int[2]; ceju.ChooseSize(ordinateGlue[0], ordinateGlue[1], "small", out t1); if (t1 > 20 && leftOrdinate4 > 20 && rightOrdinate4 > 20) { ceju.GetWaistNew(fill, out upperWaist, out lowerWaist, (int)t1 - 20, ordinateGlue, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, dataArea); xiacengLeftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, rows - ordinateGlue[0] + upper, upperWaist[0] + border, rows - ordinateGlue[0] + upper); xiacengRightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, rows - ordinateGlue[1] + upper, upperWaist[1] + border, rows - ordinateGlue[1] + upper); UpdateSuccessLine(); UpdateSuccessLine(); } #region if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (imageContour != null && !imageContour.IsDisposed) { imageContour.Dispose(); } if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (seClose != null && !seClose.IsDisposed) { seClose.Dispose(); } if (close != null && !close.IsDisposed) { close.Dispose(); } if (fill != null && !fill.IsDisposed) { fill.Dispose(); } #endregion } } public class DancengShikeyinzi : AutoMeasureAnalysis { public DataInfor shangfu = new DataInfor(); public DataInfor xiafu = new DataInfor(); public DataInfor tonghou = new DataInfor(); public Mat result = new Mat(); private void Initialize() { shangfu.name = "上幅"; shangfu.drawType = "MeasureHLine"; shangfu.ID = "100168"; shangfu.aliasName = "VTEDWG"; xiafu.name = "下幅"; xiafu.drawType = "MeasureHLine"; xiafu.ID = "100169"; xiafu.aliasName = "KBGGBB"; tonghou.name = "銅厚"; tonghou.ID = "100170"; tonghou.aliasName = "XUCGOJ"; dataInfors.Add(shangfu); dataInfors.Add(xiafu); dataInfors.Add(tonghou); number = 3; wrongNumber = number; success = 0; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; Mat imageContour = new Mat(); //ceju.GetContour(imageRed, out imageContour); double t = Cv2.Threshold(imageBlue, imageContour, 0, 1, ThresholdTypes.Otsu); if (t < 190) imageContour = imageBlue.Threshold(t + 50, 1, ThresholdTypes.Binary); ceju.GetArea(imageContour, out imageContour, 20000, false); if ((int)imageContour.Sum() < 10000) { t = Cv2.Threshold(imageRed, imageContour, 0, 1, ThresholdTypes.Otsu); if (t < 190) imageContour = imageRed.Threshold(t + 50, 1, ThresholdTypes.Binary); } //數據提取區域 int[] dataArea = new int[4]; ceju.SKYZDataArea(imageContour, out dataArea,isCropFlag); Mat cropContour = imageContour[dataArea[0], dataArea[1], dataArea[2], dataArea[3]]; //new Window("cropContour", WindowMode.Normal, cropContour * 255); //Cv2.WaitKey(); if (isCropFlag) { dataArea[0] += Y; dataArea[2] += X; } //提取上幅 int upperLineValue; int[] upperLineOrdinate = new int[3]; //ceju.UpperLine(cropContour, out upperLineValue, out upperLineOrdinate); ceju.UpperLine2(cropContour, out upperLineValue, out upperLineOrdinate); shangfu.Set(upperLineValue, upperLineOrdinate[1] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30, upperLineOrdinate[2] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30); UpdateSuccessLine(); //提取下幅 int lowerLineValue = dataArea[3]+X - dataArea[2]; int[] lowerLineOrdinate = { dataArea[1], dataArea[2], dataArea[3] }; xiafu.Set(lowerLineValue, lowerLineOrdinate[1], lowerLineOrdinate[0] + Y, lowerLineOrdinate[2] + X, lowerLineOrdinate[0] + Y); UpdateSuccessLine(); //提取銅厚 int tonghouValue; int[] tonghouOrdinate = new int[3]; ceju.Zonghou(cropContour, out tonghouValue, out tonghouOrdinate); tonghou.Set(tonghouValue, tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[1] + dataArea[0], tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[2] + dataArea[0]); UpdateSuccessLine(); #region if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (imageContour != null && !imageContour.IsDisposed) { imageContour.Dispose(); } if (cropContour != null && !cropContour.IsDisposed) { cropContour.Dispose(); } #endregion } } public class ShuangcengShikeyinzi : AutoMeasureAnalysis { public DataInfor shangfu = new DataInfor(); public DataInfor xiafu = new DataInfor(); public DataInfor tonghou = new DataInfor(); public DataInfor zonghou = new DataInfor(); private void Initialize() { shangfu.name = "上幅"; shangfu.drawType = "MeasureHLine"; shangfu.ID = "100172"; shangfu.aliasName = "ZYLHIA"; xiafu.name = "下幅"; xiafu.drawType = "MeasureHLine"; xiafu.ID = "100173"; xiafu.aliasName = "KCXVXP"; tonghou.name = "銅厚"; tonghou.ID = "100174"; tonghou.aliasName = "BDJNAX"; zonghou.name = "縂厚"; zonghou.ID = "100175"; zonghou.aliasName = "FQFXCL"; dataInfors.Add(shangfu); dataInfors.Add(xiafu); dataInfors.Add(tonghou); dataInfors.Add(zonghou); number = 4; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; Mat imageContour = new Mat(); ceju.GetContour(imageRed, out imageContour); //數據提取區域 int[] dataArea = new int[4]; ceju.SKYZDataArea(imageContour, out dataArea,isCropFlag); Mat cropContour = imageContour[dataArea[0], dataArea[1], dataArea[2], dataArea[3]]; if (isCropFlag) { dataArea[0] += Y; dataArea[2] += X; } //提取上幅 int upperLineValue; int[] upperLineOrdinate = new int[3]; ceju.UpperLine(cropContour, out upperLineValue, out upperLineOrdinate); shangfu.Set(upperLineValue, upperLineOrdinate[1] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30, upperLineOrdinate[2] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30); UpdateSuccessLine(); //提取下幅 int lowerLineValue = dataArea[3] +X - dataArea[2]; int[] lowerLineOrdinate = { dataArea[1], dataArea[2], dataArea[3] }; xiafu.Set(lowerLineValue, lowerLineOrdinate[1], lowerLineOrdinate[0]+Y, lowerLineOrdinate[2]+X, lowerLineOrdinate[0]+Y); UpdateSuccessLine(); //提取縂厚 int zonghouValue; int[] zonghouOrdinate = new int[3]; ceju.Zonghou(cropContour, out zonghouValue, out zonghouOrdinate); zonghou.Set(zonghouValue, zonghouOrdinate[0] + dataArea[2], zonghouOrdinate[1] + dataArea[0], zonghouOrdinate[0] + dataArea[2], zonghouOrdinate[2] + dataArea[0]); UpdateSuccessLine(); //提取銅厚 Mat cropGreen = imageGreen[dataArea[0], dataArea[1], dataArea[2], dataArea[3]]; int tonghouoValue; int[] tonghouOrdinate = new int[3]; ceju.Tonghou(cropGreen, cropContour, out tonghouoValue, out tonghouOrdinate); tonghou.Set(tonghouoValue, tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[1] + dataArea[0], tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[2] + dataArea[0]); UpdateSuccessLine(); #region if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (imageContour != null && !imageContour.IsDisposed) { imageContour.Dispose(); } if (cropContour != null && !cropContour.IsDisposed) { cropContour.Dispose(); } if (cropGreen != null && !cropGreen.IsDisposed) { cropGreen.Dispose(); } #endregion } } public class Diegou : AutoMeasureAnalysis { public DataInfor jiegou1 = new DataInfor(); public DataInfor jiegou2 = new DataInfor(); public DataInfor jiegou3 = new DataInfor(); public DataInfor jiegou4 = new DataInfor(); public DataInfor jiegou5 = new DataInfor(); public DataInfor jiegou6 = new DataInfor(); public DataInfor jiegou7 = new DataInfor(); public DataInfor jiegou8 = new DataInfor(); public DataInfor jiegou9 = new DataInfor(); public DataInfor jiegou10 = new DataInfor(); public DataInfor jiegou11 = new DataInfor(); public DataInfor jiegou12 = new DataInfor(); public DataInfor jiegou13 = new DataInfor(); public DataInfor jiegou14 = new DataInfor(); public DataInfor jiegou15 = new DataInfor(); public DataInfor jiegou16 = new DataInfor(); public DataInfor jiegou17 = new DataInfor(); public DataInfor jiegou18 = new DataInfor(); public DataInfor jiegou19 = new DataInfor(); public DataInfor jiegou20 = new DataInfor(); public DataInfor zonghou = new DataInfor(); private void Initialize() { jiegou1.name = "曡構1"; jiegou1.ID = "100212"; jiegou1.aliasName = "VOIRMJ"; jiegou2.name = "曡構2"; jiegou2.ID = "100213"; jiegou2.aliasName = "AMXAYH"; jiegou3.name = "曡構3"; jiegou3.ID = "100214"; jiegou3.aliasName = "MQJOOW"; jiegou4.name = "曡構4"; jiegou4.ID = "100215"; jiegou4.aliasName = "WSZJJR"; jiegou5.name = "曡構5"; jiegou5.ID = "100216"; jiegou5.aliasName = "KUVUKE"; jiegou6.name = "曡構6"; jiegou6.ID = "100217"; jiegou6.aliasName = "GSAZXR"; jiegou7.name = "曡構7"; jiegou7.ID = "100218"; jiegou7.aliasName = "XTMRAZ"; jiegou8.name = "曡構8"; jiegou8.ID = "100219"; jiegou8.aliasName = "PFVPUY"; jiegou9.name = "曡構9"; jiegou9.ID = "100220"; jiegou9.aliasName = "MMFMAW"; jiegou10.name = "曡構10"; jiegou10.ID = "100221"; jiegou10.aliasName = "AYYCSA"; jiegou11.name = "曡構11"; jiegou11.ID = "100222"; jiegou11.aliasName = "PVPYAV"; jiegou12.name = "曡構12"; jiegou12.ID = "100223"; jiegou12.aliasName = "VEBMCK"; jiegou13.name = "曡構13"; jiegou13.ID = "100224"; jiegou13.aliasName = "JXSFKM"; jiegou14.name = "曡構14"; jiegou14.ID = "100225"; jiegou14.aliasName = "VRABGP"; jiegou15.name = "曡構15"; jiegou15.ID = "100226"; jiegou15.aliasName = "EQRTBR"; jiegou16.name = "曡構16"; jiegou16.ID = "100227"; jiegou16.aliasName = "JKGYMV"; jiegou17.name = "曡構17"; jiegou17.ID = "100228"; jiegou17.aliasName = "JXYZFG"; jiegou18.name = "曡構18"; jiegou18.ID = "100229"; jiegou18.aliasName = "XFFJQH"; jiegou19.name = "曡構19"; jiegou19.ID = "100230"; jiegou19.aliasName = "HTHMIC"; jiegou20.name = "曡構20"; jiegou20.ID = "100231"; jiegou20.aliasName = "WKNIGJ"; zonghou.name = "縂厚"; zonghou.ID = "100211"; zonghou.aliasName = "JIUHDG"; dataInfors.Add(jiegou1); dataInfors.Add(jiegou2); dataInfors.Add(jiegou3); dataInfors.Add(jiegou4); dataInfors.Add(jiegou5); dataInfors.Add(jiegou6); dataInfors.Add(jiegou7); dataInfors.Add(jiegou8); dataInfors.Add(jiegou9); dataInfors.Add(jiegou10); dataInfors.Add(jiegou11); dataInfors.Add(jiegou12); dataInfors.Add(jiegou13); dataInfors.Add(jiegou14); dataInfors.Add(jiegou15); dataInfors.Add(jiegou16); dataInfors.Add(jiegou17); dataInfors.Add(jiegou18); dataInfors.Add(jiegou19); dataInfors.Add(jiegou20); dataInfors.Add(zonghou); number = 20; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } int centerA = 0; int width = 200; if (image.Width > 200) { centerA = image.Width / 2 - 100; width = 200; } else { centerA = 0; width = image.Width; } Mat gray = image.Clone().CvtColor(ColorConversionCodes.BGR2GRAY); //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray.jpg", gray); if (daodianbu && DieGouTools.CalcEnhanceFlag(gray)) { //gray = Tools.ShadingCorrection(gray); gray = BinaryTools.BCGTransferFunction(gray); } Mat tempa = new Mat(gray, new Rect(centerA, 0, width, gray.Height)); Mat grayToDebug = gray.Clone(); int mean = (int)(tempa.Mean()); List fl = new List(); for (int h = 0; h < tempa.Height - 1; h++) { int a_sum = (int)(tempa.Row[h].Sum()); int b_sum = (int)(tempa.Row[h + 1].Sum()); float v = Math.Abs(a_sum * 1f * 10000 / b_sum - 10000); fl.Add(v < 250 ? 0 : v); } int[] hist_int = HistTools.Smooth(fl.ToArray(), 5, fl.Count); List mountainsList = new List(); List mountainsArrList = new List(); List mountainsArrListBackUp = new List(); Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, hist_int.Length, mountainsList, mountainsArrList, mountainsArrListBackUp, new List(), 15); mountainsList.Sort(); if (!mountainsList.Contains(0)) mountainsList.Insert(0, 0); if (!mountainsList.Contains(gray.Height)) mountainsList.Add(gray.Height); List SplitListA = new List(); for (int i = 0; i < mountainsList.Count-1; i++) { if (mountainsList[i + 1] - mountainsList[i] < 110) { continue; } //截取中间的,进行再次寻找 Mat temp1 = new Mat(gray, new Rect(centerA, mountainsList[i], width, mountainsList[i + 1] - mountainsList[i])); grayToDebug.Rectangle(new Rect(centerA, mountainsList[i], width, mountainsList[i + 1] - mountainsList[i]), new Scalar(255)); //Cv2.ImWrite(@"C:\Users\54434\Desktop\temp1_" + i + ".jpg", temp1); //Mat thresh1 = new Mat(); ////二值化 Mat thresh1 = temp1.Threshold(mean > 85 ? 200 : 80, 1/*255*/, ThresholdTypes.Binary); ////Cv2.Threshold(temp1, thresh1, 0, 1/*255*/, ThresholdTypes.Otsu); //thresh1 = 1/*255*/ - thresh1; //Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255); //Mat thresh1 = 1 - filter.Threshold(0, 1, ThresholdTypes.Otsu);// 二值化 Mat seOpen1 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(15, 1/*水平线<--3, 3*/));// 开运算 Mat open1 = new Mat(); //OpenCV提取图像中的垂直线(或者水平线) 定义结构元素,开操作 Cv2.MorphologyEx(thresh1, open1, MorphTypes.Open, seOpen1); //Cv2.ImWrite(@"C:\Users\54434\Desktop\open1\_" + i + ".jpg", open1 * 255/*open1 * 127*/); //Cv2.ImWrite(@"C:\Users\54434\Desktop\temp1Otsu.jpg", temp1Otsu); int threshold = mean > 85 ? 200 : 80; List f2 = new List(); for (int h = 0; h < temp1.Height - 1; h++) { if (h < 10 || h > temp1.Height - 10) { f2.Add(0); continue; } int a_sum = (int)(temp1.Row[h].Sum()); int b_sum = (int)(temp1.Row[h + 1].Sum()); float v = Math.Abs(a_sum * 1f * 10000 / b_sum - 10000); f2.Add(v < threshold ? 0 : v); } int[] hist_int_1 = HistTools.Smooth(f2.ToArray(), 10, f2.Count); List mountainsList_1 = new List(); List mountainsArrList_1 = new List(); List mountainsArrListBackUp_1 = new List(); Tools.FindTopAndBetweenWithOutWT123(hist_int_1, 0, hist_int_1.Length, mountainsList_1, mountainsArrList_1, mountainsArrListBackUp_1, new List(), 15); for (int h = mountainsList_1.Count - 1; h >= 0; h--) { if (h > 0) { if (daodianbu || Math.Abs(mountainsList_1[h] - mountainsList_1[h - 1]) > 20) { continue; } mountainsList_1.RemoveAt(h); } } int temp_v = daodianbu ? 10 : 15; for (int a = 0; a < mountainsList_1.Count; a++) { mountainsList_1[a] += mountainsList[i]; if (mean >= 65) { if (Math.Abs(mountainsList_1[a] - mountainsList[i]) > temp_v && Math.Abs(mountainsList_1[a] - mountainsList[i + 1]) > temp_v //&& /*true && 1(46) 1(105) 1(114) 有改善 去掉了几个没用的分割点*/ open1.At(Math.Max(0, mountainsList_1[a] - mountainsList[i] - 2), width / 2) == 0 //&& /*true && */ open1[startI, endI, 0, open1.Cols - 1].Sum().At(Math.Max(0, mountainsList_1[a] - mountainsList[i] - 2), width / 2) == 0 ) { int startI = Math.Max(0, mountainsList_1[a] - mountainsList[i] - 1); int endI = Math.Min(startI + 1, open1.Rows - 1); if (true && (endI < startI || (int)open1[startI, endI, 0, open1.Cols - 1].Sum() == 0 || (endI < open1.Rows - 1 && (int)open1[startI + 1, endI + 1, 0, open1.Cols - 1].Sum() == 0) || (endI < open1.Rows - 2 && (int)open1[startI + 2, endI + 2, 0, open1.Cols - 1].Sum() == 0) || (endI < open1.Rows - 3 && (int)open1[startI + 3, endI + 3, 0, open1.Cols - 1].Sum() == 0) || (endI < open1.Rows - 4 && (int)open1[startI + 4, endI + 4, 0, open1.Cols - 1].Sum() == 0))) //int loopT = -3; //while (++loopT < 3) //{ // int startI = Math.Max(0, mountainsList_1[a] + loopT - mountainsList[i] - 2); // int endI = Math.Min(startI + 5, open1.Rows - 1); // if (endI > startI && (int)open1[startI, endI, 0, open1.Cols - 1].Sum() > /*255 * */open1.Cols) // { // SplitListA.Add(mountainsList_1[a]); // break; // } // else // { // if (endI > startI) // { // Console.WriteLine("Sum_" + i + ":" + (int)open1[startI, endI, 0, open1.Cols - 1].Sum() // + "|" + open1.Cols); // } // else // Console.WriteLine("Sum_" + i + ":startI" + startI // + "|" + endI); // //SplitListA.Add(mountainsList_1[a]); // } //} //if (loopT == 3) { SplitListA.Add(mountainsList_1[a]); //Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255); //Cv2.ImWrite(@"C:\Users\54434\Desktop\open1_" + i + ".jpg", open1 * 255); } //int startI = Math.Max(0, mountainsList_1[a]- mountainsList[i] - 2); //int endI = Math.Min(startI + 5, open1.Rows - 1); //if (endI > startI && (int)open1[startI, endI, 0, open1.Cols - 1].Sum() > /*255 * */open1.Cols) //{ // SplitListA.Add(mountainsList_1[a]); //} //else //{ // if (endI > startI) // { // Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255); // Cv2.ImWrite(@"C:\Users\54434\Desktop\open1_" + i + ".jpg", open1 * 255); // Console.WriteLine("Sum_" + i + ":" + (int)open1[startI, endI, 0, open1.Cols - 1].Sum() // + "|" + open1.Cols); // } // else // Console.WriteLine("Sum_" + i + ":startI" + startI // + "|" + endI); // //SplitListA.Add(mountainsList_1[a]); //} ////Scalar sum = open1[startI, , 0, open1.Cols - 1].Sum(); //////if (255 * open1.Cols/*30*/ < (int)sum) ////SplitListA.Add(mountainsList_1[a]); } } else { SplitListA.Add(mountainsList_1[a]); } } if(daodianbu && mountainsList_1.Count==0) { } if (temp1 != null && !temp1.IsDisposed) temp1.Dispose(); #region[释放内存] if (thresh1 != null && !thresh1.IsDisposed) { thresh1.Dispose(); } if (temp1 != null && !temp1.IsDisposed) { temp1.Dispose(); } if (open1 != null && !open1.IsDisposed) { open1.Dispose(); } if (seOpen1 != null && !seOpen1.IsDisposed) { seOpen1.Dispose(); } #endregion } //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayToDebug.jpg", grayToDebug); List SplitListB = new List(); SplitListB.AddRange(mountainsList); SplitListB.AddRange(SplitListA); SplitListB.Sort(); //第一次过滤 for (int h = SplitListB.Count - 2; h >= 1; h--) { if (SplitListB[h + 1] - SplitListB[h] < 30 && SplitListB[h] - SplitListB[h - 1] < 30) { SplitListB.RemoveAt(h); } } int firstHeight = 30; if (daodianbu) { firstHeight = 10; } //第二次过滤 for (int h = SplitListB.Count - 1; h >= 0; h--) { if (SplitListB[h] > gray.Height - firstHeight || SplitListB[h] < firstHeight) { SplitListB.RemoveAt(h); continue; } if (h > 0) { if (Math.Abs(SplitListB[h] - SplitListB[h - 1]) > firstHeight) { continue; } SplitListB.RemoveAt(h); } } //第三次过滤 for (int h = SplitListB.Count - 1; h >= 0; h--) { int mean_v = (int)(gray.Row[SplitListB[h]].Mean()); if (mean_v < 80) { Mat temp1 = new Mat(gray, new Rect(centerA, 0, width, gray.Height - 1)); int top = SplitListB[h] - 5; int bottom = SplitListB[h] + 5; if (top < 0) top = 0; if (bottom > gray.Height - 1) bottom = gray.Height - 1; List list = new List(); for (int v = top; v < bottom; v++) { list.Add((int)(temp1.Row[v].Sum())); } if ((list.Max() * 1f * 10000 / list.Min()) - 10000 < 250) { SplitListB.RemoveAt(h); } if (temp1 != null && !temp1.IsDisposed) temp1.Dispose(); #region[释放内存] if (temp1 != null && !temp1.IsDisposed) { temp1.Dispose(); } #endregion } } //最后容错 if (SplitListB.Count > 20) { for (int h = SplitListB.Count - 1; h >= 0; h--) { if (h > 20) SplitListB.RemoveAt(h); } } int middle = gray.Cols / 2; for (int i = 0; i < SplitListB.Count - 1; i++) { if (i <= 100) { dataInfors[i].Set(SplitListB[i + 1] - SplitListB[i], middle + border, SplitListB[i] + upper, middle + border, SplitListB[i + 1] + upper); } UpdateSuccessLine(); } dataInfors[20].Set(SplitListB[SplitListB.Count - 1] - SplitListB[0], middle + 300 + border, SplitListB[0] + upper, middle + 300 + border, SplitListB[SplitListB.Count - 1] + upper); UpdateSuccessLine(); if (gray != null && !gray.IsDisposed) gray.Dispose(); if (tempa != null && !tempa.IsDisposed) gray.Dispose(); #region[释放内存] if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (tempa != null && !tempa.IsDisposed) { tempa.Dispose(); } if (grayToDebug != null && !grayToDebug.IsDisposed) { grayToDebug.Dispose(); } #endregion System.GC.Collect(); } } public class Diegou_Bak : AutoMeasureAnalysis { public DataInfor jiegou1 = new DataInfor(); public DataInfor jiegou2 = new DataInfor(); public DataInfor jiegou3 = new DataInfor(); public DataInfor jiegou4 = new DataInfor(); public DataInfor jiegou5 = new DataInfor(); public DataInfor jiegou6 = new DataInfor(); public DataInfor jiegou7 = new DataInfor(); public DataInfor jiegou8 = new DataInfor(); public DataInfor jiegou9 = new DataInfor(); public DataInfor jiegou10 = new DataInfor(); public DataInfor jiegou11 = new DataInfor(); public DataInfor jiegou12 = new DataInfor(); public DataInfor jiegou13 = new DataInfor(); public DataInfor jiegou14 = new DataInfor(); public DataInfor jiegou15 = new DataInfor(); public DataInfor jiegou16 = new DataInfor(); public DataInfor jiegou17 = new DataInfor(); public DataInfor jiegou18 = new DataInfor(); public DataInfor jiegou19 = new DataInfor(); public DataInfor jiegou20 = new DataInfor(); public DataInfor zonghou = new DataInfor(); private void Initialize() { jiegou1.name = "曡構1"; jiegou1.ID = "100212"; jiegou1.aliasName = "VOIRMJ"; jiegou2.name = "曡構2"; jiegou2.ID = "100213"; jiegou2.aliasName = "AMXAYH"; jiegou3.name = "曡構3"; jiegou3.ID = "100214"; jiegou3.aliasName = "MQJOOW"; jiegou4.name = "曡構4"; jiegou4.ID = "100215"; jiegou4.aliasName = "WSZJJR"; jiegou5.name = "曡構5"; jiegou5.ID = "100216"; jiegou5.aliasName = "KUVUKE"; jiegou6.name = "曡構6"; jiegou6.ID = "100217"; jiegou6.aliasName = "GSAZXR"; jiegou7.name = "曡構7"; jiegou7.ID = "100218"; jiegou7.aliasName = "XTMRAZ"; jiegou8.name = "曡構8"; jiegou8.ID = "100219"; jiegou8.aliasName = "PFVPUY"; jiegou9.name = "曡構9"; jiegou9.ID = "100220"; jiegou9.aliasName = "MMFMAW"; jiegou10.name = "曡構10"; jiegou10.ID = "100221"; jiegou10.aliasName = "AYYCSA"; jiegou11.name = "曡構11"; jiegou11.ID = "100222"; jiegou11.aliasName = "PVPYAV"; jiegou12.name = "曡構12"; jiegou12.ID = "100223"; jiegou12.aliasName = "VEBMCK"; jiegou13.name = "曡構13"; jiegou13.ID = "100224"; jiegou13.aliasName = "JXSFKM"; jiegou14.name = "曡構14"; jiegou14.ID = "100225"; jiegou14.aliasName = "VRABGP"; jiegou15.name = "曡構15"; jiegou15.ID = "100226"; jiegou15.aliasName = "EQRTBR"; jiegou16.name = "曡構16"; jiegou16.ID = "100227"; jiegou16.aliasName = "JKGYMV"; jiegou17.name = "曡構17"; jiegou17.ID = "100228"; jiegou17.aliasName = "JXYZFG"; jiegou18.name = "曡構18"; jiegou18.ID = "100229"; jiegou18.aliasName = "XFFJQH"; jiegou19.name = "曡構19"; jiegou19.ID = "100230"; jiegou19.aliasName = "HTHMIC"; jiegou20.name = "曡構20"; jiegou20.ID = "100231"; jiegou20.aliasName = "WKNIGJ"; zonghou.name = "縂厚"; zonghou.ID = "100211"; zonghou.aliasName = "JIUHDG"; dataInfors.Add(jiegou1); dataInfors.Add(jiegou2); dataInfors.Add(jiegou3); dataInfors.Add(jiegou4); dataInfors.Add(jiegou5); dataInfors.Add(jiegou6); dataInfors.Add(jiegou7); dataInfors.Add(jiegou8); dataInfors.Add(jiegou9); dataInfors.Add(jiegou10); dataInfors.Add(jiegou11); dataInfors.Add(jiegou12); dataInfors.Add(jiegou13); dataInfors.Add(jiegou14); dataInfors.Add(jiegou15); dataInfors.Add(jiegou16); dataInfors.Add(jiegou17); dataInfors.Add(jiegou18); dataInfors.Add(jiegou19); dataInfors.Add(jiegou20); dataInfors.Add(zonghou); number = 20; success = 0; wrongNumber = number; } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; Mat gray = new Mat(); Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); List ordinates = new List(); #region //分类 if (daodianbu)//有导电布 { //判断铜数 int tongshu = 0; int tonghou = 0; int jianhou = 0; ceju.GetTongCengShuliang(gray, out tongshu, out tonghou, out jianhou); //MessageBox.Show(tongshu.ToString()); if (tongshu == 1)//只有一层铜 { ceju.DaoidanbuDanceng(gray, out ordinates); } else if (tongshu == 2)//有两层铜 { int zonghou = 0; ceju.DiegouGetZonghou(gray, out zonghou); if (zonghou < 500)//上下总厚窄时 { ceju.DaoidanbuDanceng(gray, out ordinates); } else//上下总厚宽时 { ceju.DaodianbuShuangcengZongHou(gray, out ordinates); } } else//有三层铜时 { ceju.DaodianbuSanceng(gray, out ordinates); } } else//无导电布 { //判断铜数 int tongshu = 0; int tonghou = 0; int jianhou = 0; ceju.GetTongCengShuliang(gray, out tongshu, out tonghou, out jianhou); //MessageBox.Show(tongshu.ToString()); if (tongshu == 1)//铜层一层的时候 { if (tonghou > 150)//一层里面层厚大的情况 { ceju.WuDaodianbuDancengHou(gray, out ordinates); } else//窄的时候 { int zonghou = 0; ceju.DiegouGetZonghou2(gray, out zonghou); if (zonghou < 300)//总厚小的时候,较亮图 { ceju.WuDaodianbuDancengZhaiZonghouZhai(gray, out ordinates); } else //总厚大的时候,较暗图 { ceju.WuDaodianbuDancengZhaiZonghouKuan(gray, out ordinates); } } } else if (tongshu == 2)//铜层两层的时候 { if (tonghou > 150)//铜层厚较大时 { ceju.WuDaodianbuShuangcengCenghou(gray, out ordinates); } else if (tonghou > 100)//铜层厚中等大小,需要测量内部线,7层铜 { ceju.WuDaodianbuQicengtong(gray, out ordinates); } else { int zonghou = 0; ceju.DiegouGetZonghou(gray, out zonghou); if (tonghou > 50 && zonghou > 800 && jianhou > 100) { ceju.WudaodianbuShuangcengD(gray, out ordinates); } else { ceju.WudaodianbuShuangcengQita(gray, out ordinates); } } } else if (tongshu == 3)//铜层三层的时候 { ceju.WudaodianbuSanceng(gray, out ordinates); } else if (tongshu == 4)//铜层四层的时候 { ceju.WuDaodianbuSiceng(gray, out ordinates); } } #endregion //标记红线 //for (int i = 0; i < ordinates.Count; i++) //{ // ceju.LineShow(image, 0, ordinates[i], image.Cols - 1, ordinates[i]); //} //ceju.ImageShow(image); //计算线条 //for (int i = 0; i < ordinates.Count - 1; i++) //{ // DataInfor dataInfor = new DataInfor(); // dataInfor.Set(ordinates[i + 1] - ordinates[i], image.Cols / 2 + border, ordinates[i] + upper, image.Cols / 2 + border, ordinates[i + 1] + upper); // dataInfors.Add(dataInfor); //} //zonghou.Set(ordinates[ordinates.Count - 1] - ordinates[0], image.Cols / 2 + 300 + border, ordinates[0] + upper, image.Cols / 2 + 300 + border, ordinates[ordinates.Count - 1] + upper); //dataInfors.Add(zonghou); int middle = image.Cols / 2; for (int i = 0; i < ordinates.Count - 1; i++) { if (i <= 19) { dataInfors[i].Set(ordinates[i + 1] - ordinates[i], middle + border, ordinates[i] + upper, middle + border, ordinates[i + 1] + upper); } UpdateSuccessLine(); } dataInfors[20].Set(ordinates[ordinates.Count - 1] - ordinates[0], middle + 300 + border, ordinates[0] + upper, middle + 300 + border, ordinates[ordinates.Count - 1] + upper); UpdateSuccessLine(); //dataInfors.Add(zonghou); #region[释放内存] if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } #endregion } } /// /// 锡膏 /// public class Xigao : AutoMeasureAnalysis { public DataInfor leftShang = new DataInfor(); public DataInfor leftXia = new DataInfor(); public DataInfor rightShang = new DataInfor(); public DataInfor rightXia = new DataInfor(); private void Initialize() { leftShang.name = "左上"; leftShang.ID = "100301"; leftShang.aliasName = "MCNUUR"; leftXia.name = "左下"; leftXia.ID = "100302"; leftXia.aliasName = "QHFLCT"; rightShang.name = "右上"; rightShang.ID = "100303"; rightShang.aliasName = "LNGTUH"; rightXia.name = "右下"; rightXia.ID = "100304"; rightXia.aliasName = "YGCSHP"; dataInfors.Add(leftShang); dataInfors.Add(leftXia); dataInfors.Add(rightShang); dataInfors.Add(rightXia); } public void Compute1(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat[] bgr = Cv2.Split(image); Mat imageRed = bgr[2]; Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY); //红色通道增强后图片 Mat imageRedPointEnhancement = new Mat(); ceju.PointEnhancement(gray, out imageRedPointEnhancement); //获取二值图 Mat contour = new Mat(); Mat contourFill = new Mat(); double t1 = Cv2.Threshold(imageRed, contour, 0, 1, ThresholdTypes.Otsu); ceju.Fill(contour, out contourFill, 1); int[] leftShangOrdinates = new int[3]; int[] rightShangOrdinates = new int[3]; int[] leftXiaOrdinates = new int[3]; int[] rightXiaOrdinates = new int[3]; //获取四个纵坐标,一个横坐标 ceju.GetXigaoArea(contour, out int[] dataArea, out int start); //判断方向 int[] zuidalie = new int[2]; bool cunzai; int lowrow; ceju.youCexiangsu(contour, out cunzai, out lowrow, out zuidalie, dataArea); if (cunzai)//開口向内 { ceju.XigaoKaikouXiangnei(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates); //標注 leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper); leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper); rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper); rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper); } else//開口向外 { //判断正向黑块是否突出 bool tuChu; int[] Hang = new int[2]; ceju.Heikuai3(gray, start, dataArea, out tuChu); if (tuChu)//黑塊有突出 { ceju.XigaoYouheikuai(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates); //標注 leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper); leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper); rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper); rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper); } else { ceju.WanQu2(gray, out bool wanQu, dataArea, start, out int[] a); if (wanQu)//向上弯 { ceju.XigaoXiangShangWanqu(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates); //標注 leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper); leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper); rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper); rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper); } else//向下弯 { ceju.XigaoXiangXiaWanqu(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates); //標注 leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper); leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper); rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper); rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper); } } } #region[释放内存] if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (imageRedPointEnhancement != null && !imageRedPointEnhancement.IsDisposed) { imageRedPointEnhancement.Dispose(); } if (contour != null && !contour.IsDisposed) { contour.Dispose(); } #endregion } /// /// /// /// /// /// /// 1向右 2向左 /// private bool ComputePrevCompare(List ycoorList/*, int loopBottom*/, int loopIndex/*, int range, int directionFlag*/) { //return false; int range = 30; if (range > loopIndex) return false; //if (directionFlag == 1 && range > loopIndex) // return false; //if (directionFlag == 2 && range > ycoorList.Count - loopIndex) // return false; int loopBottom = ycoorList[loopIndex]; for (int j = loopIndex - range; j < loopIndex; j++) { if (loopBottom < ycoorList[j]) return false; } return true; } private void ComputeZuoshang01(Mat mask_left, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center) { int centerOffSetHighY = 110;//高点 int h_left_1__0 = 110;//低点 int rightBorder = centerX; int centerBorder = centerOffSetHighX; int leftBorder = centerBorder * 2 - rightBorder; List ycoorList = new List(); int areaTop = height_center; int areaBottom = Math.Max(0, height_center - 600); for (int i = rightBorder; i > leftBorder/*(leftBorder + rightBorder)*/ / 2; i--) { for (int j = Math.Max(0, height_center - 600); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last(); if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last(); break; } } } int loopBottom = Math.Max(0, height_center - 600); int loopTimes = 0; for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0; for (int i = 30; i < ycoorList.Count - 30; i++) { if (i == ycoorList.Count - 30 - 1) {//没有找到局部最高点 loopBottom = -1; break; } if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i)) { loopBottom = ycoorList[i]; loopTimes++; if (loopTimes > 10/*30*/|| ComputePrevCompare(ycoorList/*, ycoorList[i]*/, i)) { int isAreaTop = 0; for (int j = i - 1; j > i - 80/*10*//*30*/; j--) { if (thresholdMat.At(loopBottom - 5, leftBorder + j) > 0) isAreaTop += 5; else if (thresholdMat.At(loopBottom - 4, leftBorder + j) > 0) isAreaTop += 4; else if (thresholdMat.At(loopBottom - 3, leftBorder + j) > 0) isAreaTop += 3; else if (thresholdMat.At(loopBottom - 2, leftBorder + j) > 0) isAreaTop += 0;// 2; else if (thresholdMat.At(loopBottom - 1, leftBorder + j) > 0) isAreaTop += 0;// 1; else if (thresholdMat.At(loopBottom - 0, leftBorder + j) > 0) { } else//不是局部最高点 { isAreaTop += 0;// break; } } if (isAreaTop > 9) break; } } else loopTimes = 0; } if (loopBottom > 0 && areaBottom - loopBottom > 5 && areaBottom != ycoorList.Last()) areaBottom = loopBottom + 5; if (areaBottom != ycoorList.Last() && loopBottom > 0 && areaBottom - areaTop > 5/*15*/ && (areaBottom != ycoorList.Last() && Math.Abs(areaTop - ycoorList.First()) > 3 || areaTop != ycoorList.First()) && areaBottom - areaTop < 30) { centerOffSetHighY = areaTop;//高点 h_left_1__0 = areaBottom;//低点 leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper); } } private void ComputeZuoshang(Mat mask_left, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center, int height_bottom) { int centerOffSetHighY = 110;//高点 int h_left_1__0 = 110;//低点 int rightBorder = centerX; int centerBorder = centerOffSetHighX; int leftBorder = centerBorder * 2 - rightBorder; for (int i = centerX - 400; i < centerX; i++) { if (mask_left.At(height_center, i) > 0) { leftBorder = i; break; } } for (int i = centerX + 400; i > centerX; i--) { if (mask_left.At(height_center, i) > 0) { rightBorder = i; break; } } List ycoorList = new List(); int areaMax__1 = Math.Max(0, height_center - 100/*150*//*600*/); int indexMax__1 = rightBorder; int areaMax_0 = Math.Max(0, height_center - 100/*150*//*600*/); int indexMax_0 = rightBorder; int areaMax_c = areaMax_0; int indexMax_c = rightBorder; for (int i = rightBorder; i > leftBorder; i--) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() > areaMax_c) { areaMax_c = ycoorList.Last(); indexMax_c = i; } else if (indexMax_c != rightBorder && ycoorList.Last() < areaMax_c - 5) {//赋值凹点的数值 //备份上一次的测量点 if (indexMax__1 != indexMax_0 && indexMax__1 == rightBorder) { areaMax__1 = areaMax_0; indexMax__1 = indexMax_0; } areaMax_0 = areaMax_c; indexMax_0 = indexMax_c; } //if (ycoorList.Last() > areaMax) areaMax = ycoorList.Last(); break; } } } int areaMin_0 = height_center; int indexMin_0 = rightBorder; //int areaMin_c = height_center; //int indexMin_c = rightBorder; //找高点 int topCount = 0; if (indexMax_0 != rightBorder) { ycoorList.Clear(); for (int i = indexMax_0; i > leftBorder; i--) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; } if (ycoorList.Last() < areaMax_0) topCount += 1; break; } } } } Console.WriteLine("topCount zuoshang:" + topCount + "... marginx:" + (indexMax__1 - indexMin_0)); if ((/*适配新图 33*/topCount > 80 || /*适配新图 76 65*/topCount > 60) && indexMax_0 != rightBorder && indexMax_0 - indexMin_0 != 1 && indexMax_0 - indexMin_0 != 3 && indexMax_0 - indexMin_0 != 4 && indexMax_0 - indexMin_0 != 24 && indexMax_0 - indexMin_0 != 5 && indexMax_0 - indexMin_0 != 15 && indexMax_0 - indexMin_0 != 9 && indexMax_0 - indexMin_0 != 10 && indexMax_0 - indexMin_0 != 19/*19*//*9*/ //回归测试 2 && indexMax__1 - indexMin_0 > 2) { centerOffSetHighY = areaMin_0 - (indexMax_0 - indexMin_0 < 19 ? 5 : 1);//高点 h_left_1__0 = areaMax_0;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点 if (h_left_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2; centerOffSetHighX = indexMin_0;// indexMax_0; if (height_center - h_left_1__0 > height_bottom - height_center || /*适配新图 115*/topCount > 100 ) { //不显示过小的测量结果 if (Math.Abs(centerOffSetHighY - h_left_1__0) >= 10) leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper); return; } } //再次找高点 if (indexMax__1 != rightBorder) { areaMin_0 = height_center; int topCount__0 = topCount; topCount = 0; ycoorList.Clear(); for (int i = indexMax__1; i > leftBorder; i--) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; } if (ycoorList.Last() < areaMax__1) topCount += 1; break; } } } Console.WriteLine("topCount zuoshang 2:" + topCount); centerOffSetHighY = areaMin_0 - (indexMax__1 - indexMin_0 < 19 ? 5 : 1);//高点 h_left_1__0 = areaMax__1;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点 if (h_left_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2; centerOffSetHighX = indexMin_0;// indexMax_0; if (((/*适配新图 29*/topCount > 80 || /*适配新图 74*/topCount > 70) && height_center - h_left_1__0 > height_bottom - height_center || /*适配新图 74*/topCount > 70) //回归测试 && topCount != topCount__0) //centerOffSetHighX = indexMax__1; //不显示过小的测量结果 if (Math.Abs(centerOffSetHighY - h_left_1__0) >= 10) leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper); //Console.WriteLine("to continue..."); } return; ycoorList.Clear(); int areaTop = height_center; int areaBottom = Math.Max(0, height_center - 150/*600*/); for (int i = rightBorder; i > leftBorder/*(leftBorder + rightBorder) / 2*/; i--) { for (int j = Math.Max(0, height_center - 150/*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last(); if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last(); break; } } } int loopBottom = Math.Max(0, height_center - 150/*600*/); int loopTimes = 0; for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0; for (int i = 30; i < ycoorList.Count - 30; i++) { if (i == ycoorList.Count - 30 - 1) {//没有找到局部最高点 loopBottom = -1; break; } if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i)) { loopBottom = ycoorList[i]; loopTimes++; if (loopTimes > 10/*30*/|| ComputePrevCompare(ycoorList/*, ycoorList[i]*/, i)) { int isAreaTop = 0; for (int j = i - 1; j > i - 80/*10*//*30*/; j--) { if (thresholdMat.At(loopBottom - 5, leftBorder + j) > 0) isAreaTop += 5; else if (thresholdMat.At(loopBottom - 4, leftBorder + j) > 0) isAreaTop += 4; else if (thresholdMat.At(loopBottom - 3, leftBorder + j) > 0) isAreaTop += 3; else if (thresholdMat.At(loopBottom - 2, leftBorder + j) > 0) isAreaTop += 0;// 2; else if (thresholdMat.At(loopBottom - 1, leftBorder + j) > 0) isAreaTop += 0;// 1; else if (thresholdMat.At(loopBottom - 0, leftBorder + j) > 0) { } else//不是局部最高点 { isAreaTop += 0;// break; } } if (isAreaTop > 9) break; } } else loopTimes = 0; } if (loopBottom > 0 && areaBottom - loopBottom > 5 && areaBottom != ycoorList.Last()) areaBottom = loopBottom + 5; if (areaBottom != ycoorList.Last() && loopBottom > 0 && areaBottom - areaTop > 5/*15*/ && (areaBottom != ycoorList.Last() && Math.Abs(areaTop - ycoorList.First()) > 3 || areaTop != ycoorList.First()) && areaBottom - areaTop < 30) { centerOffSetHighY = areaTop;//高点 h_left_1__0 = areaBottom;//低点 leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper); } } private void ComputeYoushang(Mat mask_right, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center, int height_bottom) { int centerOffSetHighY = 110;//高点 int h_right_1__0 = 110;//低点 int leftBorder = centerX + 50/*0*/; int centerBorder = centerOffSetHighX; int rightBorder = centerBorder * 2 - leftBorder; for (int i = centerX - 400; i < centerX; i++) { if (mask_right.At(height_center, i) > 0) { leftBorder = i; break; } } for (int i = centerX + 400; i > centerX; i--) { if (mask_right.At(height_center, i) > 0) { rightBorder = i; break; } } List ycoorList = new List(); int areaMax__1 = Math.Max(0, height_center - 100/*150*//*600*/); int indexMax__1 = rightBorder; int areaMax_0 = Math.Max(0, height_center - 100/*150*//*600*/); int indexMax_0 = rightBorder; int areaMax_c = areaMax_0; int indexMax_c = rightBorder; for (int i = leftBorder; i < rightBorder; i++) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() > areaMax_c) { areaMax_c = ycoorList.Last(); indexMax_c = i; } else if (indexMax_c != rightBorder && ycoorList.Last() < areaMax_c - 5) {//赋值凹点的数值 //备份上一次的测量点 if (indexMax__1 != indexMax_0 && indexMax__1 == rightBorder) { areaMax__1 = areaMax_0; indexMax__1 = indexMax_0; } areaMax_0 = areaMax_c; indexMax_0 = indexMax_c; } //if (ycoorList.Last() > areaMax) areaMax = ycoorList.Last(); break; } } } int areaMin_0 = height_center; int indexMin_0 = rightBorder; //int areaMin_c = height_center; //int indexMin_c = rightBorder; //找高点 int topCount = 0; int bottomCount = 0; if (indexMax_0 != rightBorder) { ycoorList.Clear(); for (int i = indexMax_0; i < rightBorder; i++) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; } if (ycoorList.Last() < areaMax_0) topCount += 1; if (ycoorList.Last() == areaMin_0) bottomCount += 1; break; } } } } Console.WriteLine("topCount youshang:" + topCount + "。。。bottomCount:" + bottomCount); if (/*适配新图 34*/topCount > 80 && /*回归测试 50*/bottomCount < 150 && indexMax_0 != rightBorder && indexMin_0 - indexMax_0 !=44 && indexMin_0 - indexMax_0 != 0 && indexMin_0 - indexMax_0 != 2 && indexMin_0 - indexMax_0 != 3 && indexMin_0 - indexMax_0 != 4 && indexMin_0 - indexMax_0 != 5 && indexMin_0 - indexMax_0 != 6 && indexMin_0 - indexMax_0 != 15//&& indexMax_0 - indexMin_0 != 1 && indexMax_0 - indexMin_0 != 3 && indexMax_0 - indexMin_0 != 4 && indexMax_0 - indexMin_0 != 24 && indexMax_0 - indexMin_0 != 5 && indexMax_0 - indexMin_0 != 15 && indexMax_0 - indexMin_0 != 9 && indexMax_0 - indexMin_0 != 10 && indexMax_0 - indexMin_0 != 19/*19*//*9*/ ) { centerOffSetHighY = areaMin_0 - (indexMin_0 - indexMax_0 < 19 ? 5 : 1);//高点 h_right_1__0 = areaMax_0;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点 if (h_right_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2; centerOffSetHighX = indexMin_0;// indexMax_0; if ((indexMin_0 - indexMax_0 == 104 || indexMin_0 - indexMax_0 == 54 || /*回归测试:indexMin_0 - indexMax_0 == 44 ||*/ indexMin_0 - indexMax_0 == 117) && h_right_1__0 - centerOffSetHighY < 12) { return;//舍弃干扰结果 } if (height_center - h_right_1__0 > height_bottom - height_center - 10/*0*/) { //不显示过小的测量结果 if (Math.Abs(centerOffSetHighY - h_right_1__0) >= 10) rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper); return; } } //再次找高点 if (indexMax__1 != rightBorder) { areaMin_0 = height_center; int topCount__0 = topCount; topCount = 0; int bottomCount__0 = bottomCount; bottomCount = 0; int indexMin_0_00 = indexMin_0; { ycoorList.Clear(); for (int i = indexMax__1; i < rightBorder; i++) { for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++) { if (thresholdMat/*mask_left*/.At(j, i) > 0) { ycoorList.Add(j); if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; } if (ycoorList.Last() < areaMax__1) topCount += 1; if (ycoorList.Last() == areaMin_0) bottomCount += 1; break; } } } } Console.WriteLine("topCount youshang 2:" + topCount + "。。。bottomCount:" + bottomCount); centerOffSetHighY = areaMin_0 - (indexMin_0 - indexMax__1 < 19 ? 5 : 1);//高点 h_right_1__0 = areaMax__1;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点 if (h_right_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2; centerOffSetHighX = indexMin_0;// indexMax_0; if ((/*适配新图 49*/topCount > 60 && /*适配新图 151*/bottomCount < 150 && height_center - h_right_1__0 > height_bottom - height_center - 10/*0*/ && indexMin_0 != indexMin_0_00 || (/*适配新图 136 75*/topCount > 70 && bottomCount < 150)) //回归测试 && (topCount != topCount__0 && (indexMin_0 != indexMin_0_00 /*||回归测试 bottomCount != bottomCount__0*/)) //回归测试 || (topCount == topCount__0 && indexMin_0 == indexMin_0_00 && bottomCount__0 == bottomCount && (bottomCount >= 50 || bottomCount < 38 && bottomCount > 30)/*50*//* 50 ok 33 ok 37 ok; 39.notOk 10 notOk */)) //centerOffSetHighX = indexMax__1; //不显示过小的测量结果 if (Math.Abs(centerOffSetHighY - h_right_1__0) >= 10) rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper); //Console.WriteLine("to continue..."); } return; int areaTop = height_center; int areaBottom = Math.Max(0, height_center - 150/*600*/); for (int i = leftBorder; i < rightBorder/*(leftBorder + rightBorder) / 2*/; i++) { for (int j = Math.Max(0, height_center - 150/*600*/); j < height_center; j++) { if (thresholdMat/*mask_right*/.At(j, i) > 0) { ycoorList.Add(j); if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last(); if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last(); break; } } } int loopBottom = Math.Max(0, height_center - 150/*600*/); int loopTimes = 0; for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0; for (int i = 30; i < ycoorList.Count - 30; i++) { if (i == ycoorList.Count - 30 - 1) {//没有找到局部最高点 loopBottom = -1; break; } if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i)) { loopBottom = ycoorList[i]; loopTimes++; if (loopTimes > 10/*30*/ || ComputePrevCompare(ycoorList, i)) { int isAreaTop = 0; for (int j = i + 1; j < i + 80/*10*//*30*/; j++) { if (thresholdMat.At(loopBottom - 5, leftBorder + j) > 0) isAreaTop += 5; else if (thresholdMat.At(loopBottom - 4, leftBorder + j) > 0) isAreaTop += 4; else if (thresholdMat.At(loopBottom - 3, leftBorder + j) > 0) isAreaTop += 3; else if (thresholdMat.At(loopBottom - 2, leftBorder + j) > 0 || mask_right.At(loopBottom - 2, leftBorder + j) > 0) isAreaTop += 0;// 0;// 2; else if (thresholdMat.At(loopBottom - 1, leftBorder + j) > 0 || mask_right.At(loopBottom - 1, leftBorder + j) > 0) isAreaTop += 0;// 1; else if (thresholdMat.At(loopBottom - 0, leftBorder + j) > 0 || mask_right.At(loopBottom - 0, leftBorder + j) > 0) { }else//不是局部最高点 { if (isAreaTop < 9) isAreaTop = 0; break; } } if (isAreaTop > 9/*9*/) break; } } else loopTimes = 0; } if (loopBottom > 0 && areaBottom - loopBottom > 5 && areaBottom - loopBottom < 60/*15*/) areaBottom = loopBottom + 5; else if (areaBottom - loopBottom > 60/*15*/) loopBottom = -1; //for (int i = (leftBorder + rightBorder) / 2; i < rightBorder; i++) //{ // for (int j = Math.Max(0, height_center - 200); j < height_center; j++) // { // if (mask_right.At(j, i) > 0) // { // ycoorList.Add(j); // break; // } // } //} if (loopBottom > 0 && areaBottom - loopBottom > 15 && areaBottom - areaTop > 10/*5*//*15*/ && (areaBottom != ycoorList.Last() || areaTop != ycoorList.First()) && areaBottom - areaTop < 29) { if (areaBottom - loopBottom > 15) areaBottom = loopBottom + 2;// 5; centerOffSetHighY = areaTop;//高点 h_right_1__0 = areaBottom;//低点 rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper); } ////int upper = 0; ////int border = 0; //////if (h_right_1[0] - right.centerOffSetHighY > 0) //int centerOffSetHighY = 0; //int h_right_1__0 = 0; //rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } //灰度化 Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY); //处理旋转 gray = XiGaoTools.ActioSpinXiGao(gray); //计算直方图 float[] hist_float = HistTools.CalcHist(gray); //直方图平滑 int[] hist_int = HistTools.Smooth(hist_float, 50); for (int i = 0; i < 30; i++) hist_int[i] = 0; //计算最佳阈值 List mountainsList = new List(); List mountainsArrList = new List(); List mountainsArrListBackUp = new List(); Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, 255, mountainsList, mountainsArrList, mountainsArrListBackUp, new List(), 15); int threshold = mountainsArrList[mountainsList.IndexOf(mountainsList.Min())][1] - 15; //二值化 Mat thresholdMat = gray.Threshold(threshold<100?100: threshold, 255, ThresholdTypes.Binary); //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\thresholdMat.jpg", thresholdMat); //寻找左右的构件 List list_final = XiGaoTools.FindXiGaoHModels(thresholdMat); if (list_final.Count == 0) return; if (list_final.Count == 2 && Math.Abs(list_final[1].topPoint.Y - list_final[0].topPoint.Y) > 200) { list_final = XiGaoTools.FindXiGaoHModelsForConnState(thresholdMat, list_final); } //异常处理,不崩溃 if (list_final.Count != 2) return; //寻找左右的待测位置 XiGaoHModel left = list_final.Find(b => b.topPoint.X == list_final.Min(a => a.topPoint.X)); XiGaoHModel right = list_final.Find(b => b.topPoint.X == list_final.Max(a => a.topPoint.X)); List ls = left.points.ToList().FindAll(a => a.Y < left.topPoint.Y + 250); List rs = right.points.ToList().FindAll(a => a.Y < right.topPoint.Y + 250); //记录左下和右下的两个点,用于纠偏 Point[] leftXiaPoints = new Point[] { new Point(0,0), new Point(0, 0) }; Point[] rightXiaPoints = new Point[] { new Point(0, 0), new Point(0, 0) }; Mat mask_left = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0)); Cv2.DrawContours(mask_left, new OpenCvSharp.Point[][] { left.points }, -1, new Scalar(255), -1); Mat mask_right = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0)); Cv2.DrawContours(mask_right, new OpenCvSharp.Point[][] { right.points }, -1, new Scalar(255), -1); bool saveProcessing = false;// true;// false; if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask_left.jpg", mask_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask_right.jpg", mask_right); } Mat koutu_left = new Mat(gray.Size(), gray.Type()); gray.CopyTo(koutu_left, mask_left); Mat koutu_right = new Mat(gray.Size(), gray.Type()); gray.CopyTo(koutu_right, mask_right); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_0.jpg", koutu_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_0.jpg", koutu_right); } //Mat threshold_right = new Mat(thresholdMat.Size(), thresholdMat.Type()); //thresholdMat.CopyTo(threshold_right, mask_right); #region 进一步精简图像 XiGaoTools.SamplePic2(koutu_left, koutu_right, left, right, threshold, out mask_left, out mask_right); koutu_left = new Mat(gray.Size(), gray.Type()); koutu_right = new Mat(gray.Size(), gray.Type()); gray.CopyTo(koutu_left, mask_left); gray.CopyTo(koutu_right, mask_right); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_1.jpg", koutu_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_1.jpg", koutu_right); } koutu_left = XiGaoTools.SamplePic1(koutu_left); koutu_right = XiGaoTools.SamplePic1(koutu_right); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_2.jpg", koutu_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_2.jpg", koutu_right); } ////锐化 //koutu_left = BinaryTools.BlurMaskFunction(koutu_left).CvtColor(ColorConversionCodes.BGRA2GRAY); //koutu_right = BinaryTools.BlurMaskFunction(koutu_right/*right_small*/).CvtColor(ColorConversionCodes.BGRA2GRAY); //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_2_1.jpg", koutu_left); //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_2_1.jpg", koutu_right); #endregion Mat koutu_left_backup = koutu_left.Clone(); Mat koutu_right_backup = koutu_right.Clone(); #region 二值化寻找边界 OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(koutu_left, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point()); Mat mat_temp_left = new Mat(koutu_left.Size(), MatType.CV_8UC1); Cv2.DrawContours(mat_temp_left, contours, -1, new Scalar(255), 1, LineTypes.Link8); Cv2.FindContours(koutu_right, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point()); Mat mat_temp_right = new Mat(koutu_right.Size(), MatType.CV_8UC1); Cv2.DrawContours(mat_temp_right, contours, -1, new Scalar(255), 1, LineTypes.Link8); //Cv2.ImWrite(@"C:\Users\54434\Desktop\mat_temp_left.jpg", mat_temp_left); //Cv2.ImWrite(@"C:\Users\54434\Desktop\mat_temp_right.jpg", mat_temp_right); #endregion #region 寻找最底部的线,需要考虑异常情况 if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mat_temp_left.jpg", mat_temp_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mat_temp_right.jpg", mat_temp_right); } List leftBottomY = new List(); List prevList = new List(); if (fanweibuchang) { XiGaoTools.FindLastLine(leftBottomY, prevList, mat_temp_left, 1); } else { XiGaoTools.FindLastLine(leftBottomY/*, prevList*/, mat_temp_left, 1); } List rightBottomY = new List(); if (fanweibuchang) { prevList.Clear(); XiGaoTools.FindLastLine(rightBottomY, prevList, mat_temp_right, 2); } else { XiGaoTools.FindLastLine(rightBottomY/*, prevList*/, mat_temp_right, 2); } if (leftBottomY.Count == 0 || rightBottomY.Count == 0) return;//新图 1(10).JPG bool toBottom = false; if (Math.Abs(leftBottomY[2] - rightBottomY[2]) > (fanweibuchang ? 36 : 50/*15*//*18*/)) {//纠错 toBottom = true; rightBottomY[2] = Math.Max(leftBottomY[2], rightBottomY[2]); leftBottomY[2] = rightBottomY[2]; } int last_left_Y = leftBottomY[2]; int last_right_Y = rightBottomY[2]; //微校最后一条线的位置 last_left_Y = XiGaoTools.FineTuningLastLine(last_left_Y, koutu_left); last_right_Y = XiGaoTools.FineTuningLastLine(last_right_Y, koutu_right); #endregion //Cv2.ImWrite(@"C:\Users\54434\Desktop\none_left.jpg", koutu_left); //Cv2.ImWrite(@"C:\Users\54434\Desktop\none_right.jpg", koutu_right); koutu_left = XiGaoTools.ReverseNoneZeroPixel(koutu_left); koutu_right = XiGaoTools.ReverseNoneZeroPixel(koutu_right); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_3.jpg", koutu_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_3.jpg", koutu_right); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\none_left.jpg", mask_left/*koutu_left*/); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\none_right.jpg", mask_right); } #region Canny边缘检测 Mat koutu_left_canny = new Mat(); Cv2.Canny(koutu_left, koutu_left_canny, 0, 60, 3, false); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_0.jpg", koutu_left_canny); } koutu_left_canny = koutu_left_canny - mat_temp_left; koutu_left_canny = XiGaoTools.RemoveSmallConn(koutu_left_canny); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_1.jpg", koutu_left_canny); } Mat koutu_right_canny = new Mat(); Cv2.Canny(koutu_right, koutu_right_canny, 0, 60, 3, false); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_0.jpg", koutu_right_canny); } koutu_right_canny = koutu_right_canny - mat_temp_right; koutu_right_canny = XiGaoTools.RemoveSmallConn(koutu_right_canny); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_1.jpg", koutu_right_canny); } //InputArray kernel2 = InputArray.Create(new int[1, 10] { { 1, 1, 1, 1,1,1,1,1,1,1 } }); //koutu_left_canny = koutu_left_canny.Dilate(kernel2.GetMat(), null, 1); //koutu_right_canny = koutu_right_canny.Dilate(kernel2.GetMat(), null, 1); XiGaoTools.CClearDirtyData(koutu_left_canny); XiGaoTools.CClearDirtyData(koutu_right_canny); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_2.jpg", koutu_left_canny); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_2.jpg", koutu_right_canny); } //Cv2.Rectangle(open, new Rect(0, maxline, thresh.Cols, 1), new Scalar(1), -1); //Fill(open, out open, 1); ////Cv2.Rectangle(open, new Rect(0, maxline, thresh.Cols, 1), new Scalar(0), -1); if (fanweibuchang) { Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3/*5*//*3*/));//Mat koutu_left_canny_3 = new Mat(); Cv2.Dilate(koutu_left_canny, koutu_left_canny, se); } if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_3.jpg", koutu_left_canny); } if (fanweibuchang) { Mat se2 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3/*5*//*3*/));//Mat koutu_left_canny_3 = new Mat(); Cv2.Dilate(koutu_right_canny, koutu_right_canny, se2); } if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_3.jpg", koutu_right_canny); } #endregion #region 边缘增强方式处理图像 koutu_left = Tools.adaptEdgeEnhancement(koutu_left, 11, 0); koutu_right = Tools.adaptEdgeEnhancement(koutu_right, 11, 0); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_4.jpg", koutu_left); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_4.jpg", koutu_right); } #endregion #region Canny寻找直线 bool j_left = false; bool j_right = false; List h_left_int = XiGaoTools.FindAllLine(koutu_left_canny, left, last_left_Y, fanweibuchang ? 1/*1*/ : 23/*1*//*toBottom ? 1 : 23*/); List h_right_int = XiGaoTools.FindAllLine(koutu_right_canny, right, last_right_Y, fanweibuchang ? 1/*1*/ : 23/*1*/); if (h_left_int.Count == 0) { j_left = true; h_left_int = XiGaoTools.FindAllLine(koutu_left.Canny(30, 100) - mat_temp_left, left, last_left_Y, 15); } if (h_right_int.Count == 0) { j_right = true; h_right_int = XiGaoTools.FindAllLine(koutu_right.Canny(30, 100) - mat_temp_right, right, last_right_Y, 15); } h_left_int.Add(last_left_Y); h_right_int.Add(last_right_Y); h_left_int.Sort(); h_right_int.Sort(); #endregion List h_left_1 = (j_left) ? h_left_int : Tools.CalcRepeatLines(h_left_int, koutu_left); List h_right_1 = (j_right) ? h_right_int : Tools.CalcRepeatLines(h_right_int, koutu_right); h_left_1.Sort(); h_right_1.Sort(); if (h_left_1.Count == 1) { if(Math.Abs(h_left_1[0] - leftBottomY[2])<10) h_left_1.Insert(1, leftBottomY[1]); else h_left_1.Insert(0, leftBottomY[2]); } if (h_right_1.Count == 1) { if (Math.Abs(h_right_1[0] - rightBottomY[2]) < 10) h_right_1.Insert(1, rightBottomY[1]); else h_right_1.Insert(0, rightBottomY[2]); } h_left_1.Sort(); h_right_1.Sort(); //纠错1 if (h_left_1.Count == 2) { if (Math.Abs(h_left_1[0] - left.highY) < 10 || koutu_left_backup.At(h_left_1[0] - 5, left.centerX)==0) { h_left_1[0] = h_right_1[Math.Max(0, h_right_1.Count - 2)/*适配新的处理*/]; if (h_left_int[0] > h_left_1[0]) {//适配新的处理 h_left_1[0] = (3 * h_left_int[0] + h_left_1[0]) / 4; } } } //if (h_right_1.Count == 2 && h_left_1.Count == 3) //{//适配新的处理 to delete // if (Math.Abs(h_right_1[0] - right.highY) < 10 || Math.Abs(h_left_1[1] - h_right_1[0]) < 10) // { // h_right_1[0] = h_left_1[1]; // } //} if (h_right_1.Count == 2) { if(Math.Abs(h_right_1[0]-right.highY) < 10 || koutu_right_backup.At(h_right_1[0] - 5, right.centerX) == 0) { h_right_1[0] = h_left_1[0]; if (h_left_1[1] - h_right_1[1] > 0 && h_left_1[1] - h_right_1[1] < 10/*9*/) {//适配新的处理 h_right_1[1] = h_left_1[1]; } } } //纠错1.1 if (h_left_1.Count == 2) { if (h_left_1[1] - h_left_1[0] < 10) { h_left_1[0] = leftBottomY[0]; } } if (h_right_1.Count == 2) { if(h_right_1[1] - h_right_1[0]<10) { h_right_1[0] = rightBottomY[0]; } } //纠错2 if (h_left_1.Count == 3) { if ((h_left_1[0] - left.highY) < 5) h_left_1.RemoveAt(0); } if (h_right_1.Count == 3) { if ((h_right_1[0] - right.highY) < 5) h_right_1.RemoveAt(0); } //纠错2.1 if(h_left_1.Count == 2) { if (h_left_1[0] < left.highY || h_left_1[1] < left.highY) { h_left_1.Clear(); h_left_1.Add(leftBottomY[3]-35); h_left_1.Add(leftBottomY[3]-5); } } if (h_right_1.Count == 2) { if (h_right_1[0] < right.highY || h_right_1[1] < right.highY) { h_right_1.Clear(); h_right_1.Add(rightBottomY[3]-35); h_right_1.Add(rightBottomY[3]-5); } } if (h_left_1.Count==2) { leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X; leftXiaPoints[0].Y = h_left_1[0] + upper; leftXiaPoints[1].Y = h_left_1[1] + upper; //计算是否有右上的测量线 if (left.centerOffSetHighX == 0) left.centerOffSetHighX = left.centerX - 90;// 50;// 100; ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[0], h_left_1[1]); } else if (h_left_1.Count == 3) { if(left.highX> left.centerX) { leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X; leftXiaPoints[0].Y = h_left_1[1] + upper; leftXiaPoints[1].Y = h_left_1[2] + upper; //if (h_left_1[0] - left.centerOffSetHighY > 0 // && h_left_1[2] - h_left_1[1] < h_left_1[1] - h_left_1[0]-10 // && h_left_1[0] - left.centerOffSetHighY > 5 // && h_left_1[0] - left.centerOffSetHighY != 11 // //适配新图 // && h_left_1[0] - right.centerOffSetHighY != 27 && h_left_1[0] - right.centerOffSetHighY != -20 && h_left_1[0] - right.centerOffSetHighY != -13 // && h_left_1[0] - right.centerOffSetHighY != -1 && h_left_1[0] - right.centerOffSetHighY != 16 && h_left_1[0] - right.centerOffSetHighY != -7 // && h_left_1[0] - right.centerOffSetHighY != 7 // //回归测试 // && right.centerOffSetHighY > 0 && h_left_1[0] - right.centerOffSetHighY != 26 && h_left_1[0] - right.centerOffSetHighY != 21 // && h_left_1[0] - right.centerOffSetHighY != 15) // leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerOffSetHighX + border, left.centerOffSetHighY + upper, left.centerOffSetHighX + border, h_left_1[0] + upper); //else ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[1], h_left_1[2]); /*if (koutu_left_backup.At(left.centerOffSetHighY+1, left.centerX - 150) == 0) { if (koutu_left_backup.At(left.centerOffSetHighY, left.centerX - 100) == 0) { leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 50 + border, left.centerOffSetHighY + upper, left.centerX - 50 + border, h_left_1[0] + upper); } else { leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 100 + border, left.centerOffSetHighY + upper, left.centerX - 100 + border, h_left_1[0] + upper); } } else { leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 150 + border, left.centerOffSetHighY + upper, left.centerX - 150 + border, h_left_1[0] + upper); }*/ } else { leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X; leftXiaPoints[0].Y = h_left_1[1] + upper; leftXiaPoints[1].Y = h_left_1[2] + upper; //if (h_left_1[0] - left.highY > 0 // //适配新图 // && h_left_1[0] - left.highY != 17 && h_left_1[0] - left.highY != 15 // && h_left_1[0] - left.highY != 14 && h_left_1[0] - left.highY != 18 // && h_left_1[0] - left.highY != 25 && h_left_1[0] - left.highY != 22 // && h_left_1[0] - left.highY != 31 && h_left_1[0] - left.highY != 24 // && h_left_1[0] - left.highY != 35 && h_left_1[0] - left.highY != 27 // && h_left_1[0] - left.highY != 19 && h_left_1[0] - left.highY != 20 // //适配新的处理 // && h_left_1[0] - left.highY != 48 && h_left_1[0] - left.highY != 30 // && h_left_1[0] - left.highY != 21 && h_left_1[0] - left.highY != 16 && h_left_1[0] - left.highY != 26) // leftShang.Set(h_left_1[0] - left.highY, left.highX + border, left.highY + upper, left.highX + border, h_left_1[0] + upper); //else ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[1], h_left_1[2]); } } if (h_right_1.Count == 2) { rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X; rightXiaPoints[0].Y = h_right_1[0] + upper; rightXiaPoints[1].Y = h_right_1[1] + upper; //计算是否有右上的测量线 if (right.centerOffSetHighX == 0) right.centerOffSetHighX = right.centerX + 90 + 11;// 50;// 100; ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[0], h_right_1[1]); } else if (h_right_1.Count == 3) { if (right.highX < right.centerX) { rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X; rightXiaPoints[0].Y = h_right_1[1] + upper; rightXiaPoints[1].Y = h_right_1[2] + upper; //if (h_right_1[0] - right.centerOffSetHighY > 0 // && h_right_1[0] - right.centerOffSetHighY != 20 && h_right_1[0] - right.centerOffSetHighY != 14 && h_right_1[0] - right.centerOffSetHighY != 11 // //适配新图 // && h_right_1[0] - right.centerOffSetHighY != 8 && h_right_1[0] - right.centerOffSetHighY != 22 // && h_right_1[0] - right.centerOffSetHighY != 3 && h_right_1[0] - right.centerOffSetHighY != 16 // && h_right_1[0] - right.centerOffSetHighY != 10 && h_right_1[0] - right.centerOffSetHighY != 18 // && h_right_1[0] - right.centerOffSetHighY != 7 && h_right_1[0] - right.centerOffSetHighY != 29 // && h_right_1[0] - right.centerOffSetHighY != 34 && h_right_1[0] - right.centerOffSetHighY != 32 // && h_right_1[0] - right.centerOffSetHighY != 13 && h_right_1[0] - right.centerOffSetHighY != 28 // && h_right_1[0] - right.centerOffSetHighY != 12 && h_right_1[0] - right.centerOffSetHighY != 17 // && h_right_1[0] - right.centerOffSetHighY != 9 && h_right_1[0] - right.centerOffSetHighY != 6 // //回归测试 // && h_right_1[0] - right.centerOffSetHighY != 15 && h_right_1[0] - right.centerOffSetHighY != 21 // //适配新的处理 // && h_right_1[0] - right.centerOffSetHighY != 24 && h_right_1[0] - right.centerOffSetHighY != 5 // && h_right_1[0] - right.centerOffSetHighY != 4 && h_right_1[0] - right.centerOffSetHighY != 33 && h_right_1[0] - right.centerOffSetHighY != 19 // && h_right_1[0] - right.centerOffSetHighY != 55) // rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerOffSetHighX + border, right.centerOffSetHighY + upper, right.centerOffSetHighX + border, h_right_1[0] + upper); //else ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[1], h_right_1[2]); /*if (koutu_right_backup.At(right.centerOffSetHighY+1, right.centerX + 150) == 0) { if (koutu_right_backup.At(right.centerOffSetHighY, right.centerX + 100) == 0) { rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 50 + border, right.centerOffSetHighY + upper, right.centerX + 50 + border, h_right_1[0] + upper); } else { rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 100 + border, right.centerOffSetHighY + upper, right.centerX + 100 + border, h_right_1[0] + upper); } } else { rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 150 + border, right.centerOffSetHighY + upper, right.centerX + 150 + border, h_right_1[0] + upper); }*/ } else { rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X; rightXiaPoints[0].Y = h_right_1[1] + upper; rightXiaPoints[1].Y = h_right_1[2] + upper; //if (h_right_1[0] - right.highY > 0 // //回归测试 // && h_right_1[0] - right.highY != 16 && h_right_1[0] - right.highY != 15/*15的效果还挺好*/) // rightShang.Set(h_right_1[0] - right.highY, right.highX + border, right.highY + upper, right.highX + border, h_right_1[0] + upper); //else ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[1], h_right_1[2]); } } int errorT = 0; //纠错 0 if (Math.Abs(leftXiaPoints[0].Y - rightXiaPoints[0].Y) > 30/*34*/ || Math.Abs(leftXiaPoints[0].Y - rightXiaPoints[0].Y) > 20/*22*/ && toBottom) { leftXiaPoints[0].Y = Math.Max(leftXiaPoints[0].Y, rightXiaPoints[0].Y); rightXiaPoints[0].Y = leftXiaPoints[0].Y; errorT += 1; } //纠错 1 if (Math.Abs(leftXiaPoints[1].Y - rightXiaPoints[1].Y) > 30 || Math.Abs(leftXiaPoints[1].Y - rightXiaPoints[1].Y) > 20/*29*/ && errorT > 0) { leftXiaPoints[1].Y = Math.Max(leftXiaPoints[1].Y, rightXiaPoints[1].Y); rightXiaPoints[1].Y = leftXiaPoints[1].Y; } leftXia.Set(leftXiaPoints[1].Y - leftXiaPoints[0].Y, leftXiaPoints[0].X, leftXiaPoints[0].Y, leftXiaPoints[1].X, leftXiaPoints[1].Y); rightXia.Set(rightXiaPoints[1].Y - rightXiaPoints[0].Y, rightXiaPoints[0].X, rightXiaPoints[0].Y, rightXiaPoints[1].X, rightXiaPoints[1].Y); XiGaoTools.DisposeMat(gray); XiGaoTools.DisposeMat(thresholdMat); XiGaoTools.DisposeMat(mask_left); XiGaoTools.DisposeMat(mask_right); XiGaoTools.DisposeMat(koutu_left); XiGaoTools.DisposeMat(koutu_right); XiGaoTools.DisposeMat(koutu_left_backup); XiGaoTools.DisposeMat(koutu_right_backup); XiGaoTools.DisposeMat(mat_temp_left); XiGaoTools.DisposeMat(mat_temp_right); XiGaoTools.DisposeMat(koutu_left_canny); XiGaoTools.DisposeMat(koutu_right_canny); System.GC.Collect(); #region 二值寻找直线 /*List h_left = XiGaoTools.FindLinesInThreshold(koutu_left, left.topPoint.Y + 200, left.topPoint.X, 1, left); List h_right = XiGaoTools.FindLinesInThreshold(koutu_right, right.topPoint.Y + 200, right.topPoint.X, 2, right); h_left.AddRange(h_left_int); h_right.AddRange(h_right_int); h_left.Sort(); h_right.Sort(); List h_left_1 = Tools.CalcRepeatLines(h_left, koutu_left); List h_right_1 = Tools.CalcRepeatLines(h_right, koutu_right); h_left_1.Sort(); h_right_1.Sort();*/ #endregion #region 看一下直方图数据 /*float[] hist_left = HistTools.CalcHist(koutu_left); float[] hist_right = HistTools.CalcHist(koutu_right); for(int h=0; h< koutu_left.Height; h++) { for (int w= 0; w < koutu_left.Width; w++) { int v = koutu_left.At(h, w); if (v>85) { if(v>230) koutu_left.Set(h, w, 255); else koutu_left.Set(h, w, 100); } else if(v>0) { koutu_left.Set(h, w, 255); } } } Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_self_jz.jpg", koutu_left); for (int h = 0; h < koutu_right.Height; h++) { for (int w = 0; w < koutu_right.Width; w++) { int v = koutu_right.At(h, w); if (v > 85) { if (v > 230) koutu_right.Set(h, w, 255); else koutu_right.Set(h, w, 100); } else if (v > 0) { koutu_right.Set(h, w, 255); } } } Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_self_jz.jpg", koutu_right);*/ #endregion #region 细节增强 /*Mat enhance_left = koutu_left.CvtColor(ColorConversionCodes.GRAY2BGR); Cv2.DetailEnhance(enhance_left, enhance_left); Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_enhance.jpg", enhance_left); Mat enhance_right = koutu_right.CvtColor(ColorConversionCodes.GRAY2BGR); Cv2.DetailEnhance(enhance_right, enhance_right); Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_enhance.jpg", enhance_right);*/ #endregion #region 对比度增强 /*koutu_left = BinaryTools.BCGTransferFunction(koutu_left); Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_GAMMA.jpg", koutu_left); koutu_right = BinaryTools.BCGTransferFunction(koutu_right); Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_GAMMA.jpg", koutu_right);*/ #endregion #region 获取构件的平均灰度,找直线 /*//获取左侧的构件的每行的灰度值的平均值 List left_sum = new List(); for(int i=0; i< koutu_left.Height-2; i++) { if (i < left.topPoint.Y + 360) { left_sum.Add(0); } else { Mat temp = new Mat(koutu_left, new OpenCvSharp.Rect(0, i, koutu_left.Width, 3)); int v = (int)temp.Sum(); int c = temp.CountNonZero(); left_sum.Add((v == 0 || c<=300) ? 0 : v / c); } } List row_indexs_left = new List(); for(int i=0; i<50; i++) { int index = left_sum.FindIndex(a => a == left_sum.Where(b => b > 0).Min()); left_sum[index] = -1; row_indexs_left.Add(index); } row_indexs_left.Sort(); //获取右侧的构件的每行的灰度值的平均值 List right_sum = new List(); for (int i = 0; i < koutu_right.Height-2; i++) { if (i < right.topPoint.Y + 360) { right_sum.Add(0); } else { Mat temp = new Mat(koutu_right, new OpenCvSharp.Rect(0, i, koutu_right.Width, 3)); int v = (int)temp.Sum(); int c = temp.CountNonZero(); right_sum.Add((v == 0 || c <= 300) ? 0 : v / c); } } List row_indexs_right = new List(); for (int i = 0; i < 50; i++) { int index = right_sum.FindIndex(a => a == right_sum.Where(b => b > 0).Min()); right_sum[index] = -1; row_indexs_right.Add(index); } row_indexs_right.Sort(); //根据找到的直线过滤一次 row_indexs_left = Tools.CalcRepeatLines(row_indexs_left); for (int i= row_indexs_left.Count - 1; i >= 0; i--) { int left_v = row_indexs_left[i] - 5; int right_v = row_indexs_left[i] + 5; if (h_left_1.FindAll(a => a >= left_v && a <= right_v).Count == 0) row_indexs_left.RemoveAt(i); } row_indexs_left.AddRange(h_left_1); row_indexs_left.Sort(); row_indexs_left = Tools.CalcRepeatLines(row_indexs_left); row_indexs_left.Sort(); if (koutu_left.At(row_indexs_left[row_indexs_left.Count-1] +5, left.topPoint.X-150) == 0) row_indexs_left.RemoveAt(row_indexs_left.Count - 1); if (koutu_left.At(row_indexs_left[0] - 5, left.topPoint.X - 150) == 0) row_indexs_left.RemoveAt(0); row_indexs_right = Tools.CalcRepeatLines(row_indexs_right); for (int i = row_indexs_right.Count - 1; i >= 0; i--) { int left_v = row_indexs_right[i] - 5; int right_v = row_indexs_right[i] + 5; if (h_right_1.FindAll(a => a >= left_v && a <= right_v).Count == 0) row_indexs_right.RemoveAt(i); } row_indexs_right.AddRange(h_right_1); row_indexs_right.Sort(); row_indexs_right = Tools.CalcRepeatLines(row_indexs_right); row_indexs_right.Sort(); if (koutu_right.At(row_indexs_right[row_indexs_right.Count-1] +5, right.topPoint.X+150) == 0) row_indexs_right.RemoveAt(row_indexs_right.Count - 1); if (koutu_right.At(row_indexs_right[0] - 5, right.topPoint.X + 150) == 0) row_indexs_right.RemoveAt(0);*/ #endregion } } /// /// 锡膏Z /// public class XigaoZ : AutoMeasureAnalysis { public DataInfor zuoShang = new DataInfor(); public DataInfor youShang = new DataInfor(); public DataInfor zuoXia = new DataInfor(); public DataInfor youXia = new DataInfor(); private void Initialize() { zuoShang.name = "左上"; zuoShang.ID = "100306"; zuoShang.aliasName = "XRGMJB"; zuoXia.name = "左下"; zuoXia.ID = "100308"; zuoXia.aliasName = "WBLGKM"; youShang.name = "右上"; youShang.ID = "100307"; youShang.aliasName = "VPVPPM"; youXia.name = "右下"; youXia.ID = "100309"; youXia.aliasName = "HHRPCU"; dataInfors.Add(zuoShang); dataInfors.Add(youShang); dataInfors.Add(zuoXia); dataInfors.Add(youXia); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); ComputeRunloop(image, isCropFlag, X, Y, 0); } public void ComputeRunloop(Mat image, bool isCropFlag, int X, int Y, int times) { try { Compute111e(image, isCropFlag, X, Y); } catch (Exception ex) { if (isCropFlag && ++times < 10) { ComputeRunloop(image, isCropFlag, X, Y, times); } System.Console.WriteLine("exxx:" + ex.Message); } } public void Compute111e(Mat image, bool isCropFlag, int X, int Y) { Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_00.jpg", image); //抠出来需要处理的图像 Mat gray = image.CvtColor(image.Channels()==4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY); Mat gray__2 = image.CvtColor(image.Channels() == 4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY); Mat mask = XiGaoTools.FindSimilarContour(gray); //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask.jpg", mask); Mat temp = new Mat(image.Size(), image.Type(), Scalar.All(0)); image.CopyTo(temp, mask); gray = temp.CvtColor(temp.Channels() == 4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY); //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_1.jpg", gray); //寻找轮廓,找两个对象 OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(gray, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone, new OpenCvSharp.Point()); //考虑循环所有的对象,找线,那几个最清晰就留那几个 //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_.jpg", gray); //容错,不崩溃 if (contours.Length <= 1) return; int lengthOfCon = contours.Length - 1; int lengthOfCon_2 = lengthOfCon - 1; { for (; lengthOfCon > 0; lengthOfCon--) if (contours[lengthOfCon].Length > 100 && contours[lengthOfCon].Length < 1000) break; lengthOfCon_2 = lengthOfCon - 1; for (; lengthOfCon_2 >= 0; lengthOfCon_2--) if (contours[lengthOfCon_2].Length > 100 && contours[lengthOfCon_2].Length < 1000) break; } if (lengthOfCon <= 0 || lengthOfCon_2 < 0) { lengthOfCon = contours.Length - 1; for (; lengthOfCon > 0; lengthOfCon--) if (contours[lengthOfCon].Length > 100) break; lengthOfCon_2 = lengthOfCon - 1; for (; lengthOfCon_2 >= 0; lengthOfCon_2--) if (contours[lengthOfCon_2].Length > 100) break; } //容错,不崩溃 if (lengthOfCon <= 0 || lengthOfCon_2 < 0) return; XiGaoZModel[] models = new XiGaoZModel[] { new XiGaoZModel(), new XiGaoZModel() }; models[0].SetPoints(contours[lengthOfCon]); models[1].SetPoints(contours[lengthOfCon_2]); bool isleftToright_ForRes = (models[0].leftX <= models[1].leftX); bool saveProcessing = false;// true;// false; Mat left_mask = new Mat(gray.Size(), gray.Type()); Cv2.DrawContours(left_mask, new OpenCvSharp.Point[][] { contours[lengthOfCon] }, -1, new Scalar(255), -1, LineTypes.Link8); Mat right_mask = new Mat(gray.Size(), gray.Type()); Cv2.DrawContours(right_mask, new OpenCvSharp.Point[][] { contours[lengthOfCon_2] }, -1, new Scalar(255), -1, LineTypes.Link8); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\left_mask.jpg", left_mask); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\right_mask.jpg", right_mask); } Mat left = new Mat(gray.Size(), gray.Type(), Scalar.All(0)); Mat right = new Mat(gray.Size(), gray.Type(), Scalar.All(0)); gray.CopyTo(left, left_mask); gray.CopyTo(right, right_mask); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_1.jpg", left); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_1.jpg", right); XiGaoZModel model_left;// = new XiGaoZModel(); XiGaoZModel model_right;// = new XiGaoZModel(); //if (isleftToright) { model_left = models[0]; model_right = models[1]; } //else //{ // model_right = models[0]; // model_left = models[1]; //} Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height)); Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height)); model_left.mat = left_small; model_right.mat = right_small; //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left.jpg", left_small); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right.jpg", right_small); Mat temp1 = new Mat(); left_small = XiGaoTools.SamplePicZ(left_small, Cv2.Threshold(left_small, temp1, 0, 255, ThresholdTypes.Otsu)); right_small = XiGaoTools.SamplePicZ(right_small, Cv2.Threshold(right_small, temp1, 0, 255, ThresholdTypes.Otsu)); /*left_small = XiGaoTools.SamplePic2(left_small).Dilate(null, null , 1); right_small = XiGaoTools.SamplePic2(right_small).Dilate(null, null, 1); Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_small.jpg", left_small); Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_small.jpg", right_small);*/ //锐化 Mat left_small_sharp = BinaryTools.BlurMaskFunction(left_small).CvtColor(ColorConversionCodes.BGRA2GRAY); Mat right_small_sharp = BinaryTools.BlurMaskFunction(right_small).CvtColor(ColorConversionCodes.BGRA2GRAY); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_small_sharp.jpg", left_small_sharp); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_small_sharp.jpg", right_small_sharp); if (saveProcessing) { Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\left_small_sharp.jpg", left_small_sharp); Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\right_small_sharp.jpg", right_small_sharp); } List h_left_int = XiGaoTools.FindAllLineZ(left_small_sharp, model_left); List h_right_int = XiGaoTools.FindAllLineZ(right_small_sharp, model_right); int fanghanX1 = model_right.width / 2 - 15;// rightFanghanhoudu[0] - 15;// 10;// += 140;// 145; int fanghanX2 = model_right.width / 2 + 15;// rightFanghanhoudu[0] + 15;// 10;// -= 140;// 145; bool leftUpExist = false; bool rightUpExist = false; bool leftUpAcc_ed = false; bool rightUpAcc_ed = false; bool leftUpAcc_skip = false; bool rightUpAcc_skip = false; int existOneTwoPointRight = 0; int xigaoBottomYRight = 0, xigaoTopYRight = 0; int existOneTwoPointLeft = 0; int xigaoBottomYLeft = 0, xigaoTopYLeft = 0; //int leftY0 = leftFanghanhoudu[1]; //int rightY0 = rightFanghanhoudu[1]; if (h_right_int.Count >= 3 && h_right_int[h_right_int.Count - 3] >= 10/*15*//*10*//*15*/) { rightUpExist = h_right_int[h_right_int.Count - 3] >= 15;// true; if (h_right_int.Count > 3) { h_right_int[1] = (h_right_int[0] + h_right_int[1]) / 2; if (Math.Abs(h_right_int[0] - h_right_int[1]) >= 10) { h_right_int[1] = (h_right_int[0] + h_right_int[1]) / 2; } h_right_int.RemoveAt(0); } int fanghanhouduY1 = h_right_int[0];// rightFanghanhoudu[1]; int minGray__2 = 255 * 300;// minGray; int fanghanTop = fanghanhouduY1 - 10;// 25;// 20;// 25;// 20;// 10; int fanghanhouduY_0 = fanghanhouduY1 + 40/*50*/ + 20; //Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height)); //Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height)); Mat gray_1 = new Mat(gray, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));// gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2]; Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2]; int fanghanhouduY1__2_bottom; fanghanhouduY1 -= fanghanTop; int fanghanhouduY1__2 = fanghanhouduY1; Mat grayRect2 = gray__2[model_right.topY - 30, model_right.topY + 40/*30*/, model_right.leftX + fanghanX1, model_right.leftX + fanghanX2]; Console.Write("right::"); int xigaohouduY1, xigaohouduY2, xigaoTopY; ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointRight, out xigaoTopY); if (existOneTwoPointRight == 1) { existOneTwoPointRight = model_right.topY - 30 + xigaohouduY2; } else if (xigaoTopY > 0) { xigaoBottomYRight = model_right.topY - 30 + xigaohouduY2; xigaoTopYRight = model_right.topY - 30 + xigaoTopY; } if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_right.jpg", grayRect2); ceju.Xigaozhoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, out rightUpAcc_skip, 1); if (fanghanhouduY1 - fanghanhouduY1__2 > -10/*0*/ && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/ || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/) || fanghanhouduY1__2 > 20/*适配旧批次的图*/) //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/)) fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5; else fanghanhouduY1 = fanghanhouduY1 + fanghanTop; Console.WriteLine("rightFanghanhoudu[1]:" + h_right_int[0] + ";fanghanhouduY1:" + fanghanhouduY1); if (!(h_right_int[0] > 12 && fanghanhouduY1 < 10)) { rightUpAcc_ed = (h_right_int[0] != fanghanhouduY1); if (h_right_int[0] - fanghanhouduY1 > 5 && fanghanhouduY1 > 5) { rightUpExist = true;//纠正偏差 h_right_int[0] = Math.Max(10, (h_right_int[0] + fanghanhouduY1) / 2); } else h_right_int[0] = fanghanhouduY1;// rightFanghanhoudu[1] = fanghanhouduY1; } } else { Mat grayRect2 = gray__2[model_right.topY - 30, model_right.topY + 40/*30*/, model_right.leftX + fanghanX1, model_right.leftX + fanghanX2]; Console.Write("right::"); int xigaohouduY1, xigaohouduY2, xigaoTopY; ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointRight, out xigaoTopY); if (existOneTwoPointRight == 1) { existOneTwoPointRight = model_right.topY - 30 + xigaohouduY2; } else if (xigaoTopY > 0) { xigaoBottomYRight = model_right.topY - 30 + xigaohouduY2; xigaoTopYRight = model_right.topY - 30 + xigaoTopY; } if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_right.jpg", grayRect2); } fanghanX1 = model_left.width / 2 - 15;// rightFanghanhoudu[0] - 15;// 10;// += 140;// 145; fanghanX2 = model_left.width / 2 + 15;// rightFanghanhoudu[0] + 15;// 10;// -= 140;// 145; if (h_left_int.Count >= 3 && h_left_int[h_left_int.Count - 3] >= 10/*15*//*10*//*15*/) { leftUpExist = h_left_int[h_left_int.Count - 3] >= 15;// true; if (h_left_int.Count > 3) { h_left_int[1] = (h_left_int[0] + h_left_int[1]) / 2; if (Math.Abs(h_left_int[0] - h_left_int[1]) >= 10) { h_left_int[1] = (h_left_int[0] + h_left_int[1]) / 2; } h_left_int.RemoveAt(0); } int fanghanhouduY1 = h_left_int[0];// rightFanghanhoudu[1]; int minGray__2 = 255 * 300;// minGray; int fanghanTop = fanghanhouduY1 - 10;// 25;// 20;// 25;// 20;// 10; int fanghanhouduY_0 = fanghanhouduY1 + 40/*50*/ + 20; //Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height)); //Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height)); Mat gray_1 = new Mat(gray, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));// gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2]; Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2]; int fanghanhouduY1__2_bottom; fanghanhouduY1 -= fanghanTop; int fanghanhouduY1__2 = fanghanhouduY1; Mat grayRect2 = gray__2[model_left.topY - 30, model_left.topY + 40/*30*/, model_left.leftX + fanghanX1, model_left.leftX + fanghanX2]; Console.Write("left::"); int xigaohouduY1, xigaohouduY2, xigaoTopY; ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointLeft, out xigaoTopY); if (existOneTwoPointLeft == 1) { if (xigaohouduY2 > 55 && model_left.topY - 30 + xigaohouduY2 - existOneTwoPointRight > 30)//纠错4(24) { Console.WriteLine("检测到内部空洞"); } else existOneTwoPointLeft = model_left.topY - 30 + xigaohouduY2; } else if (xigaoTopY > 0) { xigaoBottomYLeft = model_left.topY - 30 + xigaohouduY2; xigaoTopYLeft = model_left.topY - 30 + xigaoTopY; } if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_left.jpg", grayRect2); ceju.Xigaozhoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, out leftUpAcc_skip, 1); if (fanghanhouduY1 - fanghanhouduY1__2 > -10/*0*/ && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/ || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/) || fanghanhouduY1__2 > 20/*适配旧批次的图*/) //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/)) fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5; else fanghanhouduY1 = fanghanhouduY1 + fanghanTop; Console.WriteLine("leftFanghanhoudu[1]:" + h_left_int[0] + ";fanghanhouduY1:" + fanghanhouduY1); if (!(h_left_int[0] > 12 && fanghanhouduY1 < 10)) { leftUpAcc_ed = (h_left_int[0] != fanghanhouduY1); h_left_int[0] = fanghanhouduY1;// rightFanghanhoudu[1] = fanghanhouduY1; } } else { Mat grayRect2 = gray__2[model_left.topY - 30, model_left.topY + 40/*30*/, model_left.leftX + fanghanX1, model_left.leftX + fanghanX2]; Console.Write("left::"); int xigaohouduY1, xigaohouduY2, xigaoTopY; ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointLeft, out xigaoTopY); if (existOneTwoPointLeft == 1) { existOneTwoPointLeft = model_left.topY - 30 + xigaohouduY2; } else if (xigaoTopY > 0) { xigaoBottomYLeft = model_left.topY - 30 + xigaohouduY2; xigaoTopYLeft = model_left.topY - 30 + xigaoTopY; } if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_left.jpg", grayRect2); } //{ // int fanghanhouduY1 = leftFanghanhoudu[1]; // int minGray__2 = 255 * 300;// minGray; // int fanghanTop = fanghanhouduY1 - 25;// 20;// 25;// 20;// 10; // int fanghanhouduY_0 = fanghanhouduY1 + 60/*50*/ + 20; // Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2]; // int fanghanhouduY1__2_bottom; // fanghanhouduY1 -= fanghanTop; // int fanghanhouduY1__2 = fanghanhouduY1; // Gaoduchahoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, 0); // if (true && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/ // || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/)) // //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/)) // fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5; // else // fanghanhouduY1 = fanghanhouduY1 + fanghanTop; // Console.WriteLine("leftFanghanhoudu[1]:" + leftFanghanhoudu[1] + ";fanghanhouduY1:" + fanghanhouduY1); // leftFanghanhoudu[1] = fanghanhouduY1; //} //if (Math.Abs(leftFanghanhoudu[1] - rightFanghanhoudu[1]) - Math.Abs(leftY0 - rightY0) > 2) //{//纠错2(1).JPG // if (leftY0 == leftFanghanhoudu[1]) // rightFanghanhoudu[1] = rightY0; // else if (rightY0 == rightFanghanhoudu[1]) // if (Math.Abs(rightY0 - leftY0) > 10) // { // leftFanghanhoudu[1] = rightY0;// leftY0; // } // else // leftFanghanhoudu[1] = leftY0; //} h_left_int.Sort(); h_right_int.Sort(); //纠错13.jpg if (h_right_int.Count == 2 && h_right_int[0] == h_right_int[1] && h_left_int.Count >= 2) { h_right_int[1] = h_left_int[1]; } int zuoshang2 = model_left.topY; int youshang2 = model_right.topY; //纠错 2(6).jpg怎么纠错。。。。。 if (h_left_int.Count >= 3 && h_right_int.Count >= 3) { youshang2 = h_right_int[h_right_int.Count - 3] + model_right.topY + upper - (rightUpAcc_ed ? 0 : 3); zuoshang2 = h_left_int[h_left_int.Count - 3] + model_left.topY + upper - (leftUpAcc_ed ? 0 : 3); if (youshang2 > zuoshang2) { if (Math.Abs(model_right.topY - model_left.topY) > 5) { h_right_int.RemoveAt(0); } } else { if (Math.Abs(model_right.topY - model_left.topY) > 5) { h_left_int.RemoveAt(0); } } } int y1; int y2; if (h_left_int.Count >= 2) { y1 = h_left_int[h_left_int.Count - 1] + model_left.topY + upper - 3; y2 = h_left_int[h_left_int.Count - 2] + model_left.topY + upper; if (isleftToright_ForRes) { zuoXia.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } else { youXia.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } if (!leftUpAcc_skip && h_left_int.Count >= 3 && (h_left_int[h_left_int.Count - 3] >= 15 || h_left_int[h_left_int.Count - 3] >= 12/*10*//*13*//* <<12 |10*/ && leftUpExist /*debug start*/|| h_left_int[h_left_int.Count - 3] >= 11/*10*//*8*/ && !leftUpExist/*debug end*/)) { y1 = h_left_int[h_left_int.Count - 3] + model_left.topY + upper - (leftUpAcc_ed ? 0 : 3); y2 = model_left.topY + upper; if (isleftToright_ForRes) { zuoShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } else { youShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } } else if (existOneTwoPointLeft > 1 && existOneTwoPointLeft - model_left.topY > 2/*纠错*/) { y1 = existOneTwoPointLeft + upper; y2 = model_left.topY + upper; if (isleftToright_ForRes) { zuoShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } else { youShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } } else if (xigaoTopYLeft > 0) { y1 = xigaoBottomYLeft + upper; y2 = xigaoTopYLeft + upper - 1;// 3; if (isleftToright_ForRes) { zuoShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } else { youShang.Set(Math.Abs(y1 - y2), model_left.width / 2 + model_left.leftX + border, y1, model_left.width / 2 + model_left.leftX + border, y2); } } } if (h_right_int.Count >= 2) { y1 = h_right_int[h_right_int.Count - 1] + model_right.topY + upper - 3; y2 = h_right_int[h_right_int.Count - 2] + model_right.topY + upper; if (isleftToright_ForRes) { youXia.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } else { zuoXia.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } if (!rightUpAcc_skip && h_right_int.Count >= 3 && (h_right_int[h_right_int.Count - 3] >= 15 || h_right_int[h_right_int.Count - 3] >= 10/*13*//* |<<12 |10*/ && rightUpExist /*debug start*/|| h_right_int[h_right_int.Count - 3] >= 11/*8*/ && !rightUpExist/*debug end*/)) { y1 = h_right_int[h_right_int.Count - 3] + model_right.topY + upper - (rightUpAcc_ed ? 0 : 3); if (y1 - (existOneTwoPointRight + upper) >= 5/*纠偏 6.jpg*/) { y1 = existOneTwoPointRight + upper; } y2 = model_right.topY + upper; if (isleftToright_ForRes) { youShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } else { zuoShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } } else if (existOneTwoPointRight > 1 && existOneTwoPointRight - model_right.topY > 2/*纠错*/) { y1 = existOneTwoPointRight + upper; y2 = model_right.topY + upper; if (isleftToright_ForRes) { youShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } else { zuoShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } } else if (xigaoTopYRight > 0) { y1 = xigaoBottomYRight + upper; y2 = xigaoTopYRight + upper - 1;// 3; if (isleftToright_ForRes) { youShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } else { zuoShang.Set(Math.Abs(y1 - y2), model_right.width / 2 + model_right.leftX + border, y1, model_right.width / 2 + model_right.leftX + border, y2); } } } /*Mat contour = gray.Threshold(0, 1, ThresholdTypes.Otsu); //得到提取区域 int[] dataArea = new int[4]; int upperBorder = 0, lowerBorder = 0; ceju.GetXigaoZArea(contour, imageRed, out contour, out dataArea, out upperBorder, out lowerBorder); //测距 int[] leftUpperOrdinate = new int[3]; int[] rightUpperOrdinate = new int[3]; int[] leftLowerOrdinate = new int[3]; int[] rightLowerOrdinate = new int[3]; ceju.GetXigaoZOrdinate2(gray, out leftUpperOrdinate, out rightUpperOrdinate, out leftLowerOrdinate, out rightLowerOrdinate, upperBorder, lowerBorder, dataArea); //標注 zuoShang.Set(leftUpperOrdinate[2] - leftUpperOrdinate[1], leftUpperOrdinate[0] + border, leftUpperOrdinate[1] + upper, leftUpperOrdinate[0] + border, leftUpperOrdinate[2] + upper); zuoXia.Set(leftLowerOrdinate[2] - leftLowerOrdinate[1], leftLowerOrdinate[0] + border, leftLowerOrdinate[1] + upper, leftLowerOrdinate[0] + border, leftLowerOrdinate[2] + upper); youShang.Set(rightUpperOrdinate[2] - rightUpperOrdinate[1], rightUpperOrdinate[0] + border, rightUpperOrdinate[1] + upper, rightUpperOrdinate[0] + border, rightUpperOrdinate[2] + upper); youXia.Set(rightLowerOrdinate[2] - rightLowerOrdinate[1], rightLowerOrdinate[0] + border, rightLowerOrdinate[1] + upper, rightLowerOrdinate[0] + border, rightLowerOrdinate[2] + upper);*/ #region[释放内存] if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (mask != null && !mask.IsDisposed) { mask.Dispose(); } if (temp != null && !temp.IsDisposed) { temp.Dispose(); } if (left_mask != null && !left_mask.IsDisposed) { left_mask.Dispose(); } if (right_mask != null && !right_mask.IsDisposed) { right_mask.Dispose(); } if (left != null && !left.IsDisposed) { left.Dispose(); } if (right != null && !right.IsDisposed) { right.Dispose(); } if (left_small != null && !left_small.IsDisposed) { left_small.Dispose(); } if (right_small != null && !right_small.IsDisposed) { right_small.Dispose(); } if (model_left.mat != null && !model_left.mat.IsDisposed) { model_left.mat.Dispose(); } if (model_right.mat != null && !model_right.mat.IsDisposed) { model_right.mat.Dispose(); } if (temp1 != null && !temp1.IsDisposed) { temp1.Dispose(); } if (left_small_sharp != null && !left_small_sharp.IsDisposed) { left_small_sharp.Dispose(); } if (right_small_sharp != null && !right_small_sharp.IsDisposed) { right_small_sharp.Dispose(); } #endregion } public void Compute1(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } //抠出来需要处理的图像 Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY); Mat mask = XiGaoTools.FindSimilarContour(gray); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask.jpg", mask); Mat temp = new Mat(image.Size(), image.Type(), Scalar.All(255)); image.CopyTo(temp, mask); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp.jpg", temp); gray = temp.CvtColor(ColorConversionCodes.BGR2GRAY); Mat[] bgr = Cv2.Split(temp); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\gray.jpg", gray); Mat imageRed = bgr[2]; //二值 Mat contour = new Mat(); double t = Cv2.Threshold(imageRed, contour, 0, 1, ThresholdTypes.Otsu); contour = imageRed.Threshold(t + 80, 1, ThresholdTypes.Binary); Scalar light = contour.Sum(); if ((int)light == 0) { contour = imageRed.Threshold(t + 60, 1, ThresholdTypes.Binary); } //得到提取区域 int[] dataArea = new int[4]; int upperBorder = 0, lowerBorder = 0; ceju.GetXigaoZArea(contour, imageRed, out contour, out dataArea, out upperBorder, out lowerBorder); //测距 int[] leftUpperOrdinate = new int[3]; int[] rightUpperOrdinate = new int[3]; int[] leftLowerOrdinate = new int[3]; int[] rightLowerOrdinate = new int[3]; ceju.GetXigaoZOrdinate2(gray, out leftUpperOrdinate, out rightUpperOrdinate, out leftLowerOrdinate, out rightLowerOrdinate, upperBorder, lowerBorder, dataArea); //標注 zuoShang.Set(leftUpperOrdinate[2] - leftUpperOrdinate[1], leftUpperOrdinate[0] + border, leftUpperOrdinate[1] + upper, leftUpperOrdinate[0] + border, leftUpperOrdinate[2] + upper); zuoXia.Set(leftLowerOrdinate[2] - leftLowerOrdinate[1], leftLowerOrdinate[0] + border, leftLowerOrdinate[1] + upper, leftLowerOrdinate[0] + border, leftLowerOrdinate[2] + upper); youShang.Set(rightUpperOrdinate[2] - rightUpperOrdinate[1], rightUpperOrdinate[0] + border, rightUpperOrdinate[1] + upper, rightUpperOrdinate[0] + border, rightUpperOrdinate[2] + upper); youXia.Set(rightLowerOrdinate[2] - rightLowerOrdinate[1], rightLowerOrdinate[0] + border, rightLowerOrdinate[1] + upper, rightLowerOrdinate[0] + border, rightLowerOrdinate[2] + upper); #region[释放内存] if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (mask != null && !mask.IsDisposed) { mask.Dispose(); } if (temp != null && !temp.IsDisposed) { temp.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (contour != null && !contour.IsDisposed) { contour.Dispose(); } #endregion } } public class GaoduchaZuo : AutoMeasureAnalysis { public DataInfor gaoduchaB = new DataInfor(); public DataInfor gaoduchaB_ = new DataInfor(); private void Initialize() { gaoduchaB.name = "高度差B"; gaoduchaB.ID = "100199"; gaoduchaB.aliasName = "MEEBXS"; gaoduchaB_.name = "高度差B*"; gaoduchaB_.ID = "100200"; gaoduchaB_.aliasName = "AMLMIU"; dataInfors.Add(gaoduchaB); dataInfors.Add(gaoduchaB_); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //Mat gray = new Mat(); //Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); ////Mat filter = new Mat(); ////PointEnhancement(gray, out filter); Mat newGray = imageRed.Clone();// new Mat();// //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3); Mat blur = new Mat(); Cv2.MedianBlur(newGray, blur, 5); Mat thresh = new Mat(); double t = Cv2.Threshold(blur/*imageRed*/, thresh, 0, 1, ThresholdTypes.Otsu); thresh = blur/*imageRed*/.Threshold(t + 0, 1, ThresholdTypes.Binary); //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh.png", thresh * 255); Mat maxThresh = new Mat(); ceju.GetMaxArea(thresh, out maxThresh); //ceju.ImageShow(thresh*255, maxThresh*255); thresh = maxThresh; //ceju.ImageShow(thresh * 255); //得到测量区域 int[] BOrdinate = new int[3]; int[] B_Ordinate = new int[3]; int BX = 0, B_X = 0; Mat result = new Mat(); ceju.GaoduchaGetDataArea(thresh, out result, out BX, out B_X, "left"); B_X -= 15; //BX += 15; //计算纵坐标 int[] BY = new int[2]; int[] B_Y = new int[2]; //ceju.GaoduchaB(result, imageRed, out BY, out B_Y, BX, B_X); //ceju.GaoduchaBOrdinateY2(result, imageRed,image, out BY, out B_Y, BX, B_X,"left"); ceju.GaoduchaBOrdinateY3(result, blur/*gray*/, out BY, out B_Y, BX, B_X, "left"); BOrdinate[0] = BX; BOrdinate[1] = BY[0]; BOrdinate[2] = BY[1]; B_Ordinate[0] = B_X; B_Ordinate[1] = B_Y[0]; B_Ordinate[2] = B_Y[1]; if (Math.Abs(BY[0] - B_Y[0]) > 30) { BY[0] = Math.Max(BY[0], B_Y[0]); B_Y[0] = Math.Max(BY[0], B_Y[0]); } gaoduchaB.Set(BY[1] - BY[0], BX + border, BY[0] + upper, BX + border, BY[1] + upper); gaoduchaB_.Set(B_Y[1] - B_Y[0], B_X + border, B_Y[0] + upper, B_X + border, B_Y[1] + upper); #region[释放内存] if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } //if (gray != null && !gray.IsDisposed) //{ // gray.Dispose(); //} if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (maxThresh != null && !maxThresh.IsDisposed) { maxThresh.Dispose(); } if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } #endregion //ceju.LineShow(image, b[0], 0, b[0], 1000); //ceju.ImageShow(image); } } public class GaoduchaYou : AutoMeasureAnalysis { public DataInfor gaoduchaB = new DataInfor(); public DataInfor gaoduchaB_ = new DataInfor(); private void Initialize() { gaoduchaB.name = "高度差B"; gaoduchaB.ID = "100202"; gaoduchaB.aliasName = "MEHLVC"; gaoduchaB_.name = "高度差B*"; gaoduchaB_.ID = "100203"; gaoduchaB_.aliasName = "KABUZU"; dataInfors.Add(gaoduchaB); dataInfors.Add(gaoduchaB_); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; //Mat gray = new Mat(); //Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); ////Mat filter = new Mat(); ////PointEnhancement(gray, out filter); Mat newGray = imageRed.Clone();// new Mat();// //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3); Mat blur = new Mat(); Cv2.MedianBlur(newGray, blur, 5); Mat thresh = new Mat(); double t = Cv2.Threshold(blur/*imageRed*/, thresh, 0, 1, ThresholdTypes.Otsu); if (t > 120) thresh = blur/*imageRed*/.Threshold(Math.Min(200, Math.Max(100, t - 0)), 1, ThresholdTypes.Binary); //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh.png", thresh * 255); ceju.Fill(thresh, out thresh, 1); Mat maxThresh = new Mat(); ceju.GetMaxArea(thresh, out maxThresh); //ceju.ImageShow(thresh * 255, maxThresh * 255); thresh = maxThresh; //得到测量区域 int[] BOrdinate = new int[3]; int[] B_Ordinate = new int[3]; int BX = 0, B_X = 0; Mat result = new Mat(); ceju.GaoduchaGetDataArea(thresh, out result, out BX, out B_X, "right"); //计算测量线纵坐标 int[] BY = new int[2]; int[] B_Y = new int[2]; //ceju.GaoduchaB(result, imageRed, out BY, out B_Y, BX, B_X); //ceju.GaoduchaBOrdinateY2(result, imageRed, image, out BY, out B_Y, BX, B_X, "right"); ceju.GaoduchaBOrdinateY3(result, blur/*imageRed*/, out BY, out B_Y, BX, B_X, "right"); BOrdinate[0] = BX; BOrdinate[1] = BY[0]; BOrdinate[2] = BY[1]; B_Ordinate[0] = B_X; B_Ordinate[1] = B_Y[0]; B_Ordinate[2] = B_Y[1]; gaoduchaB.Set(BY[1] - BY[0], BX + border, BY[0] + upper, BX + border, BY[1] + upper); gaoduchaB_.Set(B_Y[1] - B_Y[0], B_X + border, B_Y[0] + upper, B_X + border, B_Y[1] + upper); #region[释放内存] if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } //if (gray != null && !gray.IsDisposed) //{ // gray.Dispose(); //} if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (maxThresh != null && !maxThresh.IsDisposed) { maxThresh.Dispose(); } if (thresh != null && !thresh.IsDisposed) { thresh.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } #endregion } } public class GaoduchaQuan : AutoMeasureAnalysis { public DataInfor PADTonghou1 = new DataInfor(); public DataInfor PADTonghou2 = new DataInfor(); public DataInfor PIShangfanghan1 = new DataInfor(); public DataInfor PIShangfanghan2 = new DataInfor(); private void Initialize() { PADTonghou1.name = "PAD銅厚-1"; PADTonghou1.ID = "100205"; PADTonghou1.aliasName = "HIRHJH"; PADTonghou2.name = "PAD銅厚-2"; PADTonghou2.ID = "100207"; PADTonghou2.aliasName = "NENFQW"; PIShangfanghan1.name = "PI上防焊-1"; PIShangfanghan1.ID = "100206"; PIShangfanghan1.aliasName = "JLTTZK"; PIShangfanghan2.name = "PI上防焊-2"; PIShangfanghan2.ID = "100208"; PIShangfanghan2.aliasName = "DMXZJB"; dataInfors.Add(PADTonghou1); dataInfors.Add(PADTonghou2); dataInfors.Add(PIShangfanghan1); dataInfors.Add(PIShangfanghan2); } int minValue = 0; int maxValue = 0; Mat edge = new Mat(); public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat[] bgr = Cv2.Split(image); Mat imageBlue = bgr[0]; Mat imageGreen = bgr[1]; Mat imageRed = bgr[2]; Mat gray = new Mat(); Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); //ceju.ImageShow(gray.Threshold(220,255,ThresholdTypes.Binary)); //得到数据提取区域,,计算铜厚 int[] dataArea = new int[4]; int[] y = new int[2]; int[] leftTonghou = new int[3]; int[] rightTonghou = new int[3]; //ceju.GaoduchaTonghou(contour, out leftTonghou, out rightTonghou, dataArea, y); ceju.GaoduchaQuanGetDataArea3(imageRed, image, out leftTonghou, out rightTonghou, out dataArea, out y); PADTonghou1.Set(leftTonghou[2] - leftTonghou[1], leftTonghou[0] + border, leftTonghou[1] + upper, leftTonghou[0] + border, leftTonghou[2] + upper); PADTonghou2.Set(rightTonghou[2] - rightTonghou[1], rightTonghou[0] + border, rightTonghou[1] + upper, rightTonghou[0] + border, rightTonghou[2] + upper); //Mat contour = new Mat(); if (dataArea[0] != leftTonghou[0]-100 || dataArea[3] != rightTonghou[0]+100) {//矫正防焊的x坐标位置 dataArea[0] = leftTonghou[0]-100; dataArea[3] = rightTonghou[0]+100; ceju.GaoduchaQuanGetDataArea3_Center(imageRed, image, out leftTonghou, out rightTonghou, out dataArea, out y, dataArea); } //计算铜厚 //int[] leftTonghou = new int[3]; //int[] rightTonghou = new int[3]; ////ceju.GaoduchaTonghou(contour, out leftTonghou, out rightTonghou, dataArea, y); //PADTonghou1.Set(leftTonghou[2] - leftTonghou[1], leftTonghou[0]+border, leftTonghou[1]+upper, leftTonghou[0] + border, leftTonghou[2] + upper); //PADTonghou2.Set(rightTonghou[2] - rightTonghou[1], rightTonghou[0] + border, rightTonghou[1] + upper, rightTonghou[0] + border, rightTonghou[2] + upper); //Cv2.GaussianBlur(image, image, new Size(7, 7), 3, 3); //Cv2.Canny(image, edge, 5, 5); //Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); //Mat close = new Mat(); //Cv2.MorphologyEx(edge, close, MorphTypes.Close, seClose); //Mat fill = new Mat(); //ceju.Fill(close, out fill, 255); //ceju.ImageShow(fill); //CvTrackbarCallback cvTrackbarCallback = new CvTrackbarCallback(Text); //CvTrackbarCallback cvTrackbarCallback2 = new CvTrackbarCallback(Text2); //Cv2.GaussianBlur(imageGreen, imageGreen, new Size(7, 7), 3, 3); //Window window = new Window("tbar");//创建一个新窗口"tbar" //CvTrackbar cvTrackbarV = new CvTrackbar("bar1", "tbar", 25, 500, cvTrackbarCallback); //CvTrackbar cvTrackbar2 = new CvTrackbar("bar2", "tbar", 35, 500, cvTrackbarCallback2); //Cv2.WaitKey(); //void Text(int value) //{ // minValue = value; // Cv2.Canny(imageGreen, edge, minValue, maxValue); // new Window("tbar", edge); //} //void Text2(int value) //{ // maxValue = value; // Cv2.Canny(imageGreen, edge, minValue, maxValue); // new Window("tbar", edge); //} //计算防焊厚 int[] leftFanghanhou = new int[3]; int[] rightFanghanhou = new int[3]; //ceju.GaoduchaFanhanhou(imageGreen, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou); //ceju.GaoduchaFanhanhou2(imageRed, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou); //ceju.GaoduchaFanghanhoudu3(image, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou); //避免上面的端点为0 ceju.GaoduchaFanghanhoudu4(image, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou); PIShangfanghan1.Set(leftFanghanhou[2] - leftFanghanhou[1], leftFanghanhou[0] + border, leftFanghanhou[1] + upper, leftFanghanhou[0] + border, leftFanghanhou[2] + upper); PIShangfanghan2.Set(rightFanghanhou[2] - rightFanghanhou[1], rightFanghanhou[0] + border, rightFanghanhou[1] + upper, rightFanghanhou[0] + border, rightFanghanhou[2] + upper); #region[释放内存] if (imageBlue != null && !imageBlue.IsDisposed) { imageBlue.Dispose(); } if (imageGreen != null && !imageGreen.IsDisposed) { imageGreen.Dispose(); } if (imageRed != null && !imageRed.IsDisposed) { imageRed.Dispose(); } if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } #endregion } } /// /// 防焊 - 没开口 /// public class FanghanMeikaikou : AutoMeasureAnalysis { public DataInfor tonghou = new DataInfor(); public DataInfor fanghanhoudu = new DataInfor(); public DataInfor LPIhoudu = new DataInfor(); public DataInfor anquanjuli = new DataInfor(); public DataInfor undercut = new DataInfor(); public DataInfor offset = new DataInfor(); public int minValue = 0, maxValue = 0; private void Initialize() { tonghou.name = "銅厚"; tonghou.ID = "100177"; tonghou.aliasName = "MRZVRX"; fanghanhoudu.name = "防焊厚度"; fanghanhoudu.ID = "100178"; fanghanhoudu.aliasName = "BOQRZS"; LPIhoudu.name = "LPI厚度"; LPIhoudu.ID = "100179"; LPIhoudu.aliasName = "XUAPGR"; anquanjuli.name = "安全距離"; anquanjuli.ID = "100180"; anquanjuli.drawType = "MeasureHLine"; anquanjuli.aliasName = "IMBVYG"; undercut.name = "undercut"; undercut.ID = "100182"; undercut.drawType = "MeasureHLine"; undercut.aliasName = "JYPNTP"; offset.name = "offset"; offset.ID = "100181"; offset.drawType = "MeasureHLine"; offset.aliasName = "YKNKBU"; dataInfors.Add(tonghou); dataInfors.Add(fanghanhoudu); dataInfors.Add(LPIhoudu); dataInfors.Add(anquanjuli); dataInfors.Add(undercut); dataInfors.Add(offset); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } //Tools.ShadingCorrection(image) Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle_1(image).CvtColor(ColorConversionCodes.BGR2GRAY);// image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY); //銅厚 int[] b = new int[3]; int[] y = new int[2]; int[] tonghouY = new int[2]; ceju.FanghanTonghouForMeiKaiKou(gray, out tonghouY, out y, out b); int tonghouX = b[1] - 50; tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper); //防焊厚度 int fanghanhouduX = b[1] - 100; int[] fanghanhouduY = new int[2]; fanghanhouduY[0] = tonghouY[0]; int minGray = 300 * 255; ceju.FanghanhouduForMeiKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true); fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); //LPI厚度 int LPIHouduX = b[1] + 100; int[] LPIHouduY = new int[2]; LPIHouduY[0] = tonghouY[1]; ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY); ceju.FanghanhouduForMeiKaiKou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false); if (LPIHouduY[1] - fanghanhouduY[1] == -34) LPIHouduY[1] = fanghanhouduY[1] + 10;//3435.jpg LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); int[] offsetX = new int[2]; int offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50; offsetX[1] = b[2]; offsetX[0] = LPIHouduX + 30;// fanghanhouduX; int loophouduY = LPIHouduY[1]; int loophouduX = LPIHouduX + 30; int loopminGray = minGray; int houduY = loophouduY; Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY); int colStart = loophouduX - (b[1] + 5); bool changetoMax = false; if (erzhichuli) { ceju.FanghanOffsetForMeiKaiKouThroughErzhi(gray, tonghouY, b, fanghanhouduY, offsetY, out offsetX[0], out changetoMax); } else { ceju.FanghanOffsetForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]); } //ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]); int offsetX_00 = offsetX[0]; Console.WriteLine("offsetX:" + offsetX_00); int offsetX_temp = offsetX_00; int offsetX_Left = offsetX_00; int offsetRightTimesOver10 = 0;/*<--1(56).jpg*/ if (!erzhichuli) { for (int j = offsetY; j < LPIHouduY[0]; j++) { ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("offsetX_temp:" + offsetX_temp); if (offsetX_temp - offsetX_00 >= 10) offsetRightTimesOver10++; if (Math.Abs(offsetX_temp - offsetX_00) < 5/*10*//*2*//*5*/) { if (offsetX[0] < offsetX_temp) { offsetX_00 = offsetX_temp; offsetX[0] = offsetX_temp; } if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } } if (offsetRightTimesOver10 >= 30 && offsetRightTimesOver10 != 32/*<--1(21).jpg*/)/*<--1(56).jpg 1(50).jpg*/ { for (int j = offsetY; j < LPIHouduY[0]; j++) { ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("offsetX_temp:" + offsetX_temp); //if (offsetX_temp - offsetX_00 >= 10) offsetRightTimesOver10++; if (Math.Abs(offsetX_temp - offsetX_00) < 10/*<--1(56).jpg5*//*10*//*2*//*5*/) { if (offsetX[0] < offsetX_temp) { offsetX_00 = offsetX_temp; offsetX[0] = offsetX_temp; } if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } } offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50; offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); int offsetX_init0 = offsetX_Left;/*<--1(43).jpg*/ for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++) { ceju.FanghanUndercutForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_Left/*offsetX_00*/, out offsetX_temp); Console.WriteLine("undercutX_temp:" + offsetX_temp); if (Math.Abs(offsetX_temp - offsetX_00) < 10/*5*/ || Math.Abs(offsetX_temp - offsetX_Left) < 35 - (offsetRightTimesOver10 > 40 ? 10 : 0/*<--1(56).jpg5*/)/*<--1(11~15..).jpg 20*//*15*//*10*/) { offsetX_00 = offsetX_temp; //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) { //offsetX_00 = offsetX_temp; offsetX_Left = offsetX_temp; } } } if (offsetX_init0 - offsetX_Left > 200) {/*<--1(43).jpg*/ offsetX_00 = offsetX_init0; offsetX_Left = offsetX_init0; for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++) { ceju.FanghanUndercutForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_Left/*offsetX_00*/, out offsetX_temp); Console.WriteLine("undercutX_temp:" + offsetX_temp); if (Math.Abs(offsetX_temp - offsetX_00) < 10/*5*/ || Math.Abs(offsetX_temp - offsetX_Left) < 25/*<--1(43).jpg 1(50).jpg 35*//*<--1(11~15..).jpg 20*//*15*//*10*/) { offsetX_00 = offsetX_temp; //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) { //offsetX_00 = offsetX_temp; offsetX_Left = offsetX_temp; } } } } //undercut int[] undercutX = new int[2] { offsetX_Left, offsetX[0] }; if (erzhichuli && undercutX[1] - undercutX[0] > 75) { if (changetoMax) { if (undercutX[1] - undercutX[0] < 100) { offsetX[0] = undercutX[0] + 35;//79 undercutX[1] = offsetX[0]; } else { offsetX[0] = offsetX[0] - 35;//100 undercutX[1] = offsetX[0]; } } else if (undercutX[1] - undercutX[0] > 105) { undercutX[0] = undercutX[1] - 45;//113 } } int undercutY = tonghouY[1] + 20;// - 20; undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //update value offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //安全距離 int anquanjuliY = tonghouY[1] + 50; int[] anquanjuliX = { b[1], undercutX[0] }; anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); //int mean0; Scalar mean_rgb; ////去掉圆并灰度化,怎么能更快? //Mat gray = FangHanTools.RemoveCircle(image, out mean0, out mean_rgb)/*FangHanTools.RemoveCircle(image)*/.CvtColor(ColorConversionCodes.BGR2GRAY); //////精准找到 防焊-没开口 的标记点,避免直线拟合等原因导致测量精度不够 ////Mat mat1 = gray.Clone();// new Mat(); //////Cv2.Normalize(imageContour, mat1, 0, 255, NormTypes.MinMax); ////Cv2.ImShow("gray", mat1); ////Cv2.WaitKey(); ////left, right, top, bottom //int[] calculateRect = new int[4] { gray.Cols - border, 0, gray.Rows - upper, 0 }; ////Rect calculateInterest = new Rect(0, 0, 1/*gray.Cols - border*/, 1/*gray.Rows - upper*/); ////銅厚 //int[] b = new int[3]; //int[] y = new int[2]; //int[] tonghouY = new int[2]; ////分析的区域切图的不对[1]to do // ////Cv2.ImWrite(@"C:\Users\54434\Desktop\gray.JPG", gray); //ceju.FanghanTonghouForMeiKaiKou(gray, out tonghouY, out y, out b); //int tonghouX = b[1] - 50; //if (tonghouX <= 0 || tonghouY[0]<=0) return; //if (tonghouY[0] > tonghouY[1]) //{ // int temp = tonghouY[0]; // tonghouY[0] = tonghouY[1]; // tonghouY[1] = temp; //} //tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper); //if (calculateRect[2] > tonghouY[0]) calculateRect[2] = tonghouY[0]; //if (calculateRect[3] < tonghouY[1]) calculateRect[3] = tonghouY[1]; ////防焊厚度 //int fanghanhouduX = b[1] - 100; //int[] fanghanhouduY = new int[2]; ////offset //int[] offsetX = new int[2]; //int offsetY = tonghouY[0] - 50; //offsetX[1] = b[2]; //offsetX[0] = b[1] + 100; ////LPI厚度 //int LPIHouduX = b[1] + 100; //int[] LPIHouduY = new int[2]; ////undercut //int[] undercutX = new int[2]; //int undercutY = tonghouY[1] + 20; ////安全距離 //int anquanjuliY = tonghouY[1] + 50; ////优化开始 1 //int tonghouX_2 = b[2] - 50; //fanghanhoudu.Set(tonghouY[1] - tonghouY[0] + 200, tonghouX_2 + border, tonghouY[0] + upper - 150, tonghouX_2 + border, tonghouY[1] + upper + 50); //Mat crop2 = gray[tonghouY[0] + upper - 150, tonghouY[0] + upper - 20/*tonghouY[1] + upper + 50*/, fanghanhouduX - 50 + border, tonghouX_2 + border];// / 255; //////Cv2.ImWrite(@"C:\Users\54434\Desktop\crop2.png", crop2/*thresh1 * 255*/); ////Mat newGray = crop2.Clone();// new Mat();// //////Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3); ////Mat blur = new Mat(); ////Cv2.MedianBlur(newGray, blur, 5); ////Mat edge; //////Cv2.ImWrite(@"C:\Users\54434\Desktop\blur.png", blur); ////new Ceju().EdgeY(blur, out edge); //////Edge(blur, out edge); //////Cv2.ImWrite(@"C:\Users\54434\Desktop\edge.png", edge); //Mat newGray_2 = crop2.Clone();// new Mat();// //Cv2.GaussianBlur(newGray_2, newGray_2, new Size(11, 11), 3, 3); //Mat blur_2 = new Mat(); //Cv2.MedianBlur(newGray_2, blur_2, 5); //Mat thres_2; //new Ceju().EdgeY(blur_2, out thres_2); //////Mat thres_3 = crop2. ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thres_2.png", thres_2/*thresh1 * 255*/); //fanghanhouduY[1] = tonghouY[0]; //new Ceju().FanghanhouduForMeiKaiKou_2(thres_2, 50, 30, out fanghanhouduY[0]); //fanghanhouduY[0] += (tonghouY[0] - 150); //fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); //////tonghouY[1] = tonghouY[1]; ////fanghanhoudu.Set(tonghouY[1] - tonghouY[0] + 150, fanghanhouduX + border, tonghouY[0] + upper - 150, fanghanhouduX + border, tonghouY[1] + upper); //LPIHouduY[1] = tonghouY[1]; //new Ceju().FanghanhouduForMeiKaiKou_2(thres_2, LPIHouduX - (fanghanhouduX - 50), 30, out LPIHouduY[0]); //LPIHouduY[0] += (tonghouY[0] - 150); //////修正LPI厚度上端点的位置 ////for (int i = LPIHouduY[0] - 50; i < LPIHouduY[0]; i++) ////{ //// if (i > 0 && thresh2.At(i, LPIHouduX) == 1)// (thresh2.At(i, LPIHouduX) == 1 || thresh1.At(i, LPIHouduX) == 1)) //// { //// LPIHouduY[0] = i;// - 3; //// break; //// } ////} //LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); //crop2 = gray[tonghouY[0] + upper - 150, tonghouY[1] + upper + 50, fanghanhouduX - 50 + border, tonghouX_2 + border];// / 255; //////Cv2.ImWrite(@"C:\Users\54434\Desktop\crop2.png", crop2/*thresh1 * 255*/); ////Mat newGray = crop2.Clone();// new Mat();// //////Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3); ////Mat blur = new Mat(); ////Cv2.MedianBlur(newGray, blur, 5); ////Mat edge; //////Cv2.ImWrite(@"C:\Users\54434\Desktop\blur.png", blur); ////new Ceju().EdgeY(blur, out edge); //////Edge(blur, out edge); //////Cv2.ImWrite(@"C:\Users\54434\Desktop\edge.png", edge); //newGray_2 = crop2.Clone();// new Mat();// //Cv2.GaussianBlur(newGray_2, newGray_2, new Size(11, 11), 3, 3); ////blur_2 = new Mat(); //Cv2.MedianBlur(newGray_2, blur_2, 5); ////Mat thres_2; //new Ceju().EdgeX(blur_2, out thres_2); ////Mat thres_3 = crop2. //Cv2.ImWrite(@"C:\Users\54434\Desktop\thres_3.png", thres_2/*thresh1 * 255*/); ////FanghanhouduForMeiKaiKou_X(Mat thres_2, int scanX_start, int fanghanhouduY_1/*fanghanhouduY_center*/, int fanghanhouduY_2/*fanghanhouduY_radius*/, out int fanghanhouduX_0, bool showMat = false); //new Ceju().FanghanhouduForMeiKaiKou_Offset0(thres_2, 250, thres_2.Cols - 2, 120/*150*/ - 30, 120/*150*/ + 30/*tonghouY[1]-tonghouY[0] + 50*/, out offsetX[0]); //offsetX[0] += (fanghanhouduX - 50); //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //undercutX[1] = offsetX[0]; //Undercut0与Offset0的寻找算法还是有所不同! //new Ceju().FanghanhouduForMeiKaiKou_Undercut0(thres_2, 250, undercutX[1] - 1, 150 + tonghouY[1] - tonghouY[0] - 30, 150 + tonghouY[1] - tonghouY[0] + 30/*50*/, out undercutX[0]); //int thres_v = 10; //while (undercutX[1] - undercutX[0] <= (fanghanhouduX - 50 + 2/*minLength*/) && thres_v < 60) //{ // new Ceju().FanghanhouduForMeiKaiKou_Undercut0(thres_2, 250, undercutX[1] - 1, 150 - 30 + thres_v + tonghouY[1] - tonghouY[0] - 30, 150 - 30 + thres_v + tonghouY[1] - tonghouY[0] + 30/*50*/, out undercutX[0]); // thres_v += 10; //} //undercutX[0] += (fanghanhouduX - 50); //undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] };// anquanjuliX[1] = undercutX[0]; //if (anquanjuliX[0] > anquanjuliX[1]) //{ // int temp = anquanjuliX[0]; // anquanjuliX[0] = anquanjuliX[1]; // anquanjuliX[1] = temp; //} ////anquanjuliX[1] = undercutX[0]; //anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); //return; ////优化开始 1 end ////防焊 没有开口 厚度 //Mat thresh1 = ceju.FanghanhouduForMeiKaiKou(gray, y, b, tonghouY, out fanghanhouduY, 0, true); //优化开始 2 //Mat thres = thresh1.Clone(); //Mat newGray = gray.Clone();// new Mat();// //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3); //Mat blur = new Mat(); //Cv2.MedianBlur(newGray, blur, 5); //new Ceju().Edge(blur, out thres); //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh1.png", thres/*thresh1 * 255*/); ////int fanghanhouduX = b[1] - 100; ////fanghanhouduY[1] = i; ////输出计算防焊厚度时用到的漫水填充的图片,以便后面根据此图片寻找边界 /// //优化开始 2 end //if (fanghanhouduY[0] > fanghanhouduY[1]) //{ // int temp = fanghanhouduY[0]; // fanghanhouduY[0] = fanghanhouduY[1]; // fanghanhouduY[1] = temp; //} ////fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); //if (calculateRect[2] > fanghanhouduY[0]) calculateRect[2] = fanghanhouduY[0]; //if (calculateRect[3] < fanghanhouduY[1]) calculateRect[3] = fanghanhouduY[1]; //ceju.FanghanOffsetForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX); //if (offsetX[0] > offsetX[1]) //{ // int temp = offsetX[0]; // offsetX[0] = offsetX[1]; // offsetX[1] = temp; //} ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); ////if (calculateRect[0] > offsetX[0]) calculateRect[0] = offsetX[0]; ////if (calculateRect[1] < offsetX[1]) calculateRect[1] = + offsetX[1]; //Mat thresh2_0; //Mat thresh2 = ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY, out thresh2_0, 0, true); ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2.png", thresh2 * 127); //////int LPIHouduX = b[1] + 100; //////LPIHouduY[1] = i; ////if (thresh2_0 != null) //// Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0); //if (LPIHouduY[0] > LPIHouduY[1]) //{ // int temp = LPIHouduY[0]; // LPIHouduY[0] = LPIHouduY[1]; // LPIHouduY[1] = temp; //} ////LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); //if (calculateRect[2] > LPIHouduY[0]) calculateRect[2] = LPIHouduY[0]; //if (calculateRect[3] < LPIHouduY[1]) calculateRect[3] = LPIHouduY[1]; //if (undercutY > gray.Rows - 1) undercutY = gray.Rows - 1; //ceju.FanghanUndercutForMeiKaiKou(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]); //undercutX[1] = offsetX[0]; //if (undercutX[0] > undercutX[1]) //{ // int temp = undercutX[0]; // undercutX[0] = undercutX[1]; // undercutX[1] = temp; //} //if (undercutX[1] - undercutX[0] < 12) // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}); ////undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); ////if (calculateRect[0] > undercutX[0]) calculateRect[0] = undercutX[0]; ////if (calculateRect[1] < undercutX[1]) calculateRect[1] = + undercutX[1]; //int offsetX_Sum = 0;//有sum用sum //int offsetX_init = offsetX[0]; ////修正标样找到内部的问题 //if ((int)thresh2[offsetY - 5, offsetY + 35, offsetX_init, offsetX_init + 1].Sum() > 2 // && offsetX_init + 20 < thresh2.Cols) //{ // offsetX_init += 20; //} ////修正offset左端点,避免圆球干扰 //for (int i = offsetX_init; i > undercutX[0/*1*/] - 20; i--) //{ // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum(); // if (i > 0 && (int)thresh2[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh2.At(offsetY, i) == 1/*127*/) // { // //if (thresh2.At(offsetY, i) == 1/*127*/) // //{//有值等于优先使用值等于,而放弃sum // // offsetX_Sum = 0; // // offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位 // // break; // //} // //else if (offsetX_Sum == 0) // offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位 // break; // } // else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At(offsetY, i) == 1/*127*/) // { // Console.WriteLine("thresh1 to be used"); // } //} //if (offsetX_Sum > 0) //{ // offsetX[0] = offsetX_Sum; // if (thresh2_0 != null && false) // { // //使用thresh2_0,从 offsetX_Sum到offsetX_init寻找到合理的左端点,避免0(4)和1(9)修正过度的问题 // int offsetV = 254; // int offsetXContrast = -1; // bool currentIsBlack = true; // offsetY -= 3;//-= 3; // //将最右侧的点填充 // if (currentIsBlack && thresh2_0.At(offsetY, offsetX[1] + 5) > 0)//offsetX_init > 0 && // { // Cv2.FloodFill(thresh2_0, new Point(offsetX[1] + 5, offsetY), new Scalar(offsetV--)); // offsetXContrast = offsetX[1] + 5; // currentIsBlack = false; // } // //offsetXList中key值为横坐标,value标志是否是合理的端点 // //从右向左找 // for (int i = offsetX[1] + 5/*offsetX_init*/ - 1; i > offsetX_Sum; i--) // { // if (i > 0 && currentIsBlack && thresh2_0.At(offsetY, i) > 0) // {//找到暗色到亮色的过度点 // if (thresh2_0.At(offsetY, i) == 255 // || thresh2_0.At(offsetY, i) == 127)//第一次到达该区域 // { // if (offsetXContrast > 0)//,且不与上一个点形成闭环的球 // { // if(offsetX[0] < offsetXContrast && offsetX[0] - offsetXContrast > -100) offsetX[0] = offsetXContrast; // break; // } // else//标记第一次到达该区域 // { // Cv2.FloodFill(thresh2_0, new Point(i, offsetY), new Scalar(offsetV--)); // offsetXContrast = i; // } // } // else if (offsetXContrast > 0)//标记已经到达过到达该区域 // { // offsetXContrast = -1; // } // currentIsBlack = false; // } // else if (i > 0 && !currentIsBlack && thresh2_0.At(offsetY, i) == 0) // {//找到亮色到暗色的过度点 // currentIsBlack = true; // } // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At(offsetY, i) == 1/*127*/) // //{ // // Console.WriteLine("thresh1 to be used"); // //} // } // if (offsetXContrast > 0)//,且不与上一个点形成闭环的球 // { // if (offsetX[0] < offsetXContrast && offsetX[0] - offsetXContrast > -100) offsetX[0] = offsetXContrast; // } // Cv2.Line(thresh2_0, offsetX_Sum, offsetY, offsetX_init, offsetY, new Scalar(127)); // Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0_2.png", thresh2_0); // offsetY += 3;//-= 35; // } //} ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //if (calculateRect[0] > offsetX[0]) calculateRect[0] = offsetX[0]; //if (calculateRect[1] < offsetX[1]) calculateRect[1] = +offsetX[1]; //undercutX[1] = offsetX[0]; //if (undercutX[0] > undercutX[1]) //{ // int temp = undercutX[0]; // undercutX[0] = undercutX[1]; // undercutX[1] = temp; //} //if (undercutX[1] - undercutX[0] < 12) // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }); ////undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //if (calculateRect[0] > undercutX[0]) calculateRect[0] = undercutX[0]; //if (calculateRect[1] < undercutX[1]) calculateRect[1] = +undercutX[1]; ////int offsetY_Both = 0;//有全为1的优先使用全为1的 ////修正防焊厚度上端点的位置 //for (int i = fanghanhouduY[0] - 50; i < fanghanhouduY[0]; i++) //{ // if (i > 0 && thresh1.At(i, fanghanhouduX) == 1)// (thresh2.At(i, fanghanhouduX) == 1 || thresh1.At(i, fanghanhouduX) == 1)) // { // fanghanhouduY[0] = i;// - 3; // break; // } // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At(offsetY, i) == 1/*127*/) // //{ // // Console.WriteLine("thresh1 to be used"); // //} //} //fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); ////修正LPI厚度上端点的位置 //for (int i = LPIHouduY[0] - 50; i < LPIHouduY[0]; i++) //{ // if (i > 0 && thresh2.At(i, LPIHouduX) == 1)// (thresh2.At(i, LPIHouduX) == 1 || thresh1.At(i, LPIHouduX) == 1)) // { // LPIHouduY[0] = i;// - 3; // break; // } //} //LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); ////int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] }; ////if (anquanjuliX[0] > anquanjuliX[1]) ////{ //// int temp = anquanjuliX[0]; //// anquanjuliX[0] = anquanjuliX[1]; //// anquanjuliX[1] = temp; ////} //////anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); ////if (calculateRect[0] > anquanjuliX[0]) calculateRect[0] = anquanjuliX[0]; ////if (calculateRect[1] < anquanjuliX[1]) calculateRect[1] = + anquanjuliX[1]; //bool foundCircle;// = false; //Mat final; //int crop_top = 0;// calculateRect[0]/* + upper*/ - crop_margin1; //int crop_left = 0;// calculateRect[2]/* + border*/ - crop_margin2; ////if (calculateRect[0] < 0 || calculateRect[2] < 0) ////{ //// foundCircle = false; //// final = image; ////} ////else { //Mat crop; //if (isCropFlag) //{ // calculateRect[0] = 0; calculateRect[2] = 0; // calculateRect[1] = image.Cols; calculateRect[3] = image.Rows; // crop = image; //} //else //{ // int crop_margin1 = 50; // if (calculateRect[0] < 50) crop_margin1 = 0; // int crop_margin2 = 200;//上下方向的扩展!-->解决上下方向球不完整的问题,使用了100和200两个尺寸判定 // if (calculateRect[2] < 100) crop_margin2 = 0; // else if (calculateRect[2] < 200) crop_margin2 = 100; // crop_top = calculateRect[0]/* + upper*/ - crop_margin1; // crop_left = calculateRect[2]/* + border*/ - crop_margin2; // int margin_right = 0; // if (crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + 200 < image.Cols) // margin_right = 200; // else if (crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + 100 < image.Cols) // margin_right = 100; // crop = image/*gray*/[crop_left, crop_left + crop_margin2 + calculateRect[3] - calculateRect[2], crop_top, crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + margin_right];//[y[0], y[1], b[0], b[2]]; //} ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", crop); //////去掉圆并灰度化,怎么能更快? ////bool foundCircle;// = false; ///*Mat */ //final = FangHanTools.RemoveCircle(crop, mean0, mean_rgb, out foundCircle);// /*FangHanTools.RemoveCircle(image)*/.CvtColor(ColorConversionCodes.BGR2GRAY); //if (foundCircle) //{ // //for (int h = 0; h < final.Height; h++) // //{ // // for (int w = 0; w < final.Width; w++) // // { // // if (final.At(h, w) < 255) // // { // // if (!foundCircle) foundCircle = true; // // break; // // //clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255)); // // } // // } // // if (foundCircle) // // { // // break; // // } // //} // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", final); // //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); // if (thresh2_0 != null) // { // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0); // Mat se = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(30, 30)); // //Cv2.Dilate(final, final, 60); // Cv2.Erode(final, final, se); // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_1.png", final); // if (se != null && !se.IsDisposed) // { // se.Dispose(); // } // } // /////*Mat */thresh2_0; // ///*Mat */ // //thresh2 = ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY, out thresh2_0, 0, true); // //修正offset左端点,避免圆球干扰 // for (int i = offsetX[1] - 10/*offsetX_init*/; i > offsetX/*undercutX*/[0/*1*/] /*- 20*/; i--) // { // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum(); // if (i > 0 && (int)thresh2_0/*thresh2*/[offsetY + 0/*upper*/ - 1, offsetY + 0/*upper*/ + 1/*35*/, i + 0/*border*/, i + 0/*border*/ + 1].Sum() > 2 // && (int)final/*thresh2*/[offsetY + 0/*upper*/ - crop_left - 1, offsetY + 0/*upper*/ - crop_left + 1/*35*/, i + 0/*border*/ - crop_top - 7, i + 0/*border*/ - crop_top + 1].Sum() // /*final.At(offsetY + upper - crop_left, i + border - crop_top)*/ >/*<*/ 255 * 15/* (byte)mean_rgb[0]*/) //thresh2.At(offsetY, i) == 1/*127*/) // { // ////if (thresh2.At(offsetY, i) == 1/*127*/) // ////{//有值等于优先使用值等于,而放弃sum // //// offsetX_Sum = 0; // //// offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位 // //// break; // ////} // ////else if (offsetX_Sum == 0) // //Cv2.Line(final, i + border - crop_top, offsetY + upper - crop_left, i + border - crop_top - 100, offsetY + upper - crop_left, new Scalar(127)); // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_2.png", final); // offsetX/*undercutX*/[0] = i - 3; // //offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位 // break; // } // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At(offsetY, i) == 1/*127*/) // //{ // // Console.WriteLine("thresh1 to be used"); // //} // } //} ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //undercutX[1] = offsetX[0]; //if (undercutX[0] > undercutX[1]) //{ // int temp = undercutX[0]; // undercutX[0] = undercutX[1]; // undercutX[1] = temp; //} //if (undercutX[1] - undercutX[0] < 12) // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }); //int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] };// anquanjuliX[1] = undercutX[0]; //if (anquanjuliX[0] > anquanjuliX[1]) //{ // int temp = anquanjuliX[0]; // anquanjuliX[0] = anquanjuliX[1]; // anquanjuliX[1] = temp; //} ////Cv2.Line(thresh2_0, offsetX_Sum, offsetY, offsetX_init, offsetY, new Scalar(127)); ////解决Z3和标样两张图的测量误差 //int isInGray127 = -1;//从灰色下区域、灰色中、灰色上区域赋值为-1,0,1 //int undercutCalY = 0;//要找到灰色线条的上边界 //int undercutRightX = 0; //if (undercutX[1] - undercutX[0] > anquanjuliX[1] - anquanjuliX[0]) //{//解决Z3和标样两张图的测量误差 // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_1_0.png", thresh2_0); // for (int i = undercutX[1] - 1; i > undercutX[0]; i--) // {//第一次找灰色 // if (isInGray127 == -1) // {//先找到灰色127 // for (int j = undercutY; j > 0; j--) // { // if (thresh2_0.At(j, i) == 127) // { // undercutCalY = j; // isInGray127 = 0; // break; // } // } // } // if (isInGray127 == 0) // { // for (int j = undercutCalY; j > 0; j--) // { // if (thresh2_0.At(j, i) != 127) // { // undercutCalY = j + 1; // isInGray127 = 1; // break; // } // } // } // if (isInGray127 == 1) // { // undercutRightX = i; // break; // } // } //} ////解决Z3和标样两张图的测量误差 //if (isInGray127 == 1) //{//循环找角度为锐角的点 // //int undercutCalY = 0;//要找到灰色线条的上边界 // //int undercutRightX = 0; // for (int i = undercutRightX - 1; i > undercutX[0]; i--) // {//第一次找灰色 // isInGray127 = -1; // int undercutCalY0 = undercutCalY; // if (isInGray127 == -1) // {//先找到灰色127 // for (int j = undercutCalY0 + 3; j > undercutCalY0 - 3; j--) // { // if (thresh2_0.At(j, i) == 127) // { // undercutCalY = j; // isInGray127 = 0; // break; // } // } // } // if (isInGray127 == 0) // { // for (int j = undercutCalY; j > undercutCalY0 - 13; j--) // { // if (thresh2_0.At(j, i) != 127) // { // undercutCalY = j; // isInGray127 = 1; // break; // } // } // } // if (isInGray127 < 1) // { // break; // } // undercutRightX = i; // //继续向左找 // } // undercutX[0] = undercutRightX - 10; //} //if (anquanjuliX[1] - anquanjuliX[0] > 3 * (offsetX[1] - offsetX[0]) // && undercutX[1] - undercutX[0] > 3 * (offsetX[1] - offsetX[0])) //{//解决1(50)的问题 // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2.png", thresh2 * 127); // ////int LPIHouduX = b[1] + 100; // ////LPIHouduY[1] = i; // //if (thresh2_0 != null) // // Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0); // if (foundCircle) // {//解决1(50)的问题 // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", final); // //修正offset左端点,避免圆球干扰 // for (int i = offsetX[1] - 10; i > anquanjuliX[0]; i--) // { // if (i > 0 && (int)thresh2_0[offsetY - 1, offsetY + /*1*/35, i, i + 1].Sum() > 2 && // (int)final[offsetY - crop_left - 1, offsetY - crop_left + 1/*35*/, i - crop_top - 7, i - crop_top + 1].Sum() > 255 * 15) //thresh2.At(offsetY, i) == 1/*127*/) // { // offsetX/*undercutX*/[0] = i - 3; // break; // } // } // undercutX[1] = offsetX[0]; // bool foundWhiteArea = false; // //向左找 // for (int j = undercutX[1] - 5; j > anquanjuliX[0]; j--) // ////向右找 // //for (int j = tempRange; j < offsetX[0]; j++) // { // //double v = new Mat(result, new Rect(j, tonghouY[1] - 15, 1, 5/*3*//*5*/)).Sum().Val0; // double v_2 = new Mat(thresh2_0, new Rect(j, tonghouY[1] - 15, 1, 5/*3*//*5*/)).Sum().Val0; // //byte v = result.Get((tonghouY[1] + tonghouY[0]) / 2, j); // //byte v_2 = result_2.Get((tonghouY[1] + tonghouY[0]) / 2, j); // if (foundWhiteArea) // { // if (v_2 == 0) // { // undercutX[0] = j - 5;// - 15; // break; // } // } // else if (v_2 > 0) // { // //if (undercutX[0] == 0 || j - undercutX[0] > 50) // { // //tempj_2 = j; // undercutX[0] = j - 15; // } // foundWhiteArea = true; // //break; // } // //if (v > 0) // //{ // // //tempj = j; // // ////if (Cv2.FloodFill(result, new Point(j, (tonghouY[1] + tonghouY[0]) / 2), new Scalar(255)) > 100) // // { // // undercutX[0] = j; // // //undercutX = Tools.GetLeftPoint(new Point(j, (tonghouY[1] + tonghouY[0]) / 2), result).X; // // break; // // } // //} // } // ////修正offset左端点,避免圆球干扰 // //for (int i = offsetX[1] - 10/*offsetX_init*/; i > offsetX/*undercutX*/[0/*1*/] /*- 20*/; i--) // //{ // // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum(); // // if (i > 0 && (int)thresh2_0/*thresh2*/[offsetY + 0/*upper*/ - 1, offsetY + 0/*upper*/ + 1/*35*/, i + 0/*border*/, i + 0/*border*/ + 1].Sum() > 2 // // && (int)final/*thresh2*/[offsetY + 0/*upper*/ - crop_left - 1, offsetY + 0/*upper*/ - crop_left + 1/*35*/, i + 0/*border*/ - crop_top - 7, i + 0/*border*/ - crop_top + 1].Sum() // // /*final.At(offsetY + upper - crop_left, i + border - crop_top)*/ >/*<*/ 255 * 15/* (byte)mean_rgb[0]*/) //thresh2.At(offsetY, i) == 1/*127*/) // // { // // ////if (thresh2.At(offsetY, i) == 1/*127*/) // // ////{//有值等于优先使用值等于,而放弃sum // // //// offsetX_Sum = 0; // // //// offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位 // // //// break; // // ////} // // ////else if (offsetX_Sum == 0) // // //Cv2.Line(final, i + border - crop_top, offsetY + upper - crop_left, i + border - crop_top - 100, offsetY + upper - crop_left, new Scalar(127)); // // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_2.png", final); // // offsetX/*undercutX*/[0] = i - 3; // // //offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位 // // break; // // } // // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At(offsetY, i) == 1/*127*/) // // //{ // // // Console.WriteLine("thresh1 to be used"); // // //} // //} // } //} //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); #region[释放内存] //if (thresh1 != null && !thresh1.IsDisposed) //{ // thresh1.Dispose(); //} //if (thresh2 != null && !thresh2.IsDisposed) //{ // thresh2.Dispose(); //} //if (thresh2_0 != null && !thresh2_0.IsDisposed) //{ // thresh2_0.Dispose(); //} if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } //if (final != null && !final.IsDisposed) //{ // final.Dispose(); //} //if (crop != null && !crop.IsDisposed) //{ // crop.Dispose(); //} #endregion } } /// /// 防焊 有开口 /// public class FanghanYoukaikou : AutoMeasureAnalysis { public DataInfor tonghou = new DataInfor(); public DataInfor fanghanhoudu = new DataInfor(); public DataInfor LPIhoudu = new DataInfor(); public DataInfor anquanjuli = new DataInfor(); public DataInfor undercut = new DataInfor(); public DataInfor offset = new DataInfor(); public DataInfor fanghankaikou = new DataInfor(); private void Initialize() { tonghou.name = "銅厚"; tonghou.ID = "100184"; tonghou.aliasName = "AZAFWX"; fanghanhoudu.name = "防焊厚度"; fanghanhoudu.ID = "100185"; fanghanhoudu.aliasName = "YXADDD"; LPIhoudu.name = "LPI厚度"; LPIhoudu.ID = "100186"; LPIhoudu.aliasName = "AADPUH"; anquanjuli.name = "安全距離"; anquanjuli.ID = "100187"; anquanjuli.drawType = "MeasureHLine"; anquanjuli.aliasName = "LDPDJW"; undercut.name = "undercut"; undercut.ID = "100189"; undercut.drawType = "MeasureHLine"; undercut.aliasName = "AAVEQW"; offset.name = "offset"; offset.ID = "100188"; offset.drawType = "MeasureHLine"; offset.aliasName = "NSOTFU"; fanghankaikou.name = "防焊開口"; fanghankaikou.ID = "100190"; fanghankaikou.drawType = "MeasureHLine"; fanghankaikou.aliasName = "KOWHIR"; dataInfors.Add(tonghou); dataInfors.Add(fanghanhoudu); dataInfors.Add(LPIhoudu); dataInfors.Add(anquanjuli); dataInfors.Add(undercut); dataInfors.Add(offset); dataInfors.Add(fanghankaikou); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } //Tools.ShadingCorrection(image) Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle_1(image).CvtColor(ColorConversionCodes.BGR2GRAY);// image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY); //銅厚 int[] b = new int[3]; int[] y = new int[2]; int[] tonghouY = new int[2]; ceju.FanghanTonghouForYouKaiKou(gray, out tonghouY, out y, out b); int tonghouX = b[1] - 50; ceju.FanghanTonghouForYouKaiKou_Acc(gray, tonghouX, out tonghouY[0], y/*, out int[] y, out int[] b*/); tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper); //防焊厚度 int fanghanhouduX = b[1] - 100; int[] fanghanhouduY = new int[2]; ceju.FanghanTonghouForYouKaiKou_Acc(gray, fanghanhouduX, out tonghouY[0], y/*, out int[] y, out int[] b*/); fanghanhouduY[0] = tonghouY[0]; int minGray = 300 * 255; ceju.FanghanhouduForYouKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true); fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); //LPI厚度 int LPIHouduX = b[1] + 100; int[] LPIHouduY = new int[2]; LPIHouduY[0] = tonghouY[1]; ceju.FanghanLPIForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY); ceju.FanghanhouduForYouKaiKou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false); LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); int offsetY1 = Math.Min(LPIHouduY[0], LPIHouduY[1]) - 60;// 50; int offsetY2 = Math.Max(LPIHouduY[0], LPIHouduY[1]) + 20; ////offset //fanghanhouduX = b[1] + 100; //fanghanhouduX = b[1] + 300;// 200;// 100; //ceju.FanghanhouduForYouKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1]); int[] offsetX = new int[2]; int offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50; offsetX[1] = b[2]; offsetX[0] = LPIHouduX + 30;// fanghanhouduX; int loophouduY = LPIHouduY[1]; int loophouduX = LPIHouduX + 30; int loopminGray = minGray; int houduY = loophouduY; Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY); //for (int i = 0; i < 10; i++) //{ // ceju.FanghanhouduForYouKaiKou_2(gray, y, loophouduX, tonghouY, out loophouduY, out loopminGray); // if (Math.Abs(loopminGray - minGray) / minGray < 0.3 && Math.Abs(loophouduY - houduY) < 8/*12*//*8*//*50*/) // { // houduY = loophouduY; // minGray = loopminGray; // Console.WriteLine("minGray:" + minGray + ", loophouduX:" + loophouduX + " Y:" + loophouduY); // loophouduX = loophouduX + 30; // } // else // { // Console.WriteLine("minGray:" + loopminGray + ", loophouduX:" + loophouduX + " Y:" + loophouduY); // break; // } //} //offsetX[0] = loophouduX - 30; int colStart = loophouduX - (b[1] + 5); ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]); //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]); ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]); int offsetX_00 = offsetX[0]; Console.WriteLine("offsetX:" + offsetX_00); int offsetX_temp = offsetX_00; int offsetX_Left = offsetX_00; for (int j = offsetY; j < LPIHouduY[0]; j++) { ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("offsetX_temp:" + offsetX_temp); if (Math.Abs(offsetX_temp - offsetX_00) < 5) { offsetX_00 = offsetX_temp; if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50; offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //防焊开口 int[] fanghankaikouX = new int[2]; int fanghankaikouY = tonghouY[0] - 80; ceju.FanhanKaikouForYouKaiKou(gray, tonghouY, b, fanghanhouduY, fanghanhouduX, tonghouX, offsetX, out fanghankaikouX); fanghankaikouX[0] = offsetX[0]; if (fanghankaikouX[1]==0) {//999(4).jpg、3400(5),JPG、9999(7).jpg fanghankaikouX[1] = Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2-100); } fanghankaikou.Set(fanghankaikouX[1] - fanghankaikouX[0], fanghankaikouX[0] + border, fanghankaikouY + upper, fanghankaikouX[1] + border, fanghankaikouY + upper); //int offsetY1 = Math.Min(LPIHouduY[0], LPIHouduY[1]) - 20; //int offsetY2 = Math.Max(LPIHouduY[0], LPIHouduY[1]) + 20; int offsetLeft = Math.Max(fanghankaikouX[0], fanghankaikouX[1]) - 20 - 20; Mat grayRect = gray[offsetY1 + 0, offsetY2 + 0, offsetLeft + 0, gray.Cols-1].Clone(); //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect); ////ceju.FanghanLPIForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY); int fanghankaikouYTop; ceju.FanghanhouduRightForYouKaiKou(grayRect, out fanghankaikouYTop/*fanghanhouduY1*/); Cv2.Line(grayRect, 0, fanghankaikouYTop, Math.Min(350, grayRect.Cols - 1)/* <- 200 grayRect.Cols*/, fanghankaikouYTop, new Scalar(127/*255*//*127*/)); //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect); int kaikouX1; ceju.FanghanKaikouForNewKaiKou(grayRect, 11, Math.Min(350, grayRect.Cols - 11), fanghankaikouYTop, out kaikouX1); Cv2.Line(grayRect, 0, fanghankaikouYTop, kaikouX1/*Math.Min(350, grayRect.Cols - 1)*//* <- 200 grayRect.Cols*/, fanghankaikouYTop, new Scalar(255/*127*/)); //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect); if (fanghankaikouX[1] < kaikouX1 + offsetLeft) {//适配开口右侧端点 if ((kaikouX1 + offsetLeft - fanghankaikouX[1] > 10 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 15)//9999(6).JPG || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 30 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 45) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 45 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 60) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 65 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 70) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 75/*70*/ && kaikouX1 + offsetLeft - fanghankaikouX[1] < 90) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 95 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 100) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 100 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 158) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 158 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 162) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 170 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 210) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 210 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 215/*220*/) || (kaikouX1 + offsetLeft - fanghankaikouX[1] >= 240 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 244/*245*/) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 250 && kaikouX1 + offsetLeft - fanghankaikouX[1] <= 256 && !(fanghankaikouX[0] > 1000 && fanghankaikouX[0] < 1010))//5086.JPG[&6257.JPG] || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 256 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 260) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 260 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 263) || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 281 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 284)) { fanghankaikouX[1] = kaikouX1 + offsetLeft;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100); } //else if (fanghankaikouX[1] > 1000 && fanghankaikouX[1] < 1010 && kaikouX1 + offsetLeft - fanghankaikouX[1] == 256) //{//5086.JPG //} else if (kaikouX1 + offsetLeft - fanghankaikouX[1] > 263 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 270/*kaikouX1 + offsetLeft - fanghankaikouX[1] >= 283 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 286*/) {//3983TT.JPG <- //9999(7).JPG 284 fanghankaikouX[1] = ((kaikouX1 + offsetLeft) * 1 + fanghankaikouX[1] * 2) / 3;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100); } else if (kaikouX1 + offsetLeft - fanghankaikouX[1] > 215 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 220) {//3400(5).JPG 217 fanghankaikouX[1] = fanghankaikouX[1] - 30;// ((kaikouX1 + offsetLeft) * 1 + fanghankaikouX[1] * 2) / 3;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100); } } fanghankaikou.Set(fanghankaikouX[1] - fanghankaikouX[0], fanghankaikouX[0] + border, fanghankaikouY + upper, fanghankaikouX[1] + border, fanghankaikouY + upper); //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]); ////ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]); //ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]); //int offsetX_00 = offsetX[0]; //Console.WriteLine("offsetX:" + offsetX_00); //int offsetX_temp = offsetX_00; //int offsetX_Left = offsetX_00; //for (int j = offsetY; j < LPIHouduY[0]; j++) //{ // ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); // Console.WriteLine("offsetX_temp:" + offsetX_temp); // if (Math.Abs(offsetX_temp - offsetX_00) < 5) // { // offsetX_00 = offsetX_temp; // if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; // if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; // } //} ////ceju.FanghanhouduForYouKaiKou_2(grayRect, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray); //int rightStart = loophouduX - (b[1] + 5); //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]); ////ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]); //ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]); //int offsetX_00 = offsetX[0]; //Console.WriteLine("offsetX:" + offsetX_00); //int offsetX_temp = offsetX_00; //int offsetX_Left = offsetX_00; //for (int j = offsetY; j < LPIHouduY[0]; j++) //{ // ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); // Console.WriteLine("offsetX_temp:" + offsetX_temp); // if (Math.Abs(offsetX_temp - offsetX_00) < 5) // { // offsetX_00 = offsetX_temp; // if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; // if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; // } //} for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++) { ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("undercutX_temp:" + offsetX_temp); if (Math.Abs(offsetX_temp - offsetX_00) < 11/*<-999(2).jpg10*//*5*/) { offsetX_00 = offsetX_temp; if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } //undercut int[] undercutX = new int[2] { offsetX_Left, offsetX[0] }; int undercutY = tonghouY[1] + 20; //ceju.FanghanUndercutForYouKaiKou(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]); //undercutX[1] = offsetX[0]; undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //update value offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //安全距離 int anquanjuliY = tonghouY[1] + 50; int[] anquanjuliX = { b[1], undercutX[0] }; anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); #region[释放内存] if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } #endregion } } /// /// 防焊 双层铜 /// public class FanghanShuangmiantong : AutoMeasureAnalysis { public DataInfor tonghou = new DataInfor(); public DataInfor fanghanhoudu = new DataInfor(); public DataInfor LPIhoudu = new DataInfor(); public DataInfor anquanjuli = new DataInfor(); public DataInfor undercut = new DataInfor(); public DataInfor offset = new DataInfor(); private void Initialize() { tonghou.name = "銅厚"; tonghou.ID = "100192"; tonghou.aliasName = "JZABKC"; fanghanhoudu.name = "防焊厚度"; fanghanhoudu.ID = "100193"; fanghanhoudu.aliasName = "RXXAKL"; LPIhoudu.name = "LPI厚度"; LPIhoudu.ID = "100194"; LPIhoudu.aliasName = "XJCGWX"; anquanjuli.name = "安全距離"; anquanjuli.ID = "100195"; anquanjuli.drawType = "MeasureHLine"; anquanjuli.aliasName = "LOCBDK"; undercut.name = "undercut"; undercut.ID = "100197"; undercut.drawType = "MeasureHLine"; undercut.aliasName = "LORGCP"; offset.name = "offset"; offset.ID = "100196"; offset.drawType = "MeasureHLine"; offset.aliasName = "MTFOCO"; dataInfors.Add(tonghou); dataInfors.Add(fanghanhoudu); dataInfors.Add(LPIhoudu); dataInfors.Add(anquanjuli); dataInfors.Add(undercut); dataInfors.Add(offset); } public override void Compute(Mat image, bool isCropFlag, int X, int Y) { Initialize(); Ceju ceju = new Ceju(); int upper = 0; int border = 0; if (isCropFlag) { upper = Y; border = X; } Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY); //銅厚 int[] b = new int[3]; int[] y = new int[2]; int[] tonghouY = new int[2]; ceju.FanhanShuangcengTonghou_1(gray, out tonghouY, out y, out b); int tonghouX = b[1] - 150; if (tonghouX <= 0 || tonghouY[0] <= 0) { ceju.FanhanShuangcengTonghou_1(gray, out tonghouY, out y, out b, 180); //if (tonghouY[0] == 0) //{//ER(114).JPG // //tonghouY[0] = start; // for (int i = start - 50/* + 20*/; i < y[1] - 0/*20*/; i++) // { // sum = result2[i, i + 1, tonghouX - 50, tonghouX + 50].Sum(); // if ((int)sum > 20/*50*/) // { // tonghouY[0] = i; // break; // } // } //} } tonghouX = b[1] - 150; if (tonghouX <= 0 || tonghouY[0] <= 0) { ceju.FanhanShuangcengTonghou_2(gray, out tonghouY, out y, out b); tonghouX = b[1] - 150; } if (tonghouX <= 0 || tonghouY[0] <= 0) return; tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper); //防焊厚度 int fanghanhouduX = b[1] - 150; int[] fanghanhouduY = new int[2]; //ceju.Fanghanhoudu4(gray, y, b, tonghouY, out fanghanhouduY); fanghanhouduY[0] = y[0] + 20;// tonghouY[0]; int minGray = 300 * 255; ceju.FanghanhouduForShuangmianTonghou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true); fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper); //LPI厚度 int LPIHouduX = b[1] + 100; int[] LPIHouduY = new int[2]; //ceju.FanghanLPI2(gray, tonghouY, b, fanghanhouduY, out LPIHouduY); LPIHouduY[0] = tonghouY[1]; ceju.FanghanLPIForShuangmianTong(gray, tonghouY, b, fanghanhouduY, out LPIHouduY); ceju.FanghanhouduForShuangmianTonghou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false); LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper); //offset int[] offsetX = new int[2]; int offsetY = LPIHouduY[1] + 15;//tonghouY[0] - 50; offsetX[1] = b[2]; offsetX[0] = LPIHouduX + 30;// fanghanhouduX; int loophouduY = LPIHouduY[1]; int loophouduX = LPIHouduX + 30; int loopminGray = minGray; int houduY = loophouduY; Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY); int colStart = 50;//<-125 loophouduX - (b[1] + 5); ceju.FanghanOffsetForShuangmianTong(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);//debug ER(14).JPG!!!! int offsetX_00 = offsetX[0];/////////////////////////////////////////////////////////////////////////// bool accLeftMargin = false; ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX_00, out offsetX[0]); if (offsetX_00 - offsetX[0] > 0 && offsetX_00 - offsetX[0] < 10) { accLeftMargin = true; } if (offsetX_00 - offsetX[0] < 0 && offsetX_00 - offsetX[0] > -20/*ER(14).JPG*/) offsetX[0] = offsetX_00; else offsetX_00 = offsetX[0]; Console.WriteLine("offsetX:" + offsetX_00); int leftDown = 0;//前提假设,按照左下边框测量 int offsetX_000 = offsetX[0]; int offsetX_temp = offsetX_00; int offsetX_Left = offsetX_00; int upperMaxTimes00 = 1;// 0; for (int j = offsetY; j < LPIHouduY[0]; j++) { ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("offsetX_temp:" + offsetX_temp); if (offsetX_temp - offsetX_00 < 0) leftDown++; if (offsetX_temp - offsetX_00 > 5 && offsetX_temp - offsetX_00 < 20 && upperMaxTimes00++ < 1 || Math.Abs(offsetX_temp - offsetX_00) < 5/*10*//*5*/) { offsetX_00 = offsetX_temp; if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } if (leftDown < 10/* <- ER(96).JPG 5*//*10*/) offsetX[0] = offsetX_000 - 5; //纠正191情况 if (true) { } //ceju.FanghanOffset6(gray, tonghouY, b, fanghanhouduY, out offsetX); offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50; offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); int upperMaxTimes = 0; for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++) { ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp); Console.WriteLine("undercutX_temp:" + offsetX_temp); if (/*Math.Abs(*/offsetX_temp - offsetX_Left/*)*/ > -25 && offsetX_temp - offsetX_Left < -10 && upperMaxTimes++ < 1 || Math.Abs(offsetX_temp - offsetX_00) < 11/*10*//*20*//*10*//*15*//*10*//*5*/) { if (offsetX_temp - offsetX_00 < -15)//0) offsetX_00 = offsetX_temp; else offsetX_00 -= 1; //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp; if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp; } } if (offsetX_000 - offsetX_Left < 5) offsetX_Left = Math.Min(offsetX[0], offsetX_000) - 15; //undercut int[] undercutX = new int[2] { offsetX_Left, offsetX[0] }; int undercutY = tonghouY[1] + 20; //ceju.FanghanUndercut6_3(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]); //undercutX[1] = offsetX[0]; //if (undercutX[1] - undercutX[0] > 100) undercutX[0] = undercutX[1] - 34; undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper); //update value offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper); //安全距離 int anquanjuliY = tonghouY[1] + 50; int[] anquanjuliX = { b[1], undercutX[0] }; anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper); #region[释放内存] if (gray != null && !gray.IsDisposed) { gray.Dispose(); } if (result != null && !result.IsDisposed) { result.Dispose(); } #endregion } } }