private void TrainLetter(ref int numberOfCharactersLeaned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, List <string> charactersLearned, string s, bool bold) { Bitmap bmp = GenerateImageFromTextWithStyle(s, bold); var nbmp = new NikseBitmap(bmp); nbmp.MakeTwoColor(280); var list = NikseBitmapImageSplitter.SplitBitmapToLettersNew(nbmp, 10, false, false, 25); if (list.Count == 1) { NOcrChar match = nOcrD.GetMatch(list[0].NikseBitmap); if (match == null) { pictureBox1.Image = list[0].NikseBitmap.GetBitmap(); this.Refresh(); Application.DoEvents(); System.Threading.Thread.Sleep(100); NOcrChar nOcrChar = new NOcrChar(s); nOcrChar.Width = list[0].NikseBitmap.Width; nOcrChar.Height = list[0].NikseBitmap.Height; VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value, checkBoxVeryAccurate.Checked, nOcrChar, list[0].NikseBitmap); nOcrD.Add(nOcrChar); charactersLearned.Add(s); numberOfCharactersLeaned++; labelInfo.Text = string.Format("Now training font '{1}', total characters leaned is {0}, {2} skipped", numberOfCharactersLeaned, _subtitleFontName, numberOfCharactersSkipped); bmp.Dispose(); } else { numberOfCharactersSkipped++; } } }
private void listBoxFileNames_SelectedIndexChanged(object sender, EventArgs e) { labelNOcrCharInfo.Text = string.Empty; if (listBoxFileNames.SelectedIndex < 0) { return; } _nOcrChar = listBoxFileNames.Items[listBoxFileNames.SelectedIndex] as NOcrChar; if (_nOcrChar == null) { pictureBoxCharacter.Invalidate(); groupBoxCurrentCompareImage.Enabled = false; listBoxLinesForeground.Items.Clear(); listBoxlinesBackground.Items.Clear(); } else { textBoxText.Text = _nOcrChar.Text; checkBoxItalic.Checked = _nOcrChar.Italic; pictureBoxCharacter.Invalidate(); groupBoxCurrentCompareImage.Enabled = true; if (_nOcrChar.ExpandCount > 0) { labelNOcrCharInfo.Text = string.Format("Size: {0}x{1}, margin top: {2}, expand count: {3}", _nOcrChar.Width, _nOcrChar.Height, _nOcrChar.MarginTop, _nOcrChar.ExpandCount); } else { labelNOcrCharInfo.Text = string.Format("Size: {0}x{1}, margin top: {2} ", _nOcrChar.Width, _nOcrChar.Height, _nOcrChar.MarginTop); } if (pictureBoxCharacter.Image != null) { if (IsMatch()) { groupBoxCurrentCompareImage.BackColor = Color.LightGreen; } else { groupBoxCurrentCompareImage.BackColor = DefaultBackColor; } } _drawLineOn = false; _history = new List <NOcrChar>(); _historyIndex = -1; if (_bitmap == null) { var bitmap = new Bitmap(_nOcrChar.Width, _nOcrChar.Height); var nbmp = new NikseBitmap(bitmap); nbmp.Fill(Color.White); pictureBoxCharacter.Image = nbmp.GetBitmap(); SizePictureBox(); bitmap.Dispose(); } ShowOcrPoints(); } }
private void Redo() { if (_history.Count > 0 && _historyIndex < _history.Count - 1) { _historyIndex++; _nocrChar = new NOcrChar(_history[_historyIndex]); ShowOcrPoints(); } }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List <VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm) { listBoxLinesForeground.Items.Clear(); listBoxlinesBackground.Items.Clear(); NikseBitmap nbmp = new NikseBitmap(vobSubImage); nbmp.ReplaceTransparentWith(Color.Black); vobSubImage = nbmp.GetBitmap(); radioButtonHot.Checked = true; ShrinkSelection = false; ExpandSelection = false; textBoxCharacters.Text = string.Empty; _vobSubForm = vobSubForm; _additions = additions; _nocrChar = new NOcrChar(); _nocrChar.MarginTop = character.Y - character.ParentY; _imageWidth = character.NikseBitmap.Width; _imageHeight = character.NikseBitmap.Height; _drawLineOn = false; _warningNoNotForegroundLinesShown = false; buttonShrinkSelection.Visible = showShrink; if (position.X != -1 && position.Y != -1) { StartPosition = FormStartPosition.Manual; Left = position.X; Top = position.Y; } pictureBoxSubtitleImage.Image = vobSubImage; pictureBoxCharacter.Image = character.NikseBitmap.GetBitmap(); Bitmap org = (Bitmap)vobSubImage.Clone(); Bitmap bm = new Bitmap(org.Width, org.Height); Graphics g = Graphics.FromImage(bm); g.DrawImage(org, 0, 0, org.Width, org.Height); g.DrawRectangle(Pens.Red, character.X, character.Y, character.NikseBitmap.Width, character.NikseBitmap.Height - 1); g.Dispose(); pictureBoxSubtitleImage.Image = bm; pictureBoxCharacter.Top = labelCharacters.Top + 16; SizePictureBox(); checkBoxItalic.Checked = italicChecked; _history = new List <NOcrChar>(); _historyIndex = -1; _nocrChar.Width = _imageWidth; _nocrChar.Height = _imageHeight; GenerateLineSegments(150, false, _nocrChar, new NikseBitmap(pictureBoxCharacter.Image as Bitmap)); ShowOcrPoints(); pictureBoxCharacter.Invalidate(); }
private void buttonOK_Click(object sender, EventArgs e) { using (var form = new VobSubOcrNOcrCharacter()) { form.Initialize(_expandItem.NikseBitmap.GetBitmap(), _expandItem, new Point(0, 0), checkBoxItalic.Checked, false, textBoxText.Text); var result = form.ShowDialog(this); NOcrChar = form.NOcrChar; NOcrChar.ExpandCount = (int)numericUpDownExpandCount.Value; DialogResult = result; } }
private void AddHistoryItem(NOcrChar nocrChar) { if (_historyIndex > 0 && _historyIndex < _history.Count - 1) { while (_history.Count > _historyIndex + 1) { _history.RemoveAt(_history.Count - 1); } _historyIndex = _history.Count - 1; } _history.Add(new NOcrChar(nocrChar)); _historyIndex++; }
public void TestNOcrSaveLoad() { string tempFileName = FileUtil.GetTempFileName(".nocr"); var db = new NOcrDb(tempFileName); var nOcrChar = new NOcrChar("t"); nOcrChar.ExpandCount = 0; nOcrChar.Italic = false; nOcrChar.MarginTop = 2; nOcrChar.Width = 10; nOcrChar.Height = 10; nOcrChar.LinesForeground.Add(new NOcrPoint(new Point(1, 1), new Point(2, 2))); nOcrChar.LinesBackground.Add(new NOcrPoint(new Point(3, 4), new Point(5, 6))); db.Add(nOcrChar); var nOcrChar2 = new NOcrChar("u"); nOcrChar2.ExpandCount = 0; nOcrChar2.Italic = false; nOcrChar2.MarginTop = 3; nOcrChar2.Width = 12; nOcrChar2.Height = 12; nOcrChar2.LinesForeground.Add(new NOcrPoint(new Point(1, 1), new Point(2, 2))); nOcrChar2.LinesBackground.Add(new NOcrPoint(new Point(3, 4), new Point(5, 6))); db.Add(nOcrChar2); db.Save(); db = new NOcrDb(tempFileName); Assert.IsTrue(db.OcrCharacters.Count == 2); Assert.IsTrue(db.OcrCharacters[0].Text == nOcrChar2.Text); Assert.IsTrue(db.OcrCharacters[0].Italic == nOcrChar2.Italic); Assert.IsTrue(db.OcrCharacters[0].MarginTop == nOcrChar2.MarginTop); Assert.IsTrue(db.OcrCharacters[0].LinesForeground.Count == nOcrChar2.LinesForeground.Count); Assert.IsTrue(db.OcrCharacters[0].LinesForeground[0].Start.X == nOcrChar2.LinesForeground[0].Start.X); Assert.IsTrue(db.OcrCharacters[0].LinesForeground[0].Start.Y == nOcrChar2.LinesForeground[0].Start.Y); Assert.IsTrue(db.OcrCharacters[0].LinesBackground.Count == nOcrChar2.LinesBackground.Count); Assert.IsTrue(db.OcrCharacters[0].LinesBackground[0].Start.X == nOcrChar2.LinesBackground[0].Start.X); Assert.IsTrue(db.OcrCharacters[0].LinesBackground[0].Start.Y == nOcrChar2.LinesBackground[0].Start.Y); Assert.IsTrue(db.OcrCharacters[1].Text == nOcrChar.Text); try { File.Delete(tempFileName); } catch { } }
private void Undo() { _drawLineOn = false; _startDone = false; if (_history.Count > 0 && _historyIndex > 0) { _historyIndex--; _nocrChar = new NOcrChar(_history[_historyIndex]); } else if (_historyIndex == 0) { var c = new NOcrChar(_nocrChar); c.LinesForeground.Clear(); c.LinesBackground.Clear(); _nocrChar = c; _historyIndex--; } ShowOcrPoints(); }
private void TrainLetter(ref int numberOfCharactersLeaned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, List <string> charactersLearned, string s, bool bold) { Bitmap bmp = GenerateImageFromTextWithStyle("H " + s, bold); var nbmp = new NikseBitmap(bmp); nbmp.MakeTwoColor(280); nbmp.CropTop(0, Color.FromArgb(0, 0, 0, 0)); var list = NikseBitmapImageSplitter.SplitBitmapToLettersNew(nbmp, 10, false, false, 25); if (list.Count == 3) { var item = list[2]; NOcrChar match = nOcrD.GetMatch(item.NikseBitmap, item.Top, false, false, 0); if (match == null || match.Text != s) { labelInfo.Refresh(); Application.DoEvents(); NOcrChar nOcrChar = new NOcrChar(s) { Width = item.NikseBitmap.Width, Height = item.NikseBitmap.Height, MarginTop = item.Top, }; VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value, checkBoxVeryAccurate.Checked, nOcrChar, item.NikseBitmap); nOcrD.Add(nOcrChar); charactersLearned.Add(s); numberOfCharactersLeaned++; labelInfo.Text = string.Format("Now training font '{1}', total characters learned is {0:#,###,###}, {2:#,###,###} skipped", numberOfCharactersLeaned, _subtitleFontName, numberOfCharactersSkipped); bmp.Dispose(); } else { numberOfCharactersSkipped++; } } }
private void listBoxInspectItems_SelectedIndexChanged(object sender, EventArgs e) { labelImageSize.Text = string.Empty; labelExpandCount.Text = string.Empty; if (listBoxInspectItems.SelectedIndex < 0) { return; } var idx = _indexLookup[listBoxInspectItems.SelectedIndex]; var img = _imageList[idx]; var match = _matchList[listBoxInspectItems.SelectedIndex]; if (img.NikseBitmap != null) { pictureBoxInspectItem.Width = img.NikseBitmap.Width; pictureBoxInspectItem.Height = img.NikseBitmap.Height; labelImageSize.Top = pictureBoxInspectItem.Top + img.NikseBitmap.Height + 7; labelImageSize.Text = img.NikseBitmap.Width + "x" + img.NikseBitmap.Height; if (match != null && match.ExpandCount > 1) { var expandList = new List <ImageSplitterItem>(); for (int i = idx; i < idx + match.ExpandCount; i++) { expandList.Add(_imageList[i]); } var expandItem = VobSubOcr.GetExpandedSelectionNew(new NikseBitmap(_bitmap), expandList); var old = expandItem.NikseBitmap.GetBitmap(); pictureBoxInspectItem.Image = old; pictureBoxCharacter.Image = old; pictureBoxInspectItem.Width = old.Width; pictureBoxInspectItem.Height = old.Height; labelExpandCount.Text = $"Expand count: {match.ExpandCount}"; } else { var old = img.NikseBitmap.GetBitmap(); pictureBoxInspectItem.Image = old; pictureBoxCharacter.Image = old; } SizePictureBox(); } else { pictureBoxInspectItem.Image = null; pictureBoxCharacter.Image = null; } buttonAddBetterMatch.Text = LanguageSettings.Current.VobSubOcrCharacterInspect.AddBetterMatch; if (match == null) { if (img.NikseBitmap != null && img.SpecialCharacter == null) { // no match found buttonUpdate.Enabled = false; buttonDelete.Enabled = false; textBoxText.Text = string.Empty; _nOcrChar = null; pictureBoxCharacter.Invalidate(); buttonEditDB.Enabled = true; buttonAddBetterMatch.Enabled = true; buttonAddBetterMatch.Text = LanguageSettings.Current.VobSubOcrCharacterInspect.Add; textBoxText.Enabled = true; checkBoxItalic.Enabled = true; } else { // spaces+new lines _nOcrChar = null; pictureBoxCharacter.Invalidate(); buttonUpdate.Enabled = false; buttonDelete.Enabled = false; buttonEditDB.Enabled = false; buttonAddBetterMatch.Enabled = false; textBoxText.Text = string.Empty; textBoxText.Enabled = false; checkBoxItalic.Checked = false; checkBoxItalic.Enabled = false; } } else if (match.NOcrCharacter == null) { // no match found buttonUpdate.Enabled = false; buttonDelete.Enabled = false; textBoxText.Text = string.Empty; checkBoxItalic.Checked = match.Italic; _nOcrChar = null; pictureBoxCharacter.Invalidate(); buttonEditDB.Enabled = true; buttonAddBetterMatch.Enabled = true; buttonAddBetterMatch.Text = LanguageSettings.Current.VobSubOcrCharacterInspect.Add; textBoxText.Enabled = true; checkBoxItalic.Enabled = true; } else { buttonUpdate.Enabled = true; buttonDelete.Enabled = true; textBoxText.Text = match.Text; checkBoxItalic.Checked = match.Italic; _nOcrChar = match.NOcrCharacter; pictureBoxCharacter.Invalidate(); buttonEditDB.Enabled = true; buttonAddBetterMatch.Enabled = true; textBoxText.Enabled = true; checkBoxItalic.Enabled = true; } }
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); }
private void listBoxInspectItems_SelectedIndexChanged(object sender, EventArgs e) { if (listBoxInspectItems.SelectedIndex < 0) { return; } var img = _imageList[listBoxInspectItems.SelectedIndex]; if (img.NikseBitmap != null) { pictureBoxInspectItem.Width = img.NikseBitmap.Width; pictureBoxInspectItem.Height = img.NikseBitmap.Height; var old = img.NikseBitmap.GetBitmap(); pictureBoxInspectItem.Image = old; pictureBoxCharacter.Image = old; SizePictureBox(); } else { pictureBoxInspectItem.Image = null; pictureBoxCharacter.Image = null; } var match = _matchList[listBoxInspectItems.SelectedIndex]; if (match == null) { // spaces+new lines _nocrChar = null; pictureBoxCharacter.Invalidate(); buttonUpdate.Enabled = false; buttonDelete.Enabled = false; buttonEditDB.Enabled = false; buttonAddBetterMatch.Enabled = false; textBoxText.Text = string.Empty; textBoxText.Enabled = false; checkBoxItalic.Checked = false; checkBoxItalic.Enabled = false; } else if (match.NOcrCharacter == null) { // no match found buttonUpdate.Enabled = false; buttonDelete.Enabled = false; textBoxText.Text = string.Empty; checkBoxItalic.Checked = match.Italic; _nocrChar = null; pictureBoxCharacter.Invalidate(); buttonEditDB.Enabled = true; buttonAddBetterMatch.Enabled = true; textBoxText.Enabled = false; checkBoxItalic.Enabled = false; } else { buttonUpdate.Enabled = true; buttonDelete.Enabled = true; textBoxText.Text = match.Text; checkBoxItalic.Checked = match.Italic; _nocrChar = match.NOcrCharacter; pictureBoxCharacter.Invalidate(); buttonEditDB.Enabled = true; buttonAddBetterMatch.Enabled = true; textBoxText.Enabled = true; checkBoxItalic.Enabled = 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); }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showExpand, bool showShrink, string text) { listBoxLinesForeground.Items.Clear(); listBoxlinesBackground.Items.Clear(); var nbmp = new NikseBitmap(vobSubImage); vobSubImage = nbmp.GetBitmap(); radioButtonHot.Checked = true; ShrinkSelection = false; ExpandSelection = false; textBoxCharacters.Text = text; NOcrChar = new NOcrChar { MarginTop = character.Top }; _imageWidth = character.NikseBitmap.Width; _imageHeight = character.NikseBitmap.Height; _drawLineOn = false; _warningNoNotForegroundLinesShown = false; buttonExpandSelection.Visible = showExpand; buttonShrinkSelection.Visible = showShrink; if (position.X != -1 && position.Y != -1) { StartPosition = FormStartPosition.Manual; Left = position.X; Top = position.Y; } pictureBoxSubtitleImage.Image = vobSubImage; pictureBoxCharacter.Image = character.NikseBitmap.GetBitmap(); Bitmap org = (Bitmap)vobSubImage.Clone(); Bitmap bm = new Bitmap(org.Width, org.Height); Graphics g = Graphics.FromImage(bm); g.DrawImage(org, 0, 0, org.Width, org.Height); g.DrawRectangle(Pens.Red, character.X, character.Y, character.NikseBitmap.Width, character.NikseBitmap.Height - 1); g.Dispose(); pictureBoxSubtitleImage.Image = bm; pictureBoxCharacter.Top = labelCharacters.Top + 16; SizePictureBox(); checkBoxItalic.Checked = italicChecked; _history = new List <NOcrChar>(); _historyIndex = -1; NOcrChar.Width = _imageWidth; NOcrChar.Height = _imageHeight; numericUpDownLinesToDraw.Value = Configuration.Settings.VobSubOcr.LineOcrLinesToAutoGuess; GenerateLineSegments((int)numericUpDownLinesToDraw.Value, false, NOcrChar, new NikseBitmap(pictureBoxCharacter.Image as Bitmap)); ShowOcrPoints(); pictureBoxCharacter.Invalidate(); numericUpDownLinesToDraw.ValueChanged += (sender, args) => { Configuration.Settings.VobSubOcr.LineOcrLinesToAutoGuess = (int)numericUpDownLinesToDraw.Value; buttonGuessAgain_Click(null, null); }; textBoxCharacters.Focus(); }
private void TrainLetter(ref int numberOfCharactersLearned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, string s, bool bold, bool italic, bool doubleLetter) { var bmp = GenerateImageFromTextWithStyle("H " + s, bold, italic); var nikseBitmap = new NikseBitmap(bmp); nikseBitmap.MakeTwoColor(280); nikseBitmap.CropTop(0, Color.FromArgb(0, 0, 0, 0)); var list = NikseBitmapImageSplitter.SplitBitmapToLettersNew(nikseBitmap, 10, false, false, 25, false); if (list.Count == 3) { var item = list[2]; var match = nOcrD.GetMatch(item.NikseBitmap, item.Top, false, 25); if (match == null || match.Text != s) { labelInfo.Refresh(); Application.DoEvents(); var nOcrChar = new NOcrChar(s) { Width = item.NikseBitmap.Width, Height = item.NikseBitmap.Height, MarginTop = item.Top, Italic = italic, }; VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value + (doubleLetter ? 20 : 0), false, nOcrChar, item.NikseBitmap); nOcrD.Add(nOcrChar); numberOfCharactersLearned++; labelInfo.Text = string.Format(Configuration.Settings.Language.VobSubOcr.NowTraining, numberOfCharactersLearned, _subtitleFontName, numberOfCharactersSkipped); bmp.Dispose(); } else { numberOfCharactersSkipped++; } } else if (!doubleLetter) { if (list.Count == 4 && list[2].NikseBitmap != null && list[3].NikseBitmap != null) { // e.g. quote (") var expandItem = VobSubOcr.GetExpandedSelectionNew(nikseBitmap, new List <ImageSplitterItem> { list[2], list[3] }); var match = nOcrD.GetMatchExpanded(nikseBitmap, expandItem, 2, list); if (match != null && match.Text == s) { numberOfCharactersSkipped++; return; } var nOcrChar = new NOcrChar(s) { Width = expandItem.NikseBitmap.Width, Height = expandItem.NikseBitmap.Height, MarginTop = expandItem.Top, Italic = italic, ExpandCount = 2, }; VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value + 5, false, nOcrChar, expandItem.NikseBitmap); nOcrD.Add(nOcrChar); return; } if (list.Count == 5 && list[2].NikseBitmap != null && list[3].NikseBitmap != null && list[4].NikseBitmap != null) { // e.g. "%" var expandItem = VobSubOcr.GetExpandedSelectionNew(nikseBitmap, new List <ImageSplitterItem> { list[2], list[3], list[4] }); var match = nOcrD.GetMatchExpanded(nikseBitmap, expandItem, 2, list); if (match != null && match.Text == s) { numberOfCharactersSkipped++; return; } var nOcrChar = new NOcrChar(s) { Width = expandItem.NikseBitmap.Width, Height = expandItem.NikseBitmap.Height, MarginTop = expandItem.Top, Italic = italic, ExpandCount = 3, }; nOcrD.Add(nOcrChar); VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value + 10, false, nOcrChar, expandItem.NikseBitmap); return; } numberOfCharactersSkipped++; } }
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; } } }
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); }