public IEnumerable<OCRSegment> DefineSegments2() { calculateRowAndColumnSums(); int topLine = determineTopLine(); int leftEdge = determineLeftEdge(); int rightEdge = determineRightEdge(); int subSegWidth = 0; OCRSegment segToReturn = new OCRSegment(); int lineHeight = 9; int[][] segmentToReturn; for (int leftPointer = leftEdge; leftPointer < rightEdge; leftPointer++) { for (int rightPointer = leftPointer + 3; rightPointer < leftPointer + 10 && rightPointer < rightEdge; rightPointer++) { subSegWidth = rightPointer - leftPointer; if (subSegWidth < 3) throw new Exception("width too small"); segmentToReturn = new int[subSegWidth][]; for (int i = 0; i < subSegWidth; i++) segmentToReturn[i] = new int[lineHeight]; for (int i = 0; i < subSegWidth; i++) { for (int j = 0; j < lineHeight; j++) { int xRenderIdx = i + leftPointer; int yRenderIdx = j + topLine; segmentToReturn[i][j] = uploadedDocument[xRenderIdx][yRenderIdx]; } } segToReturn.InternalPoints = segmentToReturn; segToReturn.SegmentLocation = new Rectangle(leftPointer, topLine, subSegWidth, lineHeight); yield return segToReturn; } } }
//Refactor this functionality //ELIMINATE: private bool testSegmentForPlausibilty(OCRSegment returnedSegment) { //test the center pixels for complexity/information if (returnedSegment.InternalPoints.Length > 14 && returnedSegment.InternalPoints[0].Length > 14 && returnedSegment.InternalPoints[0].Length < 200) return true; else return false; }
private IEnumerable<OCRSegment> takeSegmentBreaksAndReturnSubSegments(OCRSegment wordSegment, List<int> breakPoints, int height, int borderOffset) { int subSegmentWidth = 0; OCRSegment subSegmentToReturn = new OCRSegment(); int[][] newSegmentToReturn; for (int startIdx = 0; startIdx < breakPoints.Count - 1; startIdx++) { int endIndex = startIdx + 1; subSegmentWidth = breakPoints[endIndex] - breakPoints[startIdx]; while (endIndex < breakPoints.Count && subSegmentWidth <= MaximumSubSegmentWidth && subSegmentWidth > 2) { subSegmentWidth = breakPoints[endIndex] - breakPoints[startIdx]; newSegmentToReturn = new int[subSegmentWidth][]; for (int i = 0; i < subSegmentWidth; i++) newSegmentToReturn[i] = new int[height]; for (int i = 0; i < subSegmentWidth; i++) { for (int j = 0; j < height; j++) { int xRenderIndex = i + breakPoints[startIdx]; newSegmentToReturn[i][j] = wordSegment.InternalPoints[xRenderIndex][j]; } } newSegmentToReturn = addBorder(newSegmentToReturn); subSegmentToReturn.InternalPoints = newSegmentToReturn; subSegmentToReturn.SegmentLocation = new Rectangle(wordSegment.SegmentLocation.X - borderOffset + breakPoints[startIdx], wordSegment.SegmentLocation.Y, breakPoints[endIndex] - breakPoints[startIdx] - 1, wordSegment.SegmentLocation.Height); endIndex++; //DisplayUtility.NewFormForDisplay test = new DisplayUtility.NewFormForDisplay(subSegmentToReturn.InternalPoints); yield return subSegmentToReturn; } } }
private IEnumerable<OCRSegment> handleSegmentsSizes(AllBorderPoints borderPoints) { //DisplayUtility.NewFormForDisplay(borderPoints.listOfPoints, uploadedDocument); OCRSegment wordSegment = new OCRSegment(); foreach (List<Point> wordPointLoop in borderPoints.ReturnWordLoops()) { //DisplayUtility.NewFormForDisplay(wordPointLoop, uploadedDocument); if (wordPointLoop.Count > 5 && wordPointLoop.Count < 400) { //Test the amount of points in the loop wordSegment = defineSegmentObjectToReturn(wordPointLoop); if (testSegmentForPlausibilty(wordSegment)) { //Test the dimensions of the points wordSegment.IsAWord = true; foreach (OCRSegment subSegment in defineSubSegments(wordSegment)) { subSegment.IsAWord = false; SendSegmentToUI(subSegment.InternalPoints, new Rectangle(0, 0, 0, 0)); //TODO: Derive the actual location of the subsegment yield return subSegment; } SendSegmentToUI(wordSegment.InternalPoints, wordSegment.SegmentLocation); yield return wordSegment; } else { AllBorderPoints next = new AllBorderPoints(labeledPixels, wordPointLoop, uploadedDocument); handleSegmentsSizes(next); } } } }
private IEnumerable<OCRSegment> defineSubSegments(OCRSegment wordSegment) { int width = wordSegment.InternalPoints.Length, height = wordSegment.InternalPoints[0].Length; int border = segBorder / 2; List<int> listOfVerticalSums = new List<int>(); for (int i = border; i < width - border; i++) { int verticalSum = 0; for (int j = 0; j < height; j++) { verticalSum += wordSegment.InternalPoints[i][j]; } listOfVerticalSums.Add(verticalSum); } List<int> diffVerticalSums = new List<int>(); for (int i = 1; i < listOfVerticalSums.Count; i++) { diffVerticalSums.Add(listOfVerticalSums[i - 1] - listOfVerticalSums[i]); } int numberOfBreaks = (width - segBorder); var sortedVerticalSums = listOfVerticalSums.Select((x, i) => new KeyValuePair<int, int>(x, i)) .OrderBy(x => x.Key).ToList(); List<int> ignoreIndicies = new List<int>(); int thresholdRating = sortedVerticalSums[listOfVerticalSums.Count - numberOfBreaks].Key; for (int i = 0; i < listOfVerticalSums.Count - 1; i++) { if (listOfVerticalSums[i] >= thresholdRating && listOfVerticalSums[i + 1] >= thresholdRating) { if (sortedVerticalSums[i].Key >= sortedVerticalSums[i + 1].Key) { ignoreIndicies.Add(i + 1); } else ignoreIndicies.Add(i); } } List<int> segmentBreakPoints = new List<int>(); for (int i = listOfVerticalSums.Count - 1; i >= 0; i--) { if (i >= listOfVerticalSums.Count - numberOfBreaks) { if (!ignoreIndicies.Contains(sortedVerticalSums[i].Value) && sortedVerticalSums[i].Value > 1 && sortedVerticalSums[i].Value < listOfVerticalSums.Count - 2) { segmentBreakPoints.Add(sortedVerticalSums[i].Value + border); } } } segmentBreakPoints.Add(width - border); segmentBreakPoints.Add(border); segmentBreakPoints.Sort(); foreach (OCRSegment subSegToReturn in takeSegmentBreaksAndReturnSubSegments(wordSegment, segmentBreakPoints, height, border)) yield return subSegToReturn; }
private OCRSegment defineSegmentObjectToReturn(List<Point> loopOfPoints) { OCRSegment segment = new OCRSegment(); int segmentWidthIncrease = 2; // this adds some columns & rows of pixels to get back the information lost at the segment edges int segWidth = discreteLoopRectangle.Width + segBorder + segmentWidthIncrease, segHeight = discreteLoopRectangle.Height + segBorder + segmentWidthIncrease; segment.InternalPoints = new int[segWidth][]; for (int i = 0; i < segWidth; i++) segment.InternalPoints[i] = new int[segHeight]; for (int i = 0; i < segWidth; i++) for (int j = 0; j < segHeight; j++) segment.InternalPoints[i][j] = 255; int leftBound = discreteLoopRectangle.X, rightBound = discreteLoopRectangle.X + discreteLoopRectangle.Width, topBound = discreteLoopRectangle.Y, bottomBound = discreteLoopRectangle.Y + discreteLoopRectangle.Height; int lowestXVal = int.MaxValue, lowestYVal = int.MaxValue, highestYVal = int.MinValue, highestXVal = int.MinValue; int correctedX, correctedY; for (int i = leftBound - 1; i <= rightBound; i++) { for (int j = topBound - 1; j <= bottomBound; j++) { bool inBounds = i < labeledPixels.GetLength(0) && j < labeledPixels.GetLength(1) && i > 0 && j > 0; if (inBounds && labeledPixels[i, j] != wordBoundary.outsideWord) { correctedX = i - (leftBound) + (segBorder / 2) + 1; //This ensures a buffer of 5 white pixels on every border correctedY = j - (topBound) + (segBorder / 2) + 1; segment.InternalPoints[correctedX][correctedY] = uploadedDocument[i][j]; if (i < lowestXVal) lowestXVal = i; if (i > highestXVal) highestXVal = i; if (j < lowestYVal) lowestYVal = j; if (j > highestYVal) highestYVal = j; } } } //DisplayUtility.NewFormForDisplay temp = new DisplayUtility.NewFormForDisplay(segment.InternalPoints); segment.SegmentLocation = new Rectangle(lowestXVal, lowestYVal, highestXVal - lowestXVal, highestYVal - lowestYVal); return segment; }
private OCRSegment addBorder(OCRSegment seg) { int[][] doubleArray = seg.InternalPoints; int segBorder = 10; int origionalWidth = doubleArray.Length, origionalHeight = doubleArray[0].Length; int segWidth = origionalWidth + segBorder, segHeight = origionalHeight + segBorder; int[][] doubleArrayToReturn = new int[segWidth][]; for (int i = 0; i < segWidth; i++) { doubleArrayToReturn[i] = new int[segHeight]; } for (int i = 0; i < segWidth; i++) { for (int j = 0; j < segHeight; j++) { doubleArrayToReturn[i][j] = 255; } } int correctedX, correctedY; for (int i = 0; i < origionalWidth; i++) { for (int j = 0; j < origionalHeight; j++) { correctedX = i + (segBorder / 2); correctedY = j + (segBorder / 2); doubleArrayToReturn[correctedX][correctedY] = doubleArray[i][j]; } } seg.InternalPoints = doubleArrayToReturn; return seg; }
public IEnumerable<OCRSegment> BuildSegments(int MaxSegWidth, int[][] uploadedDocument) { DisplayUtility.NewFormForDisplay(uploadedDocument); int lineHeight = bottomBound - topBound; int subSegmentWidth = 0; OCRSegment segToReturn = new OCRSegment(); int[][] newSegmentToReturn; for (int startIdx = 0; startIdx < breakIndicies.Count - 1; startIdx++) { int endIndex = startIdx + 1; subSegmentWidth = breakIndicies[endIndex] - breakIndicies[startIdx]; while (endIndex < breakIndicies.Count && subSegmentWidth <= MaxSegWidth && subSegmentWidth > 1) { subSegmentWidth = breakIndicies[endIndex] - breakIndicies[startIdx]; newSegmentToReturn = new int[subSegmentWidth][]; for (int i = 0; i < subSegmentWidth; i++) newSegmentToReturn[i] = new int[lineHeight]; for (int i = 0; i < subSegmentWidth; i++) { for (int j = 0; j < lineHeight; j++) { int xRenderIndex = i + breakIndicies[startIdx]; int yRenderIndex = j + topBound; newSegmentToReturn[i][j] = uploadedDocument[xRenderIndex][yRenderIndex]; } } segToReturn.InternalPoints = newSegmentToReturn; int segWidth = breakIndicies[endIndex] - breakIndicies[startIdx] - 1; segToReturn.SegmentLocation = new Rectangle(breakIndicies[startIdx], topBound, segWidth, lineHeight); endIndex++; yield return segToReturn; } } }