More work on nOCR

This commit is contained in:
Nikolaj Olsson 2020-06-01 12:46:38 +02:00
parent 1d8cb732d0
commit 63c8c71e7e
7 changed files with 173 additions and 41 deletions

View File

@ -131,6 +131,7 @@ namespace Nikse.SubtitleEdit.Core
public string OcrAddLetterRow1 { get; set; }
public string OcrAddLetterRow2 { get; set; }
public string OcrTrainFonts { get; set; }
public string OcrTrainMergedLetters { get; set; }
public string OcrTrainSrtFile { get; set; }
public string Interjections { get; set; }
public string MicrosoftBingApiId { get; set; }
@ -326,6 +327,7 @@ namespace Nikse.SubtitleEdit.Core
OcrAddLetterRow1 = "♪;á;é;í;ó;ö;ő;ú;ü;ű;ç;ñ;å;¿";
OcrAddLetterRow2 = "♫;Á;É;Í;Ó;Ö;Ő;Ú;Ü;Ű;Ç;Ñ;Å;¡";
OcrTrainFonts = "Arial;Calibri;Corbel;Futura Std Book;Futura Bis;Helvetica Neue;Lucida Console;Tahoma;Trebuchet MS;Verdana";
OcrTrainMergedLetters = "ff ft fi fj fy fl rf rt rv rw ry rt ryt tt TV tw yt yw";
Interjections = "Ah;Ahem;Ahh;Ahhh;Ahhhh;Eh;Ehh;Ehhh;Hm;Hmm;Hmmm;Huh;Mm;Mmm;Mmmm;Phew;Gah;Oh;Ohh;Ohhh;Ow;Oww;Owww;Ugh;Ughh;Uh;Uhh;Uhhh;Whew";
MicrosoftTranslatorTokenEndpoint = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
GoogleApiV2KeyInfoShow = true;
@ -3253,6 +3255,12 @@ $HorzAlign = Center
settings.Tools.OcrTrainFonts = subNode.InnerText;
}
subNode = node.SelectSingleNode("OcrTrainMergedLetters");
if (subNode != null)
{
settings.Tools.OcrTrainMergedLetters = subNode.InnerText;
}
subNode = node.SelectSingleNode("OcrTrainSrtFile");
if (subNode != null)
{
@ -7141,6 +7149,7 @@ $HorzAlign = Center
textWriter.WriteElementString("OcrAddLetterRow1", settings.Tools.OcrAddLetterRow1);
textWriter.WriteElementString("OcrAddLetterRow2", settings.Tools.OcrAddLetterRow2);
textWriter.WriteElementString("OcrTrainFonts", settings.Tools.OcrTrainFonts);
textWriter.WriteElementString("OcrTrainMergedLetters", settings.Tools.OcrTrainMergedLetters);
textWriter.WriteElementString("OcrTrainSrtFile", settings.Tools.OcrTrainSrtFile);
textWriter.WriteElementString("Interjections", settings.Tools.Interjections);
textWriter.WriteElementString("MicrosoftBingApiId", settings.Tools.MicrosoftBingApiId);

View File

@ -488,6 +488,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
var idx = listBoxLinesForeground.SelectedIndex;
var op = listBoxLinesForeground.Items[idx] as NOcrPoint;
_nocrChar.LinesForeground.Remove(op);
ShowOcrPoints();
if (idx < listBoxLinesForeground.Items.Count)
{
listBoxLinesForeground.SelectedIndex = idx;
@ -497,7 +498,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
listBoxLinesForeground.SelectedIndex = listBoxLinesForeground.Items.Count - 1;
}
}
ShowOcrPoints();
}
private void removeBackToolStripMenuItem_Click(object sender, EventArgs e)
@ -507,6 +507,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
var idx = listBoxlinesBackground.SelectedIndex;
var op = listBoxlinesBackground.Items[idx] as NOcrPoint;
_nocrChar.LinesBackground.Remove(op);
ShowOcrPoints();
if (idx < listBoxlinesBackground.Items.Count)
{
listBoxlinesBackground.SelectedIndex = idx;
@ -516,7 +517,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
listBoxlinesBackground.SelectedIndex = listBoxlinesBackground.Items.Count -1;
}
}
ShowOcrPoints();
}
private void buttonImport_Click(object sender, EventArgs e)

View File

@ -47,6 +47,8 @@
this.buttonOK = new System.Windows.Forms.Button();
this.labelInfo = new System.Windows.Forms.Label();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.label2 = new System.Windows.Forms.Label();
this.textBoxMerged = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownSegmentsPerCharacter)).BeginInit();
this.groupBox2.SuspendLayout();
@ -65,9 +67,9 @@
this.groupBox1.Controls.Add(this.labelSubtitleFontSize);
this.groupBox1.Controls.Add(this.comboBoxSubtitleFontSize);
this.groupBox1.Controls.Add(this.labelSubtitleFont);
this.groupBox1.Location = new System.Drawing.Point(12, 92);
this.groupBox1.Location = new System.Drawing.Point(12, 153);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(493, 504);
this.groupBox1.Size = new System.Drawing.Size(493, 443);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Training options";
@ -78,7 +80,7 @@
this.checkBoxBold.AutoSize = true;
this.checkBoxBold.Checked = true;
this.checkBoxBold.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxBold.Location = new System.Drawing.Point(9, 481);
this.checkBoxBold.Location = new System.Drawing.Point(9, 420);
this.checkBoxBold.Name = "checkBoxBold";
this.checkBoxBold.Size = new System.Drawing.Size(92, 17);
this.checkBoxBold.TabIndex = 17;
@ -97,7 +99,7 @@
this.listViewFonts.HideSelection = false;
this.listViewFonts.Location = new System.Drawing.Point(9, 47);
this.listViewFonts.Name = "listViewFonts";
this.listViewFonts.Size = new System.Drawing.Size(469, 331);
this.listViewFonts.Size = new System.Drawing.Size(469, 270);
this.listViewFonts.TabIndex = 16;
this.listViewFonts.UseCompatibleStateImageBehavior = false;
this.listViewFonts.View = System.Windows.Forms.View.Details;
@ -111,7 +113,7 @@
//
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(6, 453);
this.label3.Location = new System.Drawing.Point(6, 392);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(189, 13);
this.label3.TabIndex = 16;
@ -120,7 +122,7 @@
// numericUpDownSegmentsPerCharacter
//
this.numericUpDownSegmentsPerCharacter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.numericUpDownSegmentsPerCharacter.Location = new System.Drawing.Point(264, 451);
this.numericUpDownSegmentsPerCharacter.Location = new System.Drawing.Point(264, 390);
this.numericUpDownSegmentsPerCharacter.Maximum = new decimal(new int[] {
250,
0,
@ -144,7 +146,7 @@
//
this.checkBoxVeryAccurate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkBoxVeryAccurate.AutoSize = true;
this.checkBoxVeryAccurate.Location = new System.Drawing.Point(9, 428);
this.checkBoxVeryAccurate.Location = new System.Drawing.Point(9, 367);
this.checkBoxVeryAccurate.Name = "checkBoxVeryAccurate";
this.checkBoxVeryAccurate.Size = new System.Drawing.Size(303, 17);
this.checkBoxVeryAccurate.TabIndex = 14;
@ -155,7 +157,7 @@
//
this.labelSubtitleFontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelSubtitleFontSize.AutoSize = true;
this.labelSubtitleFontSize.Location = new System.Drawing.Point(5, 395);
this.labelSubtitleFontSize.Location = new System.Drawing.Point(5, 334);
this.labelSubtitleFontSize.Name = "labelSubtitleFontSize";
this.labelSubtitleFontSize.Size = new System.Drawing.Size(84, 13);
this.labelSubtitleFontSize.TabIndex = 6;
@ -258,7 +260,7 @@
"130",
"140",
"150"});
this.comboBoxSubtitleFontSize.Location = new System.Drawing.Point(110, 392);
this.comboBoxSubtitleFontSize.Location = new System.Drawing.Point(110, 331);
this.comboBoxSubtitleFontSize.Name = "comboBoxSubtitleFontSize";
this.comboBoxSubtitleFontSize.Size = new System.Drawing.Size(121, 21);
this.comboBoxSubtitleFontSize.TabIndex = 7;
@ -301,12 +303,14 @@
//
// groupBox2
//
this.groupBox2.Controls.Add(this.label2);
this.groupBox2.Controls.Add(this.textBoxMerged);
this.groupBox2.Controls.Add(this.buttonInputChoose);
this.groupBox2.Controls.Add(this.label1);
this.groupBox2.Controls.Add(this.textBoxInputFile);
this.groupBox2.Location = new System.Drawing.Point(12, 13);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(493, 73);
this.groupBox2.Size = new System.Drawing.Size(493, 134);
this.groupBox2.TabIndex = 14;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Input file";
@ -348,6 +352,23 @@
this.labelInfo.TabIndex = 19;
this.labelInfo.Text = "labelInfo";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 82);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(201, 13);
this.label2.TabIndex = 11;
this.label2.Text = "Letter combinations that might be merged";
//
// textBoxMerged
//
this.textBoxMerged.Location = new System.Drawing.Point(9, 98);
this.textBoxMerged.Name = "textBoxMerged";
this.textBoxMerged.Size = new System.Drawing.Size(469, 20);
this.textBoxMerged.TabIndex = 12;
this.textBoxMerged.Text = "ff ft fi fj fy fl rf rt rv rw ry rt ryt tt TV tw yt yw";
//
// VobSubNOcrTrain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -397,5 +418,7 @@
private System.Windows.Forms.Label labelInfo;
private System.Windows.Forms.CheckBox checkBoxBold;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBoxMerged;
}
}

View File

@ -31,6 +31,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
UiUtil.FixFonts(this);
labelInfo.Text = string.Empty;
textBoxMerged.Text = Configuration.Settings.Tools.OcrTrainMergedLetters;
var selectedFonts = Configuration.Settings.Tools.OcrTrainFonts.Split(';');
foreach (var x in FontFamily.Families)
{
@ -109,10 +110,10 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
var s = ch.ToString();
if (!charactersLearned.Contains(s))
{
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, s, false);
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, s, false, false);
if (checkBoxBold.Checked)
{
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, s, true);
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, s, true, false);
}
}
}
@ -124,6 +125,21 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
}
foreach (var text in textBoxMerged.Text.Split(' '))
{
if (!string.IsNullOrWhiteSpace(text))
{
if (!charactersLearned.Contains(text) && text.Length > 1 && text.Length <= 3)
{
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, text, false, true);
if (checkBoxBold.Checked)
{
TrainLetter(ref numberOfCharactersLeaned, ref numberOfCharactersSkipped, nOcrD, charactersLearned, text, true,true);
}
}
}
}
if (_abort)
{
break;
@ -152,7 +168,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
_abort = false;
}
private void TrainLetter(ref int numberOfCharactersLeaned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, List<string> charactersLearned, string s, bool bold)
private void TrainLetter(ref int numberOfCharactersLeaned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, List<string> charactersLearned, string s, bool bold, bool doubleLetter)
{
Bitmap bmp = GenerateImageFromTextWithStyle("H " + s, bold);
var nikseBitmap = new NikseBitmap(bmp);
@ -186,7 +202,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
numberOfCharactersSkipped++;
}
}
else
else if (!doubleLetter)
{
if (list.Count == 4)
@ -360,6 +376,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
Configuration.Settings.Tools.OcrTrainFonts = sb.ToString().Trim(';');
Configuration.Settings.Tools.OcrTrainSrtFile = textBoxInputFile.Text;
Configuration.Settings.Tools.OcrTrainMergedLetters = textBoxMerged.Text;
}
}
}

View File

@ -152,6 +152,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
this.textBoxCurrentText = new Nikse.SubtitleEdit.Controls.SETextBox();
this.subtitleListView1 = new Nikse.SubtitleEdit.Controls.SubtitleListView();
this.timerHideStatus = new System.Windows.Forms.Timer(this.components);
this.label3 = new System.Windows.Forms.Label();
this.comboBoxNOcrLineSplitMinHeight = new System.Windows.Forms.ComboBox();
this.contextMenuStripListview.SuspendLayout();
this.groupBoxOcrMethod.SuspendLayout();
this.groupBoxNOCR.SuspendLayout();
@ -470,6 +472,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
//
// groupBoxNOCR
//
this.groupBoxNOCR.Controls.Add(this.label3);
this.groupBoxNOCR.Controls.Add(this.comboBoxNOcrLineSplitMinHeight);
this.groupBoxNOCR.Controls.Add(this.numericUpDownNOcrMaxWrongPixels);
this.groupBoxNOCR.Controls.Add(this.labelNOcrMaxWrongPixels);
this.groupBoxNOCR.Controls.Add(this.buttonLineOcrEditLanguage);
@ -516,7 +520,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
//
// buttonLineOcrEditLanguage
//
this.buttonLineOcrEditLanguage.Location = new System.Drawing.Point(210, 97);
this.buttonLineOcrEditLanguage.Location = new System.Drawing.Point(210, 100);
this.buttonLineOcrEditLanguage.Name = "buttonLineOcrEditLanguage";
this.buttonLineOcrEditLanguage.Size = new System.Drawing.Size(68, 23);
this.buttonLineOcrEditLanguage.TabIndex = 41;
@ -526,7 +530,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
//
// buttonLineOcrNewLanguage
//
this.buttonLineOcrNewLanguage.Location = new System.Drawing.Point(283, 97);
this.buttonLineOcrNewLanguage.Location = new System.Drawing.Point(283, 100);
this.buttonLineOcrNewLanguage.Name = "buttonLineOcrNewLanguage";
this.buttonLineOcrNewLanguage.Size = new System.Drawing.Size(68, 23);
this.buttonLineOcrNewLanguage.TabIndex = 40;
@ -537,7 +541,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(11, 101);
this.label2.Location = new System.Drawing.Point(11, 104);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(54, 13);
this.label2.TabIndex = 35;
@ -547,7 +551,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
//
this.comboBoxNOcrLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxNOcrLanguage.FormattingEnabled = true;
this.comboBoxNOcrLanguage.Location = new System.Drawing.Point(74, 97);
this.comboBoxNOcrLanguage.Location = new System.Drawing.Point(74, 100);
this.comboBoxNOcrLanguage.Name = "comboBoxNOcrLanguage";
this.comboBoxNOcrLanguage.Size = new System.Drawing.Size(130, 21);
this.comboBoxNOcrLanguage.TabIndex = 34;
@ -556,7 +560,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
// checkBoxNOcrItalic
//
this.checkBoxNOcrItalic.AutoSize = true;
this.checkBoxNOcrItalic.Location = new System.Drawing.Point(12, 67);
this.checkBoxNOcrItalic.Location = new System.Drawing.Point(12, 69);
this.checkBoxNOcrItalic.Name = "checkBoxNOcrItalic";
this.checkBoxNOcrItalic.Size = new System.Drawing.Size(92, 17);
this.checkBoxNOcrItalic.TabIndex = 8;
@ -1701,6 +1705,97 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
this.timerHideStatus.Interval = 2000;
this.timerHideStatus.Tick += new System.EventHandler(this.timerHideStatus_Tick);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(137, 77);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(104, 13);
this.label3.TabIndex = 49;
this.label3.Text = "Line split min. height";
this.label3.Visible = false;
//
// comboBoxNOcrLineSplitMinHeight
//
this.comboBoxNOcrLineSplitMinHeight.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxNOcrLineSplitMinHeight.FormattingEnabled = true;
this.comboBoxNOcrLineSplitMinHeight.Items.AddRange(new object[] {
"Auto",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"40",
"41",
"42",
"43",
"44",
"45",
"46",
"47",
"48",
"49",
"50",
"51",
"52",
"53",
"54",
"55",
"56",
"57",
"58",
"59",
"60",
"65",
"70",
"75",
"80",
"85",
"90",
"95",
"100",
"110",
"120",
"130",
"140",
"150"});
this.comboBoxNOcrLineSplitMinHeight.Location = new System.Drawing.Point(247, 74);
this.comboBoxNOcrLineSplitMinHeight.Name = "comboBoxNOcrLineSplitMinHeight";
this.comboBoxNOcrLineSplitMinHeight.Size = new System.Drawing.Size(103, 21);
this.comboBoxNOcrLineSplitMinHeight.TabIndex = 48;
this.comboBoxNOcrLineSplitMinHeight.Visible = false;
//
// VobSubOcr
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1910,5 +2005,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private System.Windows.Forms.NumericUpDown numericUpDownNOcrMaxWrongPixels;
private System.Windows.Forms.Label labelNOcrMaxWrongPixels;
private System.Windows.Forms.Button buttonChooseEditBinaryImageCompareDb;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox comboBoxNOcrLineSplitMinHeight;
}
}

View File

@ -2688,6 +2688,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
/// </summary>
private void FixUppercaseLowercaseIssues(ImageSplitterItem targetItem, NOcrChar result)
{
var uppercaseWithAccent = "ÉČĘĖŠŽÜÅÄÖĄŚŻŚ";
var lowercaseWithAccent = "éčęėšžüåäöąśżś";
if (result.Text == "e" || result.Text == "a" || result.Text == "d" || result.Text == "t")
{
@ -2740,8 +2742,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
}
// Polish
else if (result.Text == "Ć" || result.Text == "Ź" || result.Text == "Ż" || result.Text == "Ą" || result.Text == "Ó" || result.Text == "Ś")
// Letters with accents
else if (uppercaseWithAccent.Contains(result.Text))
{
if (_binOcrLowercaseHeightsTotalCount > 2 && _binOcrUppercaseHeightsTotalCount > 2)
{
@ -2753,7 +2755,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
}
}
else if (result.Text == "ć" || result.Text == "ź" || result.Text == "ż" || result.Text == "ą" || result.Text == "ó" || result.Text == "ś")
else if (lowercaseWithAccent.Contains(result.Text))
{
if (_binOcrLowercaseHeightsTotalCount > 2 && _binOcrUppercaseHeightsTotalCount > 2)
{
@ -2787,7 +2789,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
unItalicNikseBitmap.ReplaceColor(255, 0, 0, 0, 0, 0, 0, 0);
unItalicNikseBitmap.MakeTwoColor(200);
var oldBmp = unItalicNikseBitmap.GetBitmap();
var unItalicImage = UnItalic(oldBmp, _unItalicFactor); //TODO: make unitalic in NikseBitmap
var unItalicImage = UnItalic(oldBmp, _unItalicFactor); //TODO: make un-italic in NikseBitmap
unItalicNikseBitmap = new NikseBitmap(unItalicImage);
unItalicNikseBitmap.CropTransparentSidesAndBottom(0, false);
oldBmp.Dispose();
@ -3979,7 +3981,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (string.IsNullOrEmpty(line))
{
int minLineHeight = GetLastBinOcrLowercaseHeight() - 3;
if (minLineHeight < 5)
{

View File

@ -355,21 +355,6 @@ namespace Nikse.SubtitleEdit.Logic.Ocr
}
}
if (italic)
{
foreach (var oc in OcrCharacters)
{
if (Math.Abs(widthPercent - oc.WidthPercent) < 60 && Math.Abs(oc.MarginTop - topMargin) < 17 && oc.LinesForeground.Count + oc.LinesBackground.Count > 50)
{
var italicOc = MakeItalicNOcrChar(oc, 0, italicAngle);
if (IsMatch(bitmap, italicOc, 25))
{
return italicOc;
}
}
}
}
if (deepSeek)
{
foreach (var oc in OcrCharacters)