private static bool IsMatchPointBackGround(NOcrPoint op, bool loose, NikseBitmap nbmp, NOcrChar nOcrChar) { foreach (Point point in op.ScaledGetPoints(nOcrChar, nbmp.Width, nbmp.Height)) { if (point.X >= 0 && point.Y >= 0 && point.X < nbmp.Width && point.Y < nbmp.Height) { Color c = nbmp.GetPixel(point.X, point.Y); if (c.A > 150 && c.R + 100 + c.G + c.B > VobSubOcr.NocrMinColor) { return(false); } if (nbmp.Width > 10 && point.X + 1 < nbmp.Width) { c = nbmp.GetPixel(point.X + 1, point.Y); if (c.A > 150 && c.R + 100 + c.G + c.B > VobSubOcr.NocrMinColor) { return(false); } } if (loose) { if (nbmp.Width > 10 && point.X >= 1) { c = nbmp.GetPixel(point.X - 1, point.Y); if (c.A > 150 && c.R + 100 + c.G + c.B > VobSubOcr.NocrMinColor) { return(false); } } if (nbmp.Height > 10 && point.Y + 1 < nbmp.Height) { c = nbmp.GetPixel(point.X, point.Y + 1); if (c.A > 150 && c.R + 100 + c.G + c.B > VobSubOcr.NocrMinColor) { return(false); } } if (nbmp.Height > 10 && point.Y >= 1) { c = nbmp.GetPixel(point.X, point.Y - 1); if (c.A > 150 && c.R + 100 + c.G + c.B > VobSubOcr.NocrMinColor) { return(false); } } } } } return(true); }
private void pictureBoxCharacter_Paint(object sender, PaintEventArgs e) { if (_nocrChar == null) { return; } NOcrPoint selectedPoint = null; if (listBoxLinesForeground.Focused && listBoxLinesForeground.SelectedIndex >= 0) { selectedPoint = (NOcrPoint)listBoxLinesForeground.Items[listBoxLinesForeground.SelectedIndex]; } else if (listBoxlinesBackground.Focused && listBoxlinesBackground.SelectedIndex >= 0) { selectedPoint = (NOcrPoint)listBoxlinesBackground.Items[listBoxlinesBackground.SelectedIndex]; } var foreground = new Pen(new SolidBrush(Color.Green)); var background = new Pen(new SolidBrush(Color.Red)); var selPenF = new Pen(new SolidBrush(Color.Green), 3); var selPenB = new Pen(new SolidBrush(Color.Red), 3); if (pictureBoxCharacter.Image != null) { foreach (NOcrPoint op in _nocrChar.LinesForeground) { Point start = op.GetScaledStart(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height); Point end = op.GetScaledEnd(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height); if (start.X == end.X && start.Y == end.Y) { end.X++; } e.Graphics.DrawLine(foreground, start, end); if (op == selectedPoint) { e.Graphics.DrawLine(selPenF, op.GetScaledStart(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height), op.GetScaledEnd(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height)); } } foreach (NOcrPoint op in _nocrChar.LinesBackground) { Point start = op.GetScaledStart(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height); Point end = op.GetScaledEnd(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height); e.Graphics.DrawLine(background, start, end); if (op == selectedPoint) { e.Graphics.DrawLine(selPenB, op.GetScaledStart(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height), op.GetScaledEnd(_nocrChar, pictureBoxCharacter.Width, pictureBoxCharacter.Height)); } } } if (_drawLineOn) { if (_startDone) { var p = foreground; if (radioButtonCold.Checked) { p = background; } e.Graphics.DrawLine(p, new Point((int)Math.Round(_start.X * _zoomFactor), (int)Math.Round(_start.Y * _zoomFactor)), new Point(_mx, _my)); } } foreground.Dispose(); background.Dispose(); selPenF.Dispose(); selPenB.Dispose(); }
public static void GenerateLineSegments(int numberOfLines, bool veryPrecise, NOcrChar nOcrChar, NikseBitmap nbmp) { int giveUpCount = 10000; var r = new Random(); int count = 0; int hits = 0; bool tempVeryPrecise = veryPrecise; while (hits < numberOfLines && count < giveUpCount) { var start = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); var end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); if (hits < 5 && count < 100) // a few large lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) > nOcrChar.Height / 2) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } else // and a lot of small lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 5) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } var op = new NOcrPoint(start, end); bool ok = true; foreach (NOcrPoint existingOp in nOcrChar.LinesForeground) { if (existingOp.Start.X == op.Start.X && existingOp.Start.Y == op.Start.Y && existingOp.End.X == op.End.X && existingOp.End.Y == op.End.Y) { ok = false; } } if (ok && IsMatchPointForeGround(op, !tempVeryPrecise, nbmp, nOcrChar)) { nOcrChar.LinesForeground.Add(op); //AddHistoryItem(nOcrChar); hits++; } count++; if (count > giveUpCount - 100 && !tempVeryPrecise) { tempVeryPrecise = true; } } count = 0; hits = 0; tempVeryPrecise = veryPrecise; while (hits < numberOfLines && count < giveUpCount) { var start = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); var end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); if (hits < 5 && count < 100) // a few large lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) > nOcrChar.Height / 2) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } else // and a lot of small lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 5) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } var op = new NOcrPoint(start, end); bool ok = true; foreach (NOcrPoint existingOp in nOcrChar.LinesBackground) { if (existingOp.Start.X == op.Start.X && existingOp.Start.Y == op.Start.Y && existingOp.End.X == op.End.X && existingOp.End.Y == op.End.Y) { ok = false; } } if (ok && IsMatchPointBackGround(op, !tempVeryPrecise, nbmp, nOcrChar)) { nOcrChar.LinesBackground.Add(op); //AddHistoryItem(nOcrChar); hits++; } count++; if (count > giveUpCount - 100 && !tempVeryPrecise) { tempVeryPrecise = true; } } }
public static void GenerateLineSegments(int maxNumberOfLines, bool veryPrecise, NOcrChar nOcrChar, NikseBitmap nbmp) { const int giveUpCount = 15000; var r = new Random(); int count = 0; int hits = 0; bool tempVeryPrecise = veryPrecise; int verticalLineX = 2; int horizontalLineY = 2; while (hits < maxNumberOfLines && count < giveUpCount) { var start = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); var end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); if (hits < 5 && count < 200 && nOcrChar.Width > 4 && nOcrChar.Height > 4) // vertical lines { start = new Point(0, 0); end = new Point(0, 0); for (; verticalLineX < nOcrChar.Width - 3; verticalLineX += 1) { start = new Point(verticalLineX, 2); end = new Point(verticalLineX, nOcrChar.Height - 3); if (IsMatchPointForeGround(new NOcrPoint(start, end), true, nbmp, nOcrChar)) { verticalLineX++; break; } } } else if (hits < 10 && count < 400 && nOcrChar.Width > 4 && nOcrChar.Height > 4) // horizontal lines { start = new Point(0, 0); end = new Point(0, 0); for (; horizontalLineY < nOcrChar.Height - 3; horizontalLineY += 1) { start = new Point(2, horizontalLineY); end = new Point(nOcrChar.Width - 3, horizontalLineY); if (IsMatchPointForeGround(new NOcrPoint(start, end), true, nbmp, nOcrChar)) { horizontalLineY++; break; } } } else if (hits < 20 && count < 2000) // a few large lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) > nOcrChar.Height / 2) { break; } end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } else if (hits < 30 && count < 3000) // some medium lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 15) { break; } end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } else // and a lot of small lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 15) { break; } end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } var op = new NOcrPoint(start, end); bool ok = true; foreach (NOcrPoint existingOp in nOcrChar.LinesForeground) { if (existingOp.Start.X == op.Start.X && existingOp.Start.Y == op.Start.Y && existingOp.End.X == op.End.X && existingOp.End.Y == op.End.Y) { ok = false; } } if (end.X == start.X && end.Y == start.Y) { ok = false; } if (ok && IsMatchPointForeGround(op, !tempVeryPrecise, nbmp, nOcrChar)) { nOcrChar.LinesForeground.Add(op); hits++; } count++; if (count > giveUpCount - 100 && !tempVeryPrecise) { tempVeryPrecise = true; } } count = 0; hits = 0; horizontalLineY = 2; tempVeryPrecise = veryPrecise; while (hits < maxNumberOfLines && count < giveUpCount) { var start = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); var end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); if (hits < 5 && count < 400 && nOcrChar.Width > 4 && nOcrChar.Height > 4) // horizontal lines { for (; horizontalLineY < nOcrChar.Height - 3; horizontalLineY += 1) { start = new Point(2, horizontalLineY); end = new Point(nOcrChar.Width - 2, horizontalLineY); if (IsMatchPointBackGround(new NOcrPoint(start, end), true, nbmp, nOcrChar)) { horizontalLineY++; break; } } } if (hits < 10 && count < 1000) // a few large lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) > nOcrChar.Height / 2) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } else if (hits < 30 && count < 2000) // some medium lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 15) { break; } end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } else // and a lot of small lines { for (int k = 0; k < 500; k++) { if (Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) < 5) { break; } else { end = new Point(r.Next(nOcrChar.Width), r.Next(nOcrChar.Height)); } } } var op = new NOcrPoint(start, end); bool ok = true; foreach (NOcrPoint existingOp in nOcrChar.LinesBackground) { if (existingOp.Start.X == op.Start.X && existingOp.Start.Y == op.Start.Y && existingOp.End.X == op.End.X && existingOp.End.Y == op.End.Y) { ok = false; } } if (ok && IsMatchPointBackGround(op, !tempVeryPrecise, nbmp, nOcrChar)) { nOcrChar.LinesBackground.Add(op); hits++; } count++; if (count > giveUpCount - 100 && !tempVeryPrecise) { tempVeryPrecise = true; } } RemoveDuplicates(nOcrChar.LinesForeground); RemoveDuplicates(nOcrChar.LinesBackground); }
private static bool IsMatchPointForeGround(NOcrPoint op, bool loose, NikseBitmap nbmp, NOcrChar nOcrChar) { if (Math.Abs(op.Start.X - op.End.X) < 2 && Math.Abs(op.End.Y - op.Start.Y) < 2) { return(false); } foreach (Point point in op.ScaledGetPoints(nOcrChar, nbmp.Width, nbmp.Height)) { if (point.X >= 0 && point.Y >= 0 && point.X < nbmp.Width && point.Y < nbmp.Height) { Color c = nbmp.GetPixel(point.X, point.Y); if (c.A > 150) { } else { return(false); } if (loose) { if (nbmp.Width > 10 && point.X + 1 < nbmp.Width) { c = nbmp.GetPixel(point.X + 1, point.Y); if (c.A > 150) { } else { return(false); } } if (nbmp.Width > 10 && point.X >= 1) { c = nbmp.GetPixel(point.X - 1, point.Y); if (c.A > 150) { } else { return(false); } } if (nbmp.Height > 10 && point.Y + 1 < nbmp.Height) { c = nbmp.GetPixel(point.X, point.Y + 1); if (c.A > 150) { } else { return(false); } } if (nbmp.Height > 10 && point.Y >= 1) { c = nbmp.GetPixel(point.X, point.Y - 1); if (c.A > 150) { } else { return(false); } } } } } return(true); }