/// <summary>進行存檔</summary> public string SaveReport(RankArea rankArea) { string txtFileName; switch (rankArea) { case RankArea.Top: txtFileName = fileName + "ReportT.txt"; break; case RankArea.Down: txtFileName = fileName + "ReportD.txt"; break; default: throw SmileLib.EnumTool.OutOfEnum <RankArea>(); } string dataLine = ""; using (StreamWriter sw = new StreamWriter(txtFileName, false)) { string[] FileInfo = Path.GetFileName(fileName).Split('_'); if (FileInfo.Length == 3) { sw.WriteLine("受測者\t受測狀態\t區塊\t水平勾縫標準差\t垂直勾縫標準差\t水平傾角標準差\t垂直傾角標準差\t平均Y方向離差\t平均X方向離差\t旋轉角標準差\t3M角Y方向離差\t3M角X方向離差\t角Y方向離差\t角X方向離差"); dataLine = FileInfo[0] + "\t" + FileInfo[1] + "\t" + FileInfo[2] + "\t"; } else { sw.WriteLine("檔名\t水平勾縫標準差\t垂直勾縫標準差\t水平傾角標準差\t垂直傾角標準差\t平均Y方向離差\t平均X方向離差\t旋轉角標準差\t3M角Y方向離差\t3M角X方向離差\t角Y方向離差\t角X方向離差"); dataLine = Path.GetFileName(fileName) + "\t"; } dataLine += GapHSD.ToString() + "\t" + GapVSD.ToString() + "\t" + RowAngleSD.ToString() + "\t" + ColumnAngleSD.ToString() + "\t" + RowResidualAvg.ToString() + "\t" + ColumnResidualAvg.ToString() + "\t" + AngleSD.ToString() + "\t" + ResidualAvgY3m.ToString() + "\t" + ResidualAvgX3m.ToString() + "\t" + CornerResidualY.ToString() + "\t" + CornerResidualX.ToString(); sw.WriteLine(dataLine); foreach (string line in stringsToReport) { sw.WriteLine(line); } sw.Close(); } return(dataLine); }
public static TilesReport rankRectangleTiles(string fileName, MCvBox2D[,] Tiles, RectangleGrids myGrid, RankArea rankArea) { #region 評分 TilesReport myReport = new TilesReport(fileName); int rowEnd; int rowStart; switch (rankArea) { case RankArea.Top: rowStart = 0; rowEnd = RectangleGrids.ROW_COUNT_HALF; break; case RankArea.Down: rowStart = RectangleGrids.ROW_COUNT_HALF; rowEnd = RectangleGrids.ROW_COUNT; break; default: throw SmileLib.EnumTool.OutOfEnum <RankArea>(); } #region 評分_絕對位置 #if false myReport.newLine("絕對位置:"); double absoluteError = 0.0; for (int row = 0; row < rowEnd; row++) { string rowReport = ""; for (int column = 0; column < RectangleGrids.columnCount; column++) { if ((row + column) % 2 != 1) { Tile tempTile = new Tile(Tiles[column, row]); double tempError = 0.0; tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerLT, myGrid.TileModelLT(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerLD, myGrid.TileModelLD(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerRT, myGrid.TileModelRT(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerRD, myGrid.TileModelRD(column, row))); rowReport += "\t" + tempError; absoluteError += tempError; } else { rowReport += "\t"; } } myReport.newLine(rowReport); } myReport.newLine("絕對位置總誤差:\t" + absoluteError); #endif #endregion 評分_絕對位置 #region 評分_溝縫 myReport.newLine(""); myReport.newLine("溝縫間隔:"); List <double> gap = new List <double>(); #region 列與列間溝縫 myReport.newLine("列與列間溝縫:"); List <double> allRowError = new List <double>(); double helfTileWidth = myGrid.PixelFormMm(RectangleGrids.tileWidth) / 2; #region 考慮第0條至第6條(共7條)水平溝縫,將溝縫視為上鄰接列的附屬,所以最後一列沒有溝縫 for (int rowNum = rowStart; rowNum < rowEnd - 1; rowNum++) { string rowReport = "第" + rowNum.ToString("D2") + "條:"; List <double> rowError = new List <double>(); #region 依序考慮每一行磁磚要計算的溝縫 for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { #region 照行列,只計算"存在"磁磚位置 if ((columnNum + rowNum) % 2 == 0) { #region 只看奇數列中有存在的磁磚 #region 如果相對於本磁磚的左下磁磚存在的話 if (columnNum - 1 >= 0) { #region 溝縫差加上:左下磁磚中心點與上邊交點 與 本磁磚左下點 的y方向差 double disA = myGrid.mmFormPixel(myMath.GetDis <double>( Tiles[columnNum - 1, rowNum + 1].center.Y - helfTileWidth - new Tile(Tiles[columnNum, rowNum]).conerLD.Y)); rowError.Add(disA); allRowError.Add(disA); gap.Add(disA); #endregion 溝縫差加上:左下磁磚中心點與上邊交點 與 本磁磚左下點 的y方向差 #region 溝縫差加上:左下磁磚右上點 與 本磁磚中心點與下邊交點 的y方向差 double disB = myGrid.mmFormPixel(myMath.GetDis <double>( new Tile(Tiles[columnNum - 1, rowNum + 1]).conerRT.Y - helfTileWidth - Tiles[columnNum, rowNum].center.Y)); rowError.Add(disB); allRowError.Add(disB); gap.Add(disB); #endregion 溝縫差加上:左下磁磚右上點 與 本磁磚中心點與下邊交點 的y方向差 } #endregion 如果相對於本磁磚的左下磁磚存在的話 #region 如果相對於本磁磚的右下磁磚存在的話 if (columnNum + 1 < RectangleGrids.columnCount) { #region 溝縫差加上:右下磁磚左上點 與 本磁磚中心點與下邊交點 的y方向差 double disC = myGrid.mmFormPixel(myMath.GetDis <double>( new Tile(Tiles[columnNum + 1, rowNum + 1]).conerLT.Y - helfTileWidth - Tiles[columnNum, rowNum].center.Y)); rowError.Add(disC); allRowError.Add(disC); gap.Add(disC); #endregion 溝縫差加上:右下磁磚左上點 與 本磁磚中心點與下邊交點 的y方向差 #region 溝縫差加上:右下磁磚中心點與上邊交點 與 本磁磚右下點 的y方向差 double disD = myGrid.mmFormPixel(myMath.GetDis <double>( Tiles[columnNum + 1, rowNum + 1].center.Y - helfTileWidth - new Tile(Tiles[columnNum, rowNum]).conerRD.Y)); rowError.Add(disD); allRowError.Add(disD); gap.Add(disD); #endregion 溝縫差加上:右下磁磚中心點與上邊交點 與 本磁磚右下點 的y方向差 } #endregion 如果相對於本磁磚的右下磁磚存在的話 #endregion 只看奇數列中有存在的磁磚 } #endregion 照行列,只計算"存在"磁磚位置 } #endregion 依序考慮每一行磁磚要計算的溝縫 foreach (double err in rowError) { rowReport += "\t" + err; } rowReport += "\t平均:\t" + rowError.Average() + "\t標準差:\t" + rowError.ToArray().StandardDeviation(); myReport.newLine(rowReport); } #endregion 考慮第0條至第6條(共7條)水平溝縫,將溝縫視為上鄰接列的附屬,所以最後一列沒有溝縫 myReport.GapHSD = allRowError.ToArray().StandardDeviation(); #endregion 列與列間溝縫 #region 行與行間溝縫 myReport.newLine("行與行間溝縫:"); List <double> allColumnError = new List <double>(); for (int columnNum = 0; columnNum < RectangleGrids.gapCountInColumn; columnNum++) { string columnReport = "第" + columnNum.ToString("D2") + "條:"; List <double> columnError = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((columnNum + rowNum) % 2 == 0) { Tile tempTileLeft = new Tile(Tiles[columnNum, rowNum]); Tile tempTileRight = new Tile(Tiles[columnNum + 2, rowNum]); double disA = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileRight.conerLT.X - tempTileLeft.conerRT.X)); double disB = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileRight.conerLD.X - tempTileLeft.conerRD.X)); columnError.Add(disA); columnError.Add(disB); columnReport += "\t" + disA + "\t" + disB; allColumnError.Add(disA); allColumnError.Add(disB); gap.Add(disA); gap.Add(disB); } } columnReport += "\t平均:\t" + columnError.Average() + "\t標準差\t" + columnError.StandardDeviation(); myReport.newLine(columnReport); } myReport.GapVSD = allColumnError.StandardDeviation(); #endregion 行與行間溝縫 #region 分方向評分 double gapSD = gap.ToArray().StandardDeviation(); double gapAvg = gap.Average(); double gapMax = gap.Max(); double gapMin = gap.Min(); double gapRange = gapMax - gapMin; double gapRangeAvgRatio = gapRange / gapAvg; myReport.newLine("勾縫標準差:/t" + gapSD); myReport.GapSD = gapSD; myReport.newLine("勾縫極差:/t" + gapRange); myReport.GapRange = gapRange; myReport.newLine("平均勾縫寬:/t" + gapAvg); myReport.GapAvg = gapAvg; myReport.newLine("極差平均比/t" + gapAvg); myReport.GapRangeAvgRatio = gapRangeAvgRatio; #endregion 分方向評分 #endregion 評分_溝縫 #region 評分_磁磚角趨勢線 #if false myReport.newLine(""); myReport.newLine("磁磚角趨勢線"); #region 水平趨勢線 myReport.newLine("水平趨勢線"); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] tempTopXs = new double[RectangleGrids.ColumnCountInRow(rowNum) * 2]; double[] tempTopYs = new double[RectangleGrids.ColumnCountInRow(rowNum) * 2]; string HorizontalTrendLineTopX = ""; string HorizontalTrendLineTopY = ""; double[] tempDownXs = new double[RectangleGrids.ColumnCountInRow(rowNum) * 2]; double[] tempDownYs = new double[RectangleGrids.ColumnCountInRow(rowNum) * 2]; string HorizontalTrendLineDownX = ""; string HorizontalTrendLineDownY = ""; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { Tile tempTile = new Tile(Tiles[columnNum * 2 + (rowNum % 2), rowNum]); tempTopXs[columnNum * 2] = tempTile.conerLT.X; tempTopXs[columnNum * 2 + 1] = tempTile.conerRT.X; HorizontalTrendLineTopX += "\t" + tempTile.conerLT.X + "\t" + tempTile.conerRT.X; tempTopYs[columnNum * 2] = tempTile.conerLT.Y * -1; tempTopYs[columnNum * 2 + 1] = tempTile.conerRT.Y * -1; HorizontalTrendLineTopY += "\t" + tempTile.conerLT.Y + "\t" + tempTile.conerRT.Y; tempDownXs[columnNum * 2] = tempTile.conerLD.X; tempDownXs[columnNum * 2 + 1] = tempTile.conerRD.X; HorizontalTrendLineDownX += "\t" + tempTile.conerLD.X + "\t" + tempTile.conerRD.X; tempDownYs[columnNum * 2] = tempTile.conerLD.Y * -1; tempDownYs[columnNum * 2 + 1] = tempTile.conerRD.Y * -1; HorizontalTrendLineDownY += "\t" + tempTile.conerLD.Y + "\t" + tempTile.conerRD.Y; } myStatistics.TrendLine TrendLineTop = new myStatistics.TrendLine(tempTopXs, tempTopYs); myReport.newLine("第" + rowNum.ToString("D2") + "列上:"); myReport.newLine("角度(度數):\t" + TrendLineTop.Angle()); myReport.newLine("Xdata:\t" + HorizontalTrendLineTopX); myReport.newLine("Ydata:\t" + HorizontalTrendLineTopY); myStatistics.TrendLine TrendLineDown = new myStatistics.TrendLine(tempDownXs, tempDownYs); myReport.newLine("第" + rowNum.ToString("D2") + "列下:"); myReport.newLine("角度(度數):\t" + TrendLineDown.Angle()); myReport.newLine("Xdata:\t" + HorizontalTrendLineDownX); myReport.newLine("Ydata:\t" + HorizontalTrendLineDownY); } #endregion 水平趨勢線 #region 垂直趨勢線 myReport.newLine("垂直趨勢線"); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { double[] tempLeftXs = new double[rowEnd]; double[] tempLeftYs = new double[rowEnd]; string VerticalTrendLineLeftX = ""; string VerticalTrendLineLeftY = ""; double[] tempRightXs = new double[rowEnd]; double[] tempRightYs = new double[rowEnd]; string VerticalTrendLineRightX = ""; string VerticalTrendLineRightY = ""; for (int rowNum = rowStart; rowNum < rowEnd / 2; rowNum++) { Tile tempTile = new Tile(Tiles[columnNum, rowNum * 2 + (columnNum % 2)]); tempLeftXs[rowNum * 2] = tempTile.conerLT.X; tempLeftXs[rowNum * 2 + 1] = tempTile.conerLD.X; VerticalTrendLineLeftX += "\t" + tempTile.conerLT.X + "\t" + tempTile.conerLD.X; tempLeftYs[rowNum * 2] = tempTile.conerLT.Y * -1; tempLeftYs[rowNum * 2 + 1] = tempTile.conerLD.Y * -1; VerticalTrendLineLeftY += "\t" + tempTile.conerLT.Y + "\t" + tempTile.conerLD.Y; tempRightXs[rowNum * 2] = tempTile.conerRT.X; tempRightXs[rowNum * 2 + 1] = tempTile.conerRD.X; VerticalTrendLineRightX += "\t" + tempTile.conerRT.X + "\t" + tempTile.conerRD.X; tempRightYs[rowNum * 2] = tempTile.conerRT.Y * -1; tempRightYs[rowNum * 2 + 1] = tempTile.conerRD.Y * -1; VerticalTrendLineRightY += "\t" + tempTile.conerRT.Y + "\t" + tempTile.conerRD.Y; } myStatistics.TrendLine TrendLineTop = new myStatistics.TrendLine(tempLeftYs, tempLeftXs); myReport.newLine("第" + columnNum.ToString("D2") + "行左:"); myReport.newLine("角度(度數):\t" + myTool.CorrectingAngle_YXtoXY(TrendLineTop.Angle())); myReport.newLine("Xdata:\t" + VerticalTrendLineLeftX); myReport.newLine("Ydata:\t" + VerticalTrendLineLeftY); myStatistics.TrendLine TrendLineRight = new myStatistics.TrendLine(tempRightYs, tempRightXs); myReport.newLine("第" + columnNum.ToString("D2") + "行右:"); myReport.newLine("角度(度數):\t" + myTool.CorrectingAngle_YXtoXY(TrendLineRight.Angle())); myReport.newLine("Xdata:\t" + VerticalTrendLineRightX); myReport.newLine("Ydata:\t" + VerticalTrendLineRightY); } #endregion 垂直趨勢線 #endif #endregion 評分_磁磚角趨勢線 #region 評分_磁磚中心趨勢線 myReport.newLine(""); myReport.newLine("磁磚中心趨勢線"); #region 水平趨勢線 myReport.newLine("水平趨勢線"); List <double> HorizontalTrendLineAngle = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] Xdata = new double[RectangleGrids.ColumnCountInRow(rowNum)]; double[] Ydata = new double[RectangleGrids.ColumnCountInRow(rowNum)]; string HorizontalTrendLineX = ""; string HorizontalTrendLineY = ""; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { Xdata[columnNum] = Tiles[columnNum * 2 + (rowNum % 2), rowNum].center.X; HorizontalTrendLineX += "\t" + Xdata[columnNum]; Ydata[columnNum] = Tiles[columnNum * 2 + (rowNum % 2), rowNum].center.Y * -1; HorizontalTrendLineY += "\t" + Ydata[columnNum]; } myStatistics.TrendLine TrendLine = new myStatistics.TrendLine(Xdata, Ydata); double angle = TrendLine.Angle(); myReport.newLine("第" + rowNum.ToString("D2") + "列:"); myReport.newLine("角度(度數):\t" + TrendLine.Angle()); HorizontalTrendLineAngle.Add(angle); myReport.newLine("Xdata:\t" + HorizontalTrendLineX); myReport.newLine("Ydata:\t" + HorizontalTrendLineY); } double rowAngleSD = HorizontalTrendLineAngle.ToArray().StandardDeviation(); myReport.RowAngleSD = rowAngleSD; myReport.newLine("水平趨勢線夾角標準差" + rowAngleSD); #endregion 水平趨勢線 #region 垂直趨勢線 myReport.newLine("垂直趨勢線"); List <double> VerticalTrendLineAngle = new List <double>(); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { List <double> Xdata = new List <double>(); List <double> Ydata = new List <double>(); string VerticalTrendLineX = ""; string VerticalTrendLineY = ""; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((columnNum + rowNum) % 2 == 1) { continue; } double x = Tiles[columnNum, rowNum].center.X; double y = Tiles[columnNum, rowNum].center.Y * -1; Xdata.Add(x); VerticalTrendLineX += "\t" + x; Ydata.Add(y); VerticalTrendLineY += "\t" + y; } myStatistics.TrendLine TrendLine = new myStatistics.TrendLine(Ydata.ToArray(), Xdata.ToArray()); double angle = myTool.CorrectingAngle_YXtoXY(TrendLine.Angle()); VerticalTrendLineAngle.Add(angle); myReport.newLine("第" + columnNum.ToString("D2") + "行:"); myReport.newLine("角度(度數):\t" + angle); myReport.newLine("Xdata:\t" + VerticalTrendLineX); myReport.newLine("Ydata:\t" + VerticalTrendLineY); } double columnAngleSD = VerticalTrendLineAngle.ToArray().StandardDeviation(); myReport.ColumnAngleSD = columnAngleSD; myReport.newLine("垂直趨勢線夾角標準差" + columnAngleSD); #endregion 垂直趨勢線 #endregion 評分_磁磚中心趨勢線 #region 評分_座標標準差 #if false myReport.newLine(""); myReport.newLine("座標標準差"); #region 列中磁磚的Y方向 myReport.newLine("列中磁磚的Y方向"); List <double> RowY = new List <double>(); List <double> RowSpacing = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] TileYC = new double[RectangleGrids.ColumnCountInRow(rowNum)]; double[] TileYE = new double[RectangleGrids.ColumnCountInRow(rowNum)]; string TileYReport = "第" + rowNum.ToString("D2") + "列:"; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { TileYC[columnNum] = myGrid.mmFormPixel(Tiles[columnNum * 2 + (rowNum % 2), rowNum].center.Y); TileYReport += "\t" + TileYC[columnNum]; } double TileYC_avg = TileYC.Average(); if (rowNum % 2 == 1) { TileYReport += "\t"; } TileYReport += "\t平均:\t" + TileYC_avg + "\t標準差\t" + myStatistics.StandardDeviation(TileYC) + "\t差:"; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { TileYE[columnNum] = TileYC[columnNum] - TileYC_avg; TileYReport += "\t" + TileYE[columnNum]; } myReport.newLine(TileYReport); RowY.Add(TileYC.Average()); } myReport.newLine("列與列間隔:"); string RowSpacingReport = "\t"; for (int rowNum = 0; rowNum < RowY.Count - 1; rowNum++) { double spacing = RowY[rowNum + 1] - RowY[rowNum]; RowSpacing.Add(spacing); RowSpacingReport += "\t" + spacing; } myReport.newLine(RowSpacingReport + "\t平均\t" + RowSpacing.Average() + "\t標準差\t" + RowSpacing.StandardDeviation()); #endregion 列中磁磚的Y方向 #region 行中磁磚的X方向 myReport.newLine("行中磁磚的X方向"); List <double> ColumnX = new List <double>(); List <double> ColumnSpacing = new List <double>(); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { List <double> TileXC = new List <double>(); List <double> TileXE = new List <double>(); string TileXReport = "第" + columnNum.ToString("D2") + "行:"; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((columnNum + rowNum) % 2 == 1) { continue; } double centerX = myGrid.mmFormPixel(Tiles[columnNum, rowNum].center.X); TileXC.Add(centerX); TileXReport += "\t" + centerX; } double TileXC_avg = TileXC.Average(); if (columnNum % 2 == 1) { TileXReport += "\t"; } TileXReport += "\t平均:\t" + TileXC_avg + "\t標準差\t" + TileXC.StandardDeviation() + "\t差:"; for (int rowNum = 0; rowNum < TileXC.Count; rowNum++) { double err = TileXC[rowNum] - TileXC_avg; TileXE.Add(err); TileXReport += "\t" + err; } myReport.newLine(TileXReport); ColumnX[columnNum] = TileXC.Average(); } myReport.newLine("行與行間隔:"); string ColumnSpacingReport = "\t"; for (int columnNum = 0; columnNum < RectangleGrids.columnCount - 1; columnNum++) { ColumnSpacing[columnNum] = ColumnX[columnNum + 1] - ColumnX[columnNum]; ColumnSpacingReport += "\t" + ColumnSpacing[columnNum]; } myReport.newLine(ColumnSpacingReport + "\t平均\t" + ColumnSpacing.Average() + "\t標準差\t" + myStatistics.StandardDeviation(ColumnSpacing)); #endregion 行中磁磚的X方向 #endif #endregion 評分_座標標準差 #region 評分_磁磚中心與趨勢線距離和 myReport.newLine("筆直度:"); #region 平均Y方向離差 myReport.newLine("Y方向離差:"); double sumOfTileCenterToTrendLineH = 0; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { string rowReport = "第" + rowNum + "列"; double[] Xdata = new double[RectangleGrids.ColumnCountInRow(rowNum)]; double[] Ydata = new double[RectangleGrids.ColumnCountInRow(rowNum)]; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { Xdata[columnNum] = Tiles[columnNum * 2 + (rowNum % 2), rowNum].center.X; Ydata[columnNum] = Tiles[columnNum * 2 + (rowNum % 2), rowNum].center.Y * -1; } myStatistics.TrendLine theTrendLine = new myStatistics.TrendLine(Xdata, Ydata); for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { double Residual = Math.Abs(theTrendLine.PointToLineDis(Xdata[columnNum], Ydata[columnNum])); Residual = myGrid.mmFormPixel(Residual); sumOfTileCenterToTrendLineH += Residual; rowReport += "\t" + Residual; } myReport.newLine(rowReport); } int numberOfTile = RectangleGrids.tileCount / 2; double rowResidualAvg = sumOfTileCenterToTrendLineH / numberOfTile; string TotalRowReport = "平均y方向離差:" + rowResidualAvg.ToString("0.000"); myReport.newLine(TotalRowReport); myReport.RowResidualAvg = rowResidualAvg; #endregion 平均Y方向離差 #region 平均X方向離差 myReport.newLine("平均X方向離差"); double sumOfTileCenterToTrendLineV = 0; for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { string ColumnReport = "第" + columnNum + "行"; List <double> Xdata = new List <double>(); List <double> Ydata = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((columnNum + rowNum) % 2 == 1) { continue; } double x = Tiles[columnNum, rowNum].center.X; double y = Tiles[columnNum, rowNum].center.Y * -1; Xdata.Add(x); Ydata.Add(y); } myStatistics.TrendLine theTrendLine = new myStatistics.TrendLine(Ydata.ToArray(), Xdata.ToArray()); for (int index = 0; index < Xdata.Count; index++) { double Residual = Math.Abs(theTrendLine.PointToLineDis(Ydata[index], Xdata[index])); Residual = myGrid.mmFormPixel(Residual); sumOfTileCenterToTrendLineV += Residual; ColumnReport += "\t" + Residual; } myReport.newLine(ColumnReport); } double columnResidualAvg = sumOfTileCenterToTrendLineV / numberOfTile; string TotalColumnReport = "平均X方向離差:" + columnResidualAvg.ToString("0.000"); myReport.newLine(TotalColumnReport); myReport.ColumnResidualAvg = columnResidualAvg; #endregion 平均X方向離差 #endregion 評分_磁磚中心與趨勢線距離和 #region 評分_磁磚旋轉角 myReport.newLine(""); myReport.newLine("磁磚旋轉角"); string TileAngleFirstRow = ""; for (int columnNUm = 0; columnNUm < RectangleGrids.columnCount; columnNUm++) { TileAngleFirstRow += "\t第" + columnNUm.ToString("D2") + "行"; } TileAngleFirstRow += "\t平均\t標準差"; myReport.newLine(TileAngleFirstRow); #region 印出每列 for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { string angleReport = "第" + rowNum.ToString("D2") + "列"; if (rowNum % 2 == 1) { angleReport += "\t"; } double[] angleDataInRow = new double[RectangleGrids.ColumnCountInRow(rowNum)]; for (int columnNum = 0; columnNum < RectangleGrids.ColumnCountInRow(rowNum); columnNum++) { angleDataInRow[columnNum] = Tiles[columnNum * 2 + (rowNum % 2), rowNum].angle; if (columnNum != 0) { angleReport += "\t"; } angleReport += "\t" + angleDataInRow[columnNum]; } if (rowNum % 2 == 1) { angleReport += "\t"; } myReport.newLine(angleReport + "\t" + angleDataInRow.Average() + "\t" + myStatistics.StandardDeviation(angleDataInRow)); } #endregion 印出每列 #region 統計每行 string angleAvgInColumn = "平均"; string angleSDInColumn = "標準差"; for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { List <double> angleData = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((columnNum + rowNum) % 2 == 1) { continue; } angleData.Add(Tiles[columnNum, rowNum].angle); } angleAvgInColumn += "\t" + angleData.Average(); angleSDInColumn += "\t" + angleData.StandardDeviation(); } myReport.newLine(angleAvgInColumn); myReport.newLine(angleSDInColumn); #endregion 統計每行 #region 統計整個 List <double> wholeAngleData = new List <double>(); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((rowNum + columnNum) % 2 == 0) { wholeAngleData.Add(Tiles[columnNum, rowNum].angle); } } } #endregion 統計整個 myReport.newLine("總平均\t" + wholeAngleData.Average()); myReport.AngleSD = myStatistics.StandardDeviation(wholeAngleData); myReport.newLine("總標準差\t" + myReport.AngleSD); #endregion 評分_磁磚旋轉角 #region 林國良法(磁磚角離差) #region 垂直離差 List <double> residualSetY = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { List <PointF> pointSetInLineUpper = new List <PointF>(); List <PointF> pointSetInLineLower = new List <PointF>(); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { if ((rowNum + columnNum) % 2 != 0) { continue; } Tile currentTile = new Tile(Tiles[columnNum, rowNum]); pointSetInLineUpper.Add(currentTile.conerLT); pointSetInLineUpper.Add(currentTile.conerRT); pointSetInLineLower.Add(currentTile.conerLD); pointSetInLineLower.Add(currentTile.conerRD); } myStatistics.TrendLine currentTrendLineUpper = new myStatistics.TrendLine(pointSetInLineUpper); myStatistics.TrendLine currentTrendLineLower = new myStatistics.TrendLine(pointSetInLineLower); foreach (var point in pointSetInLineUpper) { double residual = Math.Abs(currentTrendLineUpper.PointToLineDis(point.X, point.Y)); residualSetY.Add(residual); } foreach (var point in pointSetInLineLower) { double residual = Math.Abs(currentTrendLineLower.PointToLineDis(point.X, point.Y)); residualSetY.Add(residual); } } double residualAvgY = residualSetY.Average(); double residualYPerImageWidth = myGrid.mmFormPixel(residualAvgY); myReport.newLine("平均垂直離差(mm):" + residualYPerImageWidth); myReport.CornerResidualY = residualYPerImageWidth; double imageWidthInMm = myGrid.mmFormPixel(myGrid.WidthInPixel); double residualYPer3mInMm = residualYPerImageWidth / imageWidthInMm * 3000; myReport.newLine("3m垂直離差(mm):" + residualYPer3mInMm); myReport.ResidualAvgY3m = residualYPer3mInMm; #endregion 垂直離差 #region 水平離差 myReport.newLine("磁磚角離差X方向:"); List <double> residualSetX = new List <double>(); for (int columnNum = 0; columnNum < RectangleGrids.columnCount; columnNum++) { List <PointF> pointSetInLineLeft = new List <PointF>(); List <PointF> pointSetInLineRight = new List <PointF>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { if ((rowNum + columnNum) % 2 != 0) { continue; } Tile currentTile = new Tile(Tiles[columnNum, rowNum]); pointSetInLineLeft.Add(currentTile.conerLT); pointSetInLineLeft.Add(currentTile.conerLD); pointSetInLineRight.Add(currentTile.conerRT); pointSetInLineRight.Add(currentTile.conerRD); } myStatistics.TrendLine currentTrendLineLeft = new myStatistics.TrendLine(pointSetInLineLeft, true); myStatistics.TrendLine currentTrendLineRight = new myStatistics.TrendLine(pointSetInLineRight, true); foreach (var point in pointSetInLineLeft) { double residual = Math.Abs(currentTrendLineLeft.PointToLineDis(point.Y, point.X)); residualSetX.Add(residual); } foreach (var point in pointSetInLineRight) { double residual = Math.Abs(currentTrendLineRight.PointToLineDis(point.Y, point.X)); residualSetX.Add(residual); } } double residualAvgX = residualSetX.Average(); double residualXPerImageHeight = myGrid.mmFormPixel(residualAvgX); myReport.newLine("平均水平離差(mm):" + residualXPerImageHeight); myReport.CornerResidualX = residualXPerImageHeight; double imageHeightInMm = myGrid.mmFormPixel(myGrid.HeightInPixel); double residualXPer3mInMm = residualXPerImageHeight / imageHeightInMm * 3000; myReport.newLine("3m水平離差(mm):" + residualXPer3mInMm); myReport.ResidualAvgX3m = residualXPer3mInMm; #endregion 水平離差 #endregion 林國良法(磁磚角離差) //string output = myReport.result(TilesType.Rectangle); //myReport.doToReport("評分報告"); myReport.SaveReport(rankArea); //return myReport.ScoringByVariance(TilesType.Rectangle); return(myReport); //return myReport.SaveReport(rankTopOnly); #endregion 評分 }
public static TilesReport RankSquareTile(string fileName, MCvBox2D[,] Tiles, SquareGrids myGrid, RankArea rankArea, ref ErrMark outPutErrMark) { #region 評分 TilesReport myReport = new TilesReport(fileName); int rowStart; int rowEnd; switch (rankArea) { case RankArea.Top: rowStart = 0; rowEnd = SquareGrids.ROW_COUNT_HALF; break; case RankArea.Down: rowStart = SquareGrids.ROW_COUNT_HALF; rowEnd = SquareGrids.ROW_COUNT; break; default: throw SmileLib.EnumTool.OutOfEnum <RankArea>(); } #region 評分_絕對位置 #if false myReport.newLine("絕對位置:"); double absoluteError = 0.0; for (int row = 0; row < rowEnd; row++) { string rowReport = ""; for (int column = 0; column < SquareGrids.columnCount; column++) { Tile tempTile = new Tile(Tiles[column, row]); double tempError = 0.0; tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerLT, myGrid.TileModelLT(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerLD, myGrid.TileModelLD(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerRT, myGrid.TileModelRT(column, row))); tempError += myGrid.mmFormPixel(myMath.GetDistance(tempTile.conerRD, myGrid.TileModelRD(column, row))); rowReport += "\t" + tempError; absoluteError += tempError; } myReport.newLine(rowReport); } myReport.newLine("絕對位置總誤差:\t" + absoluteError); #endif #endregion 評分_絕對位置 #region 評分_溝縫 myReport.newLine(""); myReport.newLine("溝縫間隔:"); List <double> gap = new List <double>(); Dictionary <LineSegment2DF, double> gapAndDis = new Dictionary <LineSegment2DF, double>(); #region 列與列間溝縫 myReport.newLine("列與列間溝縫:"); List <double> allRowError = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd - 1; rowNum++) { string rowReport = "第" + rowNum.ToString("D2") + "條:"; double[] rowError = new double[SquareGrids.COLUMN_COUNT * 2]; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { Tile tempTileUp = new Tile(Tiles[columnNum, rowNum]); Tile tempTileDown = new Tile(Tiles[columnNum, rowNum + 1]); rowError[columnNum * 2] = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileDown.conerLT.Y - tempTileUp.conerLD.Y)); LineSegment2DF leftLine = new LineSegment2DF(tempTileDown.conerLT, tempTileUp.conerLD); rowError[columnNum * 2 + 1] = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileDown.conerRT.Y - tempTileUp.conerRD.Y)); LineSegment2DF rightLine = new LineSegment2DF(tempTileDown.conerRT, tempTileUp.conerRD); rowReport += "\t" + rowError[columnNum * 2] + "\t" + rowError[columnNum * 2 + 1]; double gapA = rowError[columnNum * 2]; double gapB = rowError[columnNum * 2 + 1]; gapAndDis.Add(leftLine, gapA); gapAndDis.Add(rightLine, gapB); allRowError.Add(gapA); allRowError.Add(gapB); gap.Add(gapA); gap.Add(gapB); } rowReport += "\t平均:\t" + rowError.Average() + "\t標準差:\t" + rowError.StandardDeviation(); myReport.newLine(rowReport); } myReport.GapHSD = allRowError.ToArray().StandardDeviation(); #endregion 列與列間溝縫 #region 行與行間溝縫 myReport.newLine("行與行間溝縫:"); List <double> allColumnError = new List <double>(); for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT - 1; columnNum++) { string columnReport = "第" + columnNum.ToString("D2") + "條:"; List <double> columnError = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Tile tempTileLeft = new Tile(Tiles[columnNum, rowNum]); Tile tempTileRight = new Tile(Tiles[columnNum + 1, rowNum]); double gapC = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileRight.conerLT.X - tempTileLeft.conerRT.X)); columnError.Add(gapC); LineSegment2DF topLine = new LineSegment2DF(tempTileRight.conerLT, tempTileLeft.conerRT); double gapD = myGrid.mmFormPixel(myMath.GetDis <float>(tempTileRight.conerLD.X - tempTileLeft.conerRD.X)); columnError.Add(gapD); LineSegment2DF downLine = new LineSegment2DF(tempTileRight.conerLD, tempTileLeft.conerRD); columnReport += "\t" + gapC + "\t" + gapD; gapAndDis.Add(topLine, gapC); gapAndDis.Add(downLine, gapD); allColumnError.Add(gapC); allColumnError.Add(gapD); gap.Add(gapC); gap.Add(gapD); } columnReport += "\t平均:\t" + columnError.Average() + "\t標準差\t" + columnError.ToArray().StandardDeviation(); myReport.newLine(columnReport); } myReport.GapVSD = allColumnError.ToArray().StandardDeviation(); #endregion 行與行間溝縫 #region 分方向評分 double gapSD = gap.ToArray().StandardDeviation(); double gapAvg = gap.Average(); double gapMax = gap.Max(); double gapMin = gap.Min(); double gapRange = gapMax - gapMin; double gapRangeAvgRatio = gapRange / gapAvg; myReport.newLine("勾縫標準差:/t" + gapSD); myReport.GapSD = gapSD; myReport.newLine("勾縫極差:/t" + gapRange); myReport.GapRange = gapRange; myReport.newLine("平均勾縫寬:/t" + gapAvg); myReport.GapAvg = gapAvg; myReport.newLine("極差平均比/t" + gapAvg); myReport.GapRangeAvgRatio = gapRangeAvgRatio; var ErrGap = from outputGap in gapAndDis where !outputGap.Value.IsBetween(gapAvg - ErrMark.GapSquareTh, gapAvg + ErrMark.GapSquareTh) select outputGap.Key; outPutErrMark.GapErr = ErrGap.ToList(); #endregion 分方向評分 #endregion 評分_溝縫 #region 評分_磁磚角趨勢線 #if false myReport.newLine(""); myReport.newLine("磁磚角趨勢線"); #region 水平趨勢線 myReport.newLine("水平趨勢線"); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] tempTopXs = new double[SquareGrids.columnCount * 2]; double[] tempTopYs = new double[SquareGrids.columnCount * 2]; string HorizontalTrendLineX = ""; string HorizontalTrendLineY = ""; for (int columnNum = 0; columnNum < SquareGrids.columnCount; columnNum++) { Tile tempTile = new Tile(Tiles[columnNum, rowNum]); tempTopXs[columnNum * 2] = tempTile.conerLT.X; tempTopXs[columnNum * 2 + 1] = tempTile.conerRT.X; HorizontalTrendLineX += "\t" + tempTile.conerLT.X + "\t" + tempTile.conerRT.X; tempTopYs[columnNum * 2] = tempTile.conerLT.Y * -1; tempTopYs[columnNum * 2 + 1] = tempTile.conerRT.Y * -1; HorizontalTrendLineY += "\t" + tempTile.conerLT.Y + "\t" + tempTile.conerRT.Y; } myStatistics.TrendLine TrendLineTop = new myStatistics.TrendLine(tempTopXs, tempTopYs); myReport.newLine("第" + rowNum.ToString("D2") + "列上:"); myReport.newLine("角度(度數):\t" + TrendLineTop.Angle()); myReport.newLine("Xdata:\t" + HorizontalTrendLineX); myReport.newLine("Ydata:\t" + HorizontalTrendLineY); double[] tempDownXs = new double[SquareGrids.columnCount * 2]; double[] tempDownYs = new double[SquareGrids.columnCount * 2]; HorizontalTrendLineX = ""; HorizontalTrendLineY = ""; for (int columnNum = 0; columnNum < SquareGrids.columnCount; columnNum++) { Tile tempTile = new Tile(Tiles[columnNum, rowNum]); tempTopXs[columnNum * 2] = tempTile.conerLD.X; tempTopXs[columnNum * 2 + 1] = tempTile.conerRD.X; HorizontalTrendLineX += "\t" + tempTile.conerLD.X + "\t" + tempTile.conerRD.X; tempTopYs[columnNum * 2] = tempTile.conerLD.Y * -1; tempTopYs[columnNum * 2 + 1] = tempTile.conerRD.Y * -1; HorizontalTrendLineY += "\t" + tempTile.conerLD.Y + "\t" + tempTile.conerRD.Y; } myStatistics.TrendLine TrendLineDown = new myStatistics.TrendLine(tempTopXs, tempTopYs); myReport.newLine("第" + rowNum.ToString("D2") + "列下:"); myReport.newLine("角度(度數):\t" + TrendLineDown.Angle()); myReport.newLine("Xdata:\t" + HorizontalTrendLineX); myReport.newLine("Ydata:\t" + HorizontalTrendLineY); } #endregion 水平趨勢線 #region 垂直趨勢線 myReport.newLine("垂直趨勢線"); for (int columnNum = 0; columnNum < SquareGrids.columnCount; columnNum++) { double[] tempTopXs = new double[rowEnd * 2]; double[] tempTopYs = new double[rowEnd * 2]; string VerticalTrendLineX = ""; string VerticalTrendLineY = ""; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Tile tempTile = new Tile(Tiles[columnNum, rowNum]); tempTopXs[rowNum * 2] = tempTile.conerLT.X; tempTopXs[rowNum * 2 + 1] = tempTile.conerLD.X; VerticalTrendLineX += "\t" + tempTile.conerLT.X + "\t" + tempTile.conerLD.X; tempTopYs[rowNum * 2] = tempTile.conerLT.Y * -1; tempTopYs[rowNum * 2 + 1] = tempTile.conerLD.Y * -1; VerticalTrendLineY += "\t" + tempTile.conerLT.Y + "\t" + tempTile.conerLD.Y; } myStatistics.TrendLine TrendLineTop = new myStatistics.TrendLine(tempTopYs, tempTopXs); myReport.newLine("第" + columnNum.ToString("D2") + "行左:"); myReport.newLine("角度(度數):\t" + myTool.CorrectingAngle_YXtoXY(TrendLineTop.Angle())); myReport.newLine("Xdata:\t" + VerticalTrendLineX); myReport.newLine("Ydata:\t" + VerticalTrendLineY); double[] tempDownXs = new double[rowEnd * 2]; double[] tempDownYs = new double[rowEnd * 2]; VerticalTrendLineX = ""; VerticalTrendLineY = ""; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Tile tempTile = new Tile(Tiles[columnNum, rowNum]); tempTopXs[rowNum * 2] = tempTile.conerRT.X; tempTopXs[rowNum * 2 + 1] = tempTile.conerRD.X; VerticalTrendLineX += "\t" + tempTile.conerRT.X + "\t" + tempTile.conerRD.X; tempTopYs[rowNum * 2] = tempTile.conerRT.Y * -1; tempTopYs[rowNum * 2 + 1] = tempTile.conerRD.Y * -1; VerticalTrendLineY += "\t" + tempTile.conerRT.Y + "\t" + tempTile.conerRD.Y; } myStatistics.TrendLine TrendLineDown = new myStatistics.TrendLine(tempTopYs, tempTopXs); myReport.newLine("第" + columnNum.ToString("D2") + "行右:"); myReport.newLine("角度(度數):\t" + myTool.CorrectingAngle_YXtoXY(TrendLineDown.Angle())); myReport.newLine("Xdata:\t" + VerticalTrendLineX); myReport.newLine("Ydata:\t" + VerticalTrendLineY); } #endregion 垂直趨勢線 #endif #endregion 評分_磁磚角趨勢線 #region 評分_磁磚中心趨勢線 myReport.newLine(""); myReport.newLine("磁磚中心趨勢線夾角"); #region 水平趨勢線 myReport.newLine("水平趨勢線夾角"); List <double> HorizontalTrendLineaAngle = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] Xdata = new double[SquareGrids.COLUMN_COUNT]; double[] Ydata = new double[SquareGrids.COLUMN_COUNT]; string HorizontalTrendLineX = ""; string HorizontalTrendLineY = ""; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { Xdata[columnNum] = Tiles[columnNum, rowNum].center.X; HorizontalTrendLineX += "\t" + Xdata[columnNum]; Ydata[columnNum] = Tiles[columnNum, rowNum].center.Y * -1; HorizontalTrendLineY += "\t" + Ydata[columnNum]; } myStatistics.TrendLine TrendLine = new myStatistics.TrendLine(Xdata, Ydata); double angle = TrendLine.Angle(); myReport.newLine("第" + rowNum.ToString("D2") + "列:"); myReport.newLine("角度(度數):\t" + angle); HorizontalTrendLineaAngle.Add(angle); myReport.newLine("Xdata:\t" + HorizontalTrendLineX); myReport.newLine("Ydata:\t" + HorizontalTrendLineY); } double rowAngleSD = HorizontalTrendLineaAngle.ToArray().StandardDeviation(); myReport.RowAngleSD = rowAngleSD; myReport.newLine("水平趨勢線夾角標準差" + rowAngleSD); #endregion 水平趨勢線 #region 垂直趨勢線 myReport.newLine("垂直趨勢線"); List <double> VerticalTrendLineAngle = new List <double>(); for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { List <double> Xdata = new List <double>(); List <double> Ydata = new List <double>(); string VerticalTrendLineX = ""; string VerticalTrendLineY = ""; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { float x = Tiles[columnNum, rowNum].center.X; Xdata.Add(x); VerticalTrendLineX += "\t" + x; float y = Tiles[columnNum, rowNum].center.Y * -1; Ydata.Add(y); VerticalTrendLineY += "\t" + y; } myStatistics.TrendLine TrendLine = new myStatistics.TrendLine(Ydata.ToArray(), Xdata.ToArray()); double angle = myTool.CorrectingAngle_YXtoXY(TrendLine.Angle()); VerticalTrendLineAngle.Add(angle); myReport.newLine("第" + columnNum.ToString("D2") + "行:"); myReport.newLine("角度(度數):\t" + angle); myReport.newLine("Xdata:\t" + VerticalTrendLineX); myReport.newLine("Ydata:\t" + VerticalTrendLineY); } double columnAngleSD = VerticalTrendLineAngle.ToArray().StandardDeviation(); myReport.ColumnAngleSD = columnAngleSD; myReport.newLine("垂直趨勢線夾角標準差" + columnAngleSD); #endregion 垂直趨勢線 #endregion 評分_磁磚中心趨勢線 #region 評分_座標標準差 #if false myReport.newLine(""); myReport.newLine("座標標準差"); #region 列中磁磚的Y方向 myReport.newLine("列中磁磚的Y方向"); List <double> RowY = new List <double>(); List <double> RowSpacing = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double[] TileYC = new double[SquareGrids.COLUMN_COUNT]; double[] TileYE = new double[SquareGrids.COLUMN_COUNT]; string TileYReport = "第" + rowNum.ToString("D2") + "列:"; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { TileYC[columnNum] = myGrid.mmFormPixel(Tiles[columnNum, rowNum].center.Y); TileYReport += "\t" + TileYC[columnNum]; } double TileYC_avg = TileYC.Average(); TileYReport += "\t平均:\t" + TileYC_avg + "\t標準差\t" + TileYC.StandardDeviation() + "\t差:"; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { TileYE[columnNum] = TileYC[columnNum] - TileYC_avg; TileYReport += "\t" + TileYE[columnNum]; } myReport.newLine(TileYReport); RowY.Add(TileYC.Average()); } myReport.newLine("列與列間隔:"); string RowSpacingReport = "\t"; for (int rowNum = 0; rowNum < RowY.Count - 1; rowNum++) { double spacing = RowY[rowNum + 1] - RowY[rowNum]; RowSpacing.Add(spacing); RowSpacingReport += "\t" + spacing; } myReport.newLine(RowSpacingReport + "\t平均\t" + RowSpacing.Average() + "\t標準差\t" + myStatistics.StandardDeviation(RowSpacing.ToArray())); #endregion 列中磁磚的Y方向 #region 行中磁磚的X方向 myReport.newLine("行中磁磚的X方向"); double[] ColumnX = new double[SquareGrids.COLUMN_COUNT]; double[] ColumnSpacing = new double[SquareGrids.COLUMN_COUNT - 1]; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { List <double> TileXC = new List <double>(); List <double> TileXE = new List <double>(); string TileXReport = "第" + columnNum.ToString("D2") + "行:"; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { double x = myGrid.mmFormPixel(Tiles[columnNum, rowNum].center.X); TileXC.Add(x); TileXReport += "\t" + x; } double TileXC_avg = TileXC.Average(); TileXReport += "\t平均:\t" + TileXC.Average() + "\t標準差\t" + TileXC.StandardDeviation() + "\t差:"; for (int rowNum = 0; rowNum < TileXC.Count(); rowNum++) { double err = TileXC[rowNum] - TileXC_avg; TileXE.Add(err); TileXReport += "\t" + err; } myReport.newLine(TileXReport); ColumnX[columnNum] = TileXC.Average(); } myReport.newLine("行與行間隔:"); string ColumnSpacingReport = "\t"; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT - 1; columnNum++) { ColumnSpacing[columnNum] = ColumnX[columnNum + 1] - ColumnX[columnNum]; ColumnSpacingReport += "\t" + ColumnSpacing[columnNum]; } myReport.newLine(ColumnSpacingReport + "\t平均\t" + ColumnSpacing.Average() + "\t標準差\t" + myStatistics.StandardDeviation(ColumnSpacing)); #endregion 行中磁磚的X方向 #endif #endregion 評分_座標標準差 myReport.newLine("筆直度:"); #region 平均Y方向離差 myReport.newLine("Y方向離差:"); double sumOfTileCenterToTrendLineH = 0; for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { string rowReport = "第" + rowNum + "列"; double[] Xdata = new double[SquareGrids.COLUMN_COUNT]; double[] Ydata = new double[SquareGrids.COLUMN_COUNT]; for (int column = 0; column < SquareGrids.COLUMN_COUNT; column++) { Xdata[column] = Tiles[column, rowNum].center.X; Ydata[column] = Tiles[column, rowNum].center.Y * -1; } myStatistics.TrendLine theTrendLine = new myStatistics.TrendLine(Xdata, Ydata); for (int column = 0; column < SquareGrids.COLUMN_COUNT; column++) { double Residual = Math.Abs(theTrendLine.PointToLineDis(Xdata[column], Ydata[column])); Residual = myGrid.mmFormPixel(Residual); sumOfTileCenterToTrendLineH += Residual; rowReport += "\t" + Residual; } myReport.newLine(rowReport); } double rowResidualAvg = sumOfTileCenterToTrendLineH / (SquareGrids.ROW_COUNT_HALF * SquareGrids.COLUMN_COUNT); string TotalRowReport = "平均Y方向離差:" + rowResidualAvg.ToString("0.000"); myReport.newLine(TotalRowReport); myReport.RowResidualAvg = rowResidualAvg; #endregion 平均Y方向離差 #region 平均X方向離差 myReport.newLine("X方向離差:"); double sumOfTileCenterToTrendLineV = 0; for (int column = 0; column < SquareGrids.COLUMN_COUNT; column++) { string ColumnReport = "第" + column + "行"; List <double> Xdata = new List <double>(); List <double> Ydata = new List <double>(); for (int row = rowStart; row < rowEnd; row++) { Xdata.Add(Tiles[column, row].center.X); Ydata.Add(Tiles[column, row].center.Y * -1); } myStatistics.TrendLine theTrendLine = new myStatistics.TrendLine(Ydata.ToArray(), Xdata.ToArray()); for (int row = 0; row < Xdata.Count; row++) { double Residual = Math.Abs(theTrendLine.PointToLineDis(Ydata[row], Xdata[row])); Residual = myGrid.mmFormPixel(Residual); sumOfTileCenterToTrendLineV += Residual; ColumnReport += "\t" + Residual; } myReport.newLine(ColumnReport); } double columnResidualAvg = sumOfTileCenterToTrendLineV / (SquareGrids.ROW_COUNT_HALF * SquareGrids.COLUMN_COUNT); string TotalColumnReport = "平均X方向離差:" + columnResidualAvg.ToString("0.000"); myReport.newLine(TotalColumnReport); myReport.ColumnResidualAvg = columnResidualAvg; #endregion 平均X方向離差 #region 評分_磁磚旋轉角 myReport.newLine(""); myReport.newLine("磁磚旋轉角"); #region 印出每列 for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { string angleReport = "第" + rowNum.ToString("D2") + "列"; double[] angleDataInRow = new double[SquareGrids.COLUMN_COUNT]; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { angleDataInRow[columnNum] = Tiles[columnNum, rowNum].angle; angleReport += "\t" + angleDataInRow[columnNum]; } myReport.newLine(angleReport + "\t平均:\t" + angleDataInRow.Average() + "\t標準差:\t" + angleDataInRow.StandardDeviation()); } #endregion 印出每列 #region 統計每行 string angleAvgInColumn = "平均:"; string angleSDInColumn = "標準差:"; for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { List <double> angleData = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { angleData.Add(Tiles[columnNum, rowNum].angle); } angleAvgInColumn += "\t" + angleData.Average(); angleSDInColumn += "\t" + angleData.StandardDeviation(); } myReport.newLine(angleAvgInColumn); myReport.newLine(angleSDInColumn); #endregion 統計每行 #region 統計整個 List <double> wholeAngleData = new List <double>(); for (int columnNum = 0; columnNum < SquareGrids.COLUMN_COUNT; columnNum++) { for (int row = rowStart; row < rowEnd; row++) { wholeAngleData.Add(Tiles[columnNum, row].angle); } } #endregion 統計整個 myReport.newLine("總平均:\t" + wholeAngleData.Average()); double AngleSD = wholeAngleData.StandardDeviation(); myReport.newLine("總標準差:\t" + AngleSD); myReport.AngleSD = AngleSD; #endregion 評分_磁磚旋轉角 #region 林國良法(磁磚角離差) #region 垂直離差 myReport.newLine("磁磚角離差Y方向:"); List <double> residualSetY = new List <double>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { List <PointF> pointSetInLineUpper = new List <PointF>(); List <PointF> pointSetInLineLower = new List <PointF>(); for (int column = 0; column < SquareGrids.COLUMN_COUNT; column++) { Tile currentTile = new Tile(Tiles[column, rowNum]); pointSetInLineUpper.Add(currentTile.conerLT); pointSetInLineUpper.Add(currentTile.conerRT); pointSetInLineLower.Add(currentTile.conerLD); pointSetInLineLower.Add(currentTile.conerRD); } myStatistics.TrendLine currentTrendLineUpper = new myStatistics.TrendLine(pointSetInLineUpper); myStatistics.TrendLine currentTrendLineLower = new myStatistics.TrendLine(pointSetInLineLower); foreach (var point in pointSetInLineUpper) { double residual = Math.Abs(currentTrendLineUpper.PointToLineDis(point.X, point.Y)); residualSetY.Add(residual); } foreach (var point in pointSetInLineLower) { double residual = Math.Abs(currentTrendLineLower.PointToLineDis(point.X, point.Y)); residualSetY.Add(residual); } } double residualAvgY = residualSetY.Average(); double residualYPerImageWidth = myGrid.mmFormPixel(residualAvgY); myReport.newLine("平均垂直離差(mm):" + residualYPerImageWidth); myReport.CornerResidualY = residualYPerImageWidth; double imageWidthInMm = myGrid.mmFormPixel(myGrid.WidthInPixel); double residualYPer3mInMm = residualYPerImageWidth / imageWidthInMm * 3000; myReport.newLine("3m垂直離差(mm):" + residualYPer3mInMm); myReport.ResidualAvgY3m = residualYPer3mInMm; #endregion #region 水平離差 myReport.newLine("磁磚角離差X方向:"); List <double> residualSetX = new List <double>(); for (int column = 0; column < SquareGrids.COLUMN_COUNT; column++) { List <PointF> pointSetInLineLeft = new List <PointF>(); List <PointF> pointSetInLineRight = new List <PointF>(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Tile currentTile = new Tile(Tiles[column, rowNum]); pointSetInLineLeft.Add(currentTile.conerLT); pointSetInLineLeft.Add(currentTile.conerLD); pointSetInLineRight.Add(currentTile.conerRT); pointSetInLineRight.Add(currentTile.conerRD); } myStatistics.TrendLine currentTrendLineLeft = new myStatistics.TrendLine(pointSetInLineLeft, true); myStatistics.TrendLine currentTrendLineRight = new myStatistics.TrendLine(pointSetInLineRight, true); foreach (var point in pointSetInLineLeft) { double residual = Math.Abs(currentTrendLineLeft.PointToLineDis(point.Y, point.X)); residualSetX.Add(residual); } foreach (var point in pointSetInLineRight) { double residual = Math.Abs(currentTrendLineRight.PointToLineDis(point.Y, point.X)); residualSetX.Add(residual); } } double residualAvgX = residualSetX.Average(); double residualXPerImageHeight = myGrid.mmFormPixel(residualAvgX); myReport.newLine("平均水平離差(mm):" + residualXPerImageHeight); myReport.CornerResidualX = residualXPerImageHeight; double imageHeightInMm = myGrid.mmFormPixel(myGrid.HeightInPixel); double residualXPer3mInMm = residualXPerImageHeight / imageHeightInMm * 3000; myReport.newLine("3m水平離差(mm):" + residualXPer3mInMm); myReport.ResidualAvgX3m = residualXPer3mInMm; #endregion #endregion myReport.SaveReport(rankArea); //return myReport.ScoringByVariance(TilesType.Square); return(myReport); //myReport.doToReport("評分報告"); //return myReport.SaveReport(rankTopOnly); #endregion 評分 }
public RectangleTiles(Point theGridRD, Point theGridLT, List <MCvBox2D> BaseMcvBox2DList, string fileName, RankArea rankArea) { myGrid = new RectangleGrids(theGridRD, theGridLT); Tiles = RectangleTiles.TileArrayToTile2DArray(theGridRD, theGridLT, BaseMcvBox2DList); //評分 Report = rankRectangleTiles(fileName, Tiles, myGrid, rankArea); }
/// <summary>正方磁磚墻建構式</summary> public SquareTiles(Point theGridRD, Point theGridLT, List <MCvBox2D> BaseMcvBox2DList, string fileName, RankArea rankArea) { myGrid = new SquareGrids(theGridRD, theGridLT); Tiles = TileArrayToTile2DArray(theGridRD, theGridLT, BaseMcvBox2DList); CurrentErrMark = new ErrMark(); //進行評分 Report = RankSquareTile(fileName, Tiles, myGrid, rankArea, ref CurrentErrMark); }