public bool BordersMatch(SubtitleLetter other) { for (int i = 0; i < 4; i++) { if (borders[i] != -1 && other.borders[i] != -1 && Math.Abs(borders[i] - other.borders[i]) > 4) { return(false); } } return(true); }
private void subtitlePictureBox_MouseClick(object sender, MouseEventArgs e) { // Check whether the click happened within the subtitle image if (subtitleImageRectangle.Contains(e.Location)) { Point pt = e.Location; pt.Offset(-subtitleImageRectangle.Left, -subtitleImageRectangle.Top); pt = new Point((int)(pt.X / bitmapScale), (int)(pt.Y / bitmapScale)); SubtitleLetter hitLetter = null; foreach (SubtitleLetter l in currentSubtitle.letters) { if (l.Coords.Contains(pt)) { hitLetter = l; break; } } if (hitLetter != null) { // The click went inside a letter, so activate it activeLetter = hitLetter; letterInputBox.Text = hitLetter.Text; letterInputBox.SelectAll(); letterInputBox.Focus(); AcceptButton = letterOKButton; ignoreItalicChanges = true; if (activeLetter.Angle != 0.0) { italicLetter.Checked = true; } else { italicLetter.Checked = false; } ignoreItalicChanges = false; UpdateBitmaps(); } else { // No letter was hit, so unselect everything activeLetter = null; letterInputBox.Text = ""; letterOKButton.Enabled = false; UpdateBitmaps(); } } }
private void AssignLetterText(SubtitleLetter l, string text) { // Set the text on the letter that's part of the displayed subtitle activeLetter.Text = text; // Next, check whether this letter was already known before. If yes, we have to delete that one SubtitleLetter l2 = fonts.FindMatch(l, AppOptions.similarityTolerance * 100); if (l2 != null) { fonts.DeleteLetter(l2); } // Add the newly identified letter to the active font //SubtitleLetter letter = currentSubtitle.ExtractLetter(activeLetter, activeLetter.Angle); if (letterInputBox.Text != "") { activeLetter.Text = text; fonts.AddLetter(activeLetter); } }
private SubtitleImage LoadSubtitleImage(int number) { #if !DEBUG try { #endif pageNum.Text = (currentNum + 1).ToString(); //Debugger.Print("## Image " + number); SubtitleImage r = subfile.LoadSubtitleImage(number); //fixme AdjustFormScrollbars space length after narrow characters activeLetter = null; ImageOCR(r); return(r); #if !DEBUG } catch (Exception e) { fonts.Save(); throw new Exception(e.Message + "\n\n" + e.StackTrace); } #endif }
/*private int ComputeDiff(byte[,] a, byte[,] b) * { * int w = a.GetLength(1), h = a.GetLength(0); * int r = 0; * for (int j = 0; j < h; j++) * for (int i = 0; i < w; i++) * r += a[j, i] - b[j, i]; * * return r * 100 / h / w; * }*/ public int OldMatches(SubtitleLetter o) { // If the width or height differs by more than 2 pixels, it's probably another character if (Math.Abs(o.image.GetLength(1) - image.GetLength(1)) > 1 || Math.Abs(o.image.GetLength(0) - image.GetLength(0)) > 1) { return(999999); } //double translation = FindTranslation(i1, i2); double translation = FindTranslation(image, o.image); byte[,] moved = o.MoveLetter(-translation); // Build an array out of their differences DateTime t = DateTime.Now; int ad = ComputeAbsDiff(image, moved); Debugger.Print("diff (" + Text + ") = " + ad); Debugger.absDiffTime += (DateTime.Now - t).TotalMilliseconds; return(ad); }
private void ActivateNextUnknownLetter() { // Search for the first letter that hasn't yet been converted to text activeLetter = null; foreach (SubtitleLetter l in currentSubtitle.letters) { if (l.Text == null) { // If we found an unconverted letter, first try to find a match in the current font SubtitleLetter l2 = fonts.FindMatch(l, AppOptions.similarityTolerance * 100); if (l2 != null) { l.Text = l2.Text; continue; } else { activeLetter = l; break; } } } if (activeLetter != null) { // We found an unknown character, so mark it for editing letterInputBox.Focus(); AcceptButton = letterOKButton; UpdateBitmaps(); } else { // All letters can be OCR'd in this text, so just redraw everything in green UpdateBitmaps(); } }
public int Matches(SubtitleLetter o) { // If the width or height differs by more than a pixel, it's probably another character if (Math.Abs(o.image.GetLength(1) - image.GetLength(1)) > 1 || Math.Abs(o.image.GetLength(0) - image.GetLength(0)) > 1) { return(999999); } //double translation = FindTranslation(i1, i2); DateTime t = DateTime.Now; double translation = FindTranslation(image, o.image); byte[,] moved = o.MoveLetter(-translation); Debugger.translationTime += (DateTime.Now - t).TotalMilliseconds; //Debugger.Print("########################################################################"); //Debugger.Draw2DArray(image); //Debugger.Print("------------------------------------------------------------------------"); //Debugger.Draw2DArray(moved); t = DateTime.Now; int diff1 = Difference(image, moved) + Difference(moved, image); Debugger.diffTime += (DateTime.Now - t).TotalMilliseconds; if (diff1 > 0) { return(diff1 + 1000); } t = DateTime.Now; int ad = ComputeAbsDiff(image, moved); Debugger.absDiffTime += (DateTime.Now - t).TotalMilliseconds; return(Math.Min(1000, ad / 10)); }
public SortedList <int, SubtitleLetter> FindMatch(SubtitleLetter l, int tolerance) { //if (l.Coords.X != 598 && l.Coords.X != 326) return new SortedList<int, SubtitleLetter>(); SortedList <int, SubtitleLetter> results = new SortedList <int, SubtitleLetter>(); foreach (SubtitleLetter letter in letters) { if (!letter.BordersMatch(l)) { continue; } int similarity = letter.Matches(l); if (similarity == 0) { //if (debug) Debugger.Print("perfect match " + letter.Text); results.Add(similarity, letter); return(results); } if (AppOptions.IsEasilyConfusedLetter(letter.Text)) { similarity *= 10; } if (similarity < tolerance && !results.ContainsKey(similarity)) { results.Add(similarity, letter); } } //if (debug && results.Count > 0) Debugger.Print("decided on " + results.Values[0].Text + "\n"); return(results); // If we haven't found an exact match, return the best one. }
public SubtitleLetter FindMatch(SubtitleLetter l, int tolerance) { SortedList <int, SubtitleLetter> defaultFontResults, combinedResults, nextResults, userResults; //Debugger.Print(" L = " + l.Coords.Left + " / " + l.Coords.Top); if (defaultFont == null) { foreach (DictionaryEntry de in fontStats) { if ((int)de.Value > 10) { SetDefaultFont((string)de.Key); } } } // First, check whether the user font provides a very good match userResults = userFont.FindMatch(l, tolerance / 10); if (userResults.Count > 0) { return(userResults.Values[0]); } // Then, check whether the default font can scan this letter if (defaultFont != null) { defaultFontResults = defaultFont.FindMatch(l, tolerance); if (defaultFontResults.Count > 0) { debugStrings.AddLast(new PositionedString(l.Coords, defaultFontResults.Keys[0].ToString())); return(defaultFontResults.Values[0]); } } // Next, check the other fonts combinedResults = new SortedList <int, SubtitleLetter>(); foreach (SubtitleFont font in fonts) { if (font == defaultFont) { continue; } nextResults = font.FindMatch(l, tolerance); foreach (KeyValuePair <int, SubtitleLetter> kvp in nextResults) { if (!combinedResults.ContainsKey(kvp.Key)) { combinedResults.Add(kvp.Key, kvp.Value); } } if (nextResults.Count > 0) { if (fontStats[font.Name] == null) { fontStats[font.Name] = 1; } else { fontStats[font.Name] = (int)fontStats[font.Name] + 1; } } } if (combinedResults.Count > 0) { debugStrings.AddLast(new PositionedString(l.Coords, combinedResults.Keys[0].ToString())); return(combinedResults.Values[0]); } // We didn't find the letter in the built-in fonts, so let's check the user provided letters if (userResults.Count > 0) { return(userResults.Values[0]); } else { return(null); } }
public void DeleteLetter(SubtitleLetter l2) { SubtitleLetter l = FindMatch(l2, AppOptions.similarityTolerance * 100); userFont.DeleteLetter(l); }
public void AddLetter(SubtitleLetter l) { userFont.AddLetter(l); }
/*private int ComputeDiff(byte[,] a, byte[,] b) { int w = a.GetLength(1), h = a.GetLength(0); int r = 0; for (int j = 0; j < h; j++) for (int i = 0; i < w; i++) r += a[j, i] - b[j, i]; return r * 100 / h / w; }*/ public int OldMatches(SubtitleLetter o) { // If the width or height differs by more than 2 pixels, it's probably another character if (Math.Abs(o.image.GetLength(1) - image.GetLength(1)) > 1 || Math.Abs(o.image.GetLength(0) - image.GetLength(0)) > 1) return 999999; //double translation = FindTranslation(i1, i2); double translation = FindTranslation(image, o.image); byte[,] moved = o.MoveLetter(-translation); // Build an array out of their differences DateTime t = DateTime.Now; int ad = ComputeAbsDiff(image, moved); Debugger.Print("diff (" + Text + ") = " + ad); Debugger.absDiffTime += (DateTime.Now - t).TotalMilliseconds; return ad; }
public int Matches(SubtitleLetter o) { // If the width or height differs by more than a pixel, it's probably another character if (Math.Abs(o.image.GetLength(1) - image.GetLength(1)) > 1 || Math.Abs(o.image.GetLength(0) - image.GetLength(0)) > 1) return 999999; //double translation = FindTranslation(i1, i2); DateTime t = DateTime.Now; double translation = FindTranslation(image, o.image); byte[,] moved = o.MoveLetter(-translation); Debugger.translationTime += (DateTime.Now - t).TotalMilliseconds; //Debugger.Print("########################################################################"); //Debugger.Draw2DArray(image); //Debugger.Print("------------------------------------------------------------------------"); //Debugger.Draw2DArray(moved); t = DateTime.Now; int diff1 = Difference(image, moved) + Difference(moved, image); Debugger.diffTime += (DateTime.Now - t).TotalMilliseconds; if (diff1 > 0) return diff1 + 1000; t = DateTime.Now; int ad = ComputeAbsDiff(image, moved); Debugger.absDiffTime += (DateTime.Now - t).TotalMilliseconds; return Math.Min(1000, ad / 10); }
public bool BordersMatch(SubtitleLetter other) { for (int i = 0; i < 4; i++) { if (borders[i] != -1 && other.borders[i] != -1 && Math.Abs(borders[i] - other.borders[i]) > 4) return false; } return true; }
public void DeleteLetter(SubtitleLetter l2) { changed = true; letters.Remove(l2); }
private SubtitleImage LoadSubtitleImage(int number) { #if !DEBUG try { #endif pageNum.Text = (currentNum + 1).ToString(); //Debugger.Print("## Image " + number); SubtitleImage r = subfile.LoadSubtitleImage(number); //fixme AdjustFormScrollbars space length after narrow characters activeLetter = null; ImageOCR(r); return r; #if !DEBUG } catch (Exception e) { fonts.Save(); throw new Exception(e.Message + "\n\n" + e.StackTrace); } #endif }
public void DeleteLetter(SubtitleLetter l2) { changed = true; letters.Remove(l2); }
private void ActivateNextUnknownLetter() { // Search for the first letter that hasn't yet been converted to text activeLetter = null; foreach (SubtitleLetter l in currentSubtitle.letters) { if (l.Text == null) { // If we found an unconverted letter, first try to find a match in the current font SubtitleLetter l2 = fonts.FindMatch(l, AppOptions.similarityTolerance * 100); if (l2 != null) { l.Text = l2.Text; continue; } else { activeLetter = l; break; } } } if (activeLetter != null) { // We found an unknown character, so mark it for editing letterInputBox.Focus(); AcceptButton = letterOKButton; UpdateBitmaps(); } else { // All letters can be OCR'd in this text, so just redraw everything in green UpdateBitmaps(); } }
public SortedList<int, SubtitleLetter> FindMatch(SubtitleLetter l, int tolerance) { //if (l.Coords.X != 598 && l.Coords.X != 326) return new SortedList<int, SubtitleLetter>(); SortedList<int, SubtitleLetter> results = new SortedList<int, SubtitleLetter>(); foreach (SubtitleLetter letter in letters) { if (!letter.BordersMatch(l)) continue; int similarity = letter.Matches(l); if (similarity == 0) { //if (debug) Debugger.Print("perfect match " + letter.Text); results.Add(similarity, letter); return results; } if (AppOptions.IsEasilyConfusedLetter(letter.Text)) similarity *= 10; if (similarity < tolerance && !results.ContainsKey(similarity)) results.Add(similarity, letter); } //if (debug && results.Count > 0) Debugger.Print("decided on " + results.Values[0].Text + "\n"); return results; // If we haven't found an exact match, return the best one. }
public SubtitleLetter FindMatch(SubtitleLetter l, int tolerance) { SortedList<int, SubtitleLetter> defaultFontResults, combinedResults, nextResults, userResults; //Debugger.Print(" L = " + l.Coords.Left + " / " + l.Coords.Top); if (defaultFont == null) foreach (DictionaryEntry de in fontStats) if ((int)de.Value > 10) SetDefaultFont((string)de.Key); // First, check whether the user font provides a very good match userResults = userFont.FindMatch(l, tolerance / 10); if (userResults.Count > 0) return userResults.Values[0]; // Then, check whether the default font can scan this letter if (defaultFont != null) { defaultFontResults = defaultFont.FindMatch(l, tolerance); if (defaultFontResults.Count > 0) { debugStrings.AddLast(new PositionedString(l.Coords, defaultFontResults.Keys[0].ToString())); return defaultFontResults.Values[0]; } } // Next, check the other fonts combinedResults = new SortedList<int, SubtitleLetter>(); foreach (SubtitleFont font in fonts) { if (font == defaultFont) continue; nextResults = font.FindMatch(l, tolerance); foreach (KeyValuePair<int, SubtitleLetter> kvp in nextResults) if (!combinedResults.ContainsKey(kvp.Key)) combinedResults.Add(kvp.Key, kvp.Value); if (nextResults.Count > 0) { if (fontStats[font.Name] == null) fontStats[font.Name] = 1; else fontStats[font.Name] = (int)fontStats[font.Name] + 1; } } if (combinedResults.Count > 0) { debugStrings.AddLast(new PositionedString(l.Coords, combinedResults.Keys[0].ToString())); return combinedResults.Values[0]; } // We didn't find the letter in the built-in fonts, so let's check the user provided letters if (userResults.Count > 0) return userResults.Values[0]; else return null; }
public void DeleteLetter(SubtitleLetter l2) { SubtitleLetter l = FindMatch(l2, AppOptions.similarityTolerance * 100); userFont.DeleteLetter(l); }
public void AddLetter(SubtitleLetter l) { userFont.AddLetter(l); }
private void AssignLetterText(SubtitleLetter l, string text) { // Set the text on the letter that's part of the displayed subtitle activeLetter.Text = text; // Next, check whether this letter was already known before. If yes, we have to delete that one SubtitleLetter l2 = fonts.FindMatch(l, AppOptions.similarityTolerance * 100); if (l2 != null) fonts.DeleteLetter(l2); // Add the newly identified letter to the active font //SubtitleLetter letter = currentSubtitle.ExtractLetter(activeLetter, activeLetter.Angle); if (letterInputBox.Text != "") { activeLetter.Text = text; fonts.AddLetter(activeLetter); } }
public void AddLetter(SubtitleLetter l) { changed = true; letters.AddLast(l); }
private void subtitlePictureBox_MouseClick(object sender, MouseEventArgs e) { // Check whether the click happened within the subtitle image if (subtitleImageRectangle.Contains(e.Location)) { Point pt = e.Location; pt.Offset(-subtitleImageRectangle.Left, -subtitleImageRectangle.Top); pt = new Point((int)(pt.X / bitmapScale), (int)(pt.Y / bitmapScale)); SubtitleLetter hitLetter = null; foreach (SubtitleLetter l in currentSubtitle.letters) { if (l.Coords.Contains(pt)) { hitLetter = l; break; } } if (hitLetter != null) { // The click went inside a letter, so activate it activeLetter = hitLetter; letterInputBox.Text = hitLetter.Text; letterInputBox.SelectAll(); letterInputBox.Focus(); AcceptButton = letterOKButton; ignoreItalicChanges = true; if (activeLetter.Angle != 0.0) italicLetter.Checked = true; else italicLetter.Checked = false; ignoreItalicChanges = false; UpdateBitmaps(); } else { // No letter was hit, so unselect everything activeLetter = null; letterInputBox.Text = ""; letterOKButton.Enabled = false; UpdateBitmaps(); } } }
public void AddLetter(SubtitleLetter l) { changed = true; letters.AddLast(l); }